Skip to content

setuptools → flit#409

Merged
astanin merged 1 commit into
astanin:masterfrom
DimitriPapadopoulos:flit
Mar 5, 2026
Merged

setuptools → flit#409
astanin merged 1 commit into
astanin:masterfrom
DimitriPapadopoulos:flit

Conversation

@DimitriPapadopoulos
Copy link
Copy Markdown
Contributor

@DimitriPapadopoulos DimitriPapadopoulos commented Mar 5, 2026

There's no question that setuptools works. However, it strives to remain compatible with projects published many years ago, which increases complexity and limits what it can do by default. For pure Python packages, flit is a good modern alternative.

See:

Also:

  • Write package version to _version.py instead of version.py.
  • Get rid of the README symlink, README.md is good enough nowadays.
  • I have deliberately removed from the sdist: hidden files, HOWTOPUBLISH and benchmark.

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Mar 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.17%. Comparing base (3fcf88e) to head (3e70a32).
⚠️ Report is 39 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #409   +/-   ##
=======================================
  Coverage   84.17%   84.17%           
=======================================
  Files           1        1           
  Lines         891      891           
  Branches      217      217           
=======================================
  Hits          750      750           
  Misses        107      107           
  Partials       34       34           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@DimitriPapadopoulos
Copy link
Copy Markdown
Contributor Author

DimitriPapadopoulos commented Mar 5, 2026

Comparison of resulting distributions:

$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
$ python -m build
* Creating virtualenv isolated environment...
* Installing packages in isolated environment... (setuptools>=77.0.3, setuptools_scm[toml]>=3.4.3)
* Getting build dependencies for sdist...
running egg_info
creating tabulate.egg-info
writing tabulate.egg-info/PKG-INFO
writing dependency_links to tabulate.egg-info/dependency_links.txt
writing entry points to tabulate.egg-info/entry_points.txt
writing requirements to tabulate.egg-info/requires.txt
writing top-level names to tabulate.egg-info/top_level.txt
writing manifest file 'tabulate.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no files found matching 'benchmark.py'
adding license file 'LICENSE'
writing manifest file 'tabulate.egg-info/SOURCES.txt'
* Building sdist...
running sdist
running egg_info
writing tabulate.egg-info/PKG-INFO
writing dependency_links to tabulate.egg-info/dependency_links.txt
writing entry points to tabulate.egg-info/entry_points.txt
writing requirements to tabulate.egg-info/requires.txt
writing top-level names to tabulate.egg-info/top_level.txt
reading manifest template 'MANIFEST.in'
warning: no files found matching 'benchmark.py'
adding license file 'LICENSE'
writing manifest file 'tabulate.egg-info/SOURCES.txt'
running check
creating tabulate-0.10.1.dev30+gc26c2ef3f
creating tabulate-0.10.1.dev30+gc26c2ef3f/.github/workflows
creating tabulate-0.10.1.dev30+gc26c2ef3f/benchmark
creating tabulate-0.10.1.dev30+gc26c2ef3f/tabulate
creating tabulate-0.10.1.dev30+gc26c2ef3f/tabulate.egg-info
creating tabulate-0.10.1.dev30+gc26c2ef3f/test
copying files to tabulate-0.10.1.dev30+gc26c2ef3f...
copying .gitignore -> tabulate-0.10.1.dev30+gc26c2ef3f
copying .pre-commit-config.yaml -> tabulate-0.10.1.dev30+gc26c2ef3f
copying CHANGELOG -> tabulate-0.10.1.dev30+gc26c2ef3f
copying HOWTOPUBLISH -> tabulate-0.10.1.dev30+gc26c2ef3f
copying LICENSE -> tabulate-0.10.1.dev30+gc26c2ef3f
copying MANIFEST.in -> tabulate-0.10.1.dev30+gc26c2ef3f
copying README -> tabulate-0.10.1.dev30+gc26c2ef3f
copying README.md -> tabulate-0.10.1.dev30+gc26c2ef3f
copying pyproject.toml -> tabulate-0.10.1.dev30+gc26c2ef3f
copying tox.ini -> tabulate-0.10.1.dev30+gc26c2ef3f
copying .github/workflows/lint.yml -> tabulate-0.10.1.dev30+gc26c2ef3f/.github/workflows
copying .github/workflows/tabulate.yml -> tabulate-0.10.1.dev30+gc26c2ef3f/.github/workflows
copying benchmark/benchmark.py -> tabulate-0.10.1.dev30+gc26c2ef3f/benchmark
copying benchmark/requirements.txt -> tabulate-0.10.1.dev30+gc26c2ef3f/benchmark
copying tabulate/__init__.py -> tabulate-0.10.1.dev30+gc26c2ef3f/tabulate
copying tabulate.egg-info/PKG-INFO -> tabulate-0.10.1.dev30+gc26c2ef3f/tabulate.egg-info
copying tabulate.egg-info/SOURCES.txt -> tabulate-0.10.1.dev30+gc26c2ef3f/tabulate.egg-info
copying tabulate.egg-info/dependency_links.txt -> tabulate-0.10.1.dev30+gc26c2ef3f/tabulate.egg-info
copying tabulate.egg-info/entry_points.txt -> tabulate-0.10.1.dev30+gc26c2ef3f/tabulate.egg-info
copying tabulate.egg-info/requires.txt -> tabulate-0.10.1.dev30+gc26c2ef3f/tabulate.egg-info
copying tabulate.egg-info/top_level.txt -> tabulate-0.10.1.dev30+gc26c2ef3f/tabulate.egg-info
copying test/common.py -> tabulate-0.10.1.dev30+gc26c2ef3f/test
copying test/test_api.py -> tabulate-0.10.1.dev30+gc26c2ef3f/test
copying test/test_cli.py -> tabulate-0.10.1.dev30+gc26c2ef3f/test
copying test/test_grapheme_clusters.py -> tabulate-0.10.1.dev30+gc26c2ef3f/test
copying test/test_input.py -> tabulate-0.10.1.dev30+gc26c2ef3f/test
copying test/test_internal.py -> tabulate-0.10.1.dev30+gc26c2ef3f/test
copying test/test_output.py -> tabulate-0.10.1.dev30+gc26c2ef3f/test
copying test/test_regression.py -> tabulate-0.10.1.dev30+gc26c2ef3f/test
copying test/test_textwrapper.py -> tabulate-0.10.1.dev30+gc26c2ef3f/test
copying tabulate.egg-info/SOURCES.txt -> tabulate-0.10.1.dev30+gc26c2ef3f/tabulate.egg-info
Writing tabulate-0.10.1.dev30+gc26c2ef3f/setup.cfg
Creating tar archive
removing 'tabulate-0.10.1.dev30+gc26c2ef3f' (and everything under it)
* Building wheel from sdist
* Creating virtualenv isolated environment...
* Installing packages in isolated environment... (setuptools>=77.0.3, setuptools_scm[toml]>=3.4.3)
* Getting build dependencies for wheel...
running egg_info
writing tabulate.egg-info/PKG-INFO
writing dependency_links to tabulate.egg-info/dependency_links.txt
writing entry points to tabulate.egg-info/entry_points.txt
writing requirements to tabulate.egg-info/requires.txt
writing top-level names to tabulate.egg-info/top_level.txt
listing git files failed - pretending there aren't any
reading manifest file 'tabulate.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no files found matching 'benchmark.py'
adding license file 'LICENSE'
writing manifest file 'tabulate.egg-info/SOURCES.txt'
* Building wheel...
running bdist_wheel
running build
running build_py
creating build/lib/tabulate
copying tabulate/__init__.py -> build/lib/tabulate
running egg_info
writing tabulate.egg-info/PKG-INFO
writing dependency_links to tabulate.egg-info/dependency_links.txt
writing entry points to tabulate.egg-info/entry_points.txt
writing requirements to tabulate.egg-info/requires.txt
writing top-level names to tabulate.egg-info/top_level.txt
listing git files failed - pretending there aren't any
reading manifest file 'tabulate.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no files found matching 'benchmark.py'
adding license file 'LICENSE'
writing manifest file 'tabulate.egg-info/SOURCES.txt'
installing to build/bdist.linux-x86_64/wheel
running install
running install_lib
creating build/bdist.linux-x86_64/wheel
creating build/bdist.linux-x86_64/wheel/tabulate
copying build/lib/tabulate/__init__.py -> build/bdist.linux-x86_64/wheel/./tabulate
running install_egg_info
Copying tabulate.egg-info to build/bdist.linux-x86_64/wheel/./tabulate-0.10.1.dev30+gc26c2ef3f-py3.12.egg-info
running install_scripts
creating build/bdist.linux-x86_64/wheel/tabulate-0.10.1.dev30+gc26c2ef3f.dist-info/WHEEL
creating '/path/to/python-tabulate/dist/.tmp-vk5flu0k/tabulate-0.10.1.dev30+gc26c2ef3f-py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it
adding 'tabulate/__init__.py'
adding 'tabulate-0.10.1.dev30+gc26c2ef3f.dist-info/licenses/LICENSE'
adding 'tabulate-0.10.1.dev30+gc26c2ef3f.dist-info/METADATA'
adding 'tabulate-0.10.1.dev30+gc26c2ef3f.dist-info/WHEEL'
adding 'tabulate-0.10.1.dev30+gc26c2ef3f.dist-info/entry_points.txt'
adding 'tabulate-0.10.1.dev30+gc26c2ef3f.dist-info/top_level.txt'
adding 'tabulate-0.10.1.dev30+gc26c2ef3f.dist-info/RECORD'
removing build/bdist.linux-x86_64/wheel
Successfully built tabulate-0.10.1.dev30+gc26c2ef3f.tar.gz and tabulate-0.10.1.dev30+gc26c2ef3f-py3-none-any.whl
$ 
$ mv dist dist.setuptools
$ 
$ git checkout flit
Switched to branch 'flit'
Your branch is up to date with 'origin/flit'.
$ python -m build
* Creating virtualenv isolated environment...
* Installing packages in isolated environment... (flit>=3.12, flit_scm)
* Getting build dependencies for sdist...
* Building sdist...
* Building wheel from sdist
* Creating virtualenv isolated environment...
* Installing packages in isolated environment... (flit>=3.12, flit_scm)
* Getting build dependencies for wheel...
* Building wheel...
Successfully built tabulate-0.10.1.dev31+g09e71516e.tar.gz and tabulate-0.10.1.dev31+g09e71516e-py3-none-any.whl
$ 
$ mv dist dist.flit
$ 
$ 
$ tar tf dist.setuptools/tabulate-0.10.1.dev30+gc26c2ef3f.tar.gz 
tabulate-0.10.1.dev30+gc26c2ef3f/
tabulate-0.10.1.dev30+gc26c2ef3f/.github/
tabulate-0.10.1.dev30+gc26c2ef3f/.github/workflows/
tabulate-0.10.1.dev30+gc26c2ef3f/.github/workflows/lint.yml
tabulate-0.10.1.dev30+gc26c2ef3f/.github/workflows/tabulate.yml
tabulate-0.10.1.dev30+gc26c2ef3f/.gitignore
tabulate-0.10.1.dev30+gc26c2ef3f/.pre-commit-config.yaml
tabulate-0.10.1.dev30+gc26c2ef3f/CHANGELOG
tabulate-0.10.1.dev30+gc26c2ef3f/HOWTOPUBLISH
tabulate-0.10.1.dev30+gc26c2ef3f/LICENSE
tabulate-0.10.1.dev30+gc26c2ef3f/MANIFEST.in
tabulate-0.10.1.dev30+gc26c2ef3f/PKG-INFO
tabulate-0.10.1.dev30+gc26c2ef3f/README
tabulate-0.10.1.dev30+gc26c2ef3f/README.md
tabulate-0.10.1.dev30+gc26c2ef3f/benchmark/
tabulate-0.10.1.dev30+gc26c2ef3f/benchmark/benchmark.py
tabulate-0.10.1.dev30+gc26c2ef3f/benchmark/requirements.txt
tabulate-0.10.1.dev30+gc26c2ef3f/pyproject.toml
tabulate-0.10.1.dev30+gc26c2ef3f/setup.cfg
tabulate-0.10.1.dev30+gc26c2ef3f/tabulate/
tabulate-0.10.1.dev30+gc26c2ef3f/tabulate/__init__.py
tabulate-0.10.1.dev30+gc26c2ef3f/tabulate.egg-info/
tabulate-0.10.1.dev30+gc26c2ef3f/tabulate.egg-info/PKG-INFO
tabulate-0.10.1.dev30+gc26c2ef3f/tabulate.egg-info/SOURCES.txt
tabulate-0.10.1.dev30+gc26c2ef3f/tabulate.egg-info/dependency_links.txt
tabulate-0.10.1.dev30+gc26c2ef3f/tabulate.egg-info/entry_points.txt
tabulate-0.10.1.dev30+gc26c2ef3f/tabulate.egg-info/requires.txt
tabulate-0.10.1.dev30+gc26c2ef3f/tabulate.egg-info/top_level.txt
tabulate-0.10.1.dev30+gc26c2ef3f/test/
tabulate-0.10.1.dev30+gc26c2ef3f/test/common.py
tabulate-0.10.1.dev30+gc26c2ef3f/test/test_api.py
tabulate-0.10.1.dev30+gc26c2ef3f/test/test_cli.py
tabulate-0.10.1.dev30+gc26c2ef3f/test/test_grapheme_clusters.py
tabulate-0.10.1.dev30+gc26c2ef3f/test/test_input.py
tabulate-0.10.1.dev30+gc26c2ef3f/test/test_internal.py
tabulate-0.10.1.dev30+gc26c2ef3f/test/test_output.py
tabulate-0.10.1.dev30+gc26c2ef3f/test/test_regression.py
tabulate-0.10.1.dev30+gc26c2ef3f/test/test_textwrapper.py
tabulate-0.10.1.dev30+gc26c2ef3f/tox.ini
$ 
$ tar tf dist.flit/tabulate-0.10.1.dev31+g09e71516e.tar.gz       
tabulate-0.10.1.dev31+g09e71516e/CHANGELOG
tabulate-0.10.1.dev31+g09e71516e/LICENSE
tabulate-0.10.1.dev31+g09e71516e/README.md
tabulate-0.10.1.dev31+g09e71516e/pyproject.toml
tabulate-0.10.1.dev31+g09e71516e/tabulate/__init__.py
tabulate-0.10.1.dev31+g09e71516e/test/common.py
tabulate-0.10.1.dev31+g09e71516e/test/test_api.py
tabulate-0.10.1.dev31+g09e71516e/test/test_cli.py
tabulate-0.10.1.dev31+g09e71516e/test/test_grapheme_clusters.py
tabulate-0.10.1.dev31+g09e71516e/test/test_input.py
tabulate-0.10.1.dev31+g09e71516e/test/test_internal.py
tabulate-0.10.1.dev31+g09e71516e/test/test_output.py
tabulate-0.10.1.dev31+g09e71516e/test/test_regression.py
tabulate-0.10.1.dev31+g09e71516e/test/test_textwrapper.py
tabulate-0.10.1.dev31+g09e71516e/tox.ini
tabulate-0.10.1.dev31+g09e71516e/PKG-INFO
$ 
$ 
$ unzip -l dist.setuptools/tabulate-0.10.1.dev30+gc26c2ef3f-py3-none-any.whl 
Archive:  dist.setuptools/tabulate-0.10.1.dev30+gc26c2ef3f-py3-none-any.whl
  Length      Date    Time    Name
---------  ---------- -----   ----
   107853  2026-03-05 12:33   tabulate/__init__.py
     1080  2026-03-05 12:33   tabulate-0.10.1.dev30+gc26c2ef3f.dist-info/licenses/LICENSE
    39793  2026-03-05 12:33   tabulate-0.10.1.dev30+gc26c2ef3f.dist-info/METADATA
       91  2026-03-05 12:33   tabulate-0.10.1.dev30+gc26c2ef3f.dist-info/WHEEL
       44  2026-03-05 12:33   tabulate-0.10.1.dev30+gc26c2ef3f.dist-info/entry_points.txt
        9  2026-03-05 12:33   tabulate-0.10.1.dev30+gc26c2ef3f.dist-info/top_level.txt
      683  2026-03-05 12:33   tabulate-0.10.1.dev30+gc26c2ef3f.dist-info/RECORD
---------                     -------
   149553                     7 files
$ 
$ unzip -l dist.flit/tabulate-0.10.1.dev31+g09e71516e-py3-none-any.whl       
Archive:  dist.flit/tabulate-0.10.1.dev31+g09e71516e-py3-none-any.whl
  Length      Date    Time    Name
---------  ---------- -----   ----
   107854  2026-03-05 13:33   tabulate/__init__.py
      746  2026-03-05 13:34   tabulate/_version.py
       43  2016-01-01 00:00   tabulate-0.10.1.dev31+g09e71516e.dist-info/entry_points.txt
     1080  2026-03-05 09:01   tabulate-0.10.1.dev31+g09e71516e.dist-info/licenses/LICENSE
       82  2016-01-01 00:00   tabulate-0.10.1.dev31+g09e71516e.dist-info/WHEEL
    39773  2016-01-01 00:00   tabulate-0.10.1.dev31+g09e71516e.dist-info/METADATA
      649  2016-01-01 00:00   tabulate-0.10.1.dev31+g09e71516e.dist-info/RECORD
