Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add PEP 621 config via Flit #1030

Closed
wants to merge 2 commits into from

Conversation

henryiii
Copy link
Contributor

Now that there is a PEP 621 backend in the PyPA, it's probably time to add the long-awaited PEP 621 configuration to the tutorial.

@bhrutledge bhrutledge self-requested a review December 11, 2021 14:02
Copy link
Contributor

@bhrutledge bhrutledge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking the initiative here. However, I think this is too much complexity for a newcomer to packaging. I think one advantage of the tutorial is that it recommends a specific approach, that familiarizes people with the concepts and project structure, while mostly avoiding the weeds (the exception being the choice between setup.cfg and setup.py, which I see as necessary given the recent transition).

I would rather see a separate tutorial (based on the current one) that takes full advantage of Flit (along with its init, build and publish commands). We could link to it as a "simpler" alternative in the beginning and/or the end of this document.

@webknjaz
Copy link
Member

I share Brian's sentiment here. A flit-oriented tutorial could be separate. I've also invited a few folks who may have extra opinions on how to handle this.

@henryiii
Copy link
Contributor Author

henryiii commented Dec 12, 2021

Unfortunately, once you make a page, then you have to continue to maintain that page. If we make dual pages, then we now have multiplied our maintenance by 2, we can never remove the page (without dead links, anyway), and new users will now have to pick between two pages which is better but not much better than the tabs. The idea here was that eventually, if the new version works well and setuptools adds PEP 621 support, the old setup.cfg/setup.py tabs could be removed1. Then we are left with one page (the simple/modern one), rather than two.

I did consider both options, but liked this one due to the long-term result being superior. I think the long term goal should be to show ideal packaging using PEP 517, 518, and 621, and not be tool specific at all, but simply suggest PyPA tools that can fill each gap, and allow for others. And not to grow the number of pages maintained here, since many of them are pretty hard to maintain already (I still have "packaging binary extensions" updates on my todo list).

Footnotes

  1. Contents could be moved to a tutorial in setuptools.

@henryiii
Copy link
Contributor Author

henryiii commented Dec 12, 2021

And I don't think we should show flit build and publish commands, I'd rather users coming to packaging.python.org see the standards we have worked on, rather than a specific tutorial for one package only. The Flit docs can show flit specific commands. I think we should link to flit, just like we can eventually remove the setup.py/cfg parts and just link to setuptools, where setuptools specifics can be presented. But part of the idea is that this is moving toward being a general tutorial for all backends, not Flit or setuptools specific. Flit is an example of one, but it also works for PDM, Trampolim, Whey, and any other tool that comes along - hopefully, soon even setuptools. I tried to keep the tutorial completely free of package specifics for the core, then mention what Flit (and others) can do.

I don't think the goal is at all to simply have a page for each backend. That's for the backend's own docs. This happened to be a setuptools page because that was the only option for a very long time.

@henryiii
Copy link
Contributor Author

henryiii commented Dec 12, 2021

Another option could be to move the current contents (tabs and all) to setuptools, and replace this with just the PEP 621 config, using Flit (but in a completely generic way that could be swapped out for PDM, Trampolim, Whey, etc). I just thought it was too soon to do that.

Note the title. This is not adding Flit. This is adding PEP 621 using Flit as the main example for it.

@henryiii
Copy link
Contributor Author

@brettcannon and @takluyver might be interested too. I can't add reviewers.

@bhrutledge
Copy link
Contributor

Unfortunately, once you make a page, then you have to continue to maintain that page.

And I don't think we should show flit build and publish commands, I'd rather users coming to packaging.python.org see the standards we have worked on, rather than a specific tutorial for one package only.

@henryiii Good points.

Another option could be to...replace this with just the PEP 621 config...
I just thought it was too soon to do that.

It also feels too soon to me, but I'd rather take this approach; maybe once setuptools supports it?

@takluyver
Copy link
Member

