TL;DR; How does version string 1.0
compare to 1.0+abc
? Which one would get downloaded if both were available and you only specified the name of a package? Would it be deterministic?
Hello, I’ve read PEP 440 and I couldn’t find an answer to the question: how do public version identifiers compare to local version identifiers, especially when both have the same “base version”, e.g. 1.10.0
and 1.10.0+cpu
?
There is a section called “Summary of permitted suffixes and relative ordering”, but it doesn’t mention anything about local version identifiers, only how to compare two public version identifiers.
Further, the section defining local version identifiers explains how to compare local version labels of two local version identifiers and it doesn’t explain how they compare to public version identifiers.
There are only two places in PEP 440 which implicitly suggest how to compare public and local version identifiers.
The first one is the example at the end of section “Summary of permitted suffixes and relative ordering”. You can see that 1.0 < 1.0+abc.5 < 1.0.post456
. This suggests that if you want to compare a public version identifier with a local one, you have to strip away the local version label and compare remaining strings as if both were public version identifiers:
- if they compare equal, then the local version identifier compares greater than the public one by default,
- otherwise, the ordering between both identifiers is determined by the result of that comparison.
In other words, the ordering is deterministically 1.0 < 1.0+abc < 1.0.post1 < 1.1 < 1.1+abc < 1.1.post1
.
Another place that relates to the question is a sentence (near the end of subsection “Version matching”; emphasis mine):
If present, the development release segment is always the final segment in the public version, and the local version is ignored for comparison purposes, so using either in a prefix match wouldn’t make any sense.
Note that the exact phrase used is local version, not local version identifier or local version label. It allows me for two interpretations:
- it refers to a label; it means that you must strip labels away before making comparisons. If that’s true, then it means that
1.0 == 1.0+abc < 1.0.post1 < 1.1 == 1.1+abc < 1.1.post1
. - it refers to an identifier; it means that packages with local version identifiers are completely ignored and they won’t get downloaded(?), unless you provide a full identifier when downloading a package (e.g.
pip install foobar -f <url>
will download version1.0
andpip install foobar==1.0+abc -f <url>
will download1.0+abc
).
I’ve done the following empirical test:
pip install torch --find-links https://download.pytorch.org/whl/cpu/torch_stable.html
It downloaded 1.10.1+cpu
, even though 1.10.1
was also available, contradicting my second interpretation.
So, did I miss or misunderstand something in PEP 440 or is the answer actually not there?