Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

PyPI reports traitlets 5.2.2.post0 exists #12376

Closed
adam-grant-hendry opened this issue Oct 17, 2022 · 16 comments
Closed

PyPI reports traitlets 5.2.2.post0 exists #12376

adam-grant-hendry opened this issue Oct 17, 2022 · 16 comments
Labels
bug 🐛 requires triaging maintainers need to do initial inspection of issue

Comments

@adam-grant-hendry
Copy link

Describe the bug
First noticed in poetry Issue #6826, commitizen GitHub Actions CI workflows fail when poetry resolves traitlets:

Package traitlets (5.2.2.post0) not found

Neither the PyPI release history nor the repo releases indicate a version 5.2.2.post0 was released. However, when we curl pypi.org, we receive a hit for 5.2.2.post0:

$ curl -s https://pypi.org/simple/traitlets/ | grep 5.2.2.post0
    <a href="https://files.pythonhosted.org/packages/30/b6/43f78c203f11e7ce353ca7ca326332f8c020863b7904cc8aedea5a415f90/traitlets-5.2.2.post0-py3-none-any.whl#sha256=7109d1daa09aaf3aefd823eadde1d81508d039c74d9bed6b1812c58bea0cfe20" data-requires-python="&gt;=3.7" >traitlets-5.2.2.post0-py3-none-any.whl</a><br />

Expected behavior
PyPI does not identify traitlets==5.2.2.post0 as a released version with a wheel.

To Reproduce
Please refer to the details in the Describe the bug section.

My Platform

Additional context
See also traitlets Issue #729.

@neersighted
Copy link

Possibly related to caching ala #12214

@miketheman
Copy link
Member

For reference, the file 5.2.2.post0 can be found on the 5.2.2 releases: https://pypi.org/project/traitlets/5.2.2/#files

@miketheman
Copy link
Member

It appears to be a poetry issue, since I was able to downgrade to poetry 1.2.1 and successfully resolve all the commitizen dependencies. The issue is not in warehouse, as far as I can tell.

@neersighted
Copy link

neersighted commented Oct 18, 2022

I'm not convinced it's Poetry's fault -- Poetry 1.2.1 and Poetry 1.2.2 only differ in the PyPI API they consult. Poetry 1.2.1 would use the JSON API to gather filenames; Poetry 1.2.2 uses the PEP 691 implementation to gather filenames.

As determining what versions are available in the Simple API (whether HTML or JSON, PEP 503 or PEP 691) requires parsing filenames, PyPI is reporting that the spurious version exists, even if it's not reflected by the JSON API. I suspect that Warehouse somehow associated an uploaded .post0 release with 5.2.2 rather than creating a new release as one would expect.

Try curl --header "Accept: application/vnd.pypi.simple.v1+json" https://pypi.org/simple/traitlets/ to query the PEP 691 JSON API (which returns the same data as the PEP 503 Simple HTML API) -- you'll see the file there.

@miketheman
Copy link
Member

I'm not convinced it's Poetry's fault -- Poetry 1.2.1 and Poetry 1.2.2 only differ in the PyPI API they consult.

Maybe? The downgrade to poetry 1.2.1 shows the set of dependencies resolved working - resulting in traitlets 4.3.3 being successfully installed.
Changing the API used in resolution feels like more than a patch-level change to me, but that's my opinion only. Of course, if everything "just worked" then we wouldn't be having this conversation 😀.

I suspect that Warehouse somehow associated an uploaded .post0 release with 5.2.2 rather than creating a new release as one would expect.

This is an interesting preposition, so let's explore that a bit!

Looking at traitlets history for _version.py we can see that the release date for 5.2.2 was May 31, 2022 - which is when pypi version 5.2.2 and 5.2.2.post1 came into existence. 5.2.2 contains the post0 file as well as the non-post0 file, but there's no GitHub tag for 5.2.2.post0, whereas 5.2.1.post0 is tagged, has a "proper" pypi release, etc.

Sadly, we can no longer examine the GitHub Action execution logs or artifacts for 5.2.2 as they have expired: https://github.com/ipython/traitlets/actions/runs/2417447574

The GitHub tag for https://github.com/ipython/traitlets/releases/tag/5.2.2.post1 reflects a _version.py change from ipython/traitlets#739 - so there's definitely an open question in my mind of where the post0 file came from at all, as the traitlet's repo release strategy appears to be GitHub Tag-driven and hasn't changes since Sept 2021.
It's entirely possible this file was manually created outside of GitHub Actions in an attempt to "fix" the issue and never got a tag associated with it, and no commits exist in history for us to view.

Try curl --header "Accept: application/vnd.pypi.simple.v1+json" https://pypi.org/simple/traitlets/ to query the PEP 691 JSON API (which returns the same data as the PEP 503 Simple HTML API) -- you'll see the file there.

