From 732edd1eae0591b938ccee1285bf66fc0f6d62f5 Mon Sep 17 00:00:00 2001 From: Leo Singer Date: Fri, 3 May 2024 17:09:27 -0400 Subject: [PATCH] BUG: disable abi3 wheel tag for PyPy PyPy supports the limited API but not the stable ABI. --- mesonpy/__init__.py | 33 +++++++++++++++++---------------- tests/test_tags.py | 6 ++++-- tests/test_wheel.py | 1 + 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/mesonpy/__init__.py b/mesonpy/__init__.py index ea6364094..073019b02 100644 --- a/mesonpy/__init__.py +++ b/mesonpy/__init__.py @@ -406,22 +406,23 @@ def entrypoints_txt(self) -> bytes: @cached_property def _stable_abi(self) -> Optional[str]: - if self._limited_api: - # PyPy does not use a special extension module filename - # suffix for modules targeting the stable API. - if '__pypy__' not in sys.builtin_module_names: - # Verify stable ABI compatibility: examine files installed - # in {platlib} that look like extension modules, and raise - # an exception if any of them has a Python version - # specific extension filename suffix ABI tag. - for path, _ in self._manifest['platlib']: - match = _EXTENSION_SUFFIX_REGEX.match(path.name) - if match: - abi = match.group('abi') - if abi is not None and abi != 'abi3': - raise BuildError( - f'The package declares compatibility with Python limited API but extension ' - f'module {os.fspath(path)!r} is tagged for a specific Python version.') + # PyPy supports the limited API but does not provide a stable + # ABI, therefore extension modules using the limited API do + # not use the stable ABI filename suffix and wheels should not + # be tagged with the abi3 tag. + if self._limited_api and '__pypy__' not in sys.builtin_module_names: + # Verify stable ABI compatibility: examine files installed + # in {platlib} that look like extension modules, and raise + # an exception if any of them has a Python version + # specific extension filename suffix ABI tag. + for path, _ in self._manifest['platlib']: + match = _EXTENSION_SUFFIX_REGEX.match(path.name) + if match: + abi = match.group('abi') + if abi is not None and abi != 'abi3': + raise BuildError( + f'The package declares compatibility with Python limited API but extension ' + f'module {os.fspath(path)!r} is tagged for a specific Python version.') return 'abi3' return None diff --git a/tests/test_tags.py b/tests/test_tags.py index c55d69739..8100681d1 100644 --- a/tests/test_tags.py +++ b/tests/test_tags.py @@ -103,11 +103,13 @@ def test_tag_stable_abi(): builder = wheel_builder_test_factory({ 'platlib': [f'extension{ABI3SUFFIX}'], }, limited_api=True) - assert str(builder.tag) == f'{INTERPRETER}-abi3-{PLATFORM}' + # PyPy does not support the stable ABI. + abi = 'abi3' if '__pypy__' not in sys.builtin_module_names else ABI + assert str(builder.tag) == f'{INTERPRETER}-{abi}-{PLATFORM}' @pytest.mark.xfail(sys.version_info < (3, 8) and sys.platform == 'win32', reason='Extension modules suffix without ABI tags') -@pytest.mark.xfail('__pypy__' in sys.builtin_module_names, reason='PyPy does not use special modules suffix for stable ABI') +@pytest.mark.xfail('__pypy__' in sys.builtin_module_names, reason='PyPy does not support the stable ABI') def test_tag_mixed_abi(): builder = wheel_builder_test_factory({ 'platlib': [f'extension{ABI3SUFFIX}', f'another{SUFFIX}'], diff --git a/tests/test_wheel.py b/tests/test_wheel.py index 24ed59ffc..707022483 100644 --- a/tests/test_wheel.py +++ b/tests/test_wheel.py @@ -290,6 +290,7 @@ def test_skip_subprojects(package_subproject, tmp_path, arg): # Requires Meson 1.3.0, see https://github.com/mesonbuild/meson/pull/11745. @pytest.mark.skipif(MESON_VERSION < (1, 2, 99), reason='Meson version too old') @pytest.mark.skipif(NOGIL_BUILD, reason='Free-threaded CPython does not support the limited API') +@pytest.mark.xfail('__pypy__' in sys.builtin_module_names, reason='PyPy does not support the abi3 platform tag for wheels') def test_limited_api(wheel_limited_api): artifact = wheel.wheelfile.WheelFile(wheel_limited_api) name = artifact.parsed_filename