pip: pip does not ignore yanked version of package in unqualified installation when it's the only non-prerelease choice

Environment

  • pip version: 20.1
  • Python version: 3.8.2
  • OS: Arch Linux (using pyenv + virtualenv)

Description

If you have a package named mypkg with the following versions:

  • 1.0 (Yanked)
  • 2.0rc0

Running pip install mypkg will install 1.0 rather than 2.0rc0.

Expected behavior I would have expected 2.0rc0 to be installed, since that is what would happen if mypkg only published version 2.0rc0. This seems to be an edge case not super well-clarified in PEP 592, which states:

An installer MUST ignore yanked releases, if the selection constraints can be satisfied with a non-yanked version, and MAY refuse to use a yanked release even if it means that the request cannot be satisfied at all. An implementation SHOULD choose a policy that follows the spirit of the intention above, and that prevents “new” dependencies on yanked releases/files.

I believe 2.0rc0 satisfies the constraints specified if you do not consider “didn’t include --pre” to be a constraint, so depending on whether --pre or its absence a “constraint”, this may be a violation of the spec. I think the fact that pip install will take release candidates if nothing else matches argues in favor of it not being considered a “constraint”.

More clearly, though, it does not fit one of the two suggested implementation strategies:

  1. Yanked files are always ignored, unless they are the only file that matches a version specifier that “pins” to an exact version using either == (without any modifiers that make it a range, such as .*) or ===. Matching this version specifier should otherwise be done as per PEP 440 for things like local versions, zero padding, etc.
  2. Yanked files are always ignored, unless they are the only file that matches what a lock file (such as Pipfile.lock or poetry.lock) specifies to be installed. In this case, a yanked file SHOULD not be used when creating or updating a lock file from some input file or command.

Regardless of “spec lawyering”, from a user experience point of view, I am personally in favor of pip refusing to install yanked versions at all without an exact version pin (option 1). Right now it installs them but with a warning; I think the warning could be turned into an error that lists the yanked versions, and end users who want to work around the “can’t find a matching version” can add an exact version pin (though admittedly in some circumstances this can have perverse consequences if a package yanks a version because there’s something wrong with it and a consumer pins to the exact version as a workaround, thus preventing an update to a later working, non-yanked version).

How to Reproduce

At the moment the tzdata package has only yanked and release candidate packages on PyPI (and only release candidate packages on Test PyPI). Until a proper release is made of tzdata, you can reproduce it with:

  • pip install tzdata: To see the bug
  • pip install --index-url https://test.pypi.org/simple/ tzdata: To see pip’s behavior when only release candidates are available.

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 7
  • Comments: 26 (19 by maintainers)

Most upvoted comments

In fact: https://bugzilla.redhat.com/show_bug.cgi?id=2000135

Thanks, just in case you don’t already know a major fix for yanked packages was implemented in pip 20.3.2: https://github.com/pypa/pip/pull/9226 It looks like the pip that the user installs from redhat is 19.3.1?

The reason it became such an issue from 20.3 is that the new Resolver was turned on by default which backtracks on packages until a valid set of compatible requirements are found. Which inherently trades performance for correctness, and exposes users to potentially downloading a lot of package versions which is where the “yanked” issue came up.

Red Hat engineer here. If we get a customer report saying that our pip happily installs yanked versions, we will definitively do our best to fix that.

“pip” is not involved in the download of setuptools_scm, thats setuptools/easy_install please update pip and setuptools, the distribution versions are severely outdated and your build practically worked by accident,

the next release of setuptools_scm will warn better for such situations and suggest the fixes such as also installing python-setuptools_scm and/or other means of preinstalling

Definitely looks like a bug to me! PRs welcome to fix this one. 😃