Absolutely, it definitely exists, and is confirmed associated with the 5.2.2 release via the JSON API:

$ curl -s https://pypi.org/pypi/traitlets/5.2.2/json | jq '.urls[] |select(.packagetype=="bdist_wheel") |.filename'
"traitlets-5.2.2.post0-py3-none-any.whl"
"traitlets-5.2.2-py3-none-any.whl"

One of the Warehouse Admins should be able to dig up some of the Journal history to determine how that file arrived. Either via the Admin interface at https://pypi.org/admin/projects/traitlets/journals/ or via a SQL query like:

SELECT version, action, submitted_date, submitted_by FROM journals WHERE name = 'traitlets' AND version LIKE '5.2.2%';

I'd expect to see entries like new release and add py3 file traitlets-5.2.2.post0-py3-none-any.whl that could help answer "how the file came to be" and associated with the 5.2.2 release.

@di
Copy link
Member

di commented Oct 19, 2022

warehouse=> SELECT version, action, submitted_date, submitted_by FROM journals WHERE name = 'traitlets' AND version LIKE '5.2.2%';
   version   |                       action                        |       submitted_date       | submitted_by
-------------+-----------------------------------------------------+----------------------------+--------------
 5.2.2       | add py3 file traitlets-5.2.2.post0-py3-none-any.whl | 2022-05-31 21:25:53.935778 | blink1073
 5.2.2.post1 | new release                                         | 2022-05-31 21:29:45.781932 | blink1073
 5.2.2.post1 | add py3 file traitlets-5.2.2.post1-py3-none-any.whl | 2022-05-31 21:29:45.781932 | blink1073
 5.2.2.post1 | add source file traitlets-5.2.2.post1.tar.gz        | 2022-05-31 21:29:47.281823 | blink1073
 5.2.2       | new release                                         | 2022-05-31 20:07:28.210021 | blink1073
 5.2.2       | add py3 file traitlets-5.2.2-py3-none-any.whl       | 2022-05-31 20:07:28.210021 | blink1073
 5.2.2       | add source file traitlets-5.2.2.tar.gz              | 2022-05-31 20:07:30.200664 | blink1073
(7 rows)

@di
Copy link
Member

di commented Oct 19, 2022

The issue can be found here: https://inspector.pypi.io/project/traitlets/5.2.2/packages/30/b6/43f78c203f11e7ce353ca7ca326332f8c020863b7904cc8aedea5a415f90/traitlets-5.2.2.post0-py3-none-any.whl/traitlets-5.2.2.dist-info/METADATA#line.3

The file traitlets-5.2.2.post0-py3-none-any.whl actually contains the version 5.2.2 in the metadata, and not 5.2.2.post0. In this case, we ignore the filename due to #12316.

This is probably a duplicate of #12316.

@neersighted
Copy link

Argh. Without metadata being served per PEP 658 here, it really seems like we can't win. I'm inclined to call this an issue with a bad package being uploaded by the traitlets authors, who likely need to delete the file in question.

Technically we can defend against this in Poetry by checking the JSON API for files we discover using the PEP 691 API (we still rely on the JSON API for metadata, after all), but that strikes me as the wrong way to try and solve this. I think declaring it a user error that PyPI currently does not protect against is more likely the way to go.

WDYT @dimbleby?

@dimbleby
Copy link

yeah, seems like we've got to the bottom of this one

  • user error uploading bad file
  • pypi doesn't spot this, leaving pypi in a confused state
  • poetry is not defensive against this

I don't immediately see a very straightforward way in the current code to have poetry tolerate this so from a poetry point of view I'd probably call this not-worth-the-trouble / MR-welcome-if-anyone-can-do-better.

warehouse maintainers will decide whether #12316 adequately covers this case or whether it's useful to track it explicitly.

@adam-grant-hendry
Copy link
Author

poetry and PyPI teams, thank you for looking into this!

traitlets team, I'm referencing traitlets Issue #729 for your visibility. I don't know who should be pinged from the traitlets team...?

@adam-grant-hendry
Copy link
Author

@neersighted @dimbleby Is there a way the bad file can be corrected while we're working/deciding on defensive strategies so CI workflows can run?

@adam-grant-hendry
Copy link
Author

I don't know who should be pinged from the traitlets team...?

Actually, from the report it looks like @blink1073 should be pinged on the traitlets end.

@blink1073
Copy link

I just yanked traitlets 5.2.2.

@adam-grant-hendry
Copy link
Author

@blink1073 Thank you!

@miketheman
Copy link
Member

I think this issue can now be closed, and we should consider how to resolve prevention via #12316

@adam-grant-hendry
Copy link
Author

I think this issue can now be closed, and we should consider how to resolve prevention via #12316

I agree.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 requires triaging maintainers need to do initial inspection of issue
Projects
None yet
Development

No branches or pull requests

6 participants