User experience with porting off setup.py

Initial suggestion ready: Add build backend and frontend to the glossary by sinoroc · Pull Request #1329 · pypa/packaging.python.org · GitHub

Hmm, did anyone point the article’s author towards this? https://pypackaging-native.github.io/

I feel like that’s the missing guide that people who do something like the author should find answers in.

Please look up the 6+ month long discussion over this section, and the final decision to make this a tabbed list. This is intentionally tabbed to make it visually clear what changes if you pick a backend by showing that this and nothing else changes. It also keeps “packaging.python.org” from becoming a hatching tutorial and keeps it a general Python tutorial. And regardless of what people select (95% of readers do not touch the tabs or possibly even notice them), it’s still a working example.

As far as I can tell, the current focus of the thread is to make it more apparent that choosing a backend is important, not less.

3 Likes

Another article on this that was recently featured on TalkPython: An unbiased evaluation of environment management and packaging tools

From looking at that article, I noticed very little was focused on the backend. Compiled backends (scikit-build-core, meson-python, maturin) weren’t really mentioned, and Hatch/Flit/PDM were really only present as tools, without much / any mention of the backend.

3 Likes

That was a nice comparative survey, including the Venn diagrams, but in relation to PDM they did not mention that it offers its own backend, while the build frontend is part of the PDM CLI. Both of these satisfy the requirements or expectations of PEP 517. Also, in relation to the pyproject.toml PDM allows you to choose other backends as well, including setuptools, as described here.

This is because PDM is both a frontend and a backend, a fact that their docs will have to make clear to their users.

Officially, there is a clear separation of concerns. Tools that blur the lines will have to take responsibility for any confusion they create by doing it (just as setuptools is taking responsibility for confusion caused by removing their frontend aspect).

1 Like

That does seem to be the case but I’m not sure why the discussion has gone that way.

The blog post describes the experience of someone who is maintaining an existing project that already uses setuptools. They find that setuptools is not installed automatically by actions/setup-python for Python 3.12 (something that also bothered me on first encounter). They also see warnings:

Please avoid running setup.py directly.
Instead, use pypa/build, pypa/installer or other
standards-based tools.

See Why you shouldn't invoke setup.py directly for details.

Quoting from the post they then have these questions:

  1. OK, maybe this is a sign I should be modernizing to pyproject.toml and moving away from python setup.py. Maybe the missing setuptools in the 3.12 CI environment is a side-effect of this policy shift?
  2. What are pypa/build and pypa/installer? I’ve never heard of them. I know pypa is the Python Packaging Authority (I suspect most Python developers don’t know this). Are these GitHub org/repo identifiers?
  3. What exactly is a standards-based tool? Is pip not a standards-based tool?
  4. Speaking of pip, why isn’t it mentioned? I thought pip was the de facto packaging tool and had been for a while!
  5. It’s linking a URL for more info. But why is this a link to what looks like an individual’s blog and not to some more official site, like the setuptools or pip docs? Or anything under python.org?

The problem here is that all of the messaging is very confusing and will be especially confusing to anyone who has vaguely followed developments in Python packaging over the last 10 years (since the supposed direction of travel has changed repeatedly).

I don’t think that choosing a backend is immediately relevant here because the setuptools backend is already being used. Both pip and setuptools support all of the relevant standards and the only real change needed is probably to add pyproject.toml listing setuptools as the backend and any other build depenmdencies and then use

pip wheel .

rather than

python setup.py bdist_wheel

In fact I just went to go find the GitHub repo to see what the actual code change was and it was exactly that:

It is not necessary to go and learn about all of the other backends or frontends or whatever. What is needed is a clear guide that shows how a setuptools based project (the vast majority of existing projects that exist on PyPI) should be modernised to work with current standards.

As much as many people involved in packaging would like to push alternatives to setuptools or present a guide that gives equal weight to different backend options the vast majority of Python projects already use setuptools and have done since long before anyone started talking about “backends” and “standards-based tools”.

For a project that already uses setuptools and has anything nontrivial in setup.py switching to any other backend is likely a lot of work. In the first instance the question is not

Which backend should I use?

but rather

What are the minimal changes I should make to ensure that I am not using deprecated features of packaging any more?

For anyone who has an existing, working, widely-used, setuptools-based setup the answer to this question is almost certainly not that you should switch to a different build backend.

This is why I have suggested two guides that should be aimed at people who are (as in the title of this thread) porting off of setup.py i.e. maintainers of existing setuptools-based projects:

  1. A guide for updating to recommended usage while still using setuptools.
  2. A guide for considering the possibility of migrating from setuptools to something else.

The second of these guides can give equal weight to different backends but the first cannot. The first guide should make it absolutely clear that both pip and setuptools do support the standards and that anyone who is happy with the way that they work can continue to use them but should use them in the way that is expected by the standards.

12 Likes

I wrote this based on the questions I have seen on StackOverflow. It is not meant to be exhaustive, and I am sure it can be improved on over time. However imperfect this document is in this state, I think it is important to get such a document published as soon as possible and build from there.

Feedback is welcome. If possible over there on the pull request rather than here.

5 Likes

I think there’s a very important third category, and that’s exactly what the current guide is aimed at:

  1. Give users new to packaging Python projects a clean, modern introduction to how things should be done from scratch.

That’s what the current guide is for, and I think it does that well. It’s not meant to push anyone toward changing backends - both by not forcing a backend, and by not being targeted toward existing projects at all.

I do think a guide for modernizing older projects is good, and probably wouldn’t be out of scope, and people are very much coming in with those sorts of questions. But it would not be correct to modify the newcomer tutorial to include modernizing older projects or converting setuptools to something else, etc.

3 Likes

I did read the discussion, and as I have said repeatedly on this forum, I believe that decision was wrong and harmful to users.

The tutorial does not make visually clear what you say it does. But that doesn’t matter anyway, because telling people what changes if you pick a different backend is not something that should be in this tutorial at all. This tutorial is the one piece of documentation on the site that actually purports to tell people how to package their project. It should tell them how to do that, not ask them how they want to do it.

What I’m taking from this thread is that people want other people to make PRs if they think the documentation needs improvement. I think the documentation on that page needs improvement, so I made a PR with my suggested improvements. If you don’t like it, you can reject it, and the docs will continue to be flawed. But maybe this means it would be helpful to have a Python Packaging Council, so that there is a group with a clearly-defined mandate for determining the direction the docs should take.

I want to emphasize here that although I’m frustrated by this process I’m not trying to point fingers at people or cause more hassle to anyone. But I think the docs on packaging.python.org have major problems from a user perspective, and I think the best way to improve them involves a rather radical rethink; this PR is one small step in that direction.

4 Likes

I don’t believe the tutorial achieves that aim, because I think there are only two ways to do that:

  1. Pick a backend and tell them to use it.
  2. Include a complete discussion of the pros and cons of various backends so they can choose one.

Right now the tutorial doesn’t do either of those, so the net result is an increase in confusion.

1 Like

That is an interesting article. Unsurprisingly I feel it gives conda short shift. :slight_smile: But apart from that it’s nice to see a Venn diagram like that. Actually something like that for build backends might be helpful for users needing to make a choice on that front.

1 Like

What about updating Packaging and distributing projects — Python Packaging User Guide ? That is supposed to be the guide on packaging, yet it doesn’t mention pyproject.toml at all. If that page was updated, I could see a set of tabs there being useful, and then maybe the guide could have them removed. Though I still think making the guide visually generic is useful, and it makes me happy to point at it from a build-backend’s docs. It’s really obvious what needs to change to switch backends. I’ve never seen a reader who doesn’t already know packaging complain on packaging-problems about this tab set, only people here trying to “protect” other people from being confused. But if there was a good guide page, making the tutorial just a tutorial is reasonable. But not before that, IMO.

I think one of the big problems is that there are a lot of unmaintained pages with outdated info on packaging.python.org. Someone looking for packaging info sees a lot of pages, and many of them are terribly outdated. I’m always fearful when new pages are added (especially top level ones like the packaging flow) instead of rewriting the older ones to instead be current and up to date.

8 Likes

Thank you for sharing this. It’s a wonderful blog post and there is a well done talk as well: https://www.youtube.com/watch?v=MsJjzVIVs6M

Something that I really appreciate is the unbiased view instead of a tool-centric view.

2 Likes

One of the problems with consensus-based decision making (or, in fact, any sort of decision making!) is that sometimes the decision isn’t the one you want. At that point you have a choice between accepting and supporting the decision, trying to make it work in spite of your reservations, or simply repeating your assertion that the decision was wrong, in the hope of being able to say “I told you so” at some point…

Would you be so quick to say this if the council supported the current view on how the documentation is structured?

For that matter, the committers for packaging.python.org are, in effect, the council for that site. So you’re basically just suggesting that a different decision making body would be better. Why, exactly?

I don’t particularly like your PR, because it promotes hatchling, which isn’t particularly my preferred backend. And I don’t think it’s a particular improvement over what’s there already. But it’s not my choice to make, ultimately, it’s up to the documentation maintainers (or maybe a future council, if they have the authority to overrule a project’s maintainers).

7 Likes

Are we okay with the only tutorial on PyPA is a packaging tutorial that requires the users to learn about what a build backend is and go figure out how to choose one? Is this what we want for first-time package builders[1]? Why only have one tutorial[2]?

The hybrid approach of including too much for beginners and too little for experienced users is making this a bad tutorial for all. Just as an exercise how well does the PyPA packaging tutorial follow diataxis’ tutorial?


  1. Given you can perfectly build a pure python package without specifying the backend at all. ↩︎

  2. I’d like to see a tutorial that is frontend-centric that guides a beginner without mentioning backend. Perhaps an excerpt at the end to point them to a advanced tutorial or a dedicated backend guide. ↩︎

6 Likes

IMO, one place with 5-7 separate topic guides / howtos rather than “tutorials”. FWIW these are the ones I’d personally love to see:

Topic Guides

Packaging a pure-Python project with basic defaults

Walk through the simplest possible case. Given some of the more important definitions. This needs to mention that backends, etc exists, and link to other guides. It is important to convey to beginners that if they hit a wall with simplest things, that there is more to look into, and some idea where.

Using and choosing build backends

Has many definitions: what is a backend, why does it matter? Discussions and comparisons of common/popular backends and their configuration, at least one full example, and lots of links to backend projects docs.

Handling advanced cases with compilation steps

A couple of full examples, discussion and links of tools like scikit-build or advanced build capabilities of other backends. There’s lots to potentially cover here, or at least mention and link to things about: cython, wrapping C, C++ or Fortran, building/bundling Typescript. Maybe suggest DPO as a place for deep technical questions.

Modernizing legacy setup.py usage

Address all the things that came up for the OP here, links to the other guides as appropriate. Quick tips/FAQs for common things e.g. “what do I do with these command line arguments?”

Publishing packages

Information about PyPI and twine.


For all of the above, having corresponding GH repos that users can clone and immediately toy with would, where appropriate, be really nice as well.

17 Likes

3 posts were split to a new topic: Is it possible to go back to setuptools and setup.py as a frontend?

Captured in this issue: Add topic guides based on Discourse Discussion · Issue #1334 · pypa/packaging.python.org · GitHub

5 Likes

I wanted to chime in that I’ve been very encouraged with the activity on this thread!

I had typed up a lot of content that I ultimately stripped from my blog post on what I thought should be done and folks here seem to be gravitating towards a lot of what I was going to say.

In case you missed it, there was some additional discussion on this blog post on Twitter/X, Lobste.rs, and HN. The largest themes I got were:

  • Me too. I’m clearly not alone in this boat. Some people even said they gave up porting off python setup.py because they couldn’t figure out how to do it.
  • There was a lot of sentiment that authoritative guidance on what to do in Python packaging land is severely lacking. That good, trustworthy, modern documentation is hard to find.
  • Lots of people incorrectly believe that all of setuptools is deprecated and they need to delete setup.py.
  • People seemed to be largely dissatisfied with the extra complexity from the introduction of pyproject.toml. However, I think the reasons are highly varied. (Some people just don’t like any change. Others are complaining about the lack of porting docs. Etc.)

In addition to the topics discussed so far, I want to raise a few more from my post.

Lack of a Build Frontend in the Default Distribution

I don’t fully understand why a build frontend isn’t present in Python distributions by default.

I think that shipping a build frontend in Python distributions could make things vastly simpler for end-users by eliminating a lot of cognitive overhead with having to think about which build frontend to use and how to install it.

Many languages do things this way (Ruby’s gem, Rust’s cargo, Go’s go). End-users seem to love the unified toolchain approach. And the presence of a default tool doesn’t undermine innovation in the larger ecosystem.

Before Python 3.12 (or earlier 3.x releases if we want to be pedantic about setuptools availability), we had the ability to produce sdists and wheels using just the standard library’s distutils + [ensure]pip. But 3.12 fully removed this capability. If we want to be customer focused and ease the transition for existing package maintainers, shipping a [simple-to-use] build frontend in the distribution seems like an effective way to do that.

Securely Installing Packages in pyproject.toml

Are my blog’s assertions about pyproject.toml build system package installation being intrinsically insecure accurate?

This question can be answering by stating how to deterministically bootstrap a Python build system frontend and backend and all transitive dependencies in a way that is robust against new package versions being published and is resistant to content tampering.

Is there any documentation on how to do this bootstrapping securely? Are there any discussions on it folks can link me to?

FWIW I have a half baked idea for package registries to store content digest indexed manifests - think requirements.txt files or poetry’s equivalent - and then for package installer frontends like pip to be able to do something like pip install flask@sha256:deadbeef42... to download a content indexed manifest stating all transitive dependencies to install. This way, deterministic install descriptors can be generated and used for reproducible, tamper-resistant installs. All an end-user has to do is refer to a short, immutable content digest instead of having to maintain the manifest themselves. This is conceptually similar to how OCI (read: Docker) image registries work - image manifest & image index.

9 Likes