Search code examples
pythonpipsetuptoolssetup.pypypi

Pre-release versions are not matched by pip when using the `--pre` option


Imagine you have published two pre-releases:

 package 0.0.1.dev0
 package 0.0.2.dev0

My install_requires section in setup.py states:

[
    'package>=0.0.2,<1.0.0'
]

Now, when i run pip install . --upgrade --pre I get an error:

ERROR: Could not find a version that satisfies the requirement package<1.0.0,>=0.0.2 (from versions: 0.0.1.dev0, 0.0.2.dev0) ERROR: No matching distribution found for package<1.0.0,>=0.0.2

What am I doing wrong? Isn't the --pre flag supposed to tell pip to match pre-release versions?


Solution

  • Summary

    The pip --pre option directs pip to include potential matching pre-release and development versions, but it does not change the semantics of version matching.

    Since pre-release 0.0.2.dev0 is older than stable release 0.0.2, pip correctly reports an error when searching for a package that is at least as new as stable release 0.0.2.

    Explanation

    The key point of confusion is around the pip --pre option, which is documented as:

    --pre
    Include pre-release and development versions. By default, pip only finds stable versions.

    The premise of the question is that the --pre option should change the package-version-matching semantics such that pre-release version suffixes would be ignored when matching against stable versions.

    To further clarify, consider the compatible release operator ~=. PEP 440 section Compatible release, states in part:

    For a given release identifier V.N, the compatible release clause is approximately equivalent to the pair of comparison clauses:

    >= V.N, == V.*

    ...

    If a pre-release, post-release or developmental release is named in a compatible release clause as V.N.suffix, then the suffix is ignored when determining the required prefix match:

    ~= 2.2.post3 = 2.2.post3, == 2.*

    ~= 1.4.5a4 = 1.4.5a4, == 1.4.*

    This example makes it clear that the suffix is ignored.

    The following requirement does not match 0.0.2.dev0:

    install_requires=['package~=0.0.2']  # ERROR: ResolutionImpossible
    

    Whereas this example does match stable release 0.0.2:

    install_requires=['package~=0.0.2.dev0']  # OK - suffix ignored