Description
Something that comes up in several contexts is the ability to add or change tags to wheels. When using python -m build
, you don't have access to the --plat-name
setting, and it also only supports one setting and other parts of the tag are missing.
Use case 1
When packaging code that does not rely on CPython, like cmake
and ninja
, the wheels do not depend on the Python version. This can also be the case for packages that build an SO and load it with types; one refactor I'm about to work on is pullout out the common code from awkward
to sit in a single package that is depended on by the regular package, dramatically reducing the total size required on PyPI for a release.
For CMake, for example, the tags look like this:
cmake-3.20.2-py2.py3-none-win_amd64.whl
cmake-3.20.2-py2.py3-none-macosx_10_10_universal2.macosx_10_10_x86_64.macosx_11_0_arm64.macosx_11_0_universal2.whl
cmake-3.20.2-py2.py3-none-manylinux1_x86_64.whl
cmake-3.20.2-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Linux is mostly handled by auditwheel, but auditwheel has to internally do this too, using auditwheel.wheeltools
. And in CMake's case, the py2.py3
part still has to be manipulated.
macOS is actually not very special here - all Universal2 wheels should ideally be tagged with x86_64 as well to be loadable in older versions of Pip if one wants to only release a single binary. (AFAIK). This leads into use case 2.
Another case I've seen is with wcmatch
, which depends on the Python version, but not the platform.
Use case 2
In cibuildwheel, producing a single universal wheel that actually works on all versions of pip requires a platform tag like macosx_10_9_universal2.macosx_10_9_x86_64.macosx_11_0_arm64.macosx_11_0_universal2
. The final pip 20 release wasn't able to read "macosx_11_0_arm64" (as well as the default pip on macOS 11), etc. Being able to change/set the wheel tags would make this much simpler. This is much more important now with macOS on Arm.
This was done incorrectly by simply renaming the wheel for a while during development, just to get the wheel to load for testing before pip updated. The metadata was not being corrected.
Proposal
A new command could be added to wheel, wheel tags <name> --set <new_tag> --add <new_tag> --add <newtag>
. You could 0 or 1 --set
, which replaces the current tags, and 0 or more --add
, which add tags. This would add the tags to the wheel and rename it to match the new tags. An API for it would be nice too, I think.
The implementation could be basically an unpack, change tags, then pack, as in scikit-build/ninja-python-distributions#49?
Alternatives
This could be made part of a different package, but this seems like a general enough problem to be part of wheel, and isn't that different from the existing unpack/pack - the code is already mostly in wheel
. Or maybe there's another solution already? At least in the scikit-build projects, there is code doing this being dragged around scikit-build/ninja-python-distributions#49 .
There could also be better support in specifying tags when making the wheel in the first place, but it tends to be rather dynamic, depending on "universal2 on macOS" and things like that. This could be a longer-term project vs. the extra utility?
Maybe there's already something I'm not seeing, etc?
CC @mayeut (currently on vacation). @brettcannon might be interested.