diff --git a/src/auditwheel/policy/__init__.py b/src/auditwheel/policy/__init__.py index 20a72c12..7c9b1585 100644 --- a/src/auditwheel/policy/__init__.py +++ b/src/auditwheel/policy/__init__.py @@ -4,6 +4,7 @@ import logging import platform as _platform_module import re +import struct import sys from collections import defaultdict from os.path import abspath, dirname, join @@ -21,9 +22,6 @@ logger = logging.getLogger(__name__) -# https://docs.python.org/3/library/platform.html#platform.architecture -bits = 8 * (8 if sys.maxsize > 2**32 else 4) - _POLICY_JSON_MAP = { Libc.GLIBC: _HERE / "manylinux-policy.json", Libc.MUSL: _HERE / "musllinux-policy.json", @@ -224,10 +222,15 @@ def get_req_external(libs: set[str], whitelist: set[str]) -> set[str]: return ret -def get_arch_name() -> str: +def get_arch_name(*, bits: int | None = None) -> str: machine = _platform_module.machine() if sys.platform == "darwin" and machine == "arm64": return "aarch64" + + if bits is None: + # c.f. https://github.com/pypa/packaging/pull/711 + bits = 8 * struct.calcsize("P") + if machine in {"x86_64", "i686"}: return {64: "x86_64", 32: "i686"}[bits] if machine in {"aarch64", "armv8l"}: diff --git a/tests/unit/test_policy.py b/tests/unit/test_policy.py index 9fd03c24..d05418f3 100644 --- a/tests/unit/test_policy.py +++ b/tests/unit/test_policy.py @@ -1,8 +1,10 @@ from __future__ import annotations +import platform import re +import struct +import sys from contextlib import nullcontext as does_not_raise -from unittest.mock import patch import pytest @@ -32,8 +34,6 @@ def raises(exception, match=None, escape=True): return pytest.raises(exception, match=match) -@patch("auditwheel.policy._platform_module.machine") -@patch("auditwheel.policy.bits", 32) @pytest.mark.parametrize( "reported_arch,expected_arch", [ @@ -45,14 +45,12 @@ def raises(exception, match=None, escape=True): ("x86_64", "i686"), ], ) -def test_32bits_arch_name(machine_mock, reported_arch, expected_arch): - machine_mock.return_value = reported_arch - machine = get_arch_name() +def test_32bits_arch_name(reported_arch, expected_arch, monkeypatch): + monkeypatch.setattr(platform, "machine", lambda: reported_arch) + machine = get_arch_name(bits=32) assert machine == expected_arch -@patch("auditwheel.policy._platform_module.machine") -@patch("auditwheel.policy.bits", 64) @pytest.mark.parametrize( "reported_arch,expected_arch", [ @@ -63,12 +61,35 @@ def test_32bits_arch_name(machine_mock, reported_arch, expected_arch): ("x86_64", "x86_64"), ], ) -def test_64bits_arch_name(machine_mock, reported_arch, expected_arch): - machine_mock.return_value = reported_arch - machine = get_arch_name() +def test_64bits_arch_name(reported_arch, expected_arch, monkeypatch): + monkeypatch.setattr(platform, "machine", lambda: reported_arch) + machine = get_arch_name(bits=64) assert machine == expected_arch +@pytest.mark.parametrize( + "maxsize, sizeof_voidp, expected", + [ + # 64-bit + (9223372036854775807, 8, "x86_64"), + # 32-bit + (2147483647, 4, "i686"), + # 64-bit w/ 32-bit sys.maxsize: GraalPy, IronPython, Jython + (2147483647, 8, "x86_64"), + ], +) +def test_arch_name_bits(maxsize, sizeof_voidp, expected, monkeypatch): + def _calcsize(fmt): + assert fmt == "P" + return sizeof_voidp + + monkeypatch.setattr(platform, "machine", lambda: "x86_64") + monkeypatch.setattr(sys, "maxsize", maxsize) + monkeypatch.setattr(struct, "calcsize", _calcsize) + machine = get_arch_name() + assert machine == expected + + @pytest.mark.parametrize( "name,expected", [