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.

). But we have backward compatibility to contend with now, which we didn’t then.