From d88982953c9b02674beced9fa9d1ff101c8ad29c Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Sun, 19 Oct 2025 12:10:16 +0100 Subject: [PATCH 1/3] BLD: use the CPython Limited C API, and hence the Stable ABI This will build an `abi3` wheel per platform, which can be used for multiple (with-GIL) Python interpreter versions. --- meson.build | 6 +++++- pyproject.toml | 2 ++ pywt/_extensions/meson.build | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 5da23bacd..390b2a4af 100644 --- a/meson.build +++ b/meson.build @@ -3,11 +3,15 @@ project( 'c', 'cython', version: '1.10.0.dev0', license: 'MIT', - meson_version: '>= 1.1.0', + meson_version: '>= 1.5.0', default_options: [ 'buildtype=debugoptimized', 'b_ndebug=if-release', 'c_std=c17', + # We default to false here (so produce wheels like cp314), and can opt into + # producing abi3 wheels. The setting in pyproject.toml is + # `limited-api=true`, but this default will ensure it is opt-in: + 'python.allow_limited_api=false', ], ) diff --git a/pyproject.toml b/pyproject.toml index 6aca36801..48d03c90e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -60,6 +60,8 @@ documentation = "https://pywavelets.readthedocs.io/" config-settings = {setup-args = ["--vsenv"]} before-build = "bash {project}/util/cibw_before_build_win.sh" +[tool.meson-python] +limited-api = true [tool.ruff] line-length = 88 diff --git a/pywt/_extensions/meson.build b/pywt/_extensions/meson.build index 8ebf71ea2..068a1ee3c 100644 --- a/pywt/_extensions/meson.build +++ b/pywt/_extensions/meson.build @@ -106,6 +106,7 @@ foreach pyx_file: pyx_files py.extension_module(pyx_file[0], [cython_gen.process(pyx_file[1])], c_args : c_args, + limited_api: '3.12', include_directories : 'c', dependencies : [np_dep, cy_deps], link_with : libc_wt, From e2545b8c854962d081201db807324a8f582ab6b0 Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Sun, 19 Oct 2025 16:31:24 +0100 Subject: [PATCH 2/3] CI: update release job for Stable ABI usage --- .github/workflows/wheel_tests_and_release.yml | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/.github/workflows/wheel_tests_and_release.yml b/.github/workflows/wheel_tests_and_release.yml index 444c6767a..12560da1b 100644 --- a/.github/workflows/wheel_tests_and_release.yml +++ b/.github/workflows/wheel_tests_and_release.yml @@ -34,7 +34,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - cibw_python: ["cp312", "cp313", "cp313t", "cp314", "cp314t"] + cibw_python: ["cp312", "cp313t", "cp314t"] cibw_arch: ["x86_64"] steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v4.1.2 @@ -45,6 +45,11 @@ jobs: with: python-version: "3.12" + - name: Enable Stable ABI for with-GIL interpreters + if: ${{ !endsWith(matrix.cibw_python, 't') }} + run: | + echo CIBW_CONFIG_SETTINGS="setup-args=-Dpython.allow_limited_api=true" >> "$GITHUB_ENV" + - name: Build the wheel uses: pypa/cibuildwheel@63fd63b352a9a8bdcc24791c9dbee952ee9a8abc # v3.3.0 with: @@ -54,6 +59,7 @@ jobs: CIBW_ARCHS_LINUX: ${{ matrix.cibw_arch }} CIBW_ENABLE: cpython-freethreading - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + with: name: wheels_linux_${{ matrix.cibw_arch }}_${{ matrix.cibw_python }} path: ./dist/*.whl @@ -66,7 +72,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-22.04-arm] - cibw_python: ["cp312", "cp313", "cp313t", "cp314", "cp314t"] + cibw_python: ["cp312", "cp313t", "cp314t"] cibw_arch: ["aarch64"] steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v4.1.2 @@ -77,6 +83,11 @@ jobs: with: python-version: "3.12" + - name: Enable Stable ABI for with-GIL interpreters + if: ${{ !endsWith(matrix.cibw_python, 't') }} + run: | + echo CIBW_CONFIG_SETTINGS="setup-args=-Dpython.allow_limited_api=true" >> "$GITHUB_ENV" + - name: Build the wheel uses: pypa/cibuildwheel@63fd63b352a9a8bdcc24791c9dbee952ee9a8abc # v3.3.0 with: @@ -85,6 +96,7 @@ jobs: CIBW_BUILD: ${{ matrix.cibw_python }}-* CIBW_ARCHS_LINUX: ${{ matrix.cibw_arch }} CIBW_ENABLE: cpython-freethreading + - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: wheels_linux_${{ matrix.cibw_arch }}_${{ matrix.cibw_python }} @@ -97,7 +109,7 @@ jobs: fail-fast: false matrix: os: [macos-15-intel, macos-14] - cibw_python: ["cp312", "cp313", "cp313t", "cp314", "cp314t"] + cibw_python: ["cp312", "cp313t", "cp314t"] cibw_arch: ["x86_64", "arm64"] exclude: - os: macos-14 @@ -114,6 +126,11 @@ jobs: with: python-version: "3.12" + - name: Enable Stable ABI for with-GIL interpreters + if: ${{ !endsWith(matrix.cibw_python, 't') }} + run: | + echo CIBW_CONFIG_SETTINGS="setup-args=-Dpython.allow_limited_api=true" >> "$GITHUB_ENV" + - name: Build wheels for CPython (macOS) (x86_64) if: matrix.cibw_arch == 'x86_64' uses: pypa/cibuildwheel@63fd63b352a9a8bdcc24791c9dbee952ee9a8abc # v3.3.0 @@ -148,7 +165,7 @@ jobs: matrix: os: [windows-latest, windows-11-arm] cibw_arch: ["AMD64", "x86", "ARM64"] - cibw_python: ["cp312", "cp313", "cp313t", "cp314", "cp314t"] + cibw_python: ["cp312", "cp313t", "cp314t"] exclude: - os: windows-latest cibw_arch: ARM64 @@ -184,6 +201,11 @@ jobs: with: architecture: arm64 + - name: Enable Stable ABI for with-GIL interpreters + if: ${{ !endsWith(matrix.cibw_python, 't') }} + run: | + echo CIBW_CONFIG_SETTINGS="setup-args=-Dpython.allow_limited_api=true" >> $env:GITHUB_ENV + - name: Build Windows wheels for CPython uses: pypa/cibuildwheel@63fd63b352a9a8bdcc24791c9dbee952ee9a8abc # v3.3.0 with: From ddbcd62e573cf4e7f162ccd46869ab7eafa7ebcd Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Sun, 19 Oct 2025 19:32:27 +0100 Subject: [PATCH 3/3] CI: add Stable ABI jobs, build under py312, test under py314 --- .github/workflows/tests.yml | 57 +++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 03a656b23..f62cd7ae0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -243,3 +243,60 @@ jobs: pytest --pyargs pywt fi popd + + build_stable_abi_wheel: + name: build-abi3-${{ matrix.platform }} + runs-on: ${{ matrix.platform }} + strategy: + fail-fast: false + matrix: + platform: [ubuntu-latest, windows-latest, macos-latest] + steps: + - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v4.1.2 + - uses: actions/setup-python@2e3e4b15a884dc73a63f962bff250a855150a234 # v5.5.0 + with: + python-version: "3.12" + + - name: Build package + run: | + pip install build + python -m build --wheel -Csetup-args="--vsenv" -Csetup-args="-Dpython.allow_limited_api=true" + + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + path: ./dist/*.whl + name: ${{ matrix.platform }}-abi3-wheel + + test_stable_abi_wheel: + needs: build_stable_abi_wheel + name: test-abi3-${{ matrix.platform }} + runs-on: ${{ matrix.platform }} + strategy: + fail-fast: false + matrix: + platform: [ubuntu-latest, windows-latest, macos-latest] + steps: + - uses: actions/setup-python@2e3e4b15a884dc73a63f962bff250a855150a234 # v5.5.0 + with: + python-version: "3.14" + + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 + with: + name: ${{ matrix.platform }}-abi3-wheel + + - name: Check downloaded artifact + run: | + ls + + - name: Install downloaded wheel + shell: bash + run: | + pip install pywavelets-*-abi3-*.whl + + - name: Install test dependencies + run: | + pip install pytest numpy matplotlib + + - name: Run tests + run: | + pytest --pyargs pywt