TLDR: does a cp36
(or py36
) Python tag in a wheel filename indicate it’s for Python == 3.6
or for >= 3.6
?
PEP 425 is somewhat ambiguous about this, to my mind:
The Python tag indicates the implementation and version required by a distribution.
…
The version is py_version_nodot.
The example in the Use section suggests that generic Python py36
tags mean >=
but CPython cp36
tags mean ==
- the list of compatible tags for installing on Python 3.3 includes py32
down to py30
but not cp32
. But this distinction is not written explicitly anywhere.
This has come up because I have assumed the ==
meaning in Pynsist, but Cryptography (or packaging tooling it uses) seems to be releasing wheels assuming the >=
meaning (all their wheels have a cp36
tag, but are meant to work on newer versions of Python). I’m getting bug reports about it. I imagine that pip must implement the >=
option, otherwise Cryptography developers couldn’t do this. But e.g. PyQt5 uses cp36.cp37.cp38.cp39
to indicate compatibility with multiple versions of CPython.
Edit: to be clear, cryptography is not unique, there are some other smaller libraries doing the same thing. But most wheels with compiled parts (like NumPy) also specify the corresponding version-specific ABI tag, like cp36m
, and have a separate wheel for each supported Python version. The ambiguity only arises for wheels with a less specific ABI tag (like abi3
).
I’m happy enough to be told that I’ve got it wrong, but either way I think it’s worth clarifying this in the tags spec.