#pep517 — Public Fediverse posts
Live and recent posts from across the Fediverse tagged #pep517, aggregated by home.social.
-
0 days since we went from "we should replace `setup.py` with a bunch of standardized #PEP517 backends" to "every package must have its own local PEP517 backend".
-
<+ionen> I feel like I'm updating uv/uv-build more often than I use it and it takes like 10000x longer to build than the package I use it for
Who would have thought that the #RustLang fad will make people force others to install humongous tools that don't bring any benefit to them.
-
Heya folks! I wanted to share some of the work I've been doing on ypkg, our package building tool. Today's achievement was re-writing the entry point of the program into a proper CLI using Typer. Doing this was necessary for the work I've done making ypkg #PEP517 compatible. It's not glamorous, but it is necessary.
You can follow along with the PR if you want: https://github.com/getsolus/ypkg/pull/114
- Evan
-
Dziś ktoś pytał w temacie walki z ostrzeżeniami o "przestarzałej" funkcjonalności w #setuptools (w #Gentoo zbieramy je i wypisujemy ponownie, więc ludzie faktycznie mogą je zauważyć). Myślę, że moją najlepszą podpowiedzią było: użyj innego systemu budowania.
-
Someone asked about fixing #setuptools deprecation warnings today (#Gentoo collects and reprints them, so people actually notice). I think my best hint is: use another build system.
-
Biblioteki eclass związane z Pythonem w #Gentoo są całkiem aktualne. Stosują się do aktualnych zaleceń i standardów, i usuwają na bieżąco rzeczy przestarzałe. Niemniej, mają za sobą długą historię, i najlepiej chyba to widać po nazewnictwie.
Biblioteki te powstały w celu zastąpienia wcześniejszych "distutils" i "python". Dlatego też nazwałem je odpowiednio "distutils-r1" i "python-r1", podążając za schematem rewizji dla ebuildów. Dla spójności, pozostałe biblioteki również doczekały się sufiksu "-r1": "python-any-r1", "python-single-r1" i "python-utils-r1" — mimo że nigdy nie istniały w wersji "r0".
Wkrótce poznałem swój pierwszy błąd. Uczyniłem bibliotekę odpowiedzialną za budowanie paczek dla wielu implementacji "domyślną", prawdopodobnie w oparciu o ówczesne rekomendacje pisania ebuildów. Jednak z czasem odkryłem, że w większości przypadków (tam, gdzie nie używamy "distutils-r1") nie potrzeba takiej funkcjonalności, a ebuildy stają się niepotrzebne skomplikowane. Gdybym wybierał nazwy dzisiaj, najpewniej nazwałbym ją "python-multi", żeby podkreślić zastosowanie. A "domyślnej" albo by nie było w ogóle, albo byłaby nią "python-single".
Z "distutils-r1" jest jeszcze gorzej. Oczywiście, kiedy powstawała, distutils wciąż istniało, a niektórzy ludzie (jak ja) preferowali je nad zależnością od setuptools. A dziś zostało już całkiem pochłonięte przez setuptools, a za sprawą #PEP517 nawet "setuptools" nie jest już dobrą nazwą. No i ludzie dziwią się, że np. dla systemu budowania Hatchling mają używać "distutils-r1".
No i to już jest coś, co mogłem zrobić lepiej. Wprowadzenie wsparcia PEP517 była sporą zmianą, i zamiast dodawać zmienną DISTUTILS_USE_PEP517 (nazwa ze sprzecznością), mogłem utworzyć nową bibliotekę. Dlaczego tego nie zrobiłem? Cóż, jeden i drugi tryb dzieliły ze sobą sporo kodu, i nie było sensu go duplikować. Oczywiście, z czasem wspólnego kodu było trochę mniej, i w końcu wsparcie starego trybu wyleciało — ale to już po ptakach.
(1/2)
-
So #Gentoo #Python eclasses are pretty modern, in the sense that they tend to follow the best practices and standards, and eventually deal with deprecations. Nevertheless, they have a long history and carry quite some historical burden, particularly regarding to naming.
The key point is that the eclasses were conceived as a replacement for the old eclasses: "distutils" and "python". Hence, much like we revision ebuilds, I've named the matching eclasses "distutils-r1" and "python-r1". For consistency, I've also used the "-r1" suffix for the remaining eclasses introduced at the time: "python-any-r1", "python-single-r1" and "python-utils-r1" — even though there were never "r0"s.
It didn't take long to realize my first mistake. I've made the multi-impl eclass effectively the "main" eclass, probably largely inspired by the previous Gentoo recommendations. However, in the end I've found out that for the most use cases (i.e. where "distutils-r1" is not involved), there is no real need for multi-impl, and it makes things much harder. So if I were naming them today, I would have named it "python-multi", to indicate the specific use case — and either avoid designating a default at all, or made "python-single" the default.
What aged even worse is the "distutils-r1" eclass. Admittedly, back when it was conceived, distutils was still largely a thing — and there were people (like me) who avoided unnecessary dependency on setuptools. Of course, nowadays it has been entirely devoured by setuptools, and with #PEP517 even "setuptools" wouldn't be a good name anymore. Nowadays, people are getting confused why they are supposed to use "distutils-r1" for, say, Hatchling.
Admittedly, this is something I could have done differently — PEP517 support was a major migration, and involved an explicit switch. Instead of adding DISTUTILS_USE_PEP517 (what a self-contradictory name) variable, I could have forked the eclass. Why didn't I do that? Because there used to be a lot of code shared between the two paths. Of course, over time they diverged more, and eventually I've dropped the legacy support — but the opportunity to rename was lost.
In fact, as a semi-related fact, I've recognized another design problem with the eclass earlier — I should have gone for two eclasses rather than one: a "python-phase" eclass with generic sub-phase support, and a "distutils" (or later "python-pep517") implementing default sub-phases for the common backends. And again, this is precisely how I could have solved the code reuse problem when I introduced PEP517 support.
But then, I didn't anticipate how the eclasses would end up looking like in the end — and I can't really predict what new challenges the Python ecosystem is going to bring us. And I think it's too late to rename or split stuff — too much busywork on everyone.
-
Ciekawostki o Pythonowym "limited API" i "stable ABI".
1. #CPython ma "limited API". Jak się tego używa, to kompilowane rozszerzenia są zgodne ze wskazaną wersją i wersjami nowszymi. Takie rozszerzenia dostają sufiks `.abi3.so` (albo podobny) zamiast np. `.cpython-313-x86_64-linux-gnu.so`.
2. Wsparcie podzielone jest między CPythona i systemy budowania #PEP517. Np. w #setuptools podaje się `py_limited_api=`, i wówczas przy budowaniu dodawane są odpowiednie flagi kompilatora i podmieniany jest sufiks rozszerzeń. #Meson ma coś podobnego.
3. Ale wersja "freethreading" aktualnie nie obsługuje "stable ABI", więc przy budowaniu z "limited API" dostaje się błąd kompilacji. Podobnie, setuptools rzuca błąd jeżeli z interpreterem freethreading podamy `py_limited_api`, a Meson po prostu pozwala się wysypać kompilacji. Tak więc autorzy paczek muszą sami sprawdzać, czy użyto kompilatora "freethreading", i wyłączyć wówczas "limited API".
4. Bliżej nieokreślona przyszła wersja CPythona naprawi to wsparcie. Nie przyglądałem się tematowi dokładnie, ale podejrzewam, że będzie to tylko możliwe, jeżeli będziemy budować rozszerzenia dla tej bądź nowszej wersji. Więc ludzie pewnie będą musieli budować dwie wersje — tę dla starszych CPythonów, i dla nowszych + "freethreading". No i oczywiście będzie trzeba odpowiednio zaktualizować warunkowe załączanie "limited API".
5. No i jest jeszcze #PyPy. PyPy nie ma "stable ABI", ale pozwala budować rozszerzenia z "limited API". Setuptools i Meson po prostu wykrywają, że interpreter nie obsługuje sufiksu `.abi3.so`, i buduje rozszerzenia z normalnym sufiksem.
-
Some fun facts about #Python limited API / stable ABI.
1. #CPython supports "limited API". When you use it, you get extensions that are compatible with the specified CPython version and versions newer than that. To indicate this compatibility, such extensions use `.abi3.so` suffix (or equivalent) rather than the usual `.cpython-313-x86_64-linux-gnu.so` or alike.
2. The actual support is split between CPython itself and #PEP517 build systems. For example, if you use #setuptools and specify `py_limited_api=` argument to the extension, setuptools will pass appropriate C compiler flags and swap extension suffix. There's a similar support in #meson, and probably other build systems.
3. Except that CPython freethreading builds don't support stable ABI right now, so building with "limited API" triggers an explicit error from the headers. Setuptools have opted for building explicit about this: it emits an error if you try to use `py_limited_api` on a freethreading interpreter. Meson currently just gives the compile error. This implies that package authors need to actively special-case freethreading builds and enable "limited API" conditionally.
4. A some future versions of CPython will support "limited API" in freethreading builds. I haven't been following the discussions closely, but I suspect that it will only be possible when you target that version or newer. So I guess people will need to be building two stable ABI wheels for a time — one targeting older Python versions, and one targeting newer versions plus freethreading. On top of that, all these projects will need to update their "no 'limited API' on freethreading" conditions.
5. And then there's #PyPy. PyPy does not feature a stable ABI, but it allows you to build extensions using "limited API". So setuptools and meson just detect that there is no `.abi3.so` on PyPy, and use regular suffix for the extensions built with "limited API".
-
New reason not to use #PythonPoetry just dropped: they reinvented "reproducible builds", poorly. The problem is, they missed the purpose of reproducible builds entirely and they use it for source distributions too, and when you don't use SOURCE_DATE_EPOCH, they force all files to epoch (as in timestamp 0) instead of leaving them alone.
Like, all source distributions created by Poetry and uploaded to #PyPI now have 1970 timestamps that, simply speaking, break stuff. The most absurd thing is that ZIP can't handle that timestamp, so they override it and use another date for wheels 🤦.
-
co jest gorsze niż #setuptools? Paczka, która przechodzi na #Hatchling, ale wewnętrznie woła w paskudny sposób setuptools, żeby zbudować rozszerzenie w C — i w ten sposób ignoruje budowanie poza katalogiem źródłowym.
-
What's worse than #setuptools? A package switching over to #Hatchling, then internally calling setuptools in an awful way to build a C extension, completely bypassing out-of-tree builds.
-
Zapomniałem się pochwalić: w systemie budowania #hatchling jest błąd, który sprawia, że przypadkowo instalowany jest niewłaściwy zestaw plików, jeżeli buduje się w katalogu, do którego ścieżka przypadkiem pokrywa się z jednym z wpisów gitignore.
Na przykład, jak projekt ignoruje "var/", a my budujemy paczkę w /var/tmp…
-
Oh, I forgot to post that: there's a bug in #hatchling that makes it randomly install the wrong files if you're building in a path that just happens to match one of the gitignore entries.
Say, if upstream ignores "var/", and you happen to be building inside /var/tmp…
-
Więc uważacie, że wasz instalator do pythonowych paczek "wheel" jest spoko?
A czy obsługuje tworzenie dowiązań symbolicznych pomiędzy plikami `.pyc` na różnych poziomach optymalizacji, żeby zaoszczędzić przestrzeń dyskową, kiedy są identyczne?
A czy obsługuje tworzenie dowiązań symbolicznych pomiędzy wszystkimi plikami w różnych lokalizacjach (np. site-packages dla różnych implementacji Pythona), żeby zaoszczędzić sporo przestrzeni, kiedy instaluje się 6 identycznych kopii tej samej paczki?
Rzecz jasna, dopiero się przekonam, ile to psuje, ale #gpep517 19 wyszedł z tymi funkcjami, i mam gotowe łatki dla #Gentoo.
https://pypi.org/project/gpep517/19/
https://github.com/gentoo/gentoo/pull/41905 -
So you think your #Python wheel installer is cool?
And does it support symlinking `.pyc` files across optimization levels, so that you can save space when they are identical?
And does it support symlinking all files across different install locations (e.g. site-packages for different Python implementations), so that you can save lots of space when you are installing 6 identical copies of the same package?
Of course, I am about to find out how much these symlinks break, but #gpep517 19 is out with support for all this, and #Gentoo eclass patches are ready.
https://pypi.org/project/gpep517/19/
https://github.com/gentoo/gentoo/pull/41905 -
Uwaga: #setuptools ogłosiło, że `setup.py install` wyleci 2025-10-31.
-
PSA: #setuptools added a deadline for `setup.py install` removal: 2025-10-31.
-
#PEP517: rozdzielmy część backendową systemu budowania od frontendów.
Praktycznie wszystkie backendy PEP517: mają własny frontend.
-
#PEP517: let's split build system backend from frontend.
Practically all PEP517 build systems: bringing their own frontend.
-
#Gentoo is also going "full #PEP517" now, or to be more precise, we are going to rip out the legacy code paths that used `setup.py install`. However, that doesn't mean that PEP517 support is a solved problem.
1. There are still packages that require `setup.py install`, and either outright reject or ignore PEP517. And I'm not talking of dead packages but actively maintained projects. #Fail2Ban is a particularly notorious example (the way I see it, it's going to stop working sooner or later).
2. Some packages that do work with PEP517 builds, still require some hacks to install correctly. Sometimes it means moving files around, sometimes installing some files manually, sometimes patching stuff.
3. There are many packages that use the legacy setuptools backend to workaround their broken PEP517 port. Fortunately, these are at least easy to fix, provided you can convince upstream that actually altering sys.path is the correct solution.
4. Finally, we have removed a fair bunch of "hopeless" packages.
-
#Gentoo przechodzi na "100% #PEP517", a dokładniej, to usuwamy kod wspierający `setup.py install`. Nie oznacza to jednak, że ekosystem doczekał się bezproblemowego wsparcia dla tego standardu.
1. Nadal mamy paczki, które wymagają `setup.py install`, i albo odrzucają, albo ignorują, PEP517. I nie mówię tu o nierozwijanych starociach, lecz aktywnych projektach. #Fail2Ban jest tu przykładem wartym nagany (jestem przekonany, że prędzej czy później przestanie działać).
2. Niektóre paczki działają, ale wymagają obejść. Czasem trzeba przerzucić pliki po instalacji, czasem trzeba doinstalować jakiś brakujący plik, a czasem coś połatać.
3. Wiele paczek nadal wymaga przestarzałego ("legacy") backendu setuptools, by obejść problemy z portem na PEP517. Szczęśliwie, z reguły łatwo się je naprawia, o ile uda się przekonać autorów, że modyfikacja sys.path to właściwe rozwiązanie.
4. No i sporo paczek, dla których "nie było nadziei", wyleciało.
-
Skoro już ugaszono te największe pożary, porozmawiajmy o innych fajnych rzeczach, które dzieją się z #setuptools.
Na ten przykład, setuptools niedawno zaimplementowało PEP 639 (nowe metadane, dotyczące licencji). Przy okazji oznaczyli swoje poprzednie pole `license-field` jako przestarzałe, dając ludziom czas do 2026-02-18 na podmianę. Ostrzeżenie podpowiada też, że nowe pole wymaga setputools w wersji 77, którą wydano… tydzień temu.
No więc setuptools praktycznie mówi nam, że mamy do wyboru: albo używać starego rozwiązania, które oznacza, że wszystkie używające go wersje paczki przestaną się budować w lutym przyszłego roku, albo nowego rozwiązania, które wymagać będzie wersji setuptools sprzed tygodnia (i pozbawi was możliwości wsparcia starszych wersji Pythona, które najwyraźniej obchodzą jeszcze parę projektów).
No i rzecz jasna społeczność pythonowa podpowie: przypnij konkretną wersję zależności. Możecie sobie wyobrazić, jaka to będzie wielka frajda, kiedy jedne projekty zaczną arbitralnie przypinać wersję setuptools (np. do <77), żeby pozbyć się ostrzeżeń, a inne będą wymagać >=77 ze względu na nową konfigurację.
W takim razie… może mają państwo ochotę porozmawiać o systemie budowania flit? Albo o hatchling?
PS. A najśmieszniejsze w tym wszystkim to, że ostrzeżenie odnosi się do instrukcji, której jeszcze nawet nie zaktualizowano i która nadal twierdzi, że setuptools nie obsługują PEP 639.
https://github.com/pypa/setuptools/blob/6ead555c5fb29bc57fe6105b1bffc163f56fd558/setuptools/config/_apply_pyprojecttoml.py#L100-L106
https://web.archive.org/web/20250324035753/https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license-files -
So, now that the urgent fires have been put out for the time being, let's talk what other fun stuff #setuptools are doing these days.
For example, they have implemented PEP 639 recently (new license metadata). While doing that, they immediately deprecated their previous `license-field` field, giving people until 2026-02-18 to update their projects. The deprecation warnings also gives a helpful hint that you need setuptools 77 for the new field, which was released… a week ago.
So yeah, setuptools pretty much tells you that you need to choose between the old solution that means that all the versions of your package using it will stop building next February, or the new solution which means that your package will now require a week-old setuptools release (and effectively kill support for EOL Python versions, for which some projects apparently still care).
And of course the #Python community will tell you to solve the problem by pinning dependencies. And guess what happens when people put arbitrary pins (say, <77) to silence this deprecation warning, and other people have >=77 dependency, because they use the new variant.
So… would you like to talk about flit, perhaps? Or hatchling?
PS. The best joke is that they're pointing at a packaging guide that hasn't even been updated yet and still states that setuptools do not implement PEP 639.
https://github.com/pypa/setuptools/blob/6ead555c5fb29bc57fe6105b1bffc163f56fd558/setuptools/config/_apply_pyprojecttoml.py#L100-L106
https://web.archive.org/web/20250324035753/https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license-files -
> Nowy system budowania #PEP517 zbudowany na "dziesiątkach lat doświadczenia w ekosystemie i pracy z oprogramowaniem enterprise w skali światowej." [tłum. własne]
Sprawdza.
> Cykliczne zależność od samego siebie, przez co w ogóle tego nie da się zbudować.
-
> A new #PEP517 build system built on "decades of experience in the ecosystem and working on enterprise software at a global scale."
Looks inside.
> A cyclic dependency on itself, making bootstrap impossible.
-
Porównajmy backendy #PEP517 dla paczek napisanych w samym Pythonie:
#flit-core: 51 KiB archiwum źródłowe, bez zależności, instaluje się 0,05 s, ~150 KiB po zainstalowaniu, działa wszedzie
#UvBuild: 300 KiB archiwum, wymaga ~250 zależności crate (54 MiB pobierania, ~600 MiB w .cargo), buduje się 1 min 20 s (na 12-wątkowym procesorze), 4,2 MiB po zainstalowaniu, wspiera kilkanaście platformI oczywiście, że flit-core ma szerszą funkcjonalność. Ale jestem przekonany, że gdzieś ktoś potrzebuje zaoszczędzić te kilka milisekund budowania paczek Pythona.
-
Let's compare #PEP517 backends for pure #Python packages:
#flit-core: 51 KiB sdist, no dependencies, 0.05 s to install, ~150 KiB after installing, works everywhere
#UvBuild: 300 KiB sdist, requires ~250 crates (54 MiB download, ~600 MiB .cargo directory), 1 min 20 s to install (on a 12-thread system), 4.2 MiB after installing, supports a dozen platformsAnd yes, you guessed right, flit-core has more functionality. But I'm sure that there are performance-critical wheel building workflows that will benefit from these few milliseconds shaved off wheel building time.