twine: `twine check` should guard against `python_requires` conflicting with the wheel tags

The Issue

With the sunset of Python 2, distribution maintainers should stop producing universal wheels with (ones with py2.py3 tag).

The solution is to drop universal = 1 or turn that into 0 (https://github.com/pypa/packaging.python.org/issues/726) but it’s easy to miss this bit. So this results in people adding things like python_requires = >= 3.6 but still having that py2 tag in the wheels which is rather useless (and, well, incorrect).

The same could happen to platform-specific wheels specifying ABI3 with tags like abi3-py36 while having python_requires = >= 3.7, for example.

I propose improving the twine check command to detect such inconsistencies.

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 2
  • Comments: 45 (20 by maintainers)

Most upvoted comments

@bhrutledge I’d say there does not exist a proposal which everyone who has been involved in this discussion would be supportive of. I’ll try to summarize:

  • Today when you indicate that the wheel you’re building is universal, it adds py2.py3 because at the time of the implementation that was what “universal” meant (works on 2 and 3)
  • Pip versions for years have relied on that as a hint as to which wheel should be installed on a given version of Python
  • “universal” semantically means any version of Python
  • Metadata has grown the “python-requires” field which allows you to have a “universal” wheel so long as “universal” also matches the python-requires. (Many folks use python-requires to indicate the minimum version they support of Python) That seems to be contradictory though given that pypa/wheel tags “universal” wheels with py2.py3 and python-requires can have > 3.5

I think the best we could do is have a check that can never be considered an error because the confidence in that check would be so low that is also only run when provided a flag that warns if you have requires-python and the wheel is tagged py2.py3. That said, we’d be wading into a minefield by doing so and I’m not sure it’s worth the effort.


All of the above is to say: There’s almost no alignment on what any of this means (the current maintainers of various pypa projects seem to have different interpretations of things compared to the PEPs when they were written) and tools have grown behaviour based on what was available. Twine taking any action here seems like it would result in endless churn and heartburn for us.


Finally as a total aside, it seems all members of PyPA can tag issues on this project despite not being maintainers and thus can give an issue a sense of being accepted as a feature/enhancement. That’s kind of crappy and doesn’t let the actual maintainers guard their “no” appropriately.

I’d like to voice my -1 – universal just means “pure python and works on any version” and presumably will hold the same meaning when C-incompatible python 4.x rolls around. For the same reason that python_requires = <4 is bad I don’t think this should be implemented.

To achieve that intent the wheel tag this should map would need to be just py, not py2.py3 . because py2.py3 is not python 4 compatible tag.

IMO twine printing warning when there’s some sort of obvious mismatch like the valid-but-uninstallable wheel example that @pfmoore gave above, or a wheel that’s tagged for Python 2 but can’t be installed there due to python_requires is a good idea.


It’s probably a good idea to check if the last version of pip that supported Python 2 does not work with py, because if it does, then there’s not much discussion to be had here. 😃


imo attempting to match a wheel tag to python_requires is kind of a lost cause, what would you do for python_requires >= 3.6.1?

FWIW, I think this issue’s OP isn’t to suggest that we should try to have them match precisely though. Rather, it’s about being tagged for a Python version that the package can’t be installed on. And this whole thing about inferring tags should likely move to the wheel issue tracker.

FWIW, I’d like to put the py tag on this example TBH. Because we don’t have that yet, it’d need to be py3 instead (which is fine until we have to figure out what to do for Python 4, and continuing to put py2 here isn’t going to help with that problem anyway).

We can add py in before Python 3/4 though, as @henryiii suggests, but that’s probably better for discuss.python.org.

👋 (relatively new) Twine maintainer here. It’s been interesting to watch this discussion, but I’ve only skimmed it. Can somebody write (or point to) a concise proposal for an enhancement to Twine that has (or can get) the support of the folks involved?

These sorts of discussions really should be made on the wheel issue, not here.

I’d like to voice my -1 – universal just means “pure python and works on any version” and presumably will hold the same meaning when C-incompatible python 4.x rolls around. For the same reason that python_requires = <4 is bad I don’t think this should be implemented.