From 24b049c9372447f25d06b11c2d4dd6dc36c9bec8 Mon Sep 17 00:00:00 2001 From: Tom Jakubowski Date: Mon, 16 Sep 2024 18:35:54 -0700 Subject: [PATCH] Support abi3 wheels (#32) * Support abi3 wheels abi3 is also known as the stable ABI https://docs.python.org/3/c-api/stable.html#stable-abi abi3 wheels are forwards compatible, meaning an abi3-py39 wheel will work with Python 3.9, 3.10, 3.11, 3.12, and so on. * Update CHANGELOG.md --- CHANGELOG.md | 16 ++++++++++++---- pyodide_lock/utils.py | 5 +++++ tests/test_wheel.py | 18 ++++++++++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69b18e4..f3944b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ # Changelog + All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), @@ -6,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## [0.1.0a8] - 2024-09-17 + +### Added + +- Support stable ABI (`abi3`) wheels in lock file. + [#32](https://github.com/pyodide/pyodide-lock/pull/32) + ## [0.1.0a7] - 2024-08-08 ### Added @@ -57,10 +65,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - - Add `check_wheel_filenames` method to `PyodideLockSpec` that checks that the - package name in version are consistent between the wheel filename and the - corresponding pyodide-lock.json fields - [#11](https://github.com/pyodide/pyodide-lock/pull/11) +- Add `check_wheel_filenames` method to `PyodideLockSpec` that checks that the + package name in version are consistent between the wheel filename and the + corresponding pyodide-lock.json fields + [#11](https://github.com/pyodide/pyodide-lock/pull/11) ## [0.1.0a1] - 2023-06-23 diff --git a/pyodide_lock/utils.py b/pyodide_lock/utils.py index b783a6a..1cc3c54 100644 --- a/pyodide_lock/utils.py +++ b/pyodide_lock/utils.py @@ -321,6 +321,9 @@ def _check_wheel_compatible(path: Path, info: InfoSpec) -> None: raise RuntimeError(f"Wheel filename {path.name} is not valid") from e python_binary_abi = f"cp{target_python.major}{target_python.minor}" tags = list(tags) + abi3_compat = { + f"cp{target_python.major}{minor}" for minor in range(target_python.minor + 1) + } tag_match = False for t in tags: @@ -331,6 +334,8 @@ def _check_wheel_compatible(path: Path, info: InfoSpec) -> None: and t.platform == target_platform ): tag_match = True + elif t.abi == "abi3" and t.interpreter in abi3_compat: + tag_match = True elif t.abi == "none" and t.platform == "any": match = re.match(rf"py{target_python.major}(\d*)", t.interpreter) if match: diff --git a/tests/test_wheel.py b/tests/test_wheel.py index d1526e5..f512b03 100644 --- a/tests/test_wheel.py +++ b/tests/test_wheel.py @@ -169,6 +169,17 @@ def test_wheel_compatibility_checking(example_lock_spec): Path(f"test_wheel-1.0.0-{cpython_tag}-{cpython_tag}-{emscripten_tag}.whl"), example_lock_spec.info, ) + # abi3, current version + _check_wheel_compatible( + Path(f"test_wheel-1.0.0-{cpython_tag}-abi3-{emscripten_tag}.whl"), + example_lock_spec.info, + ) + # abi3, past version + past_cpython_tag = f"cp{target_python.major}{target_python.minor-1}" + _check_wheel_compatible( + Path(f"test_wheel-1.0.0-{past_cpython_tag}-abi3-{emscripten_tag}.whl"), + example_lock_spec.info, + ) with pytest.raises(RuntimeError): # cpython emscripten incorrect version _check_wheel_compatible( @@ -177,6 +188,13 @@ def test_wheel_compatibility_checking(example_lock_spec): ), example_lock_spec.info, ) + with pytest.raises(RuntimeError): + # abi3, interpreter version too large + future_cpython_tag = f"cp{target_python.major}{target_python.minor+1}" + _check_wheel_compatible( + Path(f"test_wheel-1.0.0-{future_cpython_tag}-abi3-{emscripten_tag}.whl"), + example_lock_spec.info, + ) with pytest.raises(RuntimeError): # a linux wheel _check_wheel_compatible(