From 03cefa35abee69d17de021252f17edb9b8f656d6 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Tue, 4 Aug 2026 14:41:22 -0700 Subject: [PATCH] feat: add pyodide_315 support (#2958) * Add pyodide_315 support Guarded by cpython_prerelease for the moment. * Update * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update constraints to pyodide-build 0.39.0 * Update to 315.0.0a2 * Remove example versions --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .github/workflows/test.yml | 4 +- README.md | 2 +- cibuildwheel/resources/build-platforms.toml | 1 + .../resources/constraints-pyodide315.txt | 86 ++++++++++++++++ cibuildwheel/selector.py | 13 --- docs/_internal/pyodide-maintenance.md | 98 +++++++++---------- docs/options.md | 8 +- test/test_pyodide.py | 8 +- test/utils.py | 3 + unit_test/build_selector_test.py | 13 +-- 10 files changed, 151 insertions(+), 85 deletions(-) create mode 100644 cibuildwheel/resources/constraints-pyodide315.txt diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d248dae3..87d02a88 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -328,13 +328,13 @@ jobs: output-dir: wheelhouse env: CIBW_PLATFORM: pyodide - CIBW_ENABLE: pyodide-prerelease + CIBW_ENABLE: cpython-prerelease - name: Run tests with 'CIBW_PLATFORM' set to 'pyodide' run: uv run --no-sync ./bin/run_tests.py env: CIBW_PLATFORM: pyodide - CIBW_ENABLE: pyodide-prerelease + CIBW_ENABLE: cpython-prerelease test-uv-extras: name: Test uv extra on ${{ matrix.os }} ${{ matrix.test_select }} diff --git a/README.md b/README.md index ef116e2f..12585957 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ While cibuildwheel itself requires a recent Python version to run (we support th | CPython 3.12 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | N/A | N/A | ✅3 | | CPython 3.13 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | ✅ | ✅ | ✅ | | CPython 3.14 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | ✅ | ✅ | ✅ | -| CPython 3.155 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | ✅ | ✅ | N/A | +| CPython 3.155 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | ✅ | ✅ | ✅ | | PyPy 3.9 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅1 | ✅1 | ✅1 | N/A | N/A | N/A | N/A | N/A | N/A | | PyPy 3.10 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅1 | ✅1 | ✅1 | N/A | N/A | N/A | N/A | N/A | N/A | | PyPy 3.11 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅1 | ✅1 | ✅1 | N/A | N/A | N/A | N/A | N/A | N/A | diff --git a/cibuildwheel/resources/build-platforms.toml b/cibuildwheel/resources/build-platforms.toml index cae97baf..5b2596dc 100644 --- a/cibuildwheel/resources/build-platforms.toml +++ b/cibuildwheel/resources/build-platforms.toml @@ -218,6 +218,7 @@ python_configurations = [ { identifier = "cp312-pyodide_wasm32", version = "3.12", default_pyodide_version = "0.27.7", node_version = "v22", sha256 = "0c2e7db42efa5d1dac38b50f8b3d659a1e3885d0a233494831b8206281307d52" }, { identifier = "cp313-pyodide_wasm32", version = "3.13", default_pyodide_version = "0.29.4", node_version = "v22", sha256 = "a29fc4a076408a18fc29eb4b280f80c6dddc95c19514c874c29e590d0931c02a" }, { identifier = "cp314-pyodide_wasm32", version = "3.14", default_pyodide_version = "314.0.3", node_version = "v24", sha256 = "fa341e162e3e9e46fff8caa20e5f319feb6443252aebdb8494ee6a5f697ac2c6" }, + { identifier = "cp315-pyodide_wasm32", version = "3.15", default_pyodide_version = "315.0.0a2", node_version = "v24", sha256 = "d7c0d6ddf0fce807668d7413d0e0f20fbc7922128ba8361ed71d9cff048cb96a" }, ] [android] diff --git a/cibuildwheel/resources/constraints-pyodide315.txt b/cibuildwheel/resources/constraints-pyodide315.txt new file mode 100644 index 00000000..4bea4659 --- /dev/null +++ b/cibuildwheel/resources/constraints-pyodide315.txt @@ -0,0 +1,86 @@ +# This file was autogenerated by uv via the following command: +# nox -s update_constraints +attrs==26.1.0 + # via + # cattrs + # pyodide-build + # pyodide-lock +auditwheel-emscripten==0.2.5 + # via pyodide-build +build==1.5.0 + # via + # -r .nox/update_constraints/tmp/constraints-pyodide.in + # pyodide-build +cattrs==26.1.0 + # via + # pyodide-build + # pyodide-lock +certifi==2026.7.22 + # via requests +charset-normalizer==3.4.9 + # via requests +click==8.1.8 + # via + # -r .nox/update_constraints/tmp/constraints-pyodide.in + # pyodide-build + # pyodide-cli +distlib==0.4.3 + # via virtualenv +filelock==3.32.2 + # via + # python-discovery + # virtualenv +idna==3.18 + # via requests +leb128==1.0.9 + # via auditwheel-emscripten +markdown-it-py==4.2.0 + # via rich +mdurl==0.1.2 + # via markdown-it-py +packaging==26.2 + # via + # auditwheel-emscripten + # build + # pyodide-build + # wheel +pip==26.2 + # via -r .nox/update_constraints/tmp/constraints-pyodide.in +platformdirs==4.11.0 + # via + # pyodide-build + # virtualenv +pygments==2.20.0 + # via rich +pyodide-build==0.39.0 + # via -r .nox/update_constraints/tmp/constraints-pyodide.in +pyodide-cli==0.5.0 + # via + # auditwheel-emscripten + # pyodide-build +pyodide-lock==0.2.0 + # via pyodide-build +pyproject-hooks==1.2.0 + # via build +python-discovery==1.5.1 + # via virtualenv +requests==2.34.2 + # via pyodide-build +rich==15.0.0 + # via + # pyodide-build + # pyodide-cli +ruamel-yaml==0.19.1 + # via pyodide-build +typing-extensions==4.16.0 + # via cattrs +urllib3==2.7.0 + # via requests +virtualenv==21.7.1 + # via + # build + # pyodide-build +wheel==0.47.0 + # via + # auditwheel-emscripten + # pyodide-build diff --git a/cibuildwheel/selector.py b/cibuildwheel/selector.py index 9314fa1e..2a8892dd 100644 --- a/cibuildwheel/selector.py +++ b/cibuildwheel/selector.py @@ -104,19 +104,6 @@ class BuildSelector: return False if EnableGroup.PyodideEoL not in self.enable and fnmatch(build_id, "cp312-pyodide_*"): return False - # NOTE: Re-enable this when we have a new Pyodide prerelease (e.g., 315.0.0a1+) - # When doing this, also: - # 1. update Pyodide tests in unit_test/build_selector_test.py and unit_test/options_test.py accordingly. - # 2. update Python versions for Pyodide identifiers in cibuildwheel/selector.py. - # 3. update constraints as necessary via bin/generate_pyodide_constraints.py and add/delete - # Pyodide constraints files in cibuildwheel/resources/constraints/ as necessary. - # When re-enabling, update the pattern to match the experimental Python version when - # it is bumped to Python 3.15 (likely cp315-pyodide_*). - # This depends on the CPython version being used in the Pyodide runtime at the time. - # if EnableGroup.PyodidePrerelease not in self.enable and fnmatch( - # build_id, "cp315-pyodide_*" - # ): - # return False should_build = selector_matches(self.build_config, build_id) should_skip = selector_matches(self.skip_config, build_id) diff --git a/docs/_internal/pyodide-maintenance.md b/docs/_internal/pyodide-maintenance.md index ad790048..422da5b5 100644 --- a/docs/_internal/pyodide-maintenance.md +++ b/docs/_internal/pyodide-maintenance.md @@ -1,6 +1,6 @@ # Maintaining Pyodide support -Last updated: May 2026 +Last updated: August 2026 This page describes how to update cibuildwheel's Pyodide platform code when either: @@ -11,17 +11,26 @@ This page describes how to update cibuildwheel's Pyodide platform code when eith Pyodide has three types of releases that matter to cibuildwheel: -- **Stable** – the most recent full Pyodide release (e.g., `0.29.x` / cp313). This is enabled by default with no special `CIBW_ENABLE` flag needed. -- **Prerelease** – an alpha/beta/rc Pyodide release that uses the _next_ CPython version (e.g., `314.0.0a1` / cp314). Users must opt in with `CIBW_ENABLE: pyodide-prerelease` to build against this version. This may or may not be available at any given time, depending on the Pyodide release cycle. -- **End-of-life (EoL)** – older Pyodide stable releases that are no longer the current stable. These are kept available behind `CIBW_ENABLE: pyodide-eol` so that users who still need to build for older Pyodide versions can do so. +- **Stable** – the most recent full Pyodide release. + This is enabled by default with no special `CIBW_ENABLE` flag needed. +- **Prerelease** – an alpha/beta/rc Pyodide release that uses the _next_ CPython + version. Users must opt in with `CIBW_ENABLE: + cpython-prerelease` to build against this version. This may or may not be + available at any given time, depending on the Pyodide release cycle. +- **End-of-life (EoL)** – older Pyodide stable releases that are no longer the + current stable. These are kept available behind `CIBW_ENABLE: pyodide-eol` so + that users who still need to build for older Pyodide versions can do so. -The guards in `cibuildwheel/selector.py` enforce this distinction. The constraints files under `cibuildwheel/resources/` pin the exact tool versions that go with each build. +The guards in `cibuildwheel/selector.py` enforce this distinction. The +constraints files under `cibuildwheel/resources/` pin the exact tool versions +that go with each build. --- ## When a new Pyodide prerelease becomes available -For example, consider a scenario when Pyodide ships a new `315.0.0a1` with cp315 support. +For example, consider a scenario when Pyodide ships a new `315.0.0a1` with cp315 +support. ### 1. Add the new Python configuration @@ -31,61 +40,39 @@ In `cibuildwheel/resources/build-platforms.toml`, add an entry under `[pyodide]` { identifier = "cp315-pyodide_wasm32", version = "3.15", default_pyodide_version = "315.0.0a1", node_version = "v24", sha256 = "SHA256" }, ``` -`version` is the CPython version string, `default_pyodide_version` is the Pyodide release to use when the user does not pin one explicitly (use the latest available alpha/beta for a prerelease entry), and `node_version` is the minimum Node.js major required by that Pyodide release — check the [pyodide-build FAQ](https://pyodide-build.readthedocs.io/en/latest/faq.html#what-node-js-version-do-i-need) for a rudimentary idea of what the correct value is. `sha256` is the checksum of the Pyodide xbuildenv tarball. +`version` is the CPython version string, `default_pyodide_version` is the +Pyodide release to use when the user does not pin one explicitly (use the latest +available alpha/beta for a prerelease entry), and `node_version` is the minimum +Node.js major required by that Pyodide release — check the +[pyodide-build FAQ](https://pyodide-build.readthedocs.io/en/latest/faq.html#what-node-js-version-do-i-need) +for a rudimentary idea of what the correct value is. `sha256` is the checksum of +the Pyodide xbuildenv tarball. -### 2. Update the prerelease guards in the selector +### 2. Generate and pin a constraints file -In `cibuildwheel/selector.py`, update the patterns in the `PyodidePrerelease` guards to match the new identifier: - -```python -if EnableGroup.PyodidePrerelease not in self.enable and fnmatch( - build_id, "cp315-pyodide_*" -): - return False -``` - -### 3. Generate and pin a constraints file - -Run the `update_constraints` `nox` session, which reads `build-platforms.toml` and regenerates all Pyodide constraints files automatically: +Run the `update_constraints` `nox` session, which reads `build-platforms.toml` +and regenerates all Pyodide constraints files automatically: ```bash nox -s update_constraints ``` -### 4. Update tests +### 3. Update tests -Update the unit tests so the new identifier is accepted by the selector with `PyodidePrerelease` enabled and rejected without it. Pyodide-specific integration tests may also need their hardcoded expected-wheel lists extended. - -## When a Pyodide prerelease becomes stable - -Pyodide uses a versioning scheme where the stable release for a given CPython version is named `[PythonMajorMinor].0.0`, so the first stable release shipping cp314 will be **`314.0.0`**. See [pyodide/pyodide#6084](https://github.com/pyodide/pyodide/issues/6084) for a rationale of this versioning scheme. - -### 1. Update the stable entries, and remove (or replace) the prerelease entry - -In `build-platforms.toml`, update the former prerelease entry's `default_pyodide_version` to the new stable release (e.g. `314.0.0`) and remove the prerelease marker from the identifier if present. Remove previous prerelease entries if they are now obsolete, or update them to the next prerelease if one is available. Move the previous stable version behind `pyodide-eol` rather than dropping it outright (see below). - -### 2. Disable or update the prerelease guards - -In `selector.py`: - -- **If a new prerelease is available**: update the `fnmatch` pattern to the next identifier (e.g. `cp315-pyodide_*`) as described above. -- **If there is no new prerelease**: comment out the `PyodidePrerelease` logic. - -### 3. Update the constraints file - -Run `nox -s update_constraints` to regenerate the constraints file for the newly stable version. If the entry was already in `build-platforms.toml` as a prerelease, its constraints file already exists, and this step just refreshes it against the stable Pyodide release and updates the dependencies' versions. - -### 4. Update tests - -Update the unit tests so the newly stable identifier is accepted by the selector without needing `PyodidePrerelease` in the enable set. Pyodide-specific integration tests may also need their hardcoded expected-wheel lists extended. +Update the unit tests so the new identifier is accepted by the selector with +`CPythonPrerelease` enabled and rejected without it. Pyodide-specific +integration tests may also need their hardcoded expected-wheel lists extended. ## When an old Pyodide version is to be moved to end-of-life -When a Pyodide version is superseded by a new stable release, move it behind the `pyodide-eol` enable flag. We want to allow users who still build for older Pyodide ABIs time to upgrade. +When a Pyodide version is superseded by a new stable release, move it behind the +`pyodide-eol` enable flag. We want to allow users who still build for older +Pyodide ABIs time to upgrade. ### 1. Add the `pyodide-eol` guard in the selector -In `cibuildwheel/selector.py`, add (or update) the `PyodideEoL` guard to include the old identifier: +In `cibuildwheel/selector.py`, add (or update) the `PyodideEoL` guard to include +the old identifier: ```python if EnableGroup.PyodideEoL not in self.enable and fnmatch(build_id, "cp312-pyodide_*"): @@ -94,15 +81,23 @@ if EnableGroup.PyodideEoL not in self.enable and fnmatch(build_id, "cp312-pyodid ### 2. Update tests -Update the unit tests so the EoL identifier requires `PyodideEoL` to be included in the enable set. The default (no `CIBW_ENABLE`) should exclude it. +Update the unit tests so the EoL identifier requires `PyodideEoL` to be included +in the enable set. The default (no `CIBW_ENABLE`) should exclude it. ## When an old Pyodide version is to be fully retired -Retirement is not expected to happen on a routine basis. It is only warranted when the Pyodide ecosystem itself has evolved to the point where an older ABI version is considered obsolete – for example, if the surrounding toolchain, packaging standards, or runtime infrastructure have moved on so substantially that building for the older version no longer makes practical sense. Any retirement is to be discussed and agreed upon by Pyodide maintainers before proceeding. +Retirement is not expected to happen on a routine basis. It is only warranted +when the Pyodide ecosystem itself has evolved to the point where an older ABI +version is considered obsolete – for example, if the surrounding toolchain, +packaging standards, or runtime infrastructure have moved on so substantially +that building for the older version no longer makes practical sense. Any +retirement is to be discussed and agreed upon by Pyodide maintainers before +proceeding. ### 1. Remove the Python configuration -Delete the entry from `build-platforms.toml` and remove the `PyodideEoL` guard for that identifier in `selector.py`. +Delete the entry from `build-platforms.toml` and remove the `PyodideEoL` guard +for that identifier in `selector.py`. ### 2. Delete the constraints file @@ -110,4 +105,5 @@ Remove `cibuildwheel/resources/constraints-pyodideXYZ.txt`. ### 3. Update tests -Remove references to the old identifier from the unit tests, integration tests, and drop any expected-wheel entries for it from the test helper. +Remove references to the old identifier from the unit tests, integration tests, +and drop any expected-wheel entries for it from the test helper. diff --git a/docs/options.md b/docs/options.md index 539c81ca..c50400bd 100644 --- a/docs/options.md +++ b/docs/options.md @@ -65,7 +65,7 @@ When setting the options, you can use shell-style globbing syntax, as per [fnmat | Python 3.12 | cp312-macosx_x86_64
cp312-macosx_universal2
cp312-macosx_arm64 | cp312-win_amd64
cp312-win32
cp312-win_arm64 | cp312-manylinux_x86_64
cp312-manylinux_i686
cp312-musllinux_x86_64
cp312-musllinux_i686 | cp312-manylinux_aarch64
cp312-manylinux_ppc64le
cp312-manylinux_s390x
cp312-manylinux_armv7l
cp312-manylinux_riscv64
cp312-musllinux_aarch64
cp312-musllinux_ppc64le
cp312-musllinux_s390x
cp312-musllinux_armv7l
cp312-musllinux_riscv64 | | | cp312-pyodide_wasm32 | | Python 3.13 | cp313-macosx_x86_64
cp313-macosx_universal2
cp313-macosx_arm64 | cp313-win_amd64
cp313-win32
cp313-win_arm64 | cp313-manylinux_x86_64
cp313-manylinux_i686
cp313-musllinux_x86_64
cp313-musllinux_i686 | cp313-manylinux_aarch64
cp313-manylinux_ppc64le
cp313-manylinux_s390x
cp313-manylinux_armv7l
cp313-manylinux_riscv64
cp313-musllinux_aarch64
cp313-musllinux_ppc64le
cp313-musllinux_s390x
cp313-musllinux_armv7l
cp313-musllinux_riscv64 | cp313-android_arm64_v8a
cp313-android_x86_64 | cp313-ios_arm64_iphoneos
cp313-ios_arm64_iphonesimulator
cp313-ios_x86_64_iphonesimulator | cp313-pyodide_wasm32 | | Python 3.14 | cp314-macosx_x86_64
cp314-macosx_universal2
cp314-macosx_arm64

cp314t-macosx_x86_64
cp314t-macosx_universal2
cp314t-macosx_arm64 | cp314-win_amd64
cp314-win32
cp314-win_arm64

cp314t-win_amd64
cp314t-win32
cp314t-win_arm64 | cp314-manylinux_x86_64
cp314-manylinux_i686
cp314-musllinux_x86_64
cp314-musllinux_i686

cp314t-manylinux_x86_64
cp314t-manylinux_i686
cp314t-musllinux_x86_64
cp314t-musllinux_i686 | cp314-manylinux_aarch64
cp314-manylinux_ppc64le
cp314-manylinux_s390x
cp314-manylinux_armv7l
cp314-manylinux_riscv64
cp314-musllinux_aarch64
cp314-musllinux_ppc64le
cp314-musllinux_s390x
cp314-musllinux_armv7l
cp314-musllinux_riscv64

cp314t-manylinux_aarch64
cp314t-manylinux_ppc64le
cp314t-manylinux_s390x
cp314t-manylinux_armv7l
cp314t-manylinux_riscv64
cp314t-musllinux_aarch64
cp314t-musllinux_ppc64le
cp314t-musllinux_s390x
cp314t-musllinux_armv7l
cp314t-musllinux_riscv64 | cp314-android_arm64_v8a
cp314-android_x86_64 | cp314-ios_arm64_iphoneos
cp314-ios_arm64_iphonesimulator
cp314-ios_x86_64_iphonesimulator | cp314-pyodide_wasm32 | -| Python 3.15 | cp315-macosx_x86_64
cp315-macosx_universal2
cp315-macosx_arm64

cp315t-macosx_x86_64
cp315t-macosx_universal2
cp315t-macosx_arm64 | cp315-win_amd64
cp315-win32
cp315-win_arm64

cp315t-win_amd64
cp315t-win32
cp315t-win_arm64 | cp315-manylinux_x86_64
cp315-manylinux_i686
cp315-musllinux_x86_64
cp315-musllinux_i686

cp315t-manylinux_x86_64
cp315t-manylinux_i686
cp315t-musllinux_x86_64
cp315t-musllinux_i686 | cp315-manylinux_aarch64
cp315-manylinux_ppc64le
cp315-manylinux_s390x
cp315-manylinux_armv7l
cp315-manylinux_riscv64
cp315-musllinux_aarch64
cp315-musllinux_ppc64le
cp315-musllinux_s390x
cp315-musllinux_armv7l
cp315-musllinux_riscv64

cp315t-manylinux_aarch64
cp315t-manylinux_ppc64le
cp315t-manylinux_s390x
cp315t-manylinux_armv7l
cp315t-manylinux_riscv64
cp315t-musllinux_aarch64
cp315t-musllinux_ppc64le
cp315t-musllinux_s390x
cp315t-musllinux_armv7l
cp315t-musllinux_riscv64 | cp315-android_arm64_v8a
cp315-android_x86_64 | cp315-ios_arm64_iphoneos
cp315-ios_arm64_iphonesimulator
cp315-ios_x86_64_iphonesimulator | | +| Python 3.15 | cp315-macosx_x86_64
cp315-macosx_universal2
cp315-macosx_arm64

cp315t-macosx_x86_64
cp315t-macosx_universal2
cp315t-macosx_arm64 | cp315-win_amd64
cp315-win32
cp315-win_arm64

cp315t-win_amd64
cp315t-win32
cp315t-win_arm64 | cp315-manylinux_x86_64
cp315-manylinux_i686
cp315-musllinux_x86_64
cp315-musllinux_i686

cp315t-manylinux_x86_64
cp315t-manylinux_i686
cp315t-musllinux_x86_64
cp315t-musllinux_i686 | cp315-manylinux_aarch64
cp315-manylinux_ppc64le
cp315-manylinux_s390x
cp315-manylinux_armv7l
cp315-manylinux_riscv64
cp315-musllinux_aarch64
cp315-musllinux_ppc64le
cp315-musllinux_s390x
cp315-musllinux_armv7l
cp315-musllinux_riscv64

cp315t-manylinux_aarch64
cp315t-manylinux_ppc64le
cp315t-manylinux_s390x
cp315t-manylinux_armv7l
cp315t-manylinux_riscv64
cp315t-musllinux_aarch64
cp315t-musllinux_ppc64le
cp315t-musllinux_s390x
cp315t-musllinux_armv7l
cp315t-musllinux_riscv64 | cp315-android_arm64_v8a
cp315-android_x86_64 | cp315-ios_arm64_iphoneos
cp315-ios_arm64_iphonesimulator
cp315-ios_x86_64_iphonesimulator | cp315-pyodide_wasm32 | | PyPy3.9 v7.3 | pp39-macosx_x86_64
pp39-macosx_arm64 | pp39-win_amd64 | pp39-manylinux_x86_64
pp39-manylinux_i686 | pp39-manylinux_aarch64 | | | | | PyPy3.10 v7.3 | pp310-macosx_x86_64
pp310-macosx_arm64 | pp310-win_amd64 | pp310-manylinux_x86_64
pp310-manylinux_i686 | pp310-manylinux_aarch64 | | | | | PyPy3.11 v7.3 | pp311-macosx_x86_64
pp311-macosx_arm64 | pp311-win_amd64 | pp311-manylinux_x86_64
pp311-manylinux_i686 | pp311-manylinux_aarch64 | | | | @@ -357,13 +357,11 @@ values are: - `cpython-prerelease`: Enables beta versions of Pythons if any are available - (May-July, approximately). + (May-July, approximately). This also covers Pyodide versions built against a + beta CPython, which is the case for the current Pyodide prerelease. - `pypy`: Enable PyPy. - `pypy-eol`: Enable PyPy versions that have passed end of life (if still available). - `graalpy`: Enable GraalPy. -- `pyodide-prerelease`: Pyodide versions that haven't released yet, if one is - available. Safe if you are shipping a site with an early build, not for - general distribution. - `pyodide-eol`: Enable Pyodide versions that are no longer the current stable release (if still available). - `all`: Enable all of the above. diff --git a/test/test_pyodide.py b/test/test_pyodide.py index 709dd21b..da36d180 100644 --- a/test/test_pyodide.py +++ b/test/test_pyodide.py @@ -71,7 +71,9 @@ def test_pyodide_build(tmp_path: Path, use_pyproject_toml: bool) -> None: basic_project.generate(project_dir) # check for node in 1 case only to reduce CI load - add_env = {"CIBW_ENABLE": "pyodide-prerelease"} + # cp315 is a Pyodide prerelease embedding a prerelease CPython, so it is + # gated by `cpython-prerelease`. + add_env = {"CIBW_ENABLE": "cpython-prerelease"} if use_pyproject_toml: add_env["CIBW_TEST_COMMAND"] = f"python {{project}}/check_node.py {CIBW_CACHE_PATH}" @@ -86,6 +88,7 @@ def test_pyodide_build(tmp_path: Path, use_pyproject_toml: bool) -> None: expected_wheels = [ "spam-0.1.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl", "spam-0.1.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", + "spam-0.1.0-cp315-cp315-pyemscripten_2026_5_wasm32.whl", ] print("actual_wheels", actual_wheels) @@ -144,13 +147,14 @@ def test_pyodide_build_and_test(tmp_path: Path, expect_failure: bool) -> None: add_env={ "CIBW_TEST_REQUIRES": "pytest", "CIBW_TEST_COMMAND": "python -m pytest {project}", - "CIBW_ENABLE": "pyodide-prerelease", + "CIBW_ENABLE": "cpython-prerelease", }, ) # check that the expected wheels are produced expected_wheels = [ "spam-0.1.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl", "spam-0.1.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", + "spam-0.1.0-cp315-cp315-pyemscripten_2026_5_wasm32.whl", ] assert set(actual_wheels) == set(expected_wheels) diff --git a/test/utils.py b/test/utils.py index 1553bb2c..e0131bb9 100644 --- a/test/utils.py +++ b/test/utils.py @@ -281,6 +281,8 @@ def _expected_wheels( python_abi_tags = ["cp313-cp313", "cp314-cp314"] if EnableGroup.PyodideEoL in enable_groups: python_abi_tags.insert(0, "cp312-cp312") + if EnableGroup.CPythonPrerelease in enable_groups: + python_abi_tags.append("cp315-cp315") elif (platform == "android" and python_abi_tags is None) or ( platform == "ios" and python_abi_tags is None ): @@ -410,6 +412,7 @@ def _expected_wheels( "cp312-cp312": ["pyodide_2024_0_wasm32"], "cp313-cp313": ["pyemscripten_2025_0_wasm32"], "cp314-cp314": ["pyemscripten_2026_0_wasm32"], + "cp315-cp315": ["pyemscripten_2026_5_wasm32"], }.get(python_abi_tag, []) if not platform_tags: diff --git a/unit_test/build_selector_test.py b/unit_test/build_selector_test.py index 817cfce5..134125c1 100644 --- a/unit_test/build_selector_test.py +++ b/unit_test/build_selector_test.py @@ -91,17 +91,6 @@ def test_build_filter_pypy_all() -> None: assert build_selector("pp39-manylinux_x86_64") -# Re-enable when we have Pyodide 3.15 prerelease builds to test against -# def test_build_filter_pyodide_prerelease() -> None: -# build_selector = BuildSelector( -# build_config="*", -# skip_config="", -# enable=frozenset([EnableGroup.PyodidePrerelease]), -# ) -# assert build_selector("cp314-pyodide_wasm32") -# assert build_selector("cp315-pyodide_wasm32") - - def test_build_filter_pyodide() -> None: build_selector = BuildSelector( build_config="*", @@ -111,6 +100,7 @@ def test_build_filter_pyodide() -> None: assert build_selector("cp313-pyodide_wasm32") assert build_selector("cp314-pyodide_wasm32") assert not build_selector("cp312-pyodide_wasm32") + assert not build_selector("cp315-pyodide_wasm32") def test_build_filter_pyodide_eol() -> None: @@ -122,6 +112,7 @@ def test_build_filter_pyodide_eol() -> None: assert build_selector("cp312-pyodide_wasm32") assert build_selector("cp313-pyodide_wasm32") assert build_selector("cp314-pyodide_wasm32") + assert not build_selector("cp315-pyodide_wasm32") def test_skip() -> None: