Skip to content

Add pyodide 0.28 #2431

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion bin/generate_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@
description: How to inherit the parent's value.
enable:
enum:
- cpython-experimental-riscv64
- cpython-freethreading
- cpython-prerelease
- graalpy
- pyodide-prerelease
- pypy
- pypy-eol
- cpython-experimental-riscv64
description: A Python version or flavor to enable.
additionalProperties: false
description: cibuildwheel's settings.
Expand Down
1 change: 1 addition & 0 deletions cibuildwheel/resources/build-platforms.toml
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ python_configurations = [
[pyodide]
python_configurations = [
{ identifier = "cp312-pyodide_wasm32", version = "3.12", default_pyodide_version = "0.27.6", node_version = "v22" },
{ identifier = "cp313-pyodide_wasm32", version = "3.13", default_pyodide_version = "0.28.0a3", node_version = "v22" },
]

[ios]
Expand Down
6 changes: 4 additions & 2 deletions cibuildwheel/resources/cibuildwheel.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@
},
"enable": {
"enum": [
"cpython-experimental-riscv64",
"cpython-freethreading",
"cpython-prerelease",
"graalpy",
"pyodide-prerelease",
"pypy",
"pypy-eol",
"cpython-experimental-riscv64"
"pypy-eol"
]
},
"description": "A Python version or flavor to enable."
Expand Down
9 changes: 7 additions & 2 deletions cibuildwheel/selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@ class EnableGroup(StrEnum):
Groups of build selectors that are not enabled by default.
"""

CPythonExperimentalRiscV64 = "cpython-experimental-riscv64"
CPythonFreeThreading = "cpython-freethreading"
CPythonPrerelease = "cpython-prerelease"
GraalPy = "graalpy"
PyPy = "pypy"
PyPyEoL = "pypy-eol"
CPythonExperimentalRiscV64 = "cpython-experimental-riscv64"
GraalPy = "graalpy"
PyodidePrerelease = "pyodide-prerelease"

@classmethod
def all_groups(cls) -> frozenset["EnableGroup"]:
Expand Down Expand Up @@ -98,6 +99,10 @@ def __call__(self, build_id: str) -> bool:
return False
if EnableGroup.GraalPy not in self.enable and fnmatch(build_id, "gp*"):
return False
if EnableGroup.PyodidePrerelease not in self.enable and fnmatch(
build_id, "cp313-pyodide_*"
):
return False

should_build = selector_matches(self.build_config, build_id)
should_skip = selector_matches(self.skip_config, build_id)
Expand Down
13 changes: 8 additions & 5 deletions docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ When setting the options, you can use shell-style globbing syntax, as per [fnmat
| Python 3.10 | cp310-macosx_x86_64<br/>cp310-macosx_universal2<br/>cp310-macosx_arm64 | cp310-win_amd64<br/>cp310-win32<br/>cp310-win_arm64 | cp310-manylinux_x86_64<br/>cp310-manylinux_i686<br/>cp310-musllinux_x86_64<br/>cp310-musllinux_i686 | cp310-manylinux_aarch64<br/>cp310-manylinux_ppc64le<br/>cp310-manylinux_s390x<br/>cp310-manylinux_armv7l<br/>cp310-manylinux_riscv64<br/>cp310-musllinux_aarch64<br/>cp310-musllinux_ppc64le<br/>cp310-musllinux_s390x<br/>cp310-musllinux_armv7l<br/>cp310-musllinux_riscv64 | | |
| Python 3.11 | cp311-macosx_x86_64<br/>cp311-macosx_universal2<br/>cp311-macosx_arm64 | cp311-win_amd64<br/>cp311-win32<br/>cp311-win_arm64 | cp311-manylinux_x86_64<br/>cp311-manylinux_i686<br/>cp311-musllinux_x86_64<br/>cp311-musllinux_i686 | cp311-manylinux_aarch64<br/>cp311-manylinux_ppc64le<br/>cp311-manylinux_s390x<br/>cp311-manylinux_armv7l<br/>cp311-manylinux_riscv64<br/>cp311-musllinux_aarch64<br/>cp311-musllinux_ppc64le<br/>cp311-musllinux_s390x<br/>cp311-musllinux_armv7l<br/>cp311-musllinux_riscv64 | | |
| Python 3.12 | cp312-macosx_x86_64<br/>cp312-macosx_universal2<br/>cp312-macosx_arm64 | cp312-win_amd64<br/>cp312-win32<br/>cp312-win_arm64 | cp312-manylinux_x86_64<br/>cp312-manylinux_i686<br/>cp312-musllinux_x86_64<br/>cp312-musllinux_i686 | cp312-manylinux_aarch64<br/>cp312-manylinux_ppc64le<br/>cp312-manylinux_s390x<br/>cp312-manylinux_armv7l<br/>cp312-manylinux_riscv64<br/>cp312-musllinux_aarch64<br/>cp312-musllinux_ppc64le<br/>cp312-musllinux_s390x<br/>cp312-musllinux_armv7l<br/>cp312-musllinux_riscv64 | | cp312-pyodide_wasm32 |
| Python 3.13 | cp313-macosx_x86_64<br/>cp313-macosx_universal2<br/>cp313-macosx_arm64 | cp313-win_amd64<br/>cp313-win32<br/>cp313-win_arm64 | cp313-manylinux_x86_64<br/>cp313-manylinux_i686<br/>cp313-musllinux_x86_64<br/>cp313-musllinux_i686 | cp313-manylinux_aarch64<br/>cp313-manylinux_ppc64le<br/>cp313-manylinux_s390x<br/>cp313-manylinux_armv7l<br/>cp313-manylinux_riscv64<br/>cp313-musllinux_aarch64<br/>cp313-musllinux_ppc64le<br/>cp313-musllinux_s390x<br/>cp313-musllinux_armv7l<br/>cp313-musllinux_riscv64 | cp313-ios_arm64_iphoneos<br/>cp313-ios_arm64_iphonesimulator<br/>cp313-ios_x86_64_iphonesimulator | |
| Python 3.13 | cp313-macosx_x86_64<br/>cp313-macosx_universal2<br/>cp313-macosx_arm64 | cp313-win_amd64<br/>cp313-win32<br/>cp313-win_arm64 | cp313-manylinux_x86_64<br/>cp313-manylinux_i686<br/>cp313-musllinux_x86_64<br/>cp313-musllinux_i686 | cp313-manylinux_aarch64<br/>cp313-manylinux_ppc64le<br/>cp313-manylinux_s390x<br/>cp313-manylinux_armv7l<br/>cp313-manylinux_riscv64<br/>cp313-musllinux_aarch64<br/>cp313-musllinux_ppc64le<br/>cp313-musllinux_s390x<br/>cp313-musllinux_armv7l<br/>cp313-musllinux_riscv64 | cp313-ios_arm64_iphoneos<br/>cp313-ios_arm64_iphonesimulator<br/>cp313-ios_x86_64_iphonesimulator | cp313-pyodide_wasm32 |
| Python 3.14 | cp314-macosx_x86_64<br/>cp314-macosx_universal2<br/>cp314-macosx_arm64 | cp314-win_amd64<br/>cp314-win32<br/>cp314-win_arm64 | cp314-manylinux_x86_64<br/>cp314-manylinux_i686<br/>cp314-musllinux_x86_64<br/>cp314-musllinux_i686 | cp314-manylinux_aarch64<br/>cp314-manylinux_ppc64le<br/>cp314-manylinux_s390x<br/>cp314-manylinux_armv7l<br/>cp314-manylinux_riscv64<br/>cp314-musllinux_aarch64<br/>cp314-musllinux_ppc64le<br/>cp314-musllinux_s390x<br/>cp314-musllinux_armv7l<br/>cp314-musllinux_riscv64 | | |
| PyPy3.8 v7.3 | pp38-macosx_x86_64<br/>pp38-macosx_arm64 | pp38-win_amd64 | pp38-manylinux_x86_64<br/>pp38-manylinux_i686 | pp38-manylinux_aarch64 | | |
| PyPy3.9 v7.3 | pp39-macosx_x86_64<br/>pp39-macosx_arm64 | pp39-win_amd64 | pp39-manylinux_x86_64<br/>pp39-manylinux_i686 | pp39-manylinux_aarch64 | | |
Expand Down Expand Up @@ -334,15 +334,18 @@ values are:
are disabled by default as they can't be uploaded to PyPI and a PEP will most likely
be required before this can happen.
- `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.
- `all`: Enable all of the above.

!!! caution
`cpython-prerelease` is provided for testing purposes only. It is not
recommended to distribute wheels built with beta releases, such as
uploading to PyPI. Please _do not_ upload these wheels to PyPI, as they are
not guaranteed to work with the final Python release. Once Python is ABI
stable and enters the release candidate phase, that version of Python will
become available without this flag.
uploading to PyPI. Please _do not_ upload these wheels to PyPI (except for
pre-releases), as they are not guaranteed to work with the final Python
release. Once Python is ABI stable and enters the release candidate phase,
that version of Python will become available without this flag.

!!! note
Free threading is experimental: [What’s New In Python 3.13](https://docs.python.org/3.13/whatsnew/3.13.html#free-threaded-cpython)
Expand Down
4 changes: 3 additions & 1 deletion docs/platforms.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,9 @@ You must target pyodide with `--platform pyodide` (or use `--only` on the identi

### Choosing a Pyodide version {: #pyodide-choosing-a-version}

It is also possible to target a specific Pyodide version by setting the `pyodide-version` option to the desired version. Users are responsible for setting an appropriate Pyodide version according to the `pyodide-build` version. A list is available in Pyodide's [cross-build environments metadata file](https://github.com/pyodide/pyodide/blob/main/pyodide-cross-build-environments.json), which can be viewed more easily by installing `pyodide-build` from PyPI and using `pyodide xbuildenv search --all` to see a compatibility table.
It is also possible to target a specific Pyodide version by setting the [`pyodide-version`](options.md#pyodide-version) option to the desired version. Users are responsible for setting an appropriate Pyodide version according to the `pyodide-build` version. A list is available in Pyodide's [cross-build environments metadata file](https://github.com/pyodide/pyodide/blob/main/pyodide-cross-build-environments.json), which can be viewed more easily by installing `pyodide-build` from PyPI and using `pyodide xbuildenv search --all` to see a compatibility table.

If there are pre-releases available for a newer Python version, the `pyodide-prerelease` [`enable`](options.md#enable) can be used to include pre-release versions.

### Running tests

Expand Down
5 changes: 4 additions & 1 deletion test/test_pyodide.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def test_pyodide_build(tmp_path, use_pyproject_toml):
basic_project.generate(project_dir)

# check for node in 1 case only to reduce CI load
add_env = {}
add_env = {"CIBW_ENABLE": "pyodide-prerelease"}
if use_pyproject_toml:
add_env["CIBW_TEST_COMMAND"] = f"python {{project}}/check_node.py {CIBW_CACHE_PATH}"

Expand All @@ -72,6 +72,7 @@ def test_pyodide_build(tmp_path, use_pyproject_toml):
# 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",
]

print("actual_wheels", actual_wheels)
Expand Down Expand Up @@ -130,11 +131,13 @@ def test_filter():
add_env={
"CIBW_TEST_REQUIRES": "pytest",
"CIBW_TEST_COMMAND": "python -m pytest {project}",
"CIBW_ENABLE": "pyodide-prerelease",
},
)
# 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",
]
print("actual_wheels", actual_wheels)
print("expected_wheels", expected_wheels)
Expand Down
2 changes: 2 additions & 0 deletions test/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ def _expected_wheels(

if platform == "pyodide" and python_abi_tags is None:
python_abi_tags = ["cp312-cp312"]
if EnableGroup.PyodidePrerelease in enable_groups:
python_abi_tags.append("cp313-cp313")
elif platform == "ios" and python_abi_tags is None:
python_abi_tags = ["cp313-cp313"]
elif python_abi_tags is None:
Expand Down
20 changes: 20 additions & 0 deletions unit_test/build_selector_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,26 @@ def test_build_filter_pypy_all():
assert build_selector("pp39-manylinux_x86_64")


def test_build_filter_pyodide_prerelease():
build_selector = BuildSelector(
build_config="*",
skip_config="",
enable=frozenset([EnableGroup.PyodidePrerelease]),
)
assert build_selector("cp312-pyodide_wasm32")
assert build_selector("cp313-pyodide_wasm32")


def test_build_filter_pyodide():
build_selector = BuildSelector(
build_config="*",
skip_config="",
enable=frozenset(),
)
assert build_selector("cp312-pyodide_wasm32")
assert not build_selector("cp313-pyodide_wasm32")


def test_skip():
build_selector = BuildSelector(
build_config="*",
Expand Down