---------                     -------
   150227                     7 files
$ 

@DimitriPapadopoulos DimitriPapadopoulos force-pushed the flit branch 3 times, most recently from 375d9c6 to c093e2a Compare March 5, 2026 12:07
@DimitriPapadopoulos DimitriPapadopoulos marked this pull request as draft March 5, 2026 12:09
@DimitriPapadopoulos DimitriPapadopoulos force-pushed the flit branch 2 times, most recently from 8333f2e to 73ebca6 Compare March 5, 2026 12:15
@astanin
Copy link
Copy Markdown
Owner

astanin commented Mar 5, 2026

I approve cleanup of the source dist.

Not sold on flit yet. It may be harder to find docs and help how to do something with it.

I also regularly use "pip install -e .". Is it supported in flit?

@DimitriPapadopoulos DimitriPapadopoulos force-pushed the flit branch 2 times, most recently from e24c13e to 09e7151 Compare March 5, 2026 12:33
Also:
- Write package version to `_version.py` instead of `version.py`.
- Get rid of the `README` symlink, `README.md` is good enough nowadays.
- I have deliberately removed from the sdist: hidden files, `HOWTOPUBLISH` and `benchmark`.
@DimitriPapadopoulos
Copy link
Copy Markdown
Contributor Author

DimitriPapadopoulos commented Mar 5, 2026

