diff --git a/docs/changelog/59.bugfix.rst b/docs/changelog/59.bugfix.rst new file mode 100644 index 0000000..48ef793 --- /dev/null +++ b/docs/changelog/59.bugfix.rst @@ -0,0 +1 @@ +export normalize_isa and deprecate KNOWN_ARCHITECTURES - by :user:`rahuldevikar`. diff --git a/docs/conf.py b/docs/conf.py index 96dc78d..fc0f056 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,13 +21,19 @@ "sphinxcontrib.mermaid", ] +extlinks = { + "issue": ("https://github.com/tox-dev/python-discovery/issues/%s", "#%s"), + "pull": ("https://github.com/tox-dev/python-discovery/pull/%s", "PR #%s"), + "user": ("https://github.com/%s", "@%s"), +} + intersphinx_mapping = { "python": ("https://docs.python.org/3", None), } templates_path = [] source_suffix = ".rst" -exclude_patterns = ["_build"] +exclude_patterns = ["_build", "changelog/*.rst"] main_doc = "index" pygments_style = "default" diff --git a/src/python_discovery/__init__.py b/src/python_discovery/__init__.py index ad2a490..40307ae 100644 --- a/src/python_discovery/__init__.py +++ b/src/python_discovery/__init__.py @@ -6,7 +6,7 @@ from ._cache import ContentStore, DiskCache, PyInfoCache from ._discovery import get_interpreter -from ._py_info import KNOWN_ARCHITECTURES, PythonInfo +from ._py_info import KNOWN_ARCHITECTURES, PythonInfo, normalize_isa from ._py_spec import PythonSpec from ._specifier import SimpleSpecifier, SimpleSpecifierSet, SimpleVersion @@ -24,4 +24,5 @@ "SimpleVersion", "__version__", "get_interpreter", + "normalize_isa", ] diff --git a/src/python_discovery/_py_info.py b/src/python_discovery/_py_info.py index c145232..de9212f 100644 --- a/src/python_discovery/_py_info.py +++ b/src/python_discovery/_py_info.py @@ -770,21 +770,43 @@ def _possible_base(self) -> Generator[str, None, None]: KNOWN_ARCHITECTURES: frozenset[str] = frozenset({ "arm64", - "i686", "loongarch64", + "ppc", "ppc64", "ppc64le", "riscv64", "s390x", + "sparc64", "x86", "x86_64", }) -"""Known CPU architecture (ISA) values after normalization.""" +"""Known CPU architecture (ISA) values after normalization. + +.. deprecated:: + Use :func:`normalize_isa` instead, which handles both known and unknown architectures. +""" def normalize_isa(isa: str) -> str: + """ + Normalize an ISA (instruction set architecture) string to a canonical form. + + Known aliases are mapped (e.g. ``amd64`` → ``x86_64``, ``aarch64`` → ``arm64``). + Unrecognized values are lowercased and returned as-is. + """ low = isa.lower() - return {"amd64": "x86_64", "aarch64": "arm64", "i386": "x86", "i586": "x86"}.get(low, low) + return { + "amd64": "x86_64", + "aarch64": "arm64", + "i386": "x86", + "i486": "x86", + "i586": "x86", + "i686": "x86", + "powerpc": "ppc", + "powerpc64": "ppc64", + "powerpc64le": "ppc64le", + "sparcv9": "sparc64", + }.get(low, low) def _main() -> None: # pragma: no cover diff --git a/tests/py_info/test_py_info.py b/tests/py_info/test_py_info.py index cb67790..92c23d8 100644 --- a/tests/py_info/test_py_info.py +++ b/tests/py_info/test_py_info.py @@ -14,7 +14,7 @@ import pytest from setuptools.dist import Distribution -from python_discovery import KNOWN_ARCHITECTURES, DiskCache, PythonInfo, PythonSpec +from python_discovery import DiskCache, PythonInfo, PythonSpec from python_discovery import _cached_py_info as cached_py_info from python_discovery._py_info import VersionInfo @@ -338,7 +338,7 @@ def test_py_info_machine_property() -> None: assert machine is not None assert isinstance(machine, str) assert len(machine) > 0 - assert machine in KNOWN_ARCHITECTURES, f"unexpected machine value: {machine}" + assert machine == machine.lower(), f"machine value should be lowercase: {machine}" def test_py_info_machine_in_spec() -> None: diff --git a/tests/test_py_spec.py b/tests/test_py_spec.py index af31356..79c79cd 100644 --- a/tests/test_py_spec.py +++ b/tests/test_py_spec.py @@ -217,9 +217,19 @@ def test_spec_satisfies_machine(left: str, right: str, expected: bool) -> None: pytest.param("x86_64", "x86_64", id="x86_64"), pytest.param("arm64", "arm64", id="arm64"), pytest.param("x86", "x86", id="x86"), + pytest.param("i386", "x86", id="i386"), + pytest.param("i486", "x86", id="i486"), + pytest.param("i586", "x86", id="i586"), + pytest.param("i686", "x86", id="i686"), pytest.param("ppc64le", "ppc64le", id="ppc64le"), + pytest.param("powerpc", "ppc", id="powerpc"), + pytest.param("powerpc64", "ppc64", id="powerpc64"), + pytest.param("powerpc64le", "ppc64le", id="powerpc64le"), pytest.param("riscv64", "riscv64", id="riscv64"), pytest.param("s390x", "s390x", id="s390x"), + pytest.param("sparcv9", "sparc64", id="sparcv9"), + pytest.param("sparc64", "sparc64", id="sparc64"), + pytest.param("alpha", "alpha", id="alpha-passthrough"), ], ) def test_normalize_isa(isa: str, normalized: str) -> None: