Repository navigation
Description
Description
bdist_wheel.get_tag() derives the wheel's interpreter and ABI from the running interpreter, so a cross-build can compute a correct platform tag and still be rejected — or tagged for the build machine rather than the target.
This came out of @jameshilliard's review of #5193. It is deliberately out of scope for #5352 (which fixes the extension filename via target sysconfig) and for #5193 (which fixes the wheel tag for abi3t), so filing it separately.
The host-derived inputs
In setuptools/command/bdist_wheel.py:
-
tags.interpreter_name()andtags.interpreter_version()(lines 357–358) readsys.implementationand the host-derivedpy_version_nodot. -
tags.sys_tags()(line 369) is defined entirely in terms of the running interpreter. The current code substitutesplat_namefor each tag's platform:supported_tags = [(t.interpreter, t.abi, plat_name) for t in tags.sys_tags()] assert tag in supported_tags, f"would build wheel with unsupported tag {tag}"
Replacing only the platform leaves the interpreter-version and ABI assumptions intact, so the assertion still describes the build machine.
Note that sysconfig.get_config_var(...) is not affected in the same way: under _PYTHON_SYSCONFIGDATA_NAME it reads the target's data. That asymmetry is what makes the bug easy to miss — Py_GIL_DISABLED describes the target while sys_tags() describes the host, and the two can disagree.
Suggested direction
@jameshilliard suggests the documented tags.cpython_tags(python_version=target_version, abis=target_abis, platforms=[plat_name]) for the CPython path, with all three inputs derived from the configured target, preserving separate handling for other implementations. For CPython POSIX builds, sysconfig.get_config_var("VERSION") comes from the selected target build data.
He also warns against sysconfig.get_python_version(), py_version_short or py_version_nodot as substitutes — CPython derives those from the running interpreter too. With a real AArch64 3.14 sysconfig loaded into a 3.15 build interpreter he measured VERSION="3.14" but py_version_short="3.15" and py_version_nodot="315".
Related
- [BUG] cross compiling 3.15 abi3 wheels fails due to new multiarch support #5351 / Use target sysconfig for platform-qualified stable-ABI suffixes #5352 — the extension filename half, where the same host-vs-target confusion produced an importable-looking wheel with a wrong-architecture suffix.
- Add initial support for abi3.abi3t tag from PEP 803 #5193 — abi3t wheel tagging. If it adds a
sys.version_infocomparison to_validate_py_limited_api, that is a new instance of this same problem and should use target metadata instead; the function does not currently consult the version at all. - PEP 739 (
build-details.json) was raised in Use target sysconfig for platform-qualified stable-ABI suffixes #5352 as a cleaner long-term source of target metadata than scraping sysconfig: https://peps.python.org/pep-0739/
Also worth auditing
_is_32bit_interpreter() uses the build interpreter's struct.calcsize("P") where the target's SIZEOF_VOID_P is the relevant value.
Activity
Reference pypa#5360 in the news fragment
jameshilliard commentedon Oct 20, 2026
I think I found a few similar issues in distutils.