Have pip warn when installing for a Python version that is not covered by the Trove classifiers?

I would definitely be in favor of removing all Python version classifiers, or at least the X.Y ones. Also I really like that idea about PyPI having a table that is generated based on non-abi3 wheels.


I’m also -1 on pip warning if Trove classifiers don’t cover the current Python, because some projects don’t want to release immediately, which is fine. (Although automated releases via Trusted Publishing is good thing, and they can also release during RC.)

But I do find the x.y classifiers a useful flag to indicate which versions have been tested and are known to work. And the project might not be released to PyPI yet, but we can check the source code.

For example, Python 3.12 is due out in three weeks, and some 5% of popular projects are not ready due to the distutils/setuptools removals or other deprecations. The 3.12 classifier tells us a project is ready.

And if the package has no binary wheels at all, then this table is omitted and maybe just has a badge that says something like “Pure Python”/“All platforms”, etc.

This doesn’t help us know if Python 3.12 is supported, even if if has requires-python >= 3.8.

I think a simple table that listed wheels per Python interpreter and removed any blank rows and columns would be a great way to summarize this information irrespective of what we do with 3.x troves.

I agree, want to open an issue at pypi/warehouse/?

Here’s a fuller demo for pydantic-core:

Python Version manylinux1_i686 manylinux_2_17_aarch64 manylinux2014_ppc64le manylinux_2_17_armv7l musllinux_1_1_aarch64 win_amd64 manylinux_2_5_i686 win_arm64 musllinux_1_1_x86_64 manylinux2014_aarch64 manylinux_2_17_x86_64 manylinux2014_s390x macosx_11_0_arm64 macosx_10_7_x86_64 manylinux_2_17_s390x manylinux2014_armv7l manylinux_2_17_ppc64le manylinux2014_x86_64 win32
PyPy3.10 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
PyPy3.9 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
PyPy3.8 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
PyPy3.7 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
CPython 3.12 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
CPython 3.11 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
CPython 3.10 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
CPython 3.9 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
CPython 3.8 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
CPython 3.7 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:

That’s too wide, so here’s a rotated version:

Platform CPython 3.10 CPython 3.11 CPython 3.12 CPython 3.7 CPython 3.8 CPython 3.9 PyPy3.10 PyPy3.7 PyPy3.8 PyPy3.9
win_amd64 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
musllinux_1_1_x86_64 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
musllinux_1_1_aarch64 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
manylinux_2_17_x86_64 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
manylinux2014_x86_64 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
manylinux_2_17_aarch64 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
manylinux2014_aarch64 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
manylinux_2_5_i686 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
manylinux1_i686 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
macosx_11_0_arm64 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
macosx_10_7_x86_64 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
win_arm64 :white_check_mark: :white_check_mark:
win32 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
manylinux_2_17_s390x :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
manylinux2014_s390x :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
manylinux_2_17_ppc64le :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
manylinux2014_ppc64le :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
manylinux_2_17_armv7l :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
manylinux2014_armv7l :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:

You could the fill the table in with something other than a :white_check_mark: in those instances, e.g. :ballot_box_with_check: or something that suggests, “it’s quite possibly fine, but we don’t have any explicit confirmation”. That would also help fill in details for platforms where there’s a fallback pure Python wheel.

1 Like

Sure thing. I opened it at

1 Like

Where does the 5% figure come from? I would be surprised if 95% of “popular projects” really had CI for Python 3.12 in place already.

From my own research, looking for bugs in both CPython and packages.

I started with the list at Python 3.12 Readiness, checked off those that already have the 3.12 classifier (currently 12%!), and have been going through the rest: checking off those that are successfully testing 3.12 (and either don’t have classifiers, or haven’t released yet), and adding testing to others that use GitHub Actions or tox, and reporting/fixing issues to CPython or the projects as I go.

Of ~120: ~114 are ready for 3.12, ~6 with blockers.

I would be surprised if 95% of “popular projects” really had CI for Python 3.12 in place already.

Surprise! A quick sampling of 10 I’ve checked off: 8 are already testing 3.12 on GitHub Actions, 1 has a PR open, and the 10th is on SourceForge but has 3.12 in tox :tada:

GitHub has done good work with GitHub Actions, making it very easy to test since alpha 1. Here’s how to use it:


Interesting, thanks for doing this. However, 120 also seems much too small a number (by an order of magnitude, IMHO) for Python popular projects.

1 Like

Thanks for doing up an example of a table of the available wheels.

If the goal is to help people find whether there is a wheel for a specific PyPI distribution and version, with a certain combination of build tag, implementation, abi, and/or platform, then maybe a set of dropdowns that allow selecting by these or a search box would be easier? A table does summarise the information better than the current list of wheels, but it is still quite a lot to understand.

For example, four single-item select form elements, each of which filtered the available options in the other 3 (or a separate list) when an item was selected, would offer a very quick way to discover the available combinations of build tag, implementation + version, abi, and platform.

1 Like

@cofiem If you have ideas for this specific feature, let’s discuss those on the Github issue I created for PyPI.

1 Like