diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3d2e28fbd..a244b57fe 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -323,11 +323,13 @@ jobs: output-dir: wheelhouse env: CIBW_PLATFORM: pyodide + CIBW_ENABLE: pyodide-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 test-uv-extras: name: Test uv extra on ${{ matrix.os }} ${{ matrix.test_select }} diff --git a/cibuildwheel/platforms/pyodide.py b/cibuildwheel/platforms/pyodide.py index e0560b4a0..21d7b04a8 100644 --- a/cibuildwheel/platforms/pyodide.py +++ b/cibuildwheel/platforms/pyodide.py @@ -94,20 +94,19 @@ def ensure_node(major_version: str) -> Path: return path -def install_emscripten( - env: dict[str, str], version: str, xbuildenv_cache_path: Path, pyodide_version: str -) -> Path: +def install_emscripten(env: dict[str, str], version: str, xbuildenv_cache_path: Path) -> Path: """Install Emscripten via pyodide-build, which also applies Pyodide-specific patches.""" - emcc_path = ( - xbuildenv_cache_path / pyodide_version / "emsdk" / "upstream" / "emscripten" / "emcc" + emscripten_dir = Path( + call("pyodide", "config", "get", "emscripten_dir", env=env, capture_stdout=True).strip() ) with FileLock(CIBW_CACHE_PATH / "emscripten.lock"): - if emcc_path.exists(): - return emcc_path + if emscripten_dir.exists(): + return emscripten_dir call( "pyodide", "xbuildenv", "install-emscripten", + "--force", "--version", version, "--path", @@ -115,8 +114,8 @@ def install_emscripten( env=env, cwd=CIBW_CACHE_PATH, ) - assert emcc_path.exists() - return emcc_path + assert emscripten_dir.exists() + return emscripten_dir def get_all_xbuildenv_version_info(env: dict[str, str]) -> list[PyodideXBuildEnvInfo]: @@ -315,9 +314,9 @@ def setup_python( log.step( f"Installing Emscripten {emscripten_version} and applying Pyodide-specific patches ..." ) - emcc_path = install_emscripten(env, emscripten_version, xbuildenv_cache_path, pyodide_version) + emscripten_dir = install_emscripten(env, emscripten_version, xbuildenv_cache_path) - env["PATH"] = os.pathsep.join([str(emcc_path.parent), env["PATH"]]) + env["PATH"] = os.pathsep.join([str(emscripten_dir), env["PATH"]]) return env diff --git a/cibuildwheel/resources/build-platforms.toml b/cibuildwheel/resources/build-platforms.toml index f75627ada..234d865c0 100644 --- a/cibuildwheel/resources/build-platforms.toml +++ b/cibuildwheel/resources/build-platforms.toml @@ -225,8 +225,8 @@ python_configurations = [ [pyodide] python_configurations = [ - { identifier = "cp312-pyodide_wasm32", version = "3.12", default_pyodide_version = "0.27.7", node_version = "v22" }, { identifier = "cp313-pyodide_wasm32", version = "3.13", default_pyodide_version = "0.29.3", node_version = "v22" }, + { identifier = "cp314-pyodide_wasm32", version = "3.14", default_pyodide_version = "314.0.0a1", node_version = "v24" }, ] [android] diff --git a/cibuildwheel/resources/constraints-pyodide313.txt b/cibuildwheel/resources/constraints-pyodide313.txt index 693f4602e..53d85c36c 100644 --- a/cibuildwheel/resources/constraints-pyodide313.txt +++ b/cibuildwheel/resources/constraints-pyodide313.txt @@ -2,15 +2,15 @@ # nox -s update_constraints annotated-types==0.7.0 # via pydantic -auditwheel-emscripten==0.2.3 +auditwheel-emscripten==0.2.4 # via pyodide-build -build==1.2.2.post1 +build==1.4.2 # via # -r .nox/update_constraints/tmp/constraints-pyodide.in # pyodide-build certifi==2026.2.25 # via requests -charset-normalizer==3.4.6 +charset-normalizer==3.4.7 # via requests click==8.1.8 # via @@ -39,7 +39,7 @@ packaging==26.0 # wheel pip==26.0.1 # via -r .nox/update_constraints/tmp/constraints-pyodide.in -platformdirs==4.9.4 +platformdirs==4.9.6 # via # pyodide-build # python-discovery @@ -50,9 +50,9 @@ pydantic==2.12.5 # pyodide-lock pydantic-core==2.41.5 # via pydantic -pygments==2.19.2 +pygments==2.20.0 # via rich -pyodide-build==0.33.0 +pyodide-build==0.34.1 # via -r .nox/update_constraints/tmp/constraints-pyodide.in pyodide-cli==0.5.0 # via @@ -62,9 +62,9 @@ pyodide-lock==0.1.2 # via pyodide-build pyproject-hooks==1.2.0 # via build -python-discovery==1.2.0 +python-discovery==1.2.2 # via virtualenv -requests==2.32.5 +requests==2.33.1 # via pyodide-build rich==14.3.3 # via @@ -81,7 +81,7 @@ typing-inspection==0.4.2 # via pydantic urllib3==2.6.3 # via requests -virtualenv==21.2.0 +virtualenv==21.2.1 # via # build # pyodide-build diff --git a/cibuildwheel/resources/constraints-pyodide312.txt b/cibuildwheel/resources/constraints-pyodide314.txt similarity index 90% rename from cibuildwheel/resources/constraints-pyodide312.txt rename to cibuildwheel/resources/constraints-pyodide314.txt index 693f4602e..53d85c36c 100644 --- a/cibuildwheel/resources/constraints-pyodide312.txt +++ b/cibuildwheel/resources/constraints-pyodide314.txt @@ -2,15 +2,15 @@ # nox -s update_constraints annotated-types==0.7.0 # via pydantic -auditwheel-emscripten==0.2.3 +auditwheel-emscripten==0.2.4 # via pyodide-build -build==1.2.2.post1 +build==1.4.2 # via # -r .nox/update_constraints/tmp/constraints-pyodide.in # pyodide-build certifi==2026.2.25 # via requests -charset-normalizer==3.4.6 +charset-normalizer==3.4.7 # via requests click==8.1.8 # via @@ -39,7 +39,7 @@ packaging==26.0 # wheel pip==26.0.1 # via -r .nox/update_constraints/tmp/constraints-pyodide.in -platformdirs==4.9.4 +platformdirs==4.9.6 # via # pyodide-build # python-discovery @@ -50,9 +50,9 @@ pydantic==2.12.5 # pyodide-lock pydantic-core==2.41.5 # via pydantic -pygments==2.19.2 +pygments==2.20.0 # via rich -pyodide-build==0.33.0 +pyodide-build==0.34.1 # via -r .nox/update_constraints/tmp/constraints-pyodide.in pyodide-cli==0.5.0 # via @@ -62,9 +62,9 @@ pyodide-lock==0.1.2 # via pyodide-build pyproject-hooks==1.2.0 # via build -python-discovery==1.2.0 +python-discovery==1.2.2 # via virtualenv -requests==2.32.5 +requests==2.33.1 # via pyodide-build rich==14.3.3 # via @@ -81,7 +81,7 @@ typing-inspection==0.4.2 # via pydantic urllib3==2.6.3 # via requests -virtualenv==21.2.0 +virtualenv==21.2.1 # via # build # pyodide-build diff --git a/cibuildwheel/selector.py b/cibuildwheel/selector.py index 8b390e986..6812c9e06 100644 --- a/cibuildwheel/selector.py +++ b/cibuildwheel/selector.py @@ -96,17 +96,19 @@ def __call__(self, build_id: str) -> bool: return False if EnableGroup.GraalPy not in self.enable and fnmatch(build_id, "gp*"): return False - # TODO: Re-enable this when we have Pyodide prereleases again (e.g., 0.29.0a1+) - # Python 3.13 support became stable in Pyodide 0.28.0, so it no longer needs a prerelease - # flag. - # Also update Pyodide tests in unit_test/build_selector_test.py accordingly. - # When re-enabling, update the pattern to match the experimental Python version in case - # it is bumped to Python 3.14 (likely cp314-pyodide_* but could remain as 3.13 as well). + # NOTE: Disable this when we don't have any Pyodide prereleases (e.g., 314.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 disabling, update the pattern to match the experimental Python version in case + # it is bumped to Python 3.15 (likely cp315-pyodide_* but could remain as 3.14 as well). # 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, "cp313-pyodide_*" - # ): - # return False + if EnableGroup.PyodidePrerelease not in self.enable and fnmatch( + build_id, "cp314-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 new file mode 100644 index 000000000..6b422b337 --- /dev/null +++ b/docs/_internal/pyodide-maintenance.md @@ -0,0 +1,103 @@ +# Maintaining Pyodide support + +This page describes how to update cibuildwheel's Pyodide platform code when either: + +- a new Pyodide alpha release arrives with support for a new [PyEmscripten Platform](https://pyodide.org/en/latest/development/abi.html) (which is tied to updates in Emscripten and CPython versions, compiler/linker flags, and so on), or +- when that alpha release graduates to a stable one. + +## Background + +Pyodide has two types of releases that matter to cibuildheel: + +- **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. + +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. + +### 1. Add the new Python configuration + +In `cibuildwheel/resources/build-platforms.toml`, add an entry under `[pyodide]`: + +```toml +{ identifier = "cp315-pyodide_wasm32", version = "3.15", default_pyodide_version = "315.0.0a1", node_version = "v24" }, +``` + +`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. + +### 2. Update the prerelease guards in the selector + +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: + +```bash +nox -s update_constraints +``` + +Alternatively, run the generator script directly: + +```bash +python bin/generate_pyodide_constraints.py 315.0.0a1 \ + | uv pip compile - --python-version=3.15 \ + -o cibuildwheel/resources/constraints-pyodide315.txt +``` + +### 4. Update tests and update CI configuration + +- 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. + +- Run the full test suite with `CIBW_PLATFORM=pyodide` and `CIBW_ENABLE=pyodide-prerelease` environment variables to make sure the new configuration is exercised in CI. + +## 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. Based on your discretion, you may choose to keep the old stable entry for a while if it is still supported by Pyodide, or remove it immediately if it is already retired. + +### 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 and CI configuration + +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. + +- Run the full test suite with `CIBW_PLATFORM=pyodide` and `CIBW_ENABLE=pyodide-prerelease` environment variables to make sure the new configuration is exercised in CI. + +## When an old Pyodide version is to be retired + +### 1. Remove the python configuration + +Delete the entry from `build-platforms.toml`. + +### 2. Delete the constraints file + +Remove `cibuildwheel/resources/constraints-pyodideXYZ.txt`. + +### 3. Update tests and CI configuration + +Remove references to the old identifier from the unit tests, integration tests, and drop any expected-wheel entries for it from the test helper. Also, ensure that no CI job is still trying to build it. diff --git a/docs/contributing.md b/docs/contributing.md index 31c879a79..739e7c021 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -208,3 +208,9 @@ git push && git push --tags Then head to https://github.com/pypa/cibuildwheel/releases and create a GitHub release from the new tag, pasting in the changelog entry. Once the release is created inside GitHub, a CI job will create the assets and upload them to PyPI. If there were any schema updates, run `pipx run ./bin/generate_schema.py --schemastore > partial-cibuildwheel.json` and contribute the changes to SchemaStore. + +### Platform-specific maintenance + +This section is a stub. Please open a PR to add guidance for any platform you would like to help maintain! + +- **Pyodide**: see [Maintaining Pyodide support](_internal/pyodide-maintenance.md) for instructions and maintainer-specific information on updating Pyodide-related code in cibuildwheel and updating to new Pyodide releases. diff --git a/test/test_abi_variants.py b/test/test_abi_variants.py index 25fc9ca5d..fdf797be0 100644 --- a/test/test_abi_variants.py +++ b/test/test_abi_variants.py @@ -43,15 +43,20 @@ def test_abi3(tmp_path: Path) -> None: project_dir, add_env={ # free_threaded, GraalPy, and PyPy do not have a Py_LIMITED_API equivalent, just build one of those + # pyodide uses cp313 (the stable version) which supports limited API / abi3 # also limit the number of builds for test performance reasons - "CIBW_BUILD": "cp39-* cp310-* pp310-* gp312_250-* cp312-* cp314t-*", + "CIBW_BUILD": ( + "cp313-*" + if utils.get_platform() == "pyodide" + else "cp39-* cp310-* pp310-* gp312_250-* cp312-* cp314t-*" + ), "CIBW_ENABLE": "all", }, ) # check that the expected wheels are produced if utils.get_platform() == "pyodide": - # there's only 1 possible configuration for pyodide, cp312. It builds + # there's only 1 possible configuration for pyodide, cp313. It builds # a wheel that is tagged abi3, compatible back to 3.10 expected_wheels = utils.expected_wheels( "spam", diff --git a/test/test_custom_repair_wheel.py b/test/test_custom_repair_wheel.py index 901f559cd..8bfe6a3fa 100644 --- a/test/test_custom_repair_wheel.py +++ b/test/test_custom_repair_wheel.py @@ -18,10 +18,10 @@ wheel = Path(sys.argv[1]) dest_dir = Path(sys.argv[2]) platform = wheel.stem.split("-")[-1] -if platform.startswith("pyodide"): - # for the sake of this test, munge the pyodide platforms into one, it's +if platform.startswith("pyemscripten"): + # for the sake of this test, munge the pyemscripten platforms into one, it's # not valid, but it does activate the uniqueness check - platform = "pyodide" + platform = "pyemscripten" name = f"spam-0.1.0-py2-none-{platform}.whl" dest = dest_dir / name diff --git a/test/test_dependency_versions.py b/test/test_dependency_versions.py index 855fd3546..32cfc6ca0 100644 --- a/test/test_dependency_versions.py +++ b/test/test_dependency_versions.py @@ -77,13 +77,13 @@ def get_versions_from_constraint_file(constraint_file: Path) -> dict[str, str]: return dict(re.findall(VERSION_REGEX, constraint_file_text)) -@pytest.mark.parametrize("python_version", ["3.8", "3.12"]) +@pytest.mark.parametrize("python_version", ["3.8", "3.13"]) def test_pinned_versions( tmp_path: Path, python_version: str, build_frontend_env_nouv: dict[str, str] ) -> None: if utils.get_platform() == "linux": pytest.skip("linux doesn't pin individual tool versions, it pins manylinux images instead") - if python_version != "3.12" and utils.get_platform() == "pyodide": + if python_version != "3.13" and utils.get_platform() == "pyodide": pytest.skip(f"pyodide does not support Python {python_version}") if ( python_version == "3.8" @@ -124,7 +124,7 @@ def test_pinned_versions( expected_wheels = [ w for w in utils.expected_wheels("spam", "0.1.0") - if f"-cp{version_no_dot}" in w or f"-pp{version_no_dot}" in w + if f"-cp{version_no_dot}-cp{version_no_dot}-" in w or f"-pp{version_no_dot}-" in w ] assert set(actual_wheels) == set(expected_wheels) @@ -140,11 +140,20 @@ def test_dependency_constraints( project_dir = tmp_path / "project" test_projects.new_c_project().generate(project_dir) - tool_versions = { - "pip": "23.1.2", - "build": "1.2.2", - "delocate": "0.10.3", - } + if utils.get_platform() == "pyodide": + # pyodide-build 0.34+ requires build~=1.4.0, so we must use a + # compatible version here. delocate is macOS-only and not used on pyodide. + tool_versions = { + "pip": "23.1.2", + "build": "1.4.2", + "delocate": "0.10.3", + } + else: + tool_versions = { + "pip": "23.1.2", + "build": "1.2.2", + "delocate": "0.10.3", + } if method == "file": constraints_file = tmp_path / "constraints file.txt" diff --git a/test/test_macos_archs.py b/test/test_macos_archs.py index 534541afa..7137be2d1 100644 --- a/test/test_macos_archs.py +++ b/test/test_macos_archs.py @@ -34,7 +34,7 @@ def test_cross_compiled_build(tmp_path: Path) -> None: add_env={"CIBW_ARCHS": "x86_64, universal2, arm64"}, single_python=True, ) - python_tag = "cp{}{}".format(*utils.SINGLE_PYTHON_VERSION) + python_tag = "cp{0}{1}-cp{0}{1}-".format(*utils.SINGLE_PYTHON_VERSION) expected_wheels = [w for w in ALL_MACOS_WHEELS if python_tag in w] assert set(actual_wheels) == set(expected_wheels) @@ -176,7 +176,7 @@ def test_universal2_testing_on_x86_64( else: assert warning_message in captured.err - python_tag = "cp{}{}".format(*utils.SINGLE_PYTHON_VERSION) + python_tag = "cp{0}{1}-cp{0}{1}-".format(*utils.SINGLE_PYTHON_VERSION) expected_wheels = [w for w in ALL_MACOS_WHEELS if python_tag in w and "universal2" in w] assert set(actual_wheels) == set(expected_wheels) @@ -210,7 +210,7 @@ def test_universal2_testing_on_arm64( assert "running tests on arm64 with pillow" in captured.out assert "running tests on x86_64 with pillow" in captured.out - python_tag = "cp{}{}".format(*utils.SINGLE_PYTHON_VERSION) + python_tag = "cp{0}{1}-cp{0}{1}-".format(*utils.SINGLE_PYTHON_VERSION) expected_wheels = [w for w in ALL_MACOS_WHEELS if python_tag in w and "universal2" in w] assert set(actual_wheels) == set(expected_wheels) diff --git a/test/test_pyodide.py b/test/test_pyodide.py index 45355ad5c..96873661d 100644 --- a/test/test_pyodide.py +++ b/test/test_pyodide.py @@ -79,8 +79,8 @@ def test_pyodide_build(tmp_path: Path, use_pyproject_toml: bool) -> None: # check that the expected wheels are produced expected_wheels = [ - "spam-0.1.0-cp312-cp312-pyodide_2024_0_wasm32.whl", - "spam-0.1.0-cp313-cp313-pyodide_2025_0_wasm32.whl", + "spam-0.1.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl", + "spam-0.1.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", ] print("actual_wheels", actual_wheels) @@ -144,8 +144,8 @@ def test_filter() -> None: ) # check that the expected wheels are produced expected_wheels = [ - "spam-0.1.0-cp312-cp312-pyodide_2024_0_wasm32.whl", - "spam-0.1.0-cp313-cp313-pyodide_2025_0_wasm32.whl", + "spam-0.1.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl", + "spam-0.1.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", ] assert set(actual_wheels) == set(expected_wheels) @@ -170,6 +170,6 @@ def test_pyodide_repair_wheel(tmp_path: Path) -> None: # check that the expected wheels are produced expected_wheels = [ - "spam-0.1.0-cp312-cp312-pyodide_2024_0_wasm32.whl", + "spam-0.1.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl", ] assert set(actual_wheels) == set(expected_wheels) diff --git a/test/utils.py b/test/utils.py index 7bf3d184f..bacdcd50c 100644 --- a/test/utils.py +++ b/test/utils.py @@ -26,7 +26,7 @@ PYPY_ARCHS = ["x86_64", "i686", "AMD64", "aarch64", "arm64"] GRAALPY_ARCHS = ["x86_64", "AMD64", "aarch64", "arm64"] -SINGLE_PYTHON_VERSION: Final[tuple[int, int]] = (3, 12) +SINGLE_PYTHON_VERSION: Final[tuple[int, int]] = (3, 13) # temporary workaround: set by build_frontend_env fixture to skip graalpy # when uv is the build frontend (compatibility issue between graalpy and uv) @@ -263,11 +263,11 @@ def _expected_wheels( if musllinux_versions is None: musllinux_versions = ["musllinux_1_2"] + # To be kept in sync with Python versions for Pyodide identifiers in cibuildwheel/selector.py. if platform == "pyodide" and python_abi_tags is None: - python_abi_tags = [ - "cp312-cp312", - "cp313-cp313", - ] + python_abi_tags = ["cp313-cp313"] + if EnableGroup.PyodidePrerelease in enable_groups: + python_abi_tags.append("cp314-cp314") elif platform == "android" and python_abi_tags is None: # noqa: SIM114 python_abi_tags = [ "cp313-cp313", @@ -413,14 +413,14 @@ def _expected_wheels( elif platform == "pyodide": platform_tags = { - "cp312-cp312": ["pyodide_2024_0_wasm32"], - "cp313-cp313": ["pyodide_2025_0_wasm32"], + "cp313-cp313": ["pyemscripten_2025_0_wasm32"], + "cp314-cp314": ["pyemscripten_2026_0_wasm32"], }.get(python_abi_tag, []) if not platform_tags: - # for example if the python tag is `none` or `abi3`, all - # platform tags are built with that python tag - platform_tags = ["pyodide_2024_0_wasm32"] + # for example if the python tag is `none` or `abi3`, the wheel + # is built by the stable cp313 Python version + platform_tags = ["pyemscripten_2025_0_wasm32"] else: msg = f"Unsupported platform {platform!r}" diff --git a/unit_test/build_selector_test.py b/unit_test/build_selector_test.py index 71a6fcd6c..e98cd5fdf 100644 --- a/unit_test/build_selector_test.py +++ b/unit_test/build_selector_test.py @@ -97,8 +97,8 @@ def test_build_filter_pyodide_prerelease() -> None: skip_config="", enable=frozenset([EnableGroup.PyodidePrerelease]), ) - assert build_selector("cp312-pyodide_wasm32") assert build_selector("cp313-pyodide_wasm32") + assert build_selector("cp314-pyodide_wasm32") def test_build_filter_pyodide() -> None: @@ -107,8 +107,8 @@ def test_build_filter_pyodide() -> None: skip_config="", enable=frozenset(), ) - assert build_selector("cp312-pyodide_wasm32") assert build_selector("cp313-pyodide_wasm32") + assert not build_selector("cp314-pyodide_wasm32") def test_skip() -> None: diff --git a/unit_test/main_tests/main_platform_test.py b/unit_test/main_tests/main_platform_test.py index 874aa2575..51097d0e6 100644 --- a/unit_test/main_tests/main_platform_test.py +++ b/unit_test/main_tests/main_platform_test.py @@ -308,7 +308,7 @@ def test_pyodide_on_windows( monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str] ) -> None: monkeypatch.setattr(sys, "platform", "win32") - monkeypatch.setattr(sys, "argv", [*sys.argv, "--only", "cp312-pyodide_wasm32"]) + monkeypatch.setattr(sys, "argv", [*sys.argv, "--only", "cp314-pyodide_wasm32"]) with pytest.raises(SystemExit) as exit: main() diff --git a/unit_test/options_test.py b/unit_test/options_test.py index 0c42b1f9a..3160213c7 100644 --- a/unit_test/options_test.py +++ b/unit_test/options_test.py @@ -36,7 +36,7 @@ environment-pass = ["EXAMPLE_ENV"] -pyodide-version = "0.28.0" +pyodide-version = "0.29.3" [tool.cibuildwheel.macos] test-requires = "else" @@ -93,7 +93,7 @@ def test_options_1(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: assert local.manylinux_images["x86_64"] == pinned_x86_64_container_image["manylinux_2_34"] local = options.build_options("cp312-pyodide_wasm32") - assert local.pyodide_version == "0.28.0" + assert local.pyodide_version == "0.29.3" def test_passthrough(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: