#general
1 messages ¡ Page 1 of 1 (latest)
@lyric hedge gets access where ever I have it basically đ
So you come in two for one package deal :)
Yes, one shit Aussie and one useful Canadian!
God bless the queen.
Who's Canadian other than me in here (as I assume you are not referring to me)?
I'm the Canadian he's referring to
Thatâs my man
I m the Canadian he s referring to
What is linehaul?
https://packaging.python.org/en/latest/guides/analyzing-pypi-package-downloads/ mentions it but makes no mention of what replaces it (as the repo is archived)
I see a replacement mentioned in the project description
yeah feel free to do a pr
That's the link in the guide as of right now. :)
pypa/packaging.python.org#1119
Which channel is best to ask a BanderSnatch Question?
I don't know if I'm experience a bug or user error
Probably the bandersnatch channel...
lol, yeah I would have thought that but I see a bunch of automated messages in there
I didn't want it drowned out
You can also have a look on the existing issues, and do a quick search on https://discuss.python.org to see if the question was ever made before
I'll check once more. How embarassing for it to be there
The automated messages can come in bursts in a day that the developers are working on the project, but if you scroll past them you can see that there are very interesting discussions đ
thanks, i'll post there
any idea why Anthony is hard blocking this? https://github.com/PyCQA/flake8/issues/234#issuecomment-1206730688
is it a technical limitation of flake8 or a personal issue?
He would want to replace current config with pyproject.toml rather than handle both of them which is fair because it adds to the complexity. But if he does that, suddenly some projects are forced to migrate to pep 517 build system because that's what presence of pyproject.toml requires. I think setuptools has a separate legacy build system (build_meta.legacy?) that's pep 517 compatible but actually works the same unlike the regular build_meta? I don't think it's flake8 limitation, just his personal opinion.
More personal than technical. He doesnât like TOML and imo just uses his power to block this.
that's a bummer
Flake8-pyproject also has bad manners and force-feeds Flake8 the spam it so despises.
đ I might use it just due to that sentence
probably related to the Monty Python original spam joke...
Is anyone else a little bummed out about flake8 dropping support for user-wide configuration
My problem is mainly with file exclusion
Like, I want to globally exclude venv directories...
I think the long term plan in pip is to remove the old way of building
So everything goes through the py project path
Albeit with a default py project
If my memory is correct, once that happens it seems like the other blocker on that thread is gone
I would like to understand, why he considers this a blocker. Flake8 is not working with envs in any way
Would be cool to have statistics on projects that still use non-pep 517 build process
I assume because black got some blow back when they were a very early adopter of pyproject and people got confused by the fact using it to configure your black settings opted you into an unrelated change in how your project was built
Even actively maintained projects use those because they either didn't have to update or maybe because of the "packaging is a mess" dogma
Idk
That was a messy time back in the day
towncrier was the first tool that made us use pyproject.toml
Flake is probably the only project that actively refuses to use pyproject
Even though we used black earlier than that, just didn't set the options in pyproject.toml at the time
There's this list
https://github.com/carlosperate/awesome-pyproject
flake8 and nose2 seem like most notable projects that are in the considering category on there
And pydocstyle
I tried to argue some month ago, that there is no blocker left. Without success... https://github.com/PyCQA/flake8/issues/1570
pip still has different behaviour based on the presence of pyproject.toml
is this still true?
Technically legacy backend is supposed to do the same thing (imitate pre-pep 517 behavior) though but presence of pyproject.toml does in fact cause pip to go through different code paths and some discrepancies could occur I imagine
build isolation might work somewhat differently?
Since that's pep 517's thing
the big thing is pyproject.toml opted a project into build isolation
was the main breaking point
not sure if it still does
or rather, nto sure if non pyproject.toml still uses not build isolation
Can confirm the presence of an empty pyproject.toml triggers build isolation in pip
and setup.py without pyproject.toml means no build isolation
so, just changing it to be triggered by pyproject.toml with [build-system] section would fix the issue?
Well... I think there were loong discussions about that. I've not investigated to dig out the reasons but my instinct says this ship has sailed.
Itâs extremely unlikely since the general goal is the other way around, to enable isolation for all projects
PEP 517 was written in such a way that the frontend (pip) is free to choose between invoking setup.py (as used to be the case before the PEP) and using the setuptools.build_meta:__legacy__ PEP 517 backend. Though that was actually a change made to the PEP after it was implemented in pip.
The discrepancy seems non-ideal but if the project is already being worked on (which clearly it is if you want to start using pyproject.toml) and someone wants to use pyproject.toml then it makes sense to force them to move on and use the new way of doing things instead of that legacy thing that we would love to just go away đ
There was a brief time (well, about a year) when pyproject.toml existed (PEP 518) and PEP 517 didn't so someone might have gotten opted into that solution when they didn't want to but that was probably not that many users and kind of early adopters :P
pip does not follow the PEP though
the legacy backend should be equivalent to invoking setup.py
just makes it unnecessary to have specific code to do the setup.py invokation
pyproject.toml isn't tied to PEP 517, PEP 517 is only triggered when you specify the build system table
all other cases default to the previous behavior of invoking setup.py, even if it might be through the __legacy__ backend
I know this can be a bit confusing
eh
the problem comes from build isolation
not invokign setup.py directly or not
and neither PEP requires build isolation, or even says much about it
the closest it comes is a non normative suggestion in 518 to use isolated build environments
yep
517 does recommend using an isolated env
SHOULD not MUST
so if that recommendation is followed then running __legacy__ backend does cause it to use that isolation
@distant briar that's in a non normative section
which means it's not actually part of the spec, it's just recommendations
that's not too bad, I've been banned from PyCQA because I suggested that the Python wheel tags for a package Anthony maintains were wrong
đ
Can we get PyCQA to detox? Itâs always a bad sign when people donât engage with polite good-faith arguments.
If someone gets so paranoid they see sealioning and bad faith arguments everywhere, they should probably take a break from maintaining software
banned from the organisation or they have a discord too?
The GitHub org
apparently there's some bad history between black and PyCQA or something ÂŻ_(ă)_/ÂŻ
don't ask me for more details because I don't know, I've just noticed mentions of them in our core team chat were never positive
good luck trying to engage with anthony
I don't understand why we continue to reward his behavior
he's also unhinged on Twitter https://twitter.com/pauloxnet/status/1553691014749208576
Man has some serious issuesâŚ
to be fair to him, Twitter is broadly crazy lol
Depends on your definition of "reward". You can choose to mute/block people on Twitter, not use/promote people's projects, etc. And people can always politely point out bad behaviour so people realize what the social norms are for the community.
he was added as a PSF fellow not so long ago
last time I tried to point out his bad behavior he made fun of my boundaries, which coupled to everything else I was dealing with at the time, lead to me taking a break from open source work
largely everyone else in this community is actually pretty great, but his involvement makes me feel unsafe
"unsafe" is quite strong, we should try to avoid classifying speech or text as harmful/violent. but I feel ya đ
I mean, this is the accurate description for how I feel, but I acknowledge I may be in a particularly vulnerable place
and to be clear, the issue here is not one particular action, but rather that is it very much a pattern, and he doesn't even try to understand how his actions impact other people or take accountability
A pile on doesnât seem super helpful, but if someone makes you feel unsafe or you think theyâre creating a hostile environment then a good option would be to bring up those behaviors to the relevant CoC reporting addresses if those spaces have them
It looks like pycqa has one
(This is not any sort of official thing ofc, just my opinion of what Iâve seen work for bad behaviors in the past!)
hello o/
o7
hey there đ
Noticing the topic of discussion, FWIW Anthony is the creator and maintainer of some of my very favorite Python tools and I really wanted to like him, but unlike anyone else I've interacted with in the Python community, every single interaction I have had with him was negative. I'm not someone who says this lightly as I don't think I've had to say it about anyone else I've met in open source (or maybe even in general), but Anthony is the one person in this field whom I actively avoid any interaction with due to how badly things have gone in the past, and how interacting with him invariably harms my motivation and well being.
I thought I was the only one, but I've both seen firsthand and heard secondhand from a number of different people recently their experiences with him that were a lot worse than what I went through...legal threats, intimidation, insults, harassment, the whole nine yards. I hesitated to say anything because I also see that Anthony does a lot for the community in terms of his work as a maintainer, but it seems like things are just getting worse and worse and it is harming more people, the community and honestly himself too. I would be supportive of whatever is the best way forward to constructively handle this situation and willing to help in that regard.
That group of "we" quite possibly is unaware of what people are bringing up here. Remember that most of the community isn't on Twitter, don't congregate in the relatively small circle of proactive Python project contributors that we do, etc.
The key thing is to always report bad behaviour to the appropriate conduct group.
or even better just reach out to the person directly, I've always had success with that. in a 1-on-1 it's super duper unlikely that either party is not cordial, unlike public convos
ok, just emailed about flake8 đ¤
No need to qualify the validity of your feelings. If something someone did or said made you feel unsafe enough that you donât feel like confronting them about it, thatâs valid.
Why not? I understand that we should give the benefit of doubt, and shouldnât postulate our subjective opinion as truth, but @tidal kiln simply talked about how something made them feel, and didnât claim to know an universal truth about how to classify what happened.
And yeah, according to what everyone said here, this seems to be a pattern and not an isolated incident.
I donât want a witch hunt either, but I do want a safe community, so yeah: The CoC is there to help people figure out what to do in such a situation.
FYI arch folks already reported him to the pytest CoC and nothing really came of it
Welp, I was about to write âbut when that doesnât help, other solutions need to be foundâ, but thought I shouldnât be so pessimistic. I should have been pessimistic. My mistake was ignoring the fact that nothing has happened so far, so my assumption that the processes might work was of course flawed.
I hate situations like this. Every community has those long time problematic members that drove away countless others who tried the official channels and then left quietly when nothing happened because the problematic member is friends with people or has clout or something. I call that person the âmissing stairâ: https://en.wikipedia.org/wiki/Missing_stair
I think the PSF CoC for eg might be much better than this one, but I haven't gotten around to gather myself to do anything, and am not keen on being targeted by his community
I wish one could approach those teams without the fear of it becoming a witch hunt of the victim outweighing the hope that it might actually fix something. But I fully understand that you feel the way you do. If you need an advocate at any time, hmu.
this would be #off-topic but my point is that when something is spoken of in terms of harm/violence, quite literally anything in response to it immediately becomes justified. there's no higher escalation, no coming back from that
so we could say someone is a jerk whose actions cause distress, anxiety, etc. but we shouldn't go to safety/harm unless there's like actual hate speech
this would be off topic but my point is
Given the problem seems to be wider than just one particular project or community, and the PSF is much more likely to be a neutral body that can fairly evaluate both sides of the situation, I would advise that approach, and would be willing to support you however I can in that. I can also reach out to some PSF folks for their advice, if you like (without naming any names).
okay, I think I should just go ahead and do it... if anyone wants to share your experiences with anthony (good and bad) feel free to write something down and send it to me
that way I can attached that to the mail
and hopefully put this behind us, whatever comes out of it comes out of it
I misclicked the like button on Pradyun's tweet (which I tend to on mobile and then I remove it after few seconds) to Anthony and apparently got blocked (I assume that's the reason anyhow, I didn't have recent interactions with him otherwise) which made me kinda sad because I was actually following them on Twitter and wanted to continue to see his posts on my feed 
@high stone did you delete the tweet? I liked it and didn't get blocked
@codewithanthony A locked GitHub issue with an ultimatum that flake8 won't get support unless pip changes behaviour is... uhm... confrontational.
It's difficult to assume good intent based on your responses on this topic in various places.
Nope.
You may have luck going via sigmavirus24 than PSF?
Maybe something else contributed to it than just me liking their post then, wasn't really my intention to pile on
I certainly don't want to tell anyone not to report conduct to a conduct committee, but there's positive movement in this space but not going anywhere fast
What is the pip behavior with an empty pyproject.toml? And what is it supposed to be?
https://pip.pypa.io/en/stable/reference/build-system/pyproject-toml/#fallback-behaviour this is it right? It's done and everyone should be happy but Anthony is still pushing back?
Oh you spoke about it way up there in the chat log
https://github.com/PyCQA/meta/issues/54 can you post to this thread or are you still banned? (Can you even see it?) Is there something I could write here for you?
I'm conscious I may have fallen into the trap of telling you how not to step on the missing step
Ah yeah I found out a few weeks ago that I accidently discouraged @minor zealot from joining pycqa
Maybe @high stone could write something there because as far as I can tell everyone likes them
I don't really want to be involved with these people more than I already have, my last interaction with them was on a Twine issue where they wanted to ban a user for being a bit shall we say slow on the uptake. Clearly that's a bannable offence
sigmavirus24 or Anthony?
The former
Urgh
Not to badmouth anyone, but afaik, they are quite close friends, so I donât think it really matters in this case
Maybe talking to The-Compiler could help?
Badmouth who?
Sigma mostly, since I had interaction with him.
But yeah the whole permabanning people thing was brought to my attention by one of the banned people emailing me for help, I told them to try The-Compiler and Pierre
Maybe itâs time we enforce the fallback behaviour globally for projects without a pyproject.toml (not build isolation, just switch to always use PEP 517 to build wheels). This is what we want to do anyway and it makes the flake8 opposition moot (since the presence of pyproject.toml no longer affects anything)
Iâm only 10% sarcastic
I'm pretty sure build isolation is the behavior that flake8 is worried about
So the presence of a pyproject.toml enables build isolation, which flake8 doesnât like? Oh thatâs more complicated then (although I think I mentioned that on flake8âs issue tracker I fail to follow the reasoning and nobody has come up with any explaination)
Honestly, I donât understand why flake8 opposes pyproject.toml. Flake has nothing to do with builds or dependency managementâŚ
afaict the rationale is:
- The presence of
pyproject.tomlaffects how a project is built, primarily build isolation. - If flake8 uses
pyproject.tomlto handle configuration, then their uses will be forced to opt into those changes, regardless of whether they want to or not.
Which is not true, as a lot of people have tried to explain, but they just insist it is the case without any concrete examples
Ok, but from what I have seen, 95% of tools migrated or enabled reading configs from pyproject. Anthonys case sounds BS to me
I think both of those things are true still?
A full clear and believable case has been made ages ago, it's pretty much the same reason why pytest only has stopgap support for config via pyproject.toml since years
Sorry, I meant the second point never is true. The first is, but⌠why does it matter?
@spiral urchin I think flake8 wants to reduce the number of configuration files it supports to just (1)
OK thatâs reasonable.
IMHO People are not entitled to force maintainers Into repeating fruitless discussions again and again
In that case Iâm actually OK with their decisions on both the config format and to tell people to f off
FTR, I think at this point it's probably reasonable for tools to just assume that projects are going to be willing to opt into pyproject.toml semantics, so if it were me running flake8, I would just do that... but the decision not to do that seems reasonable?
Same
Legacy is a good reason, we still haven't found a good way to add real pyproject.toml support to pytest as it requires a lot of messy changes
It's entirely possible that there's a secret third portion of rationale which is:
- The authors of this project don't like TOML and/or the PEPs that introduced
pyproject.tomletc.
But I have no idea if that's true, and even if it were true... it's reasonable to say you don't like a format and don't want to support it.
Yea, I don't think that pyproject.toml is or should ever be considered some sort of mandatory thing for non build tools to support. It's nice if tools do, but there's probably an infinite number of good reasons not to!
Unfortunately it's impossible to stop people from wanting a tool to support X, and for them to all individually ask tool to support X
I know Anthony doesnât like TOML as format
I'd love to eventually provide an library that solves it (config +options via cli /env/ini/pyproject.toml with a sound type system
Not liking TOML as a format is a reasonable opinion.
all config file formats are awful
Wrt flake8 My understanding is that the ini details leak deeply into the plugin api, and they won't slap on sloppy toml support
I think the issue is really about the permabanning of people not necessarily technicalities in configuration
I wouldn't personally lock the pyproject.toml issue then get upset when people don't follow instructions and open up new issues about pyproject.toml, as I think at some point you're just setting yourself up for more frustration.
It's hard to say, certainly projects have a right to set their own boundaries, and enforce those boundaries, but at some point that can cross into a dark pattern. I'm not sure wrt flake8/Anthony as I don't follow that project closely and I can't see any of the tweets linked as apparently anthony blocked me though I don't remember ever interacting with them (which is fine, idc if someone blocks me, I run my mouth enough :P).
At the end of the day, if the keyholders of the PyCQA and the community disagree on what's reasonable, there's not much that can be done except for the community to stop using PyCQA projects and create their own alternatives, and stop providing space for them.
https://mobile.twitter.com/codewithanthony/status/1556979543373762562 is what Anthony said, w.r.t. pyproject.toml stuff.
@pradyunsg and if we're going to support pyproject then we're going to deprecate and remove everything else. the config system is the must complicated part of flake8 right now and it's extremely difficult to reason with at the moment
Oh I'm blocked now
Well, I'll put a moderator hat on and say that any further discussions on the flake8 / PyCQA / pyproject.toml support etc should move to #off-topic. Most of the discussion here isn't something that's packaging specific.
Is there a small library or self-contained code snippet for parsing the [project].python-requires pyproject.toml field? Black would like to provide a smarter default for --target-version if PEP 621 metadata is available. https://github.com/psf/black/issues/3124
packaging's specifierset?
Sounds about right. Not super keen on adding packaging as a dependency of Black, but I'd imagine it's the best option for parsing this field.
Thanks!
A set of small libraries for parsing that data would be coolâŚ
lol, I was looking through my downloads folder and was wondering why would I have an invoice from PSF for 50$ :O And then remembered the org user testing lol...
oh! what's the status on pypi organisations?
I forgot that a) they were being worked on, and b) it's a paid feature(?)
I think free for oss projects, paid for companies
The status is that they're in round 3 of user testing right now
The features are being worked on and each round needed you to try to do different things (as they get implemented I imagine)
All links are there
Including minutes from user testing
nice to see funding for such a requested feature đ
packaging itself is relatively small due to being such a broad, upstream dependency in packaging tools (e.g. being vendored in pip). The next release will eliminate our last dependency, and the wheel is 40.8 kB. And some of us are working on packaging.metadata to make parsing stuff easier at a higher-level
There is one being developed in the pycontribs org with the goal of moving to pypa
Anthony said in some mail to someone (quoted on GitHub) that acceptable behavior for him would be if pip would make no difference between a project with a (non PEP 621) pyproject.toml and one where that file isnât there.
Both always isolated builds and never isolated builds would be OK.
right, I meant that I don't think it's directly invoking setup.py vs going through the legacy build hook that flake8 is worried about, but that build isolation is either on or not based on that file
Now that editable support is in, is there any situation when pip still needs to directly invoke setup.py over using legacy build hook?
Barring the build isolation
That depends on whether setuptools does bdist_wheel/develop and PEP 517/610 differently. I believe there are not hard blockers if the two behave the same. (I donât think they do though.)
There are also some other considerations, see https://github.com/pypa/pip/issues/9175
develop is different from PEP 660 (was it 660 that you were talking about or actually 610- recording direct url of origin?)
I meant 660
I mean, I don't blame Anthony for being concerned about that specifically (that's not great design imo)
The actual issue is that build isolation is keyed off the presence of that file, which contains a number of specified and unspecified contents, whereas the precense of the build-system table within that file.
well originally that file was really only intended for build tools đ I don't think we were explicit about that though
and the thought was keying off the presence of that file would be more consistent
Valid content of the section would have been a better key in retrospect
The decision to use it to opt into build isolation came first, and everyone wants to put their tool configurations in that file afterward. So arguably itâs the people who use the file for non-build-tools are âwrongâ
also which valid content
PEP 518 seems pretty explicit to me... đ
The [tool] table is where any tool related to your Python project, not just build tools, can have users specify configuration data as long as they use a sub-table within [tool]
Itâs changed after everyone and their dogs started putting [tool.black] in the file
yea đ
like I said, originally it just said "tool", where the people mostly working on it mentally filled in the gap to be "build tool"
and then black came along and said "hey this is cool"
Yeah, should have checked the blame first then commented vs. the other way around, but yeah that was changed a little over 3 years ago. The original was less explicit, though it seems reasonable to not interpret it to be exclusive to build tools, since it wasn't actually specified anywhere
The
[tool]table is where tools can have users specify configuration data
The blessing and the curse of packaging PEPs being chronically underspecified, IMO
I just think the folks working on it had one thing in mind, and were insufficiently clear in the PEP, then other people interpreted it a different way, and eventually we just expanded it
I wrote like 8000 words about version numbers and that still wasn't enough to remove all the edge cases
Was the practice of tools using setup.cfg for configuration established by that point, or not? That would have been the main precedent I would have looked to at the time
I think there was a handful of things that could use it, like pytest and such
And the unfortunate historical tendency of tool authors preferring to guess instead of asking for clarifications (itâs getting better these days)
Since like it or not, the community was likely to (and did) see pyproject.toml as that latter file's replacement
but most projects used their own format as their primary
I actually think it's kidn of nice to have it used for anything
To be fair, in a lot of cases the interpretation might seem obvious enough to some readers that they wouldn't think to question it
yea I don't think it was ambigious in a noticeable way tbh
Even @fallen shuttle interpreted PEP 621's spec of the license.file field very differently then intended and didn't realize till I pointed it out, and the only reason I knew was that I had the same misconception about it for like a year that I only got corrected talking to Brett about it despite re-reading the PEP many times and being the author of PEP 639 on licensing of all things
Honestly I'd be very surprised if we're the only ones
most projects used their own format as their primary
Hatch merges with top-level key precedence https://hatch.pypa.io/latest/intro/#configuration
what was the license field misconception that you had? Just out of curiosity
That license.file was the equivalent of license_file/license_files rather than license = file:
is pep 639 accepted yet?
Actual examples showing the resulting core metadata output for the example input of each field in [project] would have gone a long way toward clarifying that and several other misconceptions people have had. I've learned the value for that firsthand in PEP 639. When I get the chance I'll propose a PR adding them
Not yet, I need to do one last round of changes splitting up the ancillary stuff into separate documents to make it way shorter (and making the terminology section into a glossary and linking terms there and to the PyPUG one, to reduce some confusion), and then do what is hopefully a final round of review in a new thread.
erm, so IIRC, the difference between these two is that license = file: goes in core metadata and license_file gets pulled into dist-info?
Yes, specifically the contents of the file specified by license.file gets injected in the License Core Metadata field, whereas the file specified by license_files (or the deprecated license_file ) gets dumped as files into the .dist-info directory (with several major caveats fixed). With PEP 639, the top level license will be a SPDX license ID/expression while license-files will basically be an enhanced license_files without its problems, and will also store the license file paths in core metadata (as Setuptools already does based on an earlier draft of the PEP)
Of course, PEP 621 doesn't actually say any of that and leaves it essentially completely implict
then why is license.file mutually exclusive with license.text?
Because they both get dumped in the same (to be deprecated) core metadata field, License
It wasn't so obvious though initially, since a lot of other packaging systems only allow specifying a license file or license text for other reasons
It makes sense if you believe that the License field from CM should contain the full text of the license but CM provides no such direction
the License field can't actually contain the full text
withuot relying on non standard behavior
at least, it can't in the general case
Iâm completely lost and just gave up on specifying licensing metadata correctly for the time being. Is there some overview document that tells me
- which combinations of fields are recommended
- which ones are deprecated
- and what exactly they all do
Right this second, it's https://packaging.python.org/en/latest/specifications/declaring-project-metadata/#license . But PEP 639 will very likely change all of this.
Ah, I thought that was already accepted. OK cool so assuming this section won't see any changes: https://peps.python.org/pep-0639/#project-source-metadata
I can use hatch right now and specify
license = 'GPL-3.0-or-later'for my own,license = 'LicenseRef-Proprietary'for my company's projects- Don't specify
license-files.globsas it defaults to a list that capturesLICENSE
The to-be-deprecated behavior is to specify a license classifier in classifiers or to specify a table as value for license.
Did i get that right?
Python Enhancement Proposals (PEPs)
yup!
Oh, because of limitations in the RFC *822 file format, because of the semantic "Text indicating the license covering the distribution where the license is not a selection from the âLicenseâ Trove classifiers," or something else? How does that intersect with license.file, then? Would be very interested to know more.
For PEP 639, I have https://peps.python.org/pep-0639/#appendix-user-scenarios (which will be moved to its own document, and hopefully to a PyPUG Guide or similar if/when the PEP is accepted giving) giving a high-level overview and https://peps.python.org/pep-0639/#appendix-examples which gives both basic and complete examples. For the legacy approach, my current guidance is just "Use license classifiers if it precisely specifies your license (see https://peps.python.org/pep-0639/#mapping-license-classifiers-to-spdx-identifiers for details, and use a SPDX identifier/expression in license.text"
You've summed it up right, and avoiding license-files if you don't need it (as the specified default globs should capture most first-party license cases; the ones I specified in the PEP are the same ones I added to conda and wheel some time ago, which spread to Setuptools and elsewhere) will insure you against any changes there. license seems pretty unlikely to change at this point since there was clear consensus on the current approach; after careful consideration I am solid on the current design for license-files and there haven't been any major objections, but its not inconceivable Brett or others could want a change, e.g. going with just a top-level key and either the paths semantics https://peps.python.org/pep-0639/#only-accept-verbatim-paths, the globs semantics https://peps.python.org/pep-0639/#only-accept-glob-patterns or some (un)happy medium https://peps.python.org/pep-0639/#infer-whether-paths-or-globs I don't expect the default behavior to change, though, since it is what most if not almost all current tools do now, so it should be safe to rely upon.
Python Enhancement Proposals (PEPs)
the file format can't actually handle new lines in anything but the body of the metadata file
you can sort of fake it by using the RFCs case folding
but if you unfold the case folding, then you lose the new lines completely
@noble matrix longer form - https://github.com/pypa/packaging/issues/570#issuecomment-1186286610
For those who work on packaging, would it be fine to update Specifier.filter and SpecifierSet.filter's return type annotation to use Iterator instead of Iterable? It's causing mypy to think next isn't supported on the return result of those methods as the Iterable protocol only requires __iter__.
I was about to submit a PR, but I thought "hmm, maybe this type annotation is purposefully lax so the API (specifically what it returns) can be changed later on." đ
Hmm, actually it's probably better to not change the return type annotation, I don't want to make changes to packaging even more annoying :)
wrapping the method in a iter(...) call isn't that annoying
The return type of the filter builtin is Iterator, so it's likely sensible to do that. Wanna file a PR?
SupportsIter[SupportsNext[T]]?
I'm not sure how that's any better than Iterator
Also a bit of an odd interface
Maybe you want a Callable[[Version | str], bool]
Then people pass it to whatever filter they want
what...? why would you want a callable anywhere in Specifier.filter ?
It's filtering an iterable of versions (either str or packaging.versions.Version) using the specifier value of the instance, currently returning an iterable
Matching return type of filter makes sense. Side note, this makes me kind of want to be able to write filter(specs.matcher(prereleases), versions) but itâs probably me being weird
I'm proposing a brand new method
People would use it with:
[x for x in items if specifier.specified(x)]
wait does that actually work? @mortal shore ?
it should
there's also .contains()
.filter() is smarter than contains though
This method is smarter than just ``filter(Specifier().contains, [...])``
because it implements the rule from :pep:`440` that a prerelease item
SHOULD be accepted if no other versions match the given specifier.
Maybe just pick the most efficient implementation and expose that as the only implementation
well it depends on what question you're asking exactly
Both are awkward with prereleases=True (functools.partial is cumbersome)
I was going through PEP 517 again tying to understand the metadata_directory for prepare_metadata_for_build_wheel...
Does anyone know if there is any guarantees about metadata_directory not containing any previous files at the prepare_metadata_for_build_wheel stage? Is it valid to pass metadata_directory="."?
I can see that the backend can add other files to this directory, but there seems to be no restriction about it being pre-populated before the first time the backend is presented to it.
metadata_directory must be a directory generated by the prepare hook
the goal is to allow people to look at the metadata without building
Thanks Filipe, but I am referring to the step before the build_* method, when the metadata_directory is passed to the prepare_metadata_for_build_wheel hook itself (ie, before the .dist-info directory is generated).
In my mind this should be simply an empty directory (possible temporary), which then would be used by the prepare hook
But, this does not seem to be guaranteed by the PEP... so apparently it could be any directory?
Ok, thank you very much for the clarification
IMO the build backend should just do its own thing and let errors raise in case of conflicts etc
but in practice, I think practically everyone is supplying an empty directory
otherwise you risk issues đ
It seems that . is also being used, which may contain .tox/.venv
Well, time to revert some refactoring I did last time
hum, interesting
I don't think you should use that directory for anything other than actually writing out the metadata
Yeah, it is more about a check that I changed, although the PEP does seem to allow other files to be written there (that are not metadata, e.g. could be some sort of cache)
Anyway, thank you very much Filipe
Yes the PEP only says the backend must put metadata files there, as long as you do that, other files are not forbidden
Actually IIRC there were discussions to use that as a cache directory to make rebuilds faster. The discussion didnât go anywhere but at least arbitrary files are not unexpected
Not that one. The linked thread is about the metadata output not being respected by build_wheel, not about the input of the prepare metadata hook
Changing it to Iterator on its own isn't accurate thanks to https://github.com/pypa/packaging/blob/main/packaging/specifiers.py#L915 which returns a list which itself is not an iterator. So to switch to Iterator will also require updating other code to return an iterator directly (which I'm personally not opposed to, just wanted to point out it's not a simple find-and-replace change)
I already noticed, I haven't filed the PR though ÂŻ_(ă)_/ÂŻ
thanks for pointing it either way! I reworded my PR description to note this just so we are making more informed decisions
What is the correct way to do codegen in the context of modern python packaging? I've tried searching the internets but nothing came up, though I might be using the wrong keywords.
By codegen I mean have data files and compile them to python files during build / packaging, so that on user systems the project can delegate the loading to python rather than need to parse the data files then convert that to python datastructures.
The impression I have from PEP 517 is that I should develop a local / custom build backend, do my codegen there, then delegate back to some other build backend, but I don't know that that's the right solution. Also are there frontends/backends to avoid for such a task (aka which just don't support it)?
And finally, old-style packaging (setup.py) allowed custom commands, is that still supported or should that be moved to external scripts / utilities / ...?
develop a local / custom build backend, do my codegen there, then delegate back to some other build backend
Yes
Also are there frontends/backends to avoid for such a task (aka which just don't support it)
The project-building API is entirely Python, so all backends should have at least some support for being called as a Python module (otherwise it canât work as a backend. All frontends should also support this since frontends treat all backends the same
old-style packaging (setup.py) allowed custom commands
I believe you can still write those if you want to, assuming you use setuptools as your build backend. But yes generally external scripts are more preferred
Thanks đ
By the way is there a known pattern / convention for making the delegation dynamic? I assume a local backend would just be hardcoded against the project's selected "real" build backend but how should a tool like cython or similar handle delegating after it's done its preprocessing? I assume it would be using a key in its own tools section but is there a customary name for the name of that key? And are there standard APIs for discovering backends the way frontends handle build-backend? Pep517HookCaller?
Since the PEP 517 API is just Python, you can just call the Python functions directly, no? And backends just read the TOML on their own, so you should just put the configs in their specified sections. Thereâs no magic involved whatsoever, just plain Python functions all the way down.
Yah but I meant if I create / provide a backend which only does codegen, it'll need to delegate to a "real" backend for the actual building, but I probably don't want to impose a backend on downstream users.
This means my codegen backend needs a way to configure and then call the real backend (or even chain into a second codegen / preprocessing backend).
So I was wondering if there was already a customary way to do that, or even direct support in foundational libraries.
No thereâs not an established way for that, as far as I know, so configuring it under your own tool section is probably the most straightforward way.
Thereâs a discussion on providing a cleaner way to hook directly into the build tool though (the most obvious use case is for C modules but essentially it covers any kind of âcompilingâ including codegen) but thereâs not much work done on it yet (let me find the link to that)
Ok cool! Thanks a bunch for the helpful answers.
You may want to look at using Hatch and it's plug-in system https://hatch.pypa.io/latest/plugins/about/
Modern, extensible Python project management
Sure. Is it able to find plugins in the project it's being used to build? From a quick overview of the plugins doc it seems to mostly talk about self-contained external plugins.
It has support for project local plugins
Those don't use the entry points as they need to be available before a editable/full wheel exists
No idea. When I hear "build plug-in", I think "Hatch" đ
@drowsy basalt every built-in Custom plugin on the left is project-local https://hatch.pypa.io/latest/plugins/about/
Ah cool, I'd missed that bit! Thanks, that should make it much easier.
In case you missed it, PyPI was subject to a phishing attack this morning: https://twitter.com/pypi/status/1562442188285308929
Today we received reports of a phishing campaign targeting PyPI users. This is the first known phishing attack against PyPI.
Weâre publishing the details here to raise awareness of what is likely an ongoing threat.
d'oh that's unfortunate :(
you should send an email at security@pypi.org if you haven't already
2fa is already forced on top 1% most downloaded packages
hide personal emails
emails can only be exposed by a package distribution so the project author can simply not include the email in package authors
provide a forwarding proxy email (same way github does it)
GitHub doesn't forward emails from their proxy emails
or however you want to call them
detect those packages and don't allow them to be posted in the first place
that's a noble goal but how do you propose this should get done? and someone has to work on this so another question is how do you think funding could be secured for this?
I know what you meant
as I said, it doesn't forward emails sent to that email
either way, it doesn't really seem like an issue if you can just not put your email if you don't want to be contacted about the package
but the thing is, the maintainers often want to be contactable
then they're signing up for it
I actually have no idea what you're asking to be done. How would you detect these packages?
A bit of context here...
The 'malware check' mentioned in the article isn't actually used on @pypi.
It was created as a proof of concept for a prototype detection system, and yeah, it's noisy (many false positives), but it also misses things & is hard to make better.
Why?
- force 2fa on packages that over 1000 downloads or packages that other packages depend on
That I somewhat agree with I guess? There's been a bunch of people discussing why 2fa wasn't just forced for everyone rather than just top 1% back when that happened on Twitter I think. I guess this would be sort of different since it wouldn't increase the barrier to making your first package (but you would very soon need to enable 2fa anyway so the barrier is still probably there as soon as you try publishing a second version).- require other maintainers approval before posting new release (same way github does it)
This might be something that will be doable with draft release functionality? Not sure, you might want to look for that.- hide personal emails and provide a forwarding proxy email (same way github does it)
I don't think making whole email forwarding thing is something that's really PyPI's job. And the only source of personal emails are the packages themselves so this is part of the distribution, it's not something that PyPI can just hide, it's literally part of each distribution if the project's maintainer added their email there. The email you have set up on your PyPI account is not publicly available on its own if you don't publish it yourself.- detect those packages and don't allow them to be posted in the first place
already talked about it above, not really anything else to add- detect those attacks (typos names, scraping of users emails, etc...) and block them along side with ip's of attackers (this won't stop them, but if you can't beat them slow them)
Scraping of users emails doesn't seem very detectable. Detecting typo names limits the available name choices to real packages a lot, I don't think it would work great unless you combine it with something else that would suggest that the package may be malicious.
â
Detecting typo names limits the available name choices to real packages a lot
Case somewhat in point, there's PyPI, there's PyPy, there's mypy (probably something else I'm forgetting, Python community sure seems to love these kind of names :)) which you could say are typo names
lol
btw publishing my new package mypi
that does not look like you
https://pypi.org/project/mypi/
unless you want to file a request for removal
but it looks like a real package, not a squat
let's put up their 2fa to a test
(no)
published in 2014 so technically mypy is the typo package!
damn
Oh wait Mypy actually has a previous life that goes back to 2009
was it name squat
No it got several releases, pretty legit to me
huh, a wsgi framework
it's part of the project endpoint
- you can just download the project distribution itself and get the same info
you can also just google for a pypi mirror and find one that doesn't implement any of this special handling
<@&815744082823348274> what about a PyPI channel?
what's the difference between a pypi channel and the warehouse channel
maybe warehouse channel should be renamed pypi
Not so smart people like me might actually find it, which has both pros and cons đ
I'd be in favor of renaming it
I feel dumb but... how does this https://github.com/microsoft/picologging/blob/main/setup.py + C++ files https://github.com/microsoft/picologging/tree/main/src/picologging create these binary wheels https://pypi.org/project/picologging/#files ?
CMakeLists.txt is compilation instruction. My guess is that with ninja and cmake in [build-system] it compiles automagically
yeah, they're using scikit-build
which wraps setuptools but does all the cmake build stuff
btw aside from using setuptools, is there any project that is gonna replace distutils for python 3.12+?
also, why is there no installer channel?
oh totally missed pyproject.toml, thank you both
Replace distutils directly? No, unless someone copies distutils and packages it up to be put up on PyPI. Otherwise look at other packaging tools like Flit, Hatch, etc.
You mean for https://github.com/pypa/installer ? No one has asked for a channel.
Not 1:1 replacement, but what I had in mind was a set of utils helpful in for example building C Extensions etc
For C extensions, Scikit-build (wrapping CMake) and Mesonpy (wrapping Meson) seem to be the main replacements projects are moving toward, though they are still under active development and evolving rapidly. However, Setuptools is (AFAIK) nearly a superset of what distutils can do when it comes to compilers, aside from really old/deprecated ones, hacky stuff, etc, as I understand it.
set of utils helpful in for example building C Extensions etc
#extensionlib eventually
Im wondering, what would be a good way to force in overrides for pyproject.toml settings on ci/other builds
Context is adding override tools to setuptools_scm/it's successor to ease stuff like test pypi uploads (which fail on dev versions with local tags) as well as easing builds for downstreams
Cc @lusty quarry @fallen shuttle
While we are at it, it would be nice to have a common standard for entrypoints of dynamic Metadata providers,
I'm not a tool expert like those two and maybe I'm misunderstanding the question, but from a standards perspective, the possible answers varies depending on the table (build-system, project and tool) you're interested in. TL;DR: There are other ways to dynamically override some settings in some tables downstream of pyproject.toml, but AFAIK the only general solution is to either have the CI/etc modify the pyproject.toml programmatically, or generate the pyproject.toml with another tool/backend at or before build time (which I believe exist). More specifically:
For [project], anything not explicitly listed as dynamic cannot be modified anywhere downstream of pyproject.toml, so in that case, the CI must modify the pyproject.toml directly (or have it be generated pre-build time). For dynamic settings, that depends entirely on the backend.
For [build-system], requires can be added to (but not, AFAIK, subtracted) by the get_requires_for_build_* PEP 517 hooks of the backend, which some backends allow you to control directly (e.g. setup_requires with Setuptools, which can be dynamic in a setup.py). I'm not aware of a way to modify the other items without just editing the file.
For [tool], it entirely depends on the tool involved, other than editing pyproject.toml directly.
Not asking for a standard wrt overrides, just need a rough agreement between tools
Oh, you mean for settings in the [tool] table? Or [project] keys listed as dynamic (e.g. entry-points)?
tool table
no need for agreement between tools. just have a plugin per thing that you care about that wraps the tool you maintain
In that case I'll just have json/toml in a env var allowing to replace all setuptools_scm configuration /version details, and I'll directly prepare it for the new tool name
Then I'll fix some details in setuptools_scm and prepare the rename /replace sometime within the next month
Btw, is there any recommendations for renaming / superseding a pypa package?
I'd just emit warning on import
I primarily mean organisational, if this was on me or pytest-dev I would simply do the work
There will be new pypi names, deprecations , backwards compat concerns, so load of fun
json/toml in a env var
it'd be nicer for ppl if your new tool supported various options as env vars rather than one that is a file dump, if you have time
Im happy to add something nicer if it comes from a lib that deals with the details
But right now im not going to invent one
I mean isn't it just foo = os.environ.get('PREFIX_FOO', options.get('foo', 'default'))?
There is multiple possible prefixes, handling types and validation, im not going to write that out or invent a good automation for it right now now, the rabbit hole doesn't fit my time constraints
because no one thought of making one for it :)
I was asking because I didn't know where to put a request for review: https://github.com/pypa/installer/pull/138
I'll defer to @high stone for whether an installer channel makes sense, but that sounds reasonable.
I didn't know installer has become a PyPA project, TIL.
Heh.
â¤ď¸
Merged it. Usually @-mention me on the PR, on a weekend?
thanks @high stone
Or Fridays.
will do in the future đ
Stuff slips, if I see it during the week day, but I usually do end up looking at my GH notifications some time during the weekend.
That reminds me I really need to clean up my github notifications
perhaps I should just mark all as done though. I used to save certain notifications for things that needed attention later on, but I do not have the time or energy to deal with that many things.
I open tabs then cull periodically
I use a tab snooze extension to re-open pages when I'm more likely to have time for them
https://chrome.google.com/webstore/detail/snooze-tabby/ododnaepjbicadkebdookecppfhjdmhp?hl=en
Anyone been able to tune dependabot's emailing? I get an email for every rebase etc. - Feel that's a little spamming. If so, got examples? Is it config driven or GUI clicking if so?
have you considered switching to something else :)
renovatebot maybe
or something based on GH Actions with cron
For the most part it's fine and I get it weekly. Just it's notifications are spammy and quick google wasn't fruitful so took lazy approach
You could also just disable automatic rebases in Dependabot
That might be a way - good call
because dependabot PRs are just standard PRs so you get same notifications as with any other PR
alternative is setting email filter for "@Dependabot pushed 1 commit" :)
FWIW there's also a configuration thing in https://github.com/settings/notifications#vulnerability-alerts-heading with a section for dependabot.
This makes sense to me. A general library + one plugin wrapping the library and acting as a bridge per backend. It seems quicker to achieve than a standard.
Regarding "dynamic Metadata providers": I am happy to participate in this conversation, but I welcome anyone that wants to lead it (I believe this is related to https://github.com/pypa/setuptools/issues/3415).
Is there a need for it? If we consider a core library is extracted from setuptools-scm, the setuptools-scm package in PyPI could only be the wrapper around this core library, acting as an adapter to setuptools plugin system.
I don't want to maintain dozens of integration packages on top of the new package +I want to get out of the accidentally exposed api of setuptools_scm
In that case, maybe what you seem to be looking for is indeed an interop PEP. I am again very happy to contribute on that, but I won't be able to lead the effort.
In https://github.com/pypa/setuptools/issues/3415 I expressed some ideas on what I think could be useful. This could be one way of doing it, but since the response was not very enthusiastic, I assume it is not what tool maintainers are looking for.
We probably need some ping-pong between what the tools are looking for and what the backends can provide. Based on the previous feedback, I think the best action for setuptools now is to take a step back and ask what the tool maintainers are looking for.
Then we can check if an implementation is viable, and if not, propose an alternative.
I pinged the hatch maintainer on that one, but it seems completely sidetracked now
There is multiple areas there, dynamic metadatas hooks are tricky
I don't have time to think about ^ for a while. too much work & Hatch stuff on my plate
just wanted to share that pip-audit and gh-action-pip-audit are now under the PyPA umbrella đ
The PyPA has voted to accept two new member projects: https://t.co/iX9r0T3oeI & the corresponding GitHub action, https://t.co/RVlB80Qkpx đ
pip-audit audits Python environments and dependency trees for known vulnerabilities, and the action lets you easily run these audits in CI.
Hello. We are doing a Packaging survey to understand community requirements- https://www.surveymonkey.co.uk/r/6TLZH3P. Please do submit your responses and RT-https://twitter.com/ThePSF/status/1565415698100359169
đđŚâ¨Python people!
We want your feedback on Python Packaging!
Please help us by responding to our survey @ https://t.co/2b7Bs6PfRQ
Please RT for reach!
đđŚâ¨
Specifically: I'd really like to see maintainers of various tools fill out this survey as well. :)
Is there a specification of the minimal set of names/attributes/things that are supported in pyproject.toml? In particular, none of the tutorials that I've found mention how to define the 'long description' of a package. (If this is the wrong place for this question, a pointer to the right one would be appreciated.)
https://peps.python.org/pep-0621/ this is not a tutorial by any means, but this is the current specification for [project] fields in pyproject.toml.
Python Enhancement Proposals (PEPs)
and then according to https://packaging.python.org/en/latest/specifications/core-metadata/, only these fields are strictly required:
- Metadata-Version (the backend will handle this for you, don't worry about it)
- Name (must be static)
- Version (can either be statically or dynamically defined)
Thanks!
is that page new(-ish)?
to be honest, I've seen enough talk about how the PyPUG needs a lot of work and is pretty outdated specifications-wise. So I haven't looked at the PyPUG in a while, assuming it wouldn't be particularly useful.
not sure how new it is
I don't mean to discredit the recent work put into the PyPUG, just my perspective on the optics
I think people have been trying to get the PEPs all into packaging.p.o
that's good đ
Whenever someone asks me, I always link to packaging.python.org over whatever PEP introduced the thing when possible. packaging.python.org is great for the most part, it's just hard to find because it just doesn't show up high in Google (or at all)
There's a bunch of documents in packaging.python.org that just link to the PEPs rather than describe it directly on the page and there may be some things that aren't there at all but still, most of the things that less experienced people are looking for already are available in packaging.python.org
welcome!
Good day famil
I want to be a contritor, just getting đ with open source development
what interests you packaging-wise?
Is having dev dependencies (linters or packages for docs building) defined as extras a bad practise or just a code smell? I see it in packages sometimes, is there any official information about it?
I donât think thereâs any âofficialâ recommendations (or any recommendations really), but itâs not best practice IMO. Dev dependencies should generally be pinned down (==) for reproducibility and extras are not suitable for the job
test and doc extras specifically actually have a defined meaning in core metadata spec
whether it's a good practice is up for debate I guess, I think it's alright
if it's a dedicated extra then pining in it isn't really bad
Yeah the problem is not that using them is bad (itâs not), but more about itâs difficult to maintain them (compared to say lock file or pre-commit)
Maybe bad practice is too strong; not optimal, more like
I usually declare them in extras and pin them in separate requirement files (requirements-test.txt, requirements-doc.txt). For linters I tend to use pre-commit which has its own pinning mechanism.
I never use requirement files for development dependencies or pin them in extras and in 12 years of using python maybe had 3 times issues because of it, when excluding the broken release fixed the issue đ¤ˇââď¸ so I don't know from where @spiral urchin statement comes from, especially considering Python does not have an official lock file.
IMHO pinning is overrated đ as long as you run your CI before you cut a release and you have an exhaustive test suite there's no real need for it đ¤ˇââď¸ IMHO.
The only place I pin is linters and type checkers đ
So I think we can agree that it's not a code smell in either way, if you have pinned dependencies, or if you use requirement files or extras of not đŤđ do what works for your pipeline
I wish the lock file pep had more adoption
For me pins primarily come as constraint files to ensure many people use the same versions
One thing I lament is people have become too unimaginative about locking đ Lock files come in many forms, npm/cargo/etc. style is but one way to approach it. You donât need to make that one format fit all use cases, and locking is usually still beneficial for a use case if you look past that particular format.
Dunno locking by design pins you in to run older versions of packages all the time which for OSS is bad for security. And having to deal with update lock file ever so often in general and my experience is more hassle than benefit đ¤ˇââď¸
I wish the lock file pep had more adoption
me too đ˘ after locking Hatch would be close to feature-complete
The pep was never accepted so would be pointless to adopt it đ¤
I mean the fact __pypackages__ not being accepted didnât stop people
Not that I recommend this personally
well good news: GitHub is finally implementing support for PEP 621 https://github.com/dependabot/dependabot-core/issues/3290#issuecomment-1237310790
I'm surprised someone (almost) without any Python experience is tackling this, but my goodness has it been too long. I'm happy to something is happening :)
I'm curious; I'm looking for a new home for scikit-hep/cookie, scikit-hep/repo-review, and the Scikit-HEP developer pages. They've become more general than Scikit-HEP with it's 11 backends, etc. I'm thinking I could merge them into a single repo (or maybe 2). Would that be something useful to propose to the PyPA? PyPA/quickstart or something? Otherwise I'll be targeting scientific-python project, which is fine. Just thought I'd see if there's interest here, or if people think they are too opinionated or specific, etc.
These overlap with the PUG and the sampleproject repo to some extent and I wouldn't want the scikit-hep pages to be "sullied" by the kind of pushback we've seen on modernising their PyPA equivalents. If you think you can maintain "editorial control" in the PyPA then why not, but I think people will start worrying about how these might or might not represent PyPA's position on various (rather dull) matters that the scientific community wouldn't have to concern itself with
Agreed, I'd not want it on packaging.python.org or some other "official" location, but "quickstart.pypa.io" or something similar doesn't seem too bad. It supports 11 backends, including all PyPA builders. But happy to continue toward putting it in scientific-python, just wanted to judge interest.
Same experience here. I almost never run into problems that would have been fixed by a lockfile, and think people should pin much less than they do. E.g. you donât want to pin in CI since you want to figure out when dependency changes break stuff so you can implement a workaround and/or file an issue upstream.
although there's an argument for pinning and using Renovate (or dependabot) to create update PRs specifically for dep changes, then you can see failures in isolation
I made #1017200598363406376
lol
kind of a nitpick, but the pypa org on github has the location set to USA, wouldn't it make more sense to remove it?
Hi, i've made a proof of concept for how to have python packages without a virtualenv: https://github.com/konstin/poc-monotrail
basically, i install every package once globally and then transparently hook them into the project using a path finder that reads pyproject.toml/poetry.lock or requirements.txt (doing dependency resolution through vendored poetry if required)
Usage is monotrail run python <normal python args>. You can use -p 3.x to select a python version, it will install the version you requested through python-build-standalone
I've also made an interactive mode for jupyter notebooks (monotrail.interactive(numpy="^1.21", pandas="^1")), a pipx clone (monotrail ppipx --extras jupyter black .) and a tox clone (monotrail run -p 3.8 -p 3.9 -p 3.10 command pytest). There's either a single standalone binary to download or a pip installable package, depending on how you want to run it.
Incidentally, i've also written a wheel installer that's faster than pip's singlethreaded (e.g. 5.8s vs. 7.6s for plotly on my laptop) and can additionally be multithreaded, if anybody is interested in reusing that
The idea is that you have one binary and can just run any project without having to use any environment management, not even installing python yourself
Or you can use PEP582 compliant package manager like PDM
as far as i understood pep582 still installs every wheel again for every project and python and you still need to manually control the content of __pypackages__, right?
Well, yes. Global packages make no sense since you can have one project use package X version 1.2.3 and another project using the same package in version 2.5
install every package once globally
What does globally mean in this context? Are they installed to the global site-packages?
no on the contrary; it's installed to .cache/monotrail, each wheel in a separate folder
the path finder has the resolved set of packages for your project incl selected extras and makes only those packages importable
I have thought about doing the same thing
Done. Not sure how or why that was set.
anyone got a source for PyPy wheel of several versions?
yes that's what I have been using but only has older wheels AFAICT
most recent is Python 3.6
>>> Version('4.0.0b2.dev1') >= Version('4.0.0b2')
False
>>> Version('4.0.0b2.dev1') <= Version('4.0.0b2')
True
why is this? đ
isn't .dev1 one step ahead of the base version? đ
that's the first development release of the second beta of version 4.0
not sure why it would go the other way?
because generally you don't keep releasing dev versions đ and then one day you release the non dev variant
and it's how setuptools-scm also works đ it adds dev versions on top of the last release
so if you tag a commit with 4.0.0b2 and do a release and then add a commit, the version will be 4.0.0b2.dev1 so in theory 4.0.0b2.dev1 is after 4.0.0b2
so the version comp should evaluate as such? cc @woven plover
that sounds like setuptools-scm is producing illogical version numbers
the above comparisons are as expected with PEP 440
duno, makes sense to me đ
it works the same as any other pre release tag
4.0.0b2 is the second beta release of version 4.0.0
4.0.0.dev1 is the first dev release of version 4.0.0
that makes sense
the only thing that's really different about it is you can make a dev release of another pre-release
which is kind of weird and esoteric TBH
but if you combine those:
4.0.0b2 is the first release of beta 2 (implied zero for dev)
4.0.0b2.dev1 is the second release of beta 2, no?
be that esotheric feels like should compare the other way đ¤
that would require special casing the order of dev releases when used in conjunction with other pre-release tags, which I don't recall anyone bringing that up during PEP 440 discussions TBH, so I won't say that we really thought about doing that specific thing in that specific combination other than PEP 440 explicitly calls it out as something to be avoided in most cases becuse it creates versions numbers that are "hard for a human to parse"
We probably would have still done it the way we did because I don't think tht particular edge case is worth making a special case for, and one of the goals of PEP 440 was to minimize differences in how versions parsed/sorted from the existing pkg_resources code, and pkg_resources sorted it that way too
but maybe?
in either case, that's as specified in PEP 440
if you look past the idealistic "version number should be easy to parse for a human" and adopt a version number is dynamically calculated I think makes sense the logic seutptools-scm applies here: https://github.com/pypa/setuptools_scm#default-versioning-scheme
- latest tag (with a version number)
- the distance to this tag (e.g. number of revisions since latest tag)
- workdir state (e.g. uncommitted changes since latest tag)
in abstract the mechanisms that setuptools-scm is using make sense
this generates version that are reasonably simple to read (at least for me) '4.0.0b2.dev27+g6a097123.d20220910 so that's 27 commits past the 4.0.0b2 release and has a marker for dirty dir
they're just not producing a logically ordered version version using PEP 440 versions
yeah đ hence me getting surprised here đ and wondered why would Version('4.0.0b2.dev1') >= Version('4.0.0b2') evaluate to False, but I see what you mean
@mossy pulsar setuptools_scm adds 1 to the last number by default, so the dev version is for the next version
foo.dev comes before foo
So increment(tag).dev ensures that we get a bigger version
@woven plover on your question in a now-deleted channel, about having packaging versions created without parsing: please file a new issue on the packaging repo?
There's currently no way to do what you want to do.
thanks
Does anyone know of a software distro that ships venvs instead of packages for applications?
With more and more things assuming venvs (narrow version ranges, lots of major bumps) it's becoming hard to package apps in distros with 300+ packages while keeping pip check happy. So I'm wondering if anyone has found a way to handle that.
kinda like an anti-debian approach if you will
doesn't homebrew do something like that?
Nix should keep applications isolated but it probably doesn't use venvs for this
nix doesn't use venvs, no
homebrew example
Homebrew does not ship venvs but creates a venv for each application (if the formula specifies it)
the goal is probably isolation so I figured it's probably worth mentioning it anyway
Itâs probably the closest you can get to shipping venvs
with venv I mainly meant isolated/vendored deps yeah
thanks, I'll have a look at homebrew
nix has isolation, allthos slightly foreign
They are supported on PyPI now, so thereâs less need for a channel like that. Conda also supplies PyPy (though not wheels!)
small PR in need of a review https://github.com/pypa/packaging.python.org/pull/1143
Huh
I found out that I've ran into it but I'm a bit surprised because it would seem that this should have prevented that?
https://github.com/pypi/warehouse/blob/2d8a05d052288bb21d97964d402d8cf9683bfd2b/warehouse/packaging/views.py#L118
until PEP 639 revamps license fields in package metadata, I guess I'll just depend on the classifier
yeah convo spawned from https://github.com/pydantic/pydantic/pull/4520#issuecomment-1248614645
Hmm, I was trying to figure out what things need to be done before packaging 22.0 could be released. I see that it adds packaging.metadata but there's a WIP overhaul of that in https://github.com/pypa/packaging/pull/574 which I guess 22.0 may be somewhat dependent on (either by waiting for #574 or by dropping metadata support in 22.0 and delaying it until #574 is done)? Since you probably wouldn't want to release packaging with metadata support in an unfinished state.
Looking through the repository, switching to flit and adding some release automation may be some other things that you would want to be done before cutting a release?
I see, it's because new lines are not actually present in PyPI's license field which I guess is side-effect of how email header parsing is done
FYI I have not given up on solving this problem. Work on it for me is currently blocked on https://github.com/pypa/packaging/issues/570 which is blocked on https://github.com/pypa/packaging/issues/570 (ping @mortal shore ).
nice! how is that blocking a lock file design though?
Parse metadata -> resolver for wheels only -> generate lock file -> install from lock file . IOW trying to do the right thing by making sure there are libraries backing everything takes time đ
https://peps.python.org/pep-0665/ has made me to want to create a working implementation before I try another PEP
Python Enhancement Proposals (PEPs)
oh I thought another format would be proposed
If by "another format" you mean "something other than what PEP 665 proposed" then it will be different (or at least tweaked). Going to start opinionated and see where that takes things by making it all very concrete. I have an idea on the "sdist locking problem", but I want to get wheels working first since it's easier
I'd strongly recommend the next PEP focus heavily on use cases, then detail the format
That's the plan. I am going to lean hard on my use-cases and then see where I get pushback to control scope creep
@blazing lantern oh also maybe remove that top level created-at to avoid https://github.com/python-poetry/poetry/issues/496
Interesting take on index mirroring https://github.com/ido50/morgan
When using hatch publish with an API token, hatch attempts to use the same cached token for all projects, because the repository user is always _token_. Is there a way to cache API token per-project?
I recommend asking on github or the hatch channel (with the caveat that the primary maintainer currently is travelling and won't answer quickly)
for all those interested, Cloudflare and Yubico are having a big discount on Yubico keys (10-12 Euro for a key): https://blog.cloudflare.com/making-phishing-defense-seamless-cloudflare-yubico/
Since when can you enable 2fa requirement on projects :O
https://twitter.com/pypi/status/1577009080052293633?t=S7w74guvJ6WnQH1iQlNU8Q&s=19
Either way, just enabled it on 10 more projects đ
I wonder if there's a library capable of understanding requirements files format, or is this something I should go ahead and reinvent?
tox 4 has some logic for this, inspired by what pop does
Looked at a few libs but neither were good enough
So perhaps check what tox 4 has đ¤ˇââď¸
Could be extracted to a lib
Depends on what you need this for, if this is just for your own use then simply parsing each line with packaging.requirements.Requirement after ignoring lines with sth like if not line.strip() or line.strip().startswith("#") could be enough for you
Poetry has a very exhaustive implementation
But it's an implementation detail of Poetry and not really designed for external use (it's specifically structured for our usage)
requirementslib? https://github.com/sarugaku/requirementslib
since July! đ https://twitter.com/pypi/status/1545455458529341440
We've also enabled a feature that will allow any project to opt-in to a 2FA requirement for its maintainers: this can be enabled in the settings for each individual project.
This can be enabled/disabled for non-critical projects at any time.
I need to support -e and -i and other strange things unfortunately...
Since when can you enable 2fa
I'm curious, what are others' thoughts on this? https://github.com/renovatebot/renovate/issues/10187#issuecomment-1264194234
Libraries do not need lock files is true in its purest form: distributing a lock file with a library is always wrong, but itâs very easy for people to interpret library to mean development of a library and talk about dev dependenciesâand they are also correct to an extent, since there is definitely benefit to be able to lock certain development tools such as Black and Mypy for consistent results. This is probably the worst thing about discussions mentioning the lib-app distinction: thereâs always people in a discussion messing up what those actually mean and the whole conversation gets derailed quickly.
It's also messy when considering formatters and linters with e.g. pytest. Formatters shouldn't be changing much, so getting bugfixes and faster perf is nice when you don't pin. Linters can lead to new lints, but maybe you want that? But pytest is an API for most and so you should be specifying at least a minimum version. Basically there's reasons for pinning and not pinning when doing library development and neither side is more right than the other. This is why VS Code tries to support both approaches, although admittedly our historical stance of pushing people to install per environment has led to consistent push back (people really don't like having multiple copies of the same tool installed), and thus we are changing our position.
our historical stance of pushing people to install per environment has led to consistent push back
Itâs kind of interesting though that pre-commit has been gaining popularity recently, which installs all those dev tools in separate environments behind the scenes. Or maybe those people pushing back also refuse to use pre-commit as well? I have no idea.
The guide is deployed via ReadTheDocs and the configuration lives at https://readthedocs.org/projects/python-packaging-user-guide/. Itâs served from a custom domain and fronted by Fast.ly.
how is it possible to deploy on rtd, hide behind a cdn, and have rtd redirect to the custom domain?
or does rtd use fastly as their cdn?
Hi all! Anyone know if it's possible to use musllinux as an environment marker? I've been trying to pip install checkov under alpine, but fails since it depends on pyston and pyston-autoload for certain platforms, and wheels have only been built for manylinux. https://github.com/bridgecrewio/checkov/blob/master/setup.py#L72-L73
Unfortunately not, neither manylinux nor musllinux is a valid environment marker value (although I do wonder if thatâs a good idea; somebody must have raised this before)
Thanks! I've did a fair bit of googling without finding any mentions of this specific case. I only found someone wanting to use markers for cuda vs non-cuda systems. I think the easiest fix is either move the pyston stuff to optional or just start building the missing wheels
Probably a typo; please feel free to send a PR to fix that.
I don't know the exact details, but if it's anything like my blog, then it's having the CDN handle the DNS entry, have the CDN point to the actual source, RTD could redirect by only processing requests that come in via the custom domain and redirecting everything else
interesting
Question that should probably be obvious, but I can't find it mentioned anywhere: in a METADATA file, are the keys (Requires-Dist etc.) case-sensitive, or case-insensitive?
rfc 822 says case insensitive
Hello everyone I m still working on the
https://github.blog/changelog/2022-10-24-dependabot-updates-support-for-the-python-pep-621-standard/
Dependabot now supports updates to Python dependencies for pyproject.toml files that follow the PEP 621 standard for our supported Python package managers.
I hope this also means GitHub dependency graph starts working with PEP 621 packages?
so it really only works for dependabot đ
I donât really get why people need âused byâ on GHâŚ
Vanity is a very important motivation
I'm seeing an HTTP 530 error for https://packaging.python.org/
The Python Packaging User Guide (PyPUG) is a collection of tutorials and guides for packaging Python software.
back up and running now đ
I've had several positive interactions emerge from people and projects I've engaged with, after finding them via vanity searches on my projects. One even turned into a great feature request!
@glass sand changes to zipfile have to go to zipp first before going to CPython?
I assume a PR which adds some missing pathlib methods to zipfile.Path is uncontroversial hopefully right? Should/can I send that there then and then it'll make its way downstream to CPython?
@echo ruin The don't necessarily have to go to zipp first, but that's preferable because the workflow is simpler in that direction.
It's also beneficial to release in zipp first, get some feedback from the public, fix any unexpected bugs, then sync into CPython.
And yes, I don't expect any controversy in adding pathlib methods.
Great thanks, PR incoming in an hourish.
Hey there @echo ruin , been a minute
Just a few đ
Hey, I just found a malicious package on pypi, posted 15 hours ago.
May I name it here or is it better to just go through security@pypi.org ?
best to email
got it. ty!
using pep 621 and pep 508 specs, is this a valid dependencies array in pyproject.toml?
[project]
dependencies = [
'aiohttp>=3.7.0,<4.0; python_version < "3.11"',
'aiohttp>=3.8.2,<4.0; python_version >= "3.11"'
]
i'm not quite sure it is... i know this is valid for a requirements.txt file tho
First time I saw this construct.
Is it just me or does it feels somewhat weird/unintuitive to have a toml file and then have this 'list' stored as a semi-colon delimited string(especially with those nested quotes)?
It is a normal TOML list, it's just holding PEP 508 strings (which can contain semicolons). It pretty much looks exactly like it would inside setup.py, actually.
Yeah. IIRC there was a counter proposal PEP that suggested the approach using full TOML syntax (like Poetry does)
Yes there was a counter proposal: https://peps.python.org/pep-0633/ At the end (sadly) the PEP 508 syntax was chosen because a PEP for it already exists and is used to define build-system requirements according to PEP 518. Arguments against it like hard to write, hard to teach, hard to parse and probably hard to extend wasn't weighted in the amount I would do it.
I think we need this logic https://github.com/pypa/packaging/blob/main/packaging/tags.py#L435-L440 to be exposed in a public API. Currently, I am on the fence if it should be in packaging, or selectable by an argument in sysconfig.get_platform. Any thoughts?
I am leaning towards sysconfig TBH
but want to be careful about adding new APIs
I assume by âthis logicâ you mean choosing between native 32-bit, native 64-bit, 32-bit on 64-bit, cross the ARM/x86 split?
yes
A part of me kind of feel it shouldâve been in sys or platform TBH, but if thatâs not possible at least sysconfig
if you build a native module on a 64-bit platform with a 32-bit interpreter, build backends need to use a 32-bit tag
so they basically need to copy that code
well, platform already provides the information needed to figure it out, so I am not leading to much in that direction
sys doesn't have a full platform key anyway
so sysconfig seems a bit better to me
but this is very much arguable
Putting it in packaging is not a bad idea since this (in theory) needs to be future-compatible. Say if we bake this into platform, a 64-bit interpreter wonât be able to infer its own platform name on a 128-bit CPU; putting this in packaging allows for the possibility (just upgrade packaging)
true but that is an issue already
btw, I have some PRs in packaging adding similar stuff, which we need in meson-python, if you want to review https://github.com/pypa/packaging/pull/611 https://github.com/pypa/packaging/pull/613
@high stone (and anyone else who has an opinion) can/should we ignore these mypy type checking errors? https://results.pre-commit.ci/run/github/254940622/1668175618.ooMK-bVJRCGkZ0MoJ_GviA
Their failure doesn't relate to any possible runtime error
as far as I can tell
(you've replied outside the thread :P)
is there an uninstaller (or similar) project counterpart to the https://github.com/pypa/installer library?
If I have a setup.py, no matter how minimal, I can do python setup.py --version to see the version of my project (as well as a number of other bits of metadata).  What's the equivalent if I have a pyproject.toml-only package?
Donât think thereâs an out-of-the-box solution for that, I wonder if it makes sense to add this to #build
it's handy in my Makefile to get the current version number
@woven yarrow hatch version does that
What about other backends?
i know everyone here is probably sick of hearing it, but the proliferation of competing tools is baffling to people not interested in the mechanics of packaging.
Agreed
https://docs.python.org/3/library/importlib.metadata.html looks like an stdlib option
You could use python -c "from importlib.metadata import version; print(version('<package>'))" for a one-liner, but [I assume] it would require the package to be installed
I have the same question for python setup.py --name, I use it to pass to other commands, like to open its PyPI page or view download stats
@queen hornet hatch project metadata | jq -r .name or hatch project metadata name
And if we're not using Hatch?
I believe that this should give you the path to the dist-info folder:
import build
metadata_path = build.ProjectBuilder("path/to/project").metadata_path("path/to/project/dist")
Then for name and version specifically you can just parse the name of that folder (as it's just {name}-{version}.dist-info) and for everything else you would have to open metadata_path/METADATA file and parse it with email parser lib (or maybe importlib.metadata lib if that can parse external files, not sure)
Seems that importlib.metadata doesn't have any public API for parsing external files so yeah, you would have to just use email.message_from_string on contents of the METADATA directly.
I agree, it's annoying when people keep pushing you to switch backends when the backend you're using currently works just fine...
well, i didn't know what hatch does, but it seems to be much more than a backend. I'm not looking for total project management.
yeah, there's hatchling which is just the build backend and hatch which is whole project management tool
Hopefully this helps. Perhaps build could be extended with another API that would make this whole thing simpler but it's not as bad as I thought
I didn't know build has public API
Ohhh... There's build.util.project_wheel_metadata, I missed that...
yeah, you should use that đŹ
Because I completely missed that what I suggested wouldn't create an isolated env which is what this util will also do (unless you choose to disable it with isolated arg).
Whichever way you choose, note that some backends could not implement the hook that allows you to get just the metadata without building the wheel as well in which case the process might be slower than you'd like but on the bright side, all major backends seem to be implementing it (to my knowledge, hatch was the outlier until some time ago but now I don't think there is any)
Would be nice if the util had an option to not fallback and an option to call build_sdist instead of build_wheel for performance reasons though I'm sure the latter could definitely create some discrepancies in some cases but I feel like it could sometimes not matter to the user of that API, idk.
In this case not backend, but frontend. Hatch and most other workflow tools donât require you use their recommended backends (thatâs why we have standards!)
I get your point though, when a question like âhow can I do thisâ comes up, âswitch your workflow to use my preferred toolâ is generally not among the best sort of answers.
But it's also hard when everyone asks for their workflow to be supported. If we mandated static version numbers in pyproject.toml then you could just parse that to get the number, but then the setuptools_scm folks would be upset, so we created the concept of dynamic fields, which complicates things. Apply this to the various facets of packaging and you end up in our current situation of trying to meet people where they are with what they expect from setuptools while not locking people into setuptools
I understand there is likely not an easy balance to strike and things need to be evaluated case-by-base. In this particular one though I can imagine build or whatever tool to expose an interface for ârun prepare_metadata_for_build_wheel and extract something in the dist-info directoryâ as a general action.
yeah, build.util.project_wheel_metadata is that interface
I'd personally rather have something that spits out JSON you can pipe into jq (using the transformation from PEP 566) than setuptools-esque CLI flags. I'm not sure if that something should be build
it returns importlib.metadata.PackageMetadata instance
which aside from fields that can be defined multiple times is just a dictionary
it has a json field too
Yeah, the json method does the PEP 566 thing
so all we really need is a CLI to surface import build.util; print(build.util.project_wheel_metadata(".").json)
and, well, it should probably implement a cache... generating wheel metadata takes time
cache
There has been on-and-off talks that the frontend should have a way to provide a cache interface for the backend to reduce the cost of repeated hook calls
https://discuss.python.org/t/proposal-adding-a-persistent-cache-directory-to-pep-517-hooks/2303
I reluctantly added that to Hatch https://discuss.python.org/t/nobody-is-following-the-metadata-directory-promise-in-pep-517/6964/49
That's exactly what I was thinking and coming back here to suggest, so 2 votes for that idea đ. One question we would have to answer for ourselves, though, is how official we consider the JSON encoding scheme in PEP 566 since it isn't used anywhere officially (I don't think it's on packaging.python.org, but that's based on memory instead of checking the site)
It is used in pip inspect and pip install --report.
I'm looking for feedback on a draft blog post https://nedbatchelder.com/blog/202211/one_way_to_package_python_code_right_now.html and associated project (https://github.com/nedbat/pkgsample) that demonstrates how to make a Python project installable. I hope it doesn't come across too negative. What is unclear/wrong/confusing? I also don't understand if there are limitations because of this approach. Thanks for any comments â¤ď¸
Hi there, it's been a few days since I submitted the PR for installer : https://github.com/pypa/installer/pull/147. Can someone take a look at it and tell me what to improve so that it can be merged eventually?
- tool.setuptools table is in beta right now
- PyPI was planning to move away from login/password upload with twine in favor of api tokens so could be better to use those? Especially that you have to use them if you have 2fa (as you should) anyway
have you seen the recently updated official tutorial? https://packaging.python.org/en/latest/tutorials/packaging-projects/
I would recommend choosing Hatchling (as the official tutorial defaults to) especially for beginners
e.g. Hatchling supports static analysis tools for editable installations by default whereas the new setuptools does not i.e. it requires enabling an option for IDEs to work https://github.com/microsoft/pylance-release/issues/3407
people appreciate that https://github.com/netket/netket/pull/1365#issuecomment-1293171307
some more:
- uses Git-style glob patterns rather than stdlib globs to better match user expectations
- easy and explicit control of what gets shipped in the sdist target whereas with setuptools it's a mix of conditional wheel options and a MANIFEST.in file which can be quite confusing
disclaimer: ofek is the author of Hatchling đ
I'm a user and have been switching over from setuptools/setup.* to hatchling/pyproject.toml and it's gone just fine
Just curious - Do you have any experience with using setuptools with a pyproject.toml?
And... How complicated are your builds?
Do you do anything fancy?
for some I did a hop to setuptools/pyproject.toml as a stepping stone. so far for only simple pure Python libraries/CLI
Some useful tools for this:
-
https://github.com/abravalheri/ini2toml to convert
setup.cfgtopyproject.toml(but watch out for https://github.com/abravalheri/ini2toml/issues/50) -
https://github.com/abravalheri/validate-pyproject to check the output
-
https://github.com/tox-dev/pyproject-fmt/ to apply a consistent format
The validator and formatter have a pre-commits hook in case you want to put them in .pre-commit-config.yaml
I hadn't seen the updated tutorial. We clearly had similar approaches. Maybe I can abandon mine and just point people to that one. Nice.
personally in my migration I mostly have been concerned with tool.setuptools stuff being in beta as I would like to avoid distributing sdists that could quickly stop working
so I went with using setup.py for those things instead
About Hatchling: its readme is uninspiring: https://pypi.org/project/hatchling/, and hatch feels like more than I want. Will there be an effort to make hatchling seem more real all by itself?
in my defense, it is one sentence more than https://pypi.org/project/flit-core/ đ

Hello!
I'm going to point out a few things, but they're mostly pretty nitpicky. Overall it all seems pretty well put together, nice job!
I don't really have any comments about the blog post except -- what's this "writing docs" thing? Is that the name of one of your projects??
About the repo itself...
My biggest complaint is the inclusion of non-related file like an EditorConfig and a Makefile.
You're marketing this repo as a "just what you need to get started, nothing more", but then you're including, well, more.
When teaching, it's really best to leave out all the optional and/or non-related stuff, because newcomers will get confused.
Your Makefile is actually a perfect example of this. You're talking about "the simplest possible introduction to Python packaging", and then your repo comes up as "51% Makefile".
Preocts the Egg uses Makefiles too, and I sometimes use their repos as good examples of how to do packaging, and a couple of times I've almost accidently scared beginners away because they "didn't realize you need "so much "make" stuff" just to "make" a package".
Why make the version dynamic? It would be a lot less confusing to just leave it as a static field.
Having a dev-requirments.txt in addition to a pyproject.toml has you installing dependencies two different ways for the same package!
Since you already have a make target for it, I would just delete the dev-requirments.txt file outright.
But I would actually reccomend adding a "dev" extra to the pyproject.toml, which lets you do pip install --editable .[dev], which installs all of your normal dependencies and your dev dependencies all at once.
I stole that from Preocts as well and I've been liking it.
I would also mention the py for Windows, since most of your target audience will likely be using Windows.
Thanks, I waffled on whether to include the Makefile and so on. I made the version dynamic because it's easy and gives you an easier to maintain project.
I haven't used [dev] extras, but I can see the appeal.
I like the Makefile but it is definitely not clear that it wouldn't work on Windows and I imagine most people aren't already familiar with make. I thought about Windows but only really looked into whether twine commands will work without shell support for wildcards and as it turns out... They will!
Hello
You are being rescued
Please do not resist
I found it easier to quickly test Linux things on Windows than Windows things on Linux because man, Windows is heavy
I felt "stuck" on Windows for a long time since I need assistive technology things but Windows is awesome now
[dynamic version] gives you an easier to maintain project.
Really? How?
Genuine question -- I've never used it before
Personally, I've never used the version outside of packaging tooling, so the version only being in the packaging tooling file never bothered me
You sometimes may want to access current project version programatically and relying on packaging tooling file with this adds complexity. When itâs a variable, you can easily access it from code
I've liked having the version number available in the running code for a few reasons. This way makes that possible while keeping it in only one place.
Like in CLI tools for âversion flag
installer PR 147
I wonder if thereâre people attempting to use pre-commit for this. Instead of trying anything to deduplicate, itâs possible to simply duplicate but use tools to keep everything in sync.
That would add complexity. That tool would have to understand all build tools there are and hope they donât change they way they work. Other way would be to build package on each commit, but this sounds like a lot of wasted time and resources
Deduplicating version declaration adds complexity, you just push it into the build backend.
I can argue the exact same point for every build backend adding code to populate the version number either direction
surely there are fewer build backends than there are repos that would need pre-commit tooling? and pre-commit tooling doesn't replicate with the repo, so is easy to break.
Not sure what the difference is. Pre-commit tools can be shared as well, Iâm probably missing something from the argument against it
When I clone your repo, i don't get a pre-commit hook enable. I have to take a manual step to enable it. But you're proposing that a thousand devs install a precommit hook so that a half-dozen build backends don't have to add code?
(thousand is a low estimate đ )
No, only the devs that need to bump the versions need that hook installed. Everyone else just read the duplicated version strings from either pyproject.toml or __init__.py or wherever
there are many many devs that update version numbers....
⌠and those same number of devs also build the packages after bumping⌠still installing the logic from their chosen build backend when doing so
i must be misunderstanding something. I thought you were saying that it's not reasonable for every build backend to implement this feature. if the top five build backends implement it, then only five dev teams have to think about it. your alternative is for every project to have a pre-commit hook for their release people to make it work. It seems like an odd tradeoff.
First of all, I never said itâs not reasonable for every build backend to implement the feature. All I did was wondering whether the same can be done with a pre-commit hook. Not sure where the negativity came from.
With build tools, every dev building every project (which is usually a part of the release process) needs to install a build backend with extra logic that pulls version from code into package metadata. With a pre-comit hook, every dev doing version-bumping for a project (which is also usually a part of the release process) needs to install one extra thing to bump versions. The hook is developed once, or at most once for a backend, and that backend with a pre-commit hook available can then drop that special logic and rely solely on a static pyproject.toml. The two approaches seem to be on the exact same level of complexity to me.
I very much dislike pre-commit hooks
@woven yarrow If you'd like more feedback on your approach, I too have recently switched away from setuptools in favor of hatchling and couldn't be happier for the reasons already highlighted above. I made the switch after noticing that the official packaging tutorial had been updated with hatchling as the default
Every time I encounter pre-commit I just pip install the packages from pre-commit and run the commands manually, I can't be the only one
sounds like an overengineered approach... I honestly don't get the hate on pre-commit... (and maybe we should take it to #off-topic ?)
probably đ
sorry, i didn't mean to introduce negativity. You said "I could argue the other side" about adding complexity to build backends.
Do we think Hatchling will be presented more as a standalone tool in the future?
(and btw, sorry if I have hijacked this discord/channel/thread/etc!)
I don't know so much about the roadmap or what direction it's going, but I can say that it's been perfectly adequate for my needs. It seems to get out of the way so I can focus on my actual code instead of packaging it
suggestions?
on https://hatch.pypa.io/latest/ the very first thing says:
Standardized build system with reproducible builds by default
"build system" links to https://hatch.pypa.io/latest/build/#packaging-ecosystem & it's first line says:
Hatch complies with modern Python packaging specs and therefore your projects can be used by other tools with Hatch serving as just the build backend.
"complies" links to the PEP 517 configuration
I don't know how to make that more prominent
Thanks. My question was about hatchling, not hatch. When I look at hatch, it seems to do a lot of things, most of which I already have solutions for, so my inclination is, "not for me." Someone recommend hatchling as a build backend, so I go to read about it: https://pypi.org/project/hatchling/ A one-sentence readme doesn't help me adopt hatchling as a tool, and I am back to trying to understand hatch, whether hatchling will somehow hatch-ify my project, etc.
everything I linked is about Hatchling config
yes, but it is on the Hatch page. Will there be a Hatchling page where people can think and learn just about hatchling?
I will improve the readme ty đ
Fabulous, thank you so much.
no
oops. why not?
btw, I count the hatchling readme on pypi as "a hatchling page"
so maybe we are in agreement
in your makefile you have python -m build --sdist --wheel - this will build the sdist and wheel independently of each other. By default build will build a wheel from the unpacked sdist to make sure you've packed everything correctly
Just to be clear: I love everything you all are doing to improve the packaging world. I want to help educate and smooth the rough edges, and learn how to make better packages myself.
@woven yarrow oh btw Hatch can auto-migrate config https://hatch.pypa.io/latest/intro/#existing-project
If you're feeling brave, you can try this new thing I just made: https://github.com/greyltc-org/uninstaller
https://blog.trailofbits.com/2022/11/15/python-wheels-abi-abi3audit/ goes posted to the python-dev Discord server in case anyone is interested in tooling around verifying ABI 3 compatibility
It's meant to be an uninstaller counterpart to https://github.com/pypa/installer
I didnât read much of it, but why is whl_scheme needed? Entries in RECORD are all relative to the .dist-infoâs parent directory and shouldnât require any resolution beyond finding the dist-info directory. And that directory should be looked up from all entries in sys.path, not just in purelib or platlib.
any particular reason not to support python 3.7, 3.8 and 3.9?
No. They probably all work fine. I just haven't tested anything besides 3.10
The way I've written it, the package doesn't need to be importable to uninstall it. I don't even look at sys.path actually. The RECORD file locating I've got in there (today) uses pretty much the same logic that installer uses to figure out where to install it (where of course the package doesn't need to importable to install it). I have to do some more testing to check how important (this may be a real drawback to my approach though). installer uses whl_scheme iswhl_scheme here https://github.com/pypa/installer/blob/main/src/installer/__main__.py#L67 so I used it in the same way. Unfortunately in my project (today) the user has to supply this info whereas installer just looks it up from the wheel: https://github.com/pypa/installer/blob/0b72640fcdd95c80a73bb94eaa3377381ef5b8e0/src/installer/_core.py#L29-L33
so, for example, you could uninstall a package from a venv that's not active if you use the right --root
or you can activate the venv and not have to use --root
I do need whl_scheme because it can impact where I need to look to find the RECORD file[1]. the cli user interface i've exposed for selecting it is through the use (or not) of --not-pure-python
[1]: https://packaging.python.org/en/latest/specifications/binary-distribution-format/#what-s-the-deal-with-purelib-vs-platlib
Is it just me, or does anybody else consistently typo [tools.foo.blah] ? đ
where typo?
pyproject.toml
took me a while to realize the typo lol
I don't know if I do it consistently but I definitely did it before
well, to be that person, it isn't technically a typo (I don't think people validate pyproject.toml contents that strictly), it just wouldn't work lol
Yep, and my apologies to certain package manager maintainers to whom I've unfortunately bothered because of my typo.
it is a typo
if you type [tools.setuptools] when you meant to write [tool.setuptools], you made a typo
or I guess more generally a mistake if you didn't know that it's wrong
What pyproject.toml validation tools are available? Do package managers generally validate and warn, or are there external tools for doing so (which I'd imagine might be hard given the choices for consumers of pyproject.toml)
I'm an existence proof that sometimes you're eyes just glaze over that typo
whether something is a typo or not depends on the intentions of the author :)
I think package managers validate "their" sections of pyproject.toml or provide some command to do so
but I don't think there is a "universal validator" since it could only validate if tables' names are correct
I'm using https://github.com/abravalheri/validate-pyproject to validate (after https://github.com/tox-dev/pyproject-fmt to format)
Invalid file: pyproject.toml
[ERROR] `data` must not contain {'tools'} properties
I don't think TOML has the equivalent of JSON schemas, so I think you're looking at specific tools like what Hugo linked to
when i dug into TOML syntax recently, I was dismayed to see a few aspects that were neither Obvious nor Minimal đŚ
Like what?
Also interested
TOML syntax
Does this cover anything that wouldn't manifest as a build error or deprecation warning when building (e.g. with build and setuptools backend)?
I don't know
@noble matrix how's PEP 639 going?
Well, thereâs no reason you canât use json schema for toml, taplo does exactly that: https://taplo.tamasfe.dev/configuration/using-schemas.html#using-schemas
But how about the date types
hang onto the original value and validate it against format: "date-time" (or any of the other datetime format options)
but yes, the validator wouldn't be able to tell if the value should be of type string or a datetime
Thanks for the ping; I didn't want to reply until I had the PR up so I wasn't overpromising and underdelivering again, but I've been actively working through the final set of changes before starting a third and hopefully final round of review. Its mostly just adding the glossary and updating various places in the text to use it, though that ended up being a lot more comprehensive than I thought it would be (though also more of an improvement to the overall clarity and unambiguity).
I initially was just going to convert the existing terminology section into a glossary and use the PyPA glossary for the rest, but I ended up doing a complete rewrite/rework of the whole section to make it more focused, comprehensive and easier to navigate, and ensure the definitions were accurate, up to date, cross-referenced and more concise. That's done, and I've now been working through the document adding them and clarifying the corresponding language, which has ended up also incorporating other clarifications, cross-references and other textual refinements at the same timeâI'm about halfway through right now.
Once that's done hopefully in the next couple days, and address one other key point (related to the current "Tools" terminology and guidance, which I need to re-evaluate to align it with other PyPA standards and ensure is reasonable, clear and not over-complicated) I'll open a PR, and after that it's just the simple mechanical task of sticking the non-core parts in separate documents. To note, none of the changes should have meaningful normative impact on the content, as least isofar as you've implemented it thus far. I also want to make some non-user-visible formatting and technical changes (SemBr, using Intersphinx references instead of hardcoded URLs, etc) but I'll do that in the background after I've finished the others and start a new thread for a final round of discussion, so as to not block further substantive progress.
So... how is codegen supposed to work in modern python packaging?
I've an old library for which most of the behaviour is encoded as data files. For convenience & performance, these data files are converted to Python during packaging (or on demand for unpackaged use), currently that's achieved by overriding (hopefully) all the right distutils/setuptools cmdclass, but it's not entirely clear to me how that's supposed to work (even at a high level) following PEP 517 / PEP 518.
Is there something that's built-system independent, or is a custom build backend (?) necessary, or is this something which should be done by picking a build system / backend (hopefully one which supports this sort of things) then using its bespoke features to achieve? Is there a guide somewhere?
this should be done by the build backend of your choice (the one that supports this kind of operations)
I think you can still use setuptools
Is there a comparison of build backends which could allow picking one on that criteria? Or is this more of a case of "trawl through or try to find a project with similar needs and see what they use"?
I don't think there is a list, but as you mentioned setuptools, I would just stay with it until it doesn't fulfill your needs. Keep in mind most backends have none or very limited support for scripting via setup.py-like file
Shame. I'm using setuptools because I inherited it (and it was basically the only option for non-trivial stuff in setup.py anyway), so I figure if I'm going to redo packaging anyway I might as well redo the entire thing to a modern standard, seems a shame to just punt a bit.
didn't see the code, so it might be wrong, but maybe it would be a good idea to change the approach in code/data loading so you don't rely on such features?
setuptools supports modern standards
I imagine the main alternative that supports this kind of shenanigans would be hatch(ling)
Poetry can have plugins but it enforces an opinionated workflow on you, flit doesn't have plugins
There's also PDM which seems to support plugins too
But yeah, unless you're looking to switch, I'm not sure you really need to, setuptools supports modern stuff.
One argument I found for hatchling over setuptools is how editable installs work in setuptools after they started supporting pep 660 - not well with static analysis tools (though you can work around it)
But I personally use setuptools or flit for my things
I'm not sure that's very helpful as codegen doesn't seem to be part of any standard, so surely dropping setup.py would require finding a different way to perform the codegen step in setuptools anyway? It seems to be a bit of an open issue: https://github.com/pypa/setuptools/issues/2591. Apparently declarative cmdclass was added to setup.cfg https://github.com/pypa/setuptools/pull/2571 but it's not 100% clear that it will also work in pyproject.toml and the official doc say tools.setuptools is beta: https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html#setuptools-specific-configuration
@wicked canyon Hatchling supports custom build hooks:
The standard is describing how to communicate with a build backend to have it build an sdist/wheel archive so what is actually put in it depends entirely on the build backend
You were saying that you want to redo your packaging to a modern standard and I'm saying that setuptools supports those modern standards so you don't have to move away from it
I mean sure but I'm not especially interested in or wedded to setuptools, it's there because setup.py. I don't mind it per-se, but it's just the thing currently being hooked in to call the codegen code.
@wicked canyon example: https://github.com/facelessuser/Rummage/blob/master/hatch_build.py#L63-L80
Thanks, seems interesting, I'll take a look.
If you need to do something very custom you have to write some scripting or create a plugin for the backend of your choice... I believe you have no way around.
You might ditch setup.py if you use something like hatch, but you still will need some python file. At that point, does it really matter if your custom code is defined in a setup.py or path/to/your/customization_file.py?
I honestly have no idea. The entire ecosystem seems to be moving away from setup.py and towards a more declarative project management system so I figured taking a look might be a good idea in case it would make maintenance easier / simpler.
You might ditch setup.py if you use something like hatch, but you still will need some python file. At that point, does it really matter if your custom code is defined in a setup.py or path/to/your/customization_file.py?
Hopefully it would reduce the amount of code and the number of hooks to plug into, but I've no idea that it does. From the outside it seems a bit like the baseline is being churned and everything's off the rails, but I'll readily admit I've not had much of a look. Maybe its more to the benefit of tooling and having a one-stop shop? It seems like a great deal of improvements concern that to avoid the ever-increasing multiplication of bespoke configuration files.
The general recommendation is to use declarative metadata wherever you can which is supported by both setuptools and hatch.
In your call to setup() you would only be declaring the things that you're doing dynamically while declaring project name, dependencies and whatever other metadata directly in pyproject.toml.
So it's really a question of how much code you need to have to implement the thing you need with hatch vs setuptools but you definitely wouldn't have to declare any static metadata in py file in either.
Oh so it's possible to have some of the bits in setup.py and some in pyproject.toml? That does sound interesting as a first step, I'll look into that direction first then.
Thanks to you all.
It is, yes.
If it's an attribute that can be specified directly in the [project] table inpyproject.toml, you'll have to add it to the dynamic list but if you don't, you'll notice that immediately after trying to build since it will error and tell you that :)
a minimal working change would be a pyproject.toml with:
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
and setuptools will handle the rest. then you can move to non-setup.py metadata
it's probably not a bad idea to check whether build still works immediately after doing this as this causes pip to use build isolation and that could potentially break something depending on what custom stuff you're doing
This is a little bit surprising:
import email.utils
email.utils.parseaddr("Me [Some Department] <me@example.com>")
('', 'Me')
I would expect ('Me [Some Department]', 'me@example.com') or some kind of error if the input is invalid đ¤
Parsing of the originator fields is known to be very intricate. The rules are not very normalised (mostly since email address has very permissive rules)
I'm not sure if you control the input here but if you do then one thing you can do is quote the name
the problem is with the square brackets and it actually also occurs with email address too, I'm not sure how you can fix it there though
I once ran into it with an address in the form of 12345678+githubbot[bot]@users.noreply.github.com
Yes, I know this is very intricate. So I was hoping that email.utils is doing the hard part for me đ
Quoting works (if I use "!) đ
https://stackoverflow.com/a/24958244/9750706 seems to extract the rules quite good. So I still wonder if there's a package out there, that implement these rules already.
I summon the email oracle @bright parcel to bless us with arcane wisdom
To secure his favor, I present an offering of a holy <>
You might have some luck if you are willing to go a bit lower level and do some manual checks:
>>> from email.headerregistry import AddressHeader
>>> parsed = AddressHeader.value_parser("Me [Some Department] <me@example.com>")
>>> len(parsed.all_defects) > 0
True
>>> parsed = AddressHeader.value_parser('"Me [Some Department]" <me@example.com>')
>>> parsed.all_defects
[]
>>> parsed.mailboxes[0].addr_spec
'me@example.com'
>>> parsed.mailboxes[0].display_name
'Me [Some Department]'
whooh, looks promising đ Will play around a bit.
@soft glen is there a ticket open on this? It's been a long while since I looked at the RFCs or code. RDM often gets to these things sooner than I do these days. If there is a ticket, @-me (even though. I am on the email team)
@bright parcel No, I haven't opened a ticket for this until now. Is it worth it? Where should I open it.
If the issue is with the stdlib email not matching the relevant RFCs, then I'd assume on the CPython issue tracker...
The name value MUST be a valid email name (i.e. whatever can be put as a name, before an email, in RFC 822) and not contain commas.
Does this mean, the name must be quoted, if it must be quoted according to RFC 822?
It would seem that either it should be quoted (presumably by the backend), or characters invalid while not quoting should not be used (and the backend raise an error).
Absolutely. I have at least one project set up this way (albeit with setup.cfg for now, until setuptools+project.toml is out of beta), and will be migrating others over time.
I (1) dynamically exec() the version number out of a module in the package, and (2) replace the version of Read the Docs that any docs links point to (I want README to point to latest when shown on GitHub, but to a specific release/version when shown on PyPI).
See https://github.com/bskinn/sphobjinv for the most complete setup I've put together thus far
https://github.com/bskinn/jupyter-tempvars has an implementation with pyproject.toml
@coarse mason have you tried https://github.com/hynek/hatch-fancy-pypi-readme ?
I've not, no, but I've seen it. At whatever point I give Hatch a try, I'll definitely try that too.
(1) dynamically exec() the version number out of a module in the package
Why not just the standard
[metadata]
version = attr: sphobjinv.__version__
in setup.cfg, which is stable and has been around for many years, or
[project]
dynamic = ["version"]
[tool.setuptools.dynamic]
version = {attr = "sphobjinv.__version__"}
in pyproject.toml? Then you don't need a seperate version.py to exec either.
(2) replace the version of Read the Docs that any docs links point to (I want README to point to latest when shown on GitHub, but to a specific release/version when shown on PyPI).
That would still require a plugin or dynamic config in Setuptools, but that Hatch plugin @lusty quarry mentioned is specifically designed for that sort of use case, IIRC.
Really interesting project BTW; the name was really cryptic but once I actually gave it a look, it looks like something I'd find super useful
Actually, I think I just discovered it the other day looking for tools to programmatically extract Sphinx object inventory data; I just didn't make the connection until now since the impression I got of its main functionality looking at the docs vs. the readme was very different.
Skimming the docs (and not seeing the readme) I had no idea that its flagship functionality was interactive use searching for objects to reference via a CLI, and had assumed that it was mostly focused on use as a library (which is what I was primarily looking for at the time), since interactive use via the CLI is barely mentioned there. It was only checking out the Readme above that I realized it also contains core functionality for searching local or remote Sphinx object inventories in interactive use via a CLI, which also seems super useful to me.
I really like hatchâs ability to call a function to get the version dynamically. Then I use importlib.metadata.version() to extract the version number for display
Really interesting project BTW the name
1 dynamically exec the version number
Actually I think I just discovered it
If you like the CLI, you might also be interested in this little thing I stood up over the weekend: https://sphobjinv.sly.io/
I think the pkginfo release that just went out might have broken twine and gh-action-pypi-publish
(Trying to see what broke specifically, but twine is throwing odd lookin' AttributeErrors on builds) EDIT: PR: https://github.com/pypa/twine/pull/941/files
@high stone any chance for installer release? (mostly for types detection via py.typed marker)
I'm also waiting for him to check my PR#147 again
Both the old and new work on hand-written parser in packaging has been educative for me, cool work
what parser?
packaging package has a hand-written parser for marker and requirement strings
just leaving a note of appreciation for that work here đ
In PEP 508, it says:
specification = wsp* ( url_req | name_req ) wsp*
url_req = name wsp* extras? wsp* urlspec wsp+ quoted_marker?
Shouldn't it say (wsp+ quoted_marker?)?, like in the parsley grammar it also says (wsp+ | end)? Otherwise "pip @ https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686" (no whitespace after the url) were an invalid requirement and that clearly should be allowed
I spotted that too yesterday -- not sure if we should be updating that PEP or just copying it over to packaging.python.org and updating there.
if there's consensus to merge fixes, more examples and text clarifications i'm willing to port PEP 440 and PEP 508 over to packaging.python.org
My vote is to just update at packaging.python.org
Let's do packaging.python.org then. :)
tox 4.0.0rc3 is now out, this will soon become the stable release unless someone reports any more release blockers, help us test it with your project if you can! Thanks! https://tox.wiki/en/latest/changelog.html#v4-0-0rc3-2022-12-05 (tox 4 should be mostly backwards compatible with v3 minus some features long deprecated in v3 and now using isolated builds by default; as shiny new features I think the biggest are built-in wheel support instead of sdist for packaging, editable wheel support and fancy colors for reporting!)
i've made a PR to move PEP 508 to packaging.python.org, currently nearly verbatim without any content changes: https://github.com/pypa/packaging.python.org/pull/1177
This moves PEP 508 to packaging.python.org as discussed on discord
Diff between PEP 508 and dependency-specifiers.rst: https://gist.github.com/konstin/059c0e72ff77049e0eb2ce0d738990fd
Both the old and new work on hand
Please feel welcome to poke at the parser in this PR and try to break it. PR reviews are also appreciated, as is feedback on potential improvements to the error messages coming out of it. :)