Re: [Distutils] Immutability of Release Metadata in Warehouse
One case I could see is the use of the requires_python metadata. It was not included in the recent release of Django 2.0 (which is py 3 only) and making a new release will be useless as pip on py2 will still see Django 2.0.0 as Py 2 compatible download it and crash. I'm going to assume with time more packages will be affected even with minor version of Python. -- M On Dec 19, 2017 21:17, "Sumana Harihareswara" <sh@changeset.nyc> wrote: For those who want to track the relevant GitHub issues: * supporting Markdown https://github.com/pypa/warehouse/issues/869 * staged releases https://github.com/pypa/warehouse/issues/726 * advising packagers to run `python setup.py check -r -s` https://github.com/pypa/python-packaging-user-guide/issues/210 -- Sumana Harihareswara Changeset Consulting https://changeset.nyc _______________________________________________ Distutils-SIG maillist - Distutils-SIG@python.org https://mail.python.org/mailman/listinfo/distutils-sig
One case I could see is the use of the requires_python metadata. It was not included in the recent release of Django 2.0 (which is py 3 only) and making a new release will be useless as pip on py2 will still see Django 2.0.0 as Py 2 compatible download it and crash. Something similar happened to pytest - version 3.3 dropped support for Python 3.3 (the numbering is a coincidence, AFAIK). The requires-python
On Tue, Dec 19, 2017, at 9:10 PM, Matthias Bussonnier wrote: metadata was set in the package, but the package was published via a devpi server, which didn't preserve that metadata correctly to send to PyPI. So now 'pip install pytest' on Python 3.3 downloads the new version and fails, rather than downloading an older, compatible version. The only way the project can fix this is to delete the releases with incorrect metadata. I support the larger goal of making metadata on PyPI match the metadata in the package, however. Thomas
I support the goal of making metadata match files as well. One alternative is have the ability to "yank" a package. Make it still available, but installable only when pinned explicitly. I believe that's what Rust does. -- M On Dec 19, 2017 22:21, "Thomas Kluyver" <thomas@kluyver.me.uk> wrote: On Tue, Dec 19, 2017, at 9:10 PM, Matthias Bussonnier wrote: One case I could see is the use of the requires_python metadata. It was not included in the recent release of Django 2.0 (which is py 3 only) and making a new release will be useless as pip on py2 will still see Django 2.0.0 as Py 2 compatible download it and crash. Something similar happened to pytest - version 3.3 dropped support for Python 3.3 (the numbering is a coincidence, AFAIK). The requires-python metadata was set in the package, but the package was published via a devpi server, which didn't preserve that metadata correctly to send to PyPI. So now 'pip install pytest' on Python 3.3 downloads the new version and fails, rather than downloading an older, compatible version. The only way the project can fix this is to delete the releases with incorrect metadata. I support the larger goal of making metadata on PyPI match the metadata in the package, however. Thomas _______________________________________________ Distutils-SIG maillist - Distutils-SIG@python.org https://mail.python.org/mailman/listinfo/distutils-sig
On Dec 19, 2017, at 4:30 PM, Matthias Bussonnier <bussonniermatthias@gmail.com> wrote:
One alternative is have the ability to "yank" a package. Make it still available, but installable only when pinned explicitly. I believe that's what Rust does.
The ability to yank a package is something I’d love to introduce, unfortunately it will require changes to the API that tools like pip use, because PyPI does not currently have any idea why you’re asking for a list of the releases, just that you’re asking for one. We’d also want to do it in a way that doesn’t introduce unnecessary overhead in terms of HTTP requests or caching (for instance, previously pip would look up /simple/foo/2.0/ if you did ``pip install foo==2.0`` but we removed that because in 99% of cases it wasn’t going to be more helpful than just requesting /simple/foo/ and it made it harder to cache our pages I Fastly for everything). One possible solution is to simply add a ``data-yanked=true`` field on /simple/foo/. That would mean that much like requires-python you’d need to have a new enough pip to support yanked packages properly but it wouldn’t destroy our cacheability like the old method did. This wouldn’t require any real changes to any of the mirroring tooling and static mirrors would still be totally feature complete. Another possible option is to just exclude the yanked listing by default, but have something like ?yanked=true added to the URL which would then include *all* the yanked releases. This is “safe” to do in the case of ==, because adding extraneous yanked releases isn’t going to matter, since the == will only allow it to install one of them anyways. It bloats our cache a bit (two versions of the /simple/<foo>/ url for each project instead of 1) but it doesn’t completely destroy it like the /simple/foo/<version>/ scheme did. This option would mean that older versions of tools simply wouldn’t see the yanked versions ever, even with ==. It also would probably preclude the ability to have a fully static mirror, since you’d need something to handle the ?yanked=true handling (although we could maybe get around that by using something like /simple/_yanked/foo/ or something). There are possibly other ideas to handle this that I’m not thinking of offhand, but I think fundamentally the question will come down to whether we want older versions of the tooling to see yanked packages by default or not. Ultimately this is probably a big enough feature that it would deserve a PEP to flesh out the various options and to figure out which path we go down. Unfortunately I don’t currently have time to handle that, but would gladly participate in such a discussion if someone were to lead it.
Another thing that arises with yanking is the idea of deprecating releases or packages. While in many cases yanking is sufficient, it's nice to have a way to explicitly deprecate rather than yank packages that are e.g. no longer maintained, have been renamed, or have better replacements, without necessarily cutting a new release (as that may not inform existing users). I've done so for my packages before by editing the package description and replacing it with a deprecation notice. On Tue, Dec 19, 2017 at 4:46 PM Donald Stufft <donald@stufft.io> wrote:
On Dec 19, 2017, at 4:30 PM, Matthias Bussonnier < bussonniermatthias@gmail.com> wrote:
One alternative is have the ability to "yank" a package. Make it still available, but installable only when pinned explicitly. I believe that's what Rust does.
The ability to yank a package is something I’d love to introduce, unfortunately it will require changes to the API that tools like pip use, because PyPI does not currently have any idea why you’re asking for a list of the releases, just that you’re asking for one. We’d also want to do it in a way that doesn’t introduce unnecessary overhead in terms of HTTP requests or caching (for instance, previously pip would look up /simple/foo/2.0/ if you did ``pip install foo==2.0`` but we removed that because in 99% of cases it wasn’t going to be more helpful than just requesting /simple/foo/ and it made it harder to cache our pages I Fastly for everything).
One possible solution is to simply add a ``data-yanked=true`` field on /simple/foo/. That would mean that much like requires-python you’d need to have a new enough pip to support yanked packages properly but it wouldn’t destroy our cacheability like the old method did. This wouldn’t require any real changes to any of the mirroring tooling and static mirrors would still be totally feature complete.
Another possible option is to just exclude the yanked listing by default, but have something like ?yanked=true added to the URL which would then include *all* the yanked releases. This is “safe” to do in the case of ==, because adding extraneous yanked releases isn’t going to matter, since the == will only allow it to install one of them anyways. It bloats our cache a bit (two versions of the /simple/<foo>/ url for each project instead of 1) but it doesn’t completely destroy it like the /simple/foo/<version>/ scheme did. This option would mean that older versions of tools simply wouldn’t see the yanked versions ever, even with ==. It also would probably preclude the ability to have a fully static mirror, since you’d need something to handle the ?yanked=true handling (although we could maybe get around that by using something like /simple/_yanked/foo/ or something).
There are possibly other ideas to handle this that I’m not thinking of offhand, but I think fundamentally the question will come down to whether we want older versions of the tooling to see yanked packages by default or not.
Ultimately this is probably a big enough feature that it would deserve a PEP to flesh out the various options and to figure out which path we go down. Unfortunately I don’t currently have time to handle that, but would gladly participate in such a discussion if someone were to lead it. _______________________________________________ Distutils-SIG maillist - Distutils-SIG@python.org https://mail.python.org/mailman/listinfo/distutils-sig
participants (4)
-
Donald Stufft
-
Jimmy Jia
-
Matthias Bussonnier
-
Thomas Kluyver