> My build step is then just python3 -m build. This populates the dist/ directory with everything needed to install and run the project on a server.
> ...
> Just python, pip, rsync, and systemd are enough to build and deploy a production ready python service.

It should be noted here that, while it's a small, semi-standard tool under the PyPA umbrella, `build` is not part of the standard library. It must be installed separately, and thus should have been listed as one of the tools used. (On the other hand, I don't really see what any of this has to do with systemd; it can equally well be made to work on Windows or on non-systemd Linux distros.)

> First of all, I have nothing against Poetry, uv, pdm, and others. I just prefer not to learn more tools, more configurations, and use only standardized built-in tools wherever possible. So as a result, I use setuptools only.

`setuptools` has the advantage of preferential treatment within the ecosystem (e.g., at least transitionally, a `[build-system]` table like the one shown could be omitted completely, as Setuptools would be assumed by default; and virtual environments used to bootstrap Setuptools as well as Pip by default.

However, with current versions of Pip (and Python, thus venv from the standard library), as well as with `build`, the default behaviour is to create an "isolated environment" for building (even, AFAIK, if the project is already containerized - how would the tools know, after all?). This entails creating a new venv and installing Setuptools therein - using Pip to find the latest version (subject to any version constraints specified in pyproject.toml) on PyPI. In theory, packages that Pip downloads from PyPI are cached; but even when Setuptools hasn't released a new version since the last build, any number of things could defeat that caching scheme.

This is important because, while Setuptools works and it succeeds in making the simple cases simple (including with the new pyproject.toml-powered approach), it's a massive boat-anchor for most projects that use it. The wheel size approaches 1MB for a possibly-transient download used just to "build" your project - which in most cases doesn't even involve a compilation step (actually telling Setuptools to run compilers requires a separate setup.py file, even with pyproject.toml) but just moves some files around and creates a zip archive - and which in most cases is itself quite a bit smaller. It got to this size, effectively, by starting its life as a decades-old attempt at a full project management toolchain, and then collapsing under the weight of deprecations and backwards-compatibility hacks (including, now, the need to vendor `distutils` since that was removed from the standard library in 3.12).

Notably, originally setup.py was intended to be run directly chosen by the user, but now Setuptools does magic to spawn a new process (IIRC), run it with very specific arguments and collect the results somehow. Meanwhile, even the most conservative attempts to remove old deprecated functionality (such as the ability to run `setup.py test` manually, even though it has nothing to do with the modern Setuptools workflow and everyone uses Pytest and invokes that directly nowadays) have caused huge breakages in the ecosystem and embarrassing rollbacks (see https://github.com/pypa/setuptools/issues/4519 as a starting point), even for pure-Python projects where that functionality was grossly unnecessary and wasn't actually being used (notably: Requests - https://github.com/psf/requests/issues/6775 - and Celery - https://github.com/celery/celery/issues/9157 ).

Setuptools is one of the most popular packages on PyPI. I estimate, based on the available public data, that it accounts for about 1% of all PyPI download bandwidth - petabytes per year, worth perhaps a dev's entire salary at market rates. I suspect that a very high fraction of these downloads should be unnecessary if people were properly educated about how this works - and even where Setuptools is used, it could be much smaller while providing the same non-deprecated functionality - and most users aren't using most of that functionality anyway.

I have much more to say about this, as part of a broader discussion of Python wheel sizes. I'm hoping I can get to that blogpost within the next month or so.

In the mean time: I have been working on a build backend called `bbbb` that attempts to be minimal. It's not at all production-ready yet, but you can get a basic sense of what I'm going for: https://github.com/zahlman/bbbb/ . It's at least powerful enough to package itself, and should work for any project that's only Python code aside from its dependencies, if you use src layout and are careful about file placement. If you need something that's properly tested and such, now, I recommend Flit. It doesn't, by design, provide a way to deal with compiled extensions (whereas I will eventually), and it's definitely not as small as it could be (it vendors `tomli` and includes its tests in the wheel, which you'll never have a reason to run yourself) - but it's still much smaller than Setuptools.