I think any build backend supports pip (and this means pip install -e . too):

$ python -m venv /path/to/venv_tabulate
$ . /path/to/venv_tabulate/bin/activate
(venv_tabulate) $ 
(venv_tabulate) $ 
(venv_tabulate) $ pip list
Package Version
------- -------
pip     24.0
(venv_tabulate) $ 
(venv_tabulate) $ 
(venv_tabulate) $ pip install -e .
Obtaining file:///path/to/python-tabulate
  Installing build dependencies ... done
  Checking if build backend supports build_editable ... done
  Getting requirements to build editable ... done
  Preparing editable metadata (pyproject.toml) ... done
Building wheels for collected packages: tabulate
  Building editable for tabulate (pyproject.toml) ... done
  Created wheel for tabulate: filename=tabulate-0.10.1.dev41+g3e70a32c9-py3-none-any.whl size=14421 sha256=0122ec2c8fc02709b081d9668c11811330a36b90288942f33b621423b564d9ff
  Stored in directory: /tmp/pip-ephem-wheel-cache-1fw_9tx0/wheels/5d/c1/03/0141158fb481a647afa90077f484896ec880720bc41bfa8c54
Successfully built tabulate
Installing collected packages: tabulate
Successfully installed tabulate-0.10.1.dev41+g3e70a32c9
(venv_tabulate) $ 
(venv_tabulate) $ 
(venv_tabulate) $ pip list
Package  Version                 Editable project location
-------- ----------------------- -----------------------------
pip      24.0
tabulate 0.10.1.dev41+g3e70a32c9 /path/to/python-tabulate
(venv_tabulate) $ 
(venv_tabulate) $ 
(venv_tabulate) $ pip uninstall tabulate
Found existing installation: tabulate 0.10.1.dev41+g3e70a32c9
Uninstalling tabulate-0.10.1.dev41+g3e70a32c9:
  Would remove:
    /path/to/venv_tabulate/bin/tabulate
    /path/to/venv_tabulate/lib/python3.12/site-packages/tabulate-0.10.1.dev41+g3e70a32c9.dist-info/*
    /path/to/venv_tabulate/lib/python3.12/site-packages/tabulate.pth
Proceed (Y/n)? y
  Successfully uninstalled tabulate-0.10.1.dev41+g3e70a32c9
(venv_tabulate) $ 
(venv_tabulate) $ 
(venv_tabulate) $ pip list
Package Version
------- -------
pip     24.0
(venv_tabulate) $ 

Whatever the backend, pip used it to build. Note that the backend must support editable builds:

  Checking if build backend supports build_editable ... done

@DimitriPapadopoulos
Copy link
Copy Markdown
Contributor Author

DimitriPapadopoulos commented Mar 5, 2026

Because flit is much simpler, you'll have to resort to Stack Overflow and the like less often than with setuptools. The official documentation is straightforward and mostly sufficient. With that said, you will find online resources to help with flit.

Note that flit is much faster.

@DimitriPapadopoulos DimitriPapadopoulos marked this pull request as ready for review March 5, 2026 13:22
@astanin astanin merged commit 6050bef into astanin:master Mar 5, 2026
19 checks passed
@astanin
Copy link
Copy Markdown
Owner

astanin commented Mar 5, 2026

OK, let's give it a try.

@DimitriPapadopoulos DimitriPapadopoulos deleted the flit branch March 5, 2026 13:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants