From 5318b6704e20610dfd984fad8fa5a504da21b26b Mon Sep 17 00:00:00 2001 From: Nathan Goldbaum Date: Tue, 24 Feb 2026 11:45:14 -0700 Subject: [PATCH 1/6] Add initial support for abi3.abi3t tag from PEP 803 --- pyproject.toml | 2 +- setuptools/command/bdist_wheel.py | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2fe6669e66..696266aeab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -95,7 +95,7 @@ doc = [ ssl = [] certs = [] core = [ - "packaging>=24.2", + "packaging @ get+https://github.com/ngoldbaum/packaging@abi3.abi3t", "more_itertools>=8.8", "jaraco.text>=3.7", "importlib_metadata>=6; python_version < '3.10'", diff --git a/setuptools/command/bdist_wheel.py b/setuptools/command/bdist_wheel.py index 3bdfa0b35a..3ed8c36a5a 100644 --- a/setuptools/command/bdist_wheel.py +++ b/setuptools/command/bdist_wheel.py @@ -281,11 +281,11 @@ def _validate_py_limited_api(self) -> None: if not re.match(PY_LIMITED_API_PATTERN, self.py_limited_api): raise ValueError(f"py-limited-api must match '{PY_LIMITED_API_PATTERN}'") - if sysconfig.get_config_var("Py_GIL_DISABLED"): + if sysconfig.get_config_var("Py_GIL_DISABLED") and sys.version_info < (3, 15): raise ValueError( f"`py_limited_api={self.py_limited_api!r}` not supported. " - "`Py_LIMITED_API` is currently incompatible with " - "`Py_GIL_DISABLED`. " + "`Py_LIMITED_API` is incompatible with `Py_GIL_DISABLED` " + "on Python 3.14 and older. " "See https://github.com/python/cpython/issues/111506." ) @@ -345,7 +345,10 @@ def get_tag(self) -> tuple[str, str, str]: # We don't work on CPython 3.1, 3.0. if self.py_limited_api and (impl_name + impl_ver).startswith("cp3"): impl = self.py_limited_api - abi_tag = "abi3" + if sysconfig.get_config_var("Py_GIL_DISABLED"): + abi_tag = "abi3.abi3t" + else: + abi_tag = "abi3" else: abi_tag = str(get_abi_tag()).lower() tag = (impl, abi_tag, plat_name) @@ -354,7 +357,9 @@ def get_tag(self) -> tuple[str, str, str]: (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}" + f"would build wheel with unsupported tag {tag},\n" + "supported tags are:\n" + f"{supported_tags}" ) return tag From 5295f9b23d3039f766dc2ea4c2aeb38fa4efa404 Mon Sep 17 00:00:00 2001 From: Nathan Goldbaum Date: Tue, 3 Mar 2026 11:13:06 -0700 Subject: [PATCH 2/6] fix typo --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 696266aeab..4a671a2278 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -95,7 +95,7 @@ doc = [ ssl = [] certs = [] core = [ - "packaging @ get+https://github.com/ngoldbaum/packaging@abi3.abi3t", + "packaging @ git+https://github.com/ngoldbaum/packaging@abi3.abi3t", "more_itertools>=8.8", "jaraco.text>=3.7", "importlib_metadata>=6; python_version < '3.10'", From 669068baabedaa42804d00629039527a528528c7 Mon Sep 17 00:00:00 2001 From: Nathan Goldbaum Date: Tue, 3 Mar 2026 11:14:49 -0700 Subject: [PATCH 3/6] revert error message change --- setuptools/command/bdist_wheel.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/setuptools/command/bdist_wheel.py b/setuptools/command/bdist_wheel.py index 3ed8c36a5a..0de37cfb89 100644 --- a/setuptools/command/bdist_wheel.py +++ b/setuptools/command/bdist_wheel.py @@ -357,9 +357,7 @@ def get_tag(self) -> tuple[str, str, str]: (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},\n" - "supported tags are:\n" - f"{supported_tags}" + f"would build wheel with unsupported tag {tag}" ) return tag From a8316f9bb645dae330535f3edded70adcd7e5e41 Mon Sep 17 00:00:00 2001 From: Nathan Goldbaum Date: Thu, 5 Mar 2026 12:15:40 -0700 Subject: [PATCH 4/6] support compressed ABI tags --- setuptools/command/bdist_wheel.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setuptools/command/bdist_wheel.py b/setuptools/command/bdist_wheel.py index 0de37cfb89..97121a8796 100644 --- a/setuptools/command/bdist_wheel.py +++ b/setuptools/command/bdist_wheel.py @@ -352,11 +352,12 @@ def get_tag(self) -> tuple[str, str, str]: else: abi_tag = str(get_abi_tag()).lower() tag = (impl, abi_tag, plat_name) + tag_str = "-".join(tag) # issue gh-374: allow overriding plat_name supported_tags = [ (t.interpreter, t.abi, plat_name) for t in tags.sys_tags() ] - assert tag in supported_tags, ( + assert any((t.interpreter, t.abi, plat_name) in supported_tags for t in tags.parse_tag(tag_str)), ( f"would build wheel with unsupported tag {tag}" ) return tag From e08b624fbaf495d9951636c0e8a8a10ccb8196a0 Mon Sep 17 00:00:00 2001 From: Nathan Goldbaum Date: Mon, 16 Mar 2026 09:51:57 -0600 Subject: [PATCH 5/6] refactor to satisfy linter --- setuptools/command/bdist_wheel.py | 33 ++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/setuptools/command/bdist_wheel.py b/setuptools/command/bdist_wheel.py index 97121a8796..832d22ba78 100644 --- a/setuptools/command/bdist_wheel.py +++ b/setuptools/command/bdist_wheel.py @@ -300,6 +300,21 @@ def wheel_dist_name(self) -> str: components.append(self.build_number) return "-".join(components) + @property + def abi_tag(self) -> str: + impl_name = tags.interpreter_name() + impl_ver = tags.interpreter_version() + impl = impl_name + impl_ver + # We don't work on CPython 3.1, 3.0. + if self.py_limited_api and impl.startswith("cp3"): + if sysconfig.get_config_var("Py_GIL_DISABLED"): + abi_tag = "abi3.abi3t" + else: + abi_tag = "abi3" + else: + abi_tag = str(get_abi_tag()).lower() + return abi_tag + def get_tag(self) -> tuple[str, str, str]: # bdist sets self.plat_name if unset, we should only use it for purepy # wheels if the user supplied it. @@ -342,24 +357,18 @@ def get_tag(self) -> tuple[str, str, str]: impl_name = tags.interpreter_name() impl_ver = tags.interpreter_version() impl = impl_name + impl_ver - # We don't work on CPython 3.1, 3.0. - if self.py_limited_api and (impl_name + impl_ver).startswith("cp3"): + abi_tag = self.abi_tag + if "abi3" in abi_tag: impl = self.py_limited_api - if sysconfig.get_config_var("Py_GIL_DISABLED"): - abi_tag = "abi3.abi3t" - else: - abi_tag = "abi3" - else: - abi_tag = str(get_abi_tag()).lower() tag = (impl, abi_tag, plat_name) - tag_str = "-".join(tag) # issue gh-374: allow overriding plat_name supported_tags = [ (t.interpreter, t.abi, plat_name) for t in tags.sys_tags() ] - assert any((t.interpreter, t.abi, plat_name) in supported_tags for t in tags.parse_tag(tag_str)), ( - f"would build wheel with unsupported tag {tag}" - ) + assert any( + (t.interpreter, t.abi, plat_name) in supported_tags + for t in tags.parse_tag("-".join(tag)) + ), f"would build wheel with unsupported tag {tag}" return tag def run(self): From 44189e5f6f5694d80525403ad3628bcf2ff006dd Mon Sep 17 00:00:00 2001 From: Nathan Goldbaum Date: Mon, 16 Mar 2026 10:03:13 -0600 Subject: [PATCH 6/6] add assertion for pyright --- setuptools/command/bdist_wheel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setuptools/command/bdist_wheel.py b/setuptools/command/bdist_wheel.py index 832d22ba78..dbd9dcbb10 100644 --- a/setuptools/command/bdist_wheel.py +++ b/setuptools/command/bdist_wheel.py @@ -359,6 +359,7 @@ def get_tag(self) -> tuple[str, str, str]: impl = impl_name + impl_ver abi_tag = self.abi_tag if "abi3" in abi_tag: + assert self.py_limited_api is not False impl = self.py_limited_api tag = (impl, abi_tag, plat_name) # issue gh-374: allow overriding plat_name