diff --git a/README.md b/README.md index 12585957..6a955ad5 100644 --- a/README.md +++ b/README.md @@ -22,25 +22,24 @@ What does it do? While cibuildwheel itself requires a recent Python version to run (we support the last three releases), it can target the following versions to build wheels: -| | macOS Intel | macOS Apple Silicon | Windows 64bit | Windows 32bit | Windows Arm64 | manylinux
musllinux x86_64 | manylinux
musllinux i686 | manylinux
musllinux aarch64 | manylinux
musllinux ppc64le | manylinux
musllinux s390x | manylinux
musllinux armv7l | Android | iOS | Pyodide | -| ------------------------ | ----------- | ------------------- | ------------- | ------------- | -------------- | ------------------------------ | ---------------------------- | ------------------------------- | ------------------------------- | ----------------------------- | ------------------------------ | ------- | --- | -------------- | -| CPython 3.9 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | N/A | N/A | N/A | -| CPython 3.10 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | N/A | N/A | N/A | -| CPython 3.11 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | N/A | N/A | N/A | -| 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 | ✅ | ✅ | ✅ | -| 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 | -| GraalPy 3.12 v25.0 | ✅ | ✅ | ✅ | N/A | N/A | ✅1 | N/A | ✅1 | N/A | N/A | N/A | N/A | N/A | N/A | +| | macOS Intel | macOS Apple Silicon | Windows 64bit | Windows 32bit | Windows Arm64 | manylinux
musllinux x86_64 | manylinux
musllinux i686 | manylinux
musllinux aarch64 | manylinux
musllinux ppc64le | manylinux
musllinux s390x | manylinux
musllinux armv7l | Android | iOS | Pyodide | +|--------------------| ----------- | ------------------- | ------------- | ------------- | -------------- | ------------------------------ | ---------------------------- | ------------------------------- | ------------------------------- | ----------------------------- | ------------------------------ | ------- | --- | -------------- | +| CPython 3.9 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | N/A | N/A | N/A | +| CPython 3.10 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | N/A | N/A | N/A | +| CPython 3.11 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | N/A | N/A | N/A | +| CPython 3.12 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | N/A | N/A | ✅3 | +| CPython 3.13 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | ✅ | ✅ | ✅ | +| CPython 3.14 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | ✅ | ✅ | ✅ | +| CPython 3.15 | ✅ | ✅ | ✅ | ✅ | ✅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 | +| GraalPy 3.12 v25.0 | ✅ | ✅ | ✅ | N/A | N/A | ✅1 | N/A | ✅1 | N/A | N/A | N/A | N/A | N/A | N/A | **1** PyPy & GraalPy are only supported for manylinux wheels.
**2** Windows arm64 support is experimental.
**3** Not supported on PyPI, uses old `pyodide` tag instead of `pyemscripten`. Requires `pyodide-eol` [`enable`](https://cibuildwheel.pypa.io/en/stable/options/#enable).
**4** manylinux armv7l support is experimental. As there are no RHEL based image for this architecture, it's using an Ubuntu based image instead.
-**5** Python 3.15 requires opt-in using [`enable`](https://cibuildwheel.pypa.io/en/stable/options/#enable).
- Builds manylinux, musllinux, macOS, Windows, pyemscripten, iOS, and Android wheels - Supports CPython, PyPy, and GraalPy diff --git a/cibuildwheel/selector.py b/cibuildwheel/selector.py index 2a8892dd..d710de9d 100644 --- a/cibuildwheel/selector.py +++ b/cibuildwheel/selector.py @@ -92,7 +92,7 @@ class BuildSelector: return False # filter out groups that are not enabled - if EnableGroup.CPythonPrerelease not in self.enable and fnmatch(build_id, "cp315*"): + if EnableGroup.CPythonPrerelease not in self.enable and fnmatch(build_id, "cp316*"): return False is_pypy_eol = fnmatch(build_id, "pp3?-*") or fnmatch(build_id, "pp310-*") is_pypy = fnmatch(build_id, "pp*") and not is_pypy_eol diff --git a/test/utils.py b/test/utils.py index e0131bb9..eeaa212b 100644 --- a/test/utils.py +++ b/test/utils.py @@ -278,20 +278,18 @@ def _expected_wheels( # 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 = ["cp313-cp313", "cp314-cp314"] + python_abi_tags = ["cp313-cp313", "cp314-cp314", "cp315-cp315"] 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 - ): + elif platform in {"android", "ios"} and python_abi_tags is None: python_abi_tags = [ "cp313-cp313", "cp314-cp314", + "cp315-cp315", ] if EnableGroup.CPythonPrerelease in enable_groups: - python_abi_tags += ["cp315-cp315"] + # python_abi_tags += ["cp316-cp316"] + ... # Add cp316 here when available elif python_abi_tags is None: python_abi_tags = [ "cp39-cp39", @@ -301,13 +299,16 @@ def _expected_wheels( "cp313-cp313", "cp314-cp314", "cp314-cp314t", + "cp315-cp315", + "cp315-cp315t", ] if EnableGroup.CPythonPrerelease in enable_groups: - python_abi_tags += [ - "cp315-cp315", - "cp315-cp315t", - ] + # python_abi_tags += [ + # "cp316-cp316", + # "cp316-cp316t", + # ] + ... # Add cp316 here when available if EnableGroup.PyPyEoL in enable_groups: python_abi_tags += [ diff --git a/unit_test/build_selector_test.py b/unit_test/build_selector_test.py index 134125c1..c5431db0 100644 --- a/unit_test/build_selector_test.py +++ b/unit_test/build_selector_test.py @@ -16,6 +16,7 @@ def test_build() -> None: assert build_selector("cp312-manylinux_x86_64") assert build_selector("cp313-manylinux_x86_64") assert build_selector("cp314-manylinux_x86_64") + assert build_selector("cp315-manylinux_x86_64") assert build_selector("pp311-manylinux_x86_64") assert build_selector("cp36-manylinux_i686") assert build_selector("cp37-manylinux_i686") @@ -37,6 +38,7 @@ def test_build() -> None: assert build_selector("cp312-win_amd64") assert build_selector("cp313-win_amd64") assert build_selector("cp314-win_amd64") + assert build_selector("cp315-win_amd64") assert not build_selector("pp310-win_amd64") assert not build_selector("pp311-win_amd64") @@ -100,7 +102,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") + assert build_selector("cp315-pyodide_wasm32") def test_build_filter_pyodide_eol() -> None: @@ -112,7 +114,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") + assert build_selector("cp315-pyodide_wasm32") def test_skip() -> None: diff --git a/unit_test/linux_build_steps_test.py b/unit_test/linux_build_steps_test.py index b93530be..dd6200ab 100644 --- a/unit_test/linux_build_steps_test.py +++ b/unit_test/linux_build_steps_test.py @@ -97,9 +97,11 @@ def test_linux_container_split(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) "cp313-manylinux_x86_64", "cp314-manylinux_x86_64", "cp314t-manylinux_x86_64", + "cp315-manylinux_x86_64", + "cp315t-manylinux_x86_64", ] - assert before_alls(build_steps[3]) == [""] * 4 - assert container_engines(build_steps[3]) == [default_container_engine] * 4 + assert before_alls(build_steps[3]) == [""] * 6 + assert container_engines(build_steps[3]) == [default_container_engine] * 6 def test_package_dir_outside_working_directory_raises_configuration_error( diff --git a/unit_test/option_prepare_test.py b/unit_test/option_prepare_test.py index 5bad4d28..b277c8c4 100644 --- a/unit_test/option_prepare_test.py +++ b/unit_test/option_prepare_test.py @@ -13,7 +13,7 @@ from cibuildwheel.__main__ import main from cibuildwheel.oci_container import OCIPlatform from cibuildwheel.util import file -DEFAULT_IDS = {"cp39", "cp310", "cp311", "cp312", "cp313", "cp314", "cp314t"} +DEFAULT_IDS = {"cp39", "cp310", "cp311", "cp312", "cp313", "cp314", "cp314t", "cp315", "cp315t"} ALL_IDS = DEFAULT_IDS | {"pp39", "pp310", "pp311", "gp312_250"} @@ -155,6 +155,8 @@ before-all = "true" "cp313", "cp314", "cp314t", + "cp315", + "cp315t", "pp39", "pp310", "pp311", @@ -176,6 +178,8 @@ before-all = "true" "cp313", "cp314", "cp314t", + "cp315", + "cp315t", "pp39", "pp310", "pp311",