Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion src/packaging/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,21 @@ def _abi3_applies(python_version: PythonVersion, threading: bool) -> bool:
"""
Determine if the Python version supports abi3.

PEP 384 was first implemented in Python 3.2. The threaded (`--disable-gil`)
PEP 384 was first implemented in Python 3.2. The free-threaded
builds do not support abi3.
"""
return len(python_version) > 1 and tuple(python_version) >= (3, 2) and not threading


def _abi3t_applies(python_version: PythonVersion) -> bool:
"""
Determine if the Python version supports abi3.abi3t.

PEP 803 was first implemented in Python 3.15.
"""
return len(python_version) > 1 and tuple(python_version) >= (3, 15)


def _cpython_abis(py_version: PythonVersion, warn: bool = False) -> list[str]:
py_version = tuple(py_version) # To allow for version comparison.
abis = []
Expand Down Expand Up @@ -256,8 +265,15 @@ def cpython_tags(

threading = _is_threaded_cpython(abis)
use_abi3 = _abi3_applies(python_version, threading)
use_abi3t = _abi3t_applies(python_version)

if use_abi3:
yield from (Tag(interpreter, "abi3", platform_) for platform_ in platforms)
if use_abi3t:
yield from (
Tag(interpreter, "abi3.abi3t", platform_) for platform_ in platforms
)

yield from (Tag(interpreter, "none", platform_) for platform_ in platforms)

if use_abi3:
Expand All @@ -267,6 +283,13 @@ def cpython_tags(
interpreter = f"cp{version}"
yield Tag(interpreter, "abi3", platform_)

if use_abi3t:
for minor_version in range(python_version[1] - 1, 14, -1):
for platform_ in platforms:
version = _version_nodot((python_version[0], minor_version))
interpreter = f"cp{version}"
yield Tag(interpreter, "abi3.abi3t", platform_)


def _generic_abi() -> list[str]:
"""
Expand Down
38 changes: 38 additions & 0 deletions tests/test_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,44 @@ def test_all_args(self) -> None:
tags.Tag("cp313", "none", "plat2"),
]

result = list(tags.cpython_tags((3, 15), ["cp315t"], ["platform"]))
assert result == [
tags.Tag("cp315", "cp315t", "platform"),
tags.Tag("cp315", "abi3.abi3t", "platform"),
tags.Tag("cp315", "none", "platform"),
]

result = list(tags.cpython_tags((3, 16), ["cp316t"], ["platform"]))
assert result == [
tags.Tag("cp316", "cp316t", "platform"),
tags.Tag("cp316", "abi3.abi3t", "platform"),
tags.Tag("cp316", "none", "platform"),
tags.Tag("cp315", "abi3.abi3t", "platform"),
]

result = list(tags.cpython_tags((3, 16), ["cp316"], ["platform"]))
assert result == [
tags.Tag("cp316", "cp316", "platform"),
tags.Tag("cp316", "abi3", "platform"),
tags.Tag("cp316", "abi3.abi3t", "platform"),
tags.Tag("cp316", "none", "platform"),
tags.Tag("cp315", "abi3", "platform"),
tags.Tag("cp314", "abi3", "platform"),
tags.Tag("cp313", "abi3", "platform"),
tags.Tag("cp312", "abi3", "platform"),
tags.Tag("cp311", "abi3", "platform"),
tags.Tag("cp310", "abi3", "platform"),
tags.Tag("cp39", "abi3", "platform"),
tags.Tag("cp38", "abi3", "platform"),
tags.Tag("cp37", "abi3", "platform"),
tags.Tag("cp36", "abi3", "platform"),
tags.Tag("cp35", "abi3", "platform"),
tags.Tag("cp34", "abi3", "platform"),
tags.Tag("cp33", "abi3", "platform"),
tags.Tag("cp32", "abi3", "platform"),
tags.Tag("cp315", "abi3.abi3t", "platform"),
]

def test_python_version_defaults(self) -> None:
tag = next(tags.cpython_tags(abis=["abi3"], platforms=["any"]))
interpreter = "cp" + tags._version_nodot(sys.version_info[:2])
Expand Down
Loading