Thanks for pinging me. I'd agree with @bhrutledge: the aim of the tutorial should be to show people one specific, concrete way to make a package, not to give them lots of choices. Especially choices where the target reader won't really know how to decide (what's the advantage of PEP-621-based configuration, except that it's 'standard'? what's the disadvantage?). At some point, I hope pyproject.toml will replace setup.cfg in the tutorial (presumably when setuptools supports it), but until then I think presenting both makes it a less useful tutorial.

(I'd also personally rather this tutorial didn't refer to Flit. I don't want a repeat of the pipenv incident, where PyPA appeared to bless a new tool, people eagerly tried it out, didn't all like it, and the project got a massive backlash because it appeared to be the 'official' tool for that use case. Being extra selfish, I'm also not wild about the idea of thousands of people entirely new to packaging being directed to a project I maintain - but that bit is pure selfishness, because they're going to ask support questions somewhere, come what may.)

@pradyunsg
Copy link
Member

Piling on to the overall sentiment being expressed here - one of the explicit goals of the tutorials was to be targeted at getting a single thing done. If you want to have a detailed discussion of various options available and trade offs between them, that's what the discussions section is for.

@layday
Copy link
Member

layday commented Dec 12, 2021 via email

@pfmoore
Copy link
Member

pfmoore commented Dec 12, 2021

I'm going to stick my oar in here too. I think that for all practical purposes it's not yet possible to ignore the question of "what backend are you using", and it won't be until setuptools implements PEP 621. Until that occurs, setuptools remains the only realistic option for a tutorial that focuses on "one way to do things" - especially as flit's author has explicitly asked us not to recommend flit.

Given that, setup.cfg is the correct thing to present here. It shows the recommended practice of declaring metadata statically, and it also makes it easier for setuptools to implement PEP 621 by promoting static metadata, and so moving the community in that direction.

Once setuptools implements PEP 621, we can reasonably start looking at structuring the tutorial in a way that leaves the decision of backend to the end. But even then, I think we should stick with setuptools for the foreseeable future (at least until flit asks to be considered as the recommended backend, or a different backend starts to become significantly more popular).

@takluyver
Copy link
Member

But even then, I think we should stick with setuptools for the foreseeable future (at least until flit asks to be considered as the recommended backend...

I suspect I'll never actively ask for Flit to be recommended in this tutorial. I'm too wary of what happened to pipenv. Once there's broader support for PEP 621, though, making it easier to switch away from Flit if you need/want to do something it doesn't support, it might be a reasonable default. But then so might something like Poetry, which offers an experience much more like cargo (Rust's packaging tool).

@pradyunsg
Copy link
Member

(removing the long list of requested reviewers -- I don't think we need so many people to review and approve this PR; whenever that happens)

@layday
Copy link
Member

layday commented Dec 12, 2021

There are so many unstated assumptions in people's replies here that I find it hard to respond... to anything. Why do we need to wait for setuptools to implement PEP 621? Is it because you believe Flit is the only backend to support PEP 621? What does Poetry, a backend which does not support and is not working on suporting PEP 621 have to do with moving the tutorial to PEP 621? How is the "pipenv incident" even remotely relevant to moving the tutorial to PEP 621? Where does this notion that mentioning Flit in the tutorial will lead to an influx of user requests and demands on the Flit tracker come from? Have you observed that to be the case with setuptools?

@takluyver
Copy link
Member

@layday as things stand, putting PEP 621 front & centre means pointing new users to Flit. The PR title makes this explicit, and the text highlights Flit as the main option - it also mentions PDM, but only briefly, and without any explanation of how it differs from Flit. This tutorial is aimed at people new to packaging Python projects, so I would assume that whatever it shows as the first option, especially when that's described as the 'simplest' choice, is what 95% of people will try to do. Who doesn't like simple? 🙂

The goal of PEP 621 was metadata portability. I don't think it's really useful until it actually enables portability between the most popular backends. I hope setuptools & poetry will both implement it sooner or later. If neither of them bother, then IMO the standard kind of failed. 🤷

The parallel with pipenv seems all too clear to me. A PyPA tutorial recommended an opinionated tool, people inferred that it was the official/blessed solution for that use case, but (some of them) didn't like that solution, and then got angry with the project for pushing itself forwards as the default tool. I don't see any obvious reason that couldn't happen to Flit. I certainly make enough decisions that annoy people.

@henryiii
Copy link
Contributor Author

I agree with @layday, it seems we have a wide variety of opinions and I think this might be much clearer if I make a PR showing my PEP 621 only version, even if no one thinks we are quite ready to go that way.

Specifically, I want to answer this:

one of the explicit goals of the tutorials was to be targeted at getting a single thing done.

I think the point of PEP 621 (@pfmoore or @brettcannon or others could correct me) is that we can provide a tutorial that can apply to any PEP 621 backend by only changing two lines - the build backend. The tutorial on packaging.python.org would be able to show "how you set up a Python package" without targeting one blessed tool, Setuptools, Flit, or some other tool (like Poetry). We can provide Flit or Setuptools so that the tutorial can "get a single thing done", but the idea is that users could go and switch to PDM, Trampolim, or Whey (and in the future, scikit-build, meson, and maybe even Poetry some day) without invalidating everything that they learned, but instead just changing two lines.

Flit tutorials can go into flit.readthedocs.io. Setuptools tutorials can go in to setuptools.readthedocs.io. This is a place for a standards-based tutorial (PEP 621). It just used to be seutptools, because that was literally the only tool "blessed" for packaging, and that's slowly becoming not true anymore due to PEP 517.

@takluyver
Copy link
Member

The tutorial on packaging.python.org would be able to show "how you set up a Python package" without targeting one blessed tool... We can provide Flit or Setuptools so that the tutorial can "get a single thing done",

In practice, you are blessing whatever tool you recommend. People who just want to stick a package on PyPI don't care about our clever abstractions where the same metadata can work with different buildsystems - they want to do a thing and have it work.

I agree with the goal of putting PEP 621 in the tutorial. I just don't think we should do it yet, when 2 of the biggest backends don't support it.

@henryiii
Copy link
Contributor Author

I fully agree that we should not show anything specific to Flit, like flit publish. Showing PEP 621, however, is not showing Flit specifics, but showing a general standard, one that has at least four implementations so far. Setuptools is very much planning to, it's just a large and costly endeavor, especially to do right. I literally did not and would not recommend installing flit - it's just used for the backend. Standard tools (build, twine, etc) are still used and recommended.

Pipenv was showing a specific tool, not standards. A user couldn't change 2 lines and switch tools. I think that was the problem.

@henryiii henryiii marked this pull request as draft December 12, 2021 17:29
@henryiii
Copy link
Contributor Author

henryiii commented Dec 12, 2021

I've added an example of where I think this tutorial should go in #1031, though if we say it can't do that until setuptools is ready, that's okay. Though now that we have a PEP 621 builder in the PyPA (as well as three more outside if it), I think it's valid now too.

@pfmoore
Copy link
Member

pfmoore commented Dec 12, 2021

I think the point of PEP 621 (@pfmoore or @brettcannon or others could correct me) is that we can provide a tutorial that can apply to any PEP 621 backend by only changing two lines - the build backend.

This is correct. And when it's true, I'd support writing the tutorial like that. However, until the popular front ends1 support PEP 621, we have to explain how to do things using setuptools. And offering multiple equivalent ways of doing things depending on your choice of backend defeats the object of providing a single, straightforward way of doing things for beginners.

As for using flit in the tutorial, the author of flit has explicitly requested that we don't do that. His reasons are ultimately irrelevant, we should simply follow his request, there's no real debate to be had here. So if we don't use flit as the example backend, and setuptools doesn't support PEP 621, what backend do you suggest would make sense to use?

Footnotes

  1. At a minimum, setuptools, flit and maybe poetry, although poetry deviates in a lot of other ways from the recommended workflow so it's not a good example here

@layday
Copy link
Member

layday commented Dec 12, 2021

Nobody wants to disrespect the author's wishes. We can still have a discussion in good faith about the concerns they expressed.

@brettcannon
Copy link
Member

In case people want to know the state of setuptools supporting PEP 621, it can be found in pypa/setuptools#2671 .

@flying-sheep
Copy link
Contributor

flying-sheep commented Dec 21, 2021

What are our choices? Even once setuptools gains PEP 621 support, flit will be the most mature backend until others catch up.

At least that’s what I infer from the giant amount of changes in pypa/setuptools#2924, which seem to be necessary to support just another metadata format. I think this will result in quite some initial bugs there. flit however has been around a while, and is designed to be very simple. I think that makes it the ideal candidate for the near future.

I of course don’t want us to disrespect @takluyver’s wishes either, just stating what I think is true: If @takluyver hadn’t said said what he did, I’d suggest putting full PEP 621 metadata into the tutorial (not relying on flit’s features), specify flit as backend in example configurations, and mention that backends are interchangeable and should be picked based on features needed?

I fully agree that we should not show anything specific to Flit, like flit publish

Totally. An overhauled tutorial should be standards based, as described here: https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html#summary

  • python -m build for wheel building
  • pip install [-e] for installing into a venv
  • twine upload for publishing

If it’s ready by then, maybe we can also mention that python -m installer can be used for installing to a docker filesystem or for creating OS packages.

PS: the three tools necessary make me think of a new project idea: “standards based poetry”, a CLI with some of poetry’s features, but working only with standards based mechanisms. We’d probably need to standardize a lockfile format for it though …

@abravalheri
Copy link
Contributor

Hi @flying-sheep, I just want to clarify the following comment:

At least that’s what I infer from the giant amount of changes in pypa/setuptools#2924, which seem to be necessary to support just another metadata format.

There is a huge amount of code there specifically because I am exhaustively checking for backwards compatibility while automatically converting setup.cfg files into pyproject.toml. As I have discussed with the maintainers, once I finish wrestling with the CI and have everything green, I do plan do submit a simplified PR, which should be much more compact.

@flying-sheep
Copy link
Contributor

I see! Well, the point about complexity still stands. Will setuptools stop monkeypatching distutils? Will it stop relying on the super slow and flaky pkg_resources?

I feel more comfortable recommending flit these days because it doesn’t have all this accumulated complexity.

flit_core imports 14× faster than setuptools
package PYTHONPROFILEIMPORTTIME=1 python -c "import $package" 2>! imp.log && tuna imp.log
flit_core flit_core
setuptools setuptools

@henryiii
Copy link
Contributor Author

CLI with some of poetry’s features, but working only with standards based mechanisms

Exactly how would this differ from PDM? You can use any PEP 621 backend (Flit, for example). Etc.

Will setuptools stop monkeypatching distutils?

No, otherwise tons of code would break. But it also is still more-or-less required for complex builds, like compiled extensions. Flit can't even read the version from git like setuptools_scm can do (SDists in Flit have no build process).

An overhauled tutorial should be standards based

Umm, it already is? pip is used, twine is used, build is used, etc? Only PEP 621 is missing, which is what I was trying to add. I'd also like to see pipx used, which would simplify usage of twine, build, etc. and would unify Windows and Unix commands.

I’d suggest putting full PEP 621 metadata into the tutorial (not relying on flit’s features), specify flit as backend in example configurations, and mention that backends are interchangeable and should be picked based on features needed?

This is literally exactly what I did in #1031.

@flying-sheep
Copy link
Contributor

flying-sheep commented Dec 21, 2021

PDM

I did not know about it! Thanks for the pointer. Seems like I didn’t search properly.

No, otherwise tons of code would break.

In this case I think we should deprecate setuptools, extract the clean, fast to import core code into a new module, make that one the build backend. Then setuptools becomes a wrapper around the new thing while maintaining backwards compatible behavior.

I’m sure that hack was the best choice at the time, but carrying a hack forward forever because it’s the easiest solution is a temptation that should be resisted.

pip is used, twine is used, build is used, etc?

I mean “as opposed to relying on flit’s CLI”

This is literally exactly what I did in #1031.

Awesome! I wholeheartedly support this approach! Also lovely that it’s shorter than before.

@brettcannon
Copy link
Member

We’d probably need to standardize a lockfile format for it though …

Off-topic, but working on it.

@henryiii
Copy link
Contributor Author

henryiii commented Dec 21, 2021

#1031.

I sadly have not received a single supportive comment there. :( But I haven't received any negative ones either, so that's a plus. :)

Also, setuptools might be unlikely to support automatic src folders in the pyproject.toml backend (or even automatic package discovery?), so it will require a tool.seuptoools.* setting in the tutorial. :'(

In this case I think we should deprecate setuptools, extract the clean, fast to import core code into a new module

This is insanely hard. Packages deeply hack into the setuptools internals, into distutils, everywhere. And any time you break things, that breaks the ability to build older packages. Just the tiny, tiny change of removing 2to3 broke at least one package that hasn't had a release in 8 years (funcparserlib). (Thankfully, the authors actually were still around and released a prerelease 8 years later when this broke!). Pick any major package and look at the API that they use. I'm going to try to help on scikit-build, depending a lot on a proposal I'll hear back on next year. But this is really hard, and you will break anyone who doesn't cap setuptools. Oh, and capping setuptools is impossible because there's no "LTS" support, so capping it means you lose fixes and support for new Pythons/architectures/systems, etc.

@abravalheri
Copy link
Contributor

abravalheri commented Dec 21, 2021

Also, setuptools might be unlikely to support automatic src folders in the pyproject.toml backend (or even automatic package discovery?), so it will require a tool.seuptoools.* setting in the tutorial. :'(

Not necessarily @henryiii. I have worked on other PRs that simplify auto discovery (with nice defaults) and setuptools maintainers seem to like the idea to do more things automatically (unfortunately they have limited bandwidth for the PRs).

(Refs: pypa/setuptools#2887, pypa/setuptools#2888 and pypa/setuptools#2894).

This is complemented by my proposal on having include_package_data=True by default from configuration coming from pyproject.toml.

If my proposals are accepted, the [project] table should be enough for common scenarios (while [tool.setuptools.*] would still allow further customisation).

@brettcannon
Copy link
Member

#1031.

I sadly have not received a single supportive comment there. :( But I haven't received any negative ones either, so that's a plus. :)

I honestly didn't even notice the PR. 😅 I just left a review.

@bhrutledge
Copy link
Contributor

bhrutledge commented Dec 29, 2021

Thanks all for the thoughtful conversation here. It seems like this won't be merged, and as such feels safe to close, but further (on-topic) comments are welcome here or in #1031.

@bhrutledge bhrutledge closed this Dec 29, 2021
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.

None yet

10 participants