From f98e7e2d2fc725fc55586d1a9208af06d4d4e2ca Mon Sep 17 00:00:00 2001 From: mayeut Date: Sat, 28 Mar 2026 15:26:21 +0100 Subject: [PATCH] feat: add CPython 3.15 beta 1 --- README.md | 29 ++++---- cibuildwheel/platforms/macos.py | 2 + cibuildwheel/resources/build-platforms.toml | 40 +++++++++++ .../resources/constraints-python315.txt | 34 ++++++++++ .../resources/free-threaded-enable-315.xml | 14 ++++ .../resources/pinned_docker_images.cfg | 68 +++++++++---------- cibuildwheel/util/resources.py | 1 + docs/options.md | 1 + noxfile.py | 4 +- test/utils.py | 5 +- 10 files changed, 147 insertions(+), 51 deletions(-) create mode 100644 cibuildwheel/resources/constraints-python315.txt create mode 100644 cibuildwheel/resources/free-threaded-enable-315.xml diff --git a/README.md b/README.md index b841e9acd..10f865136 100644 --- a/README.md +++ b/README.md @@ -22,25 +22,26 @@ 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 | ✅ | ✅ | ✅3 | -| CPython 3.14 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | ✅ | ✅ | N/A | -| PyPy 3.8 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅1 | ✅1 | ✅1 | N/A | N/A | N/A | N/A | N/A | N/A | -| 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.11 v24.2 | ✅ | ✅ | ✅ | N/A | N/A | ✅1 | N/A | ✅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 | ✅ | ✅ | ✅3 | +| CPython 3.14 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | ✅ | ✅ | N/A | +| CPython 3.155 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | N/A | N/A | N/A | +| 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.11 v24.2 | ✅ | ✅ | ✅ | N/A | N/A | ✅1 | N/A | ✅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** Experimental, not yet supported on PyPI, but can be used directly in web deployment. Use `--platform pyodide` to build.
**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, and Windows wheels for CPython, PyPy, and GraalPy - Works on GitHub Actions, Azure Pipelines, CircleCI, and GitLab CI diff --git a/cibuildwheel/platforms/macos.py b/cibuildwheel/platforms/macos.py index 4fe894cf0..d2df5fb19 100644 --- a/cibuildwheel/platforms/macos.py +++ b/cibuildwheel/platforms/macos.py @@ -157,6 +157,8 @@ def install_cpython(_tmp: Path, version: str, url: str, free_threading: bool) -> args = [] if version.startswith("3.14"): args += ["-applyChoiceChangesXML", str(resources.FREE_THREAD_ENABLE_314.resolve())] + elif version.startswith("3.15"): + args += ["-applyChoiceChangesXML", str(resources.FREE_THREAD_ENABLE_315.resolve())] call("sudo", "installer", "-pkg", pkg_path, *args, "-target", "/") pkg_path.unlink() env = os.environ.copy() diff --git a/cibuildwheel/resources/build-platforms.toml b/cibuildwheel/resources/build-platforms.toml index 03abceff1..b7ebf6eaf 100644 --- a/cibuildwheel/resources/build-platforms.toml +++ b/cibuildwheel/resources/build-platforms.toml @@ -7,6 +7,8 @@ python_configurations = [ { identifier = "cp313-manylinux_x86_64", version = "3.13", path_str = "/opt/python/cp313-cp313" }, { identifier = "cp314-manylinux_x86_64", version = "3.14", path_str = "/opt/python/cp314-cp314" }, { identifier = "cp314t-manylinux_x86_64", version = "3.14", path_str = "/opt/python/cp314-cp314t" }, + { identifier = "cp315-manylinux_x86_64", version = "3.15", path_str = "/opt/python/cp315-cp315" }, + { identifier = "cp315t-manylinux_x86_64", version = "3.15", path_str = "/opt/python/cp315-cp315t" }, { identifier = "cp39-manylinux_i686", version = "3.9", path_str = "/opt/python/cp39-cp39" }, { identifier = "cp310-manylinux_i686", version = "3.10", path_str = "/opt/python/cp310-cp310" }, { identifier = "cp311-manylinux_i686", version = "3.11", path_str = "/opt/python/cp311-cp311" }, @@ -14,6 +16,8 @@ python_configurations = [ { identifier = "cp313-manylinux_i686", version = "3.13", path_str = "/opt/python/cp313-cp313" }, { identifier = "cp314-manylinux_i686", version = "3.14", path_str = "/opt/python/cp314-cp314" }, { identifier = "cp314t-manylinux_i686", version = "3.14", path_str = "/opt/python/cp314-cp314t" }, + { identifier = "cp315-manylinux_i686", version = "3.15", path_str = "/opt/python/cp315-cp315" }, + { identifier = "cp315t-manylinux_i686", version = "3.15", path_str = "/opt/python/cp315-cp315t" }, { identifier = "pp39-manylinux_x86_64", version = "3.9", path_str = "/opt/python/pp39-pypy39_pp73" }, { identifier = "pp310-manylinux_x86_64", version = "3.10", path_str = "/opt/python/pp310-pypy310_pp73" }, { identifier = "pp311-manylinux_x86_64", version = "3.11", path_str = "/opt/python/pp311-pypy311_pp73" }, @@ -26,6 +30,8 @@ python_configurations = [ { identifier = "cp313-manylinux_aarch64", version = "3.13", path_str = "/opt/python/cp313-cp313" }, { identifier = "cp314-manylinux_aarch64", version = "3.14", path_str = "/opt/python/cp314-cp314" }, { identifier = "cp314t-manylinux_aarch64", version = "3.14", path_str = "/opt/python/cp314-cp314t" }, + { identifier = "cp315-manylinux_aarch64", version = "3.15", path_str = "/opt/python/cp315-cp315" }, + { identifier = "cp315t-manylinux_aarch64", version = "3.15", path_str = "/opt/python/cp315-cp315t" }, { identifier = "cp39-manylinux_ppc64le", version = "3.9", path_str = "/opt/python/cp39-cp39" }, { identifier = "cp310-manylinux_ppc64le", version = "3.10", path_str = "/opt/python/cp310-cp310" }, { identifier = "cp311-manylinux_ppc64le", version = "3.11", path_str = "/opt/python/cp311-cp311" }, @@ -33,6 +39,8 @@ python_configurations = [ { identifier = "cp313-manylinux_ppc64le", version = "3.13", path_str = "/opt/python/cp313-cp313" }, { identifier = "cp314-manylinux_ppc64le", version = "3.14", path_str = "/opt/python/cp314-cp314" }, { identifier = "cp314t-manylinux_ppc64le", version = "3.14", path_str = "/opt/python/cp314-cp314t" }, + { identifier = "cp315-manylinux_ppc64le", version = "3.15", path_str = "/opt/python/cp315-cp315" }, + { identifier = "cp315t-manylinux_ppc64le", version = "3.15", path_str = "/opt/python/cp315-cp315t" }, { identifier = "cp39-manylinux_s390x", version = "3.9", path_str = "/opt/python/cp39-cp39" }, { identifier = "cp310-manylinux_s390x", version = "3.10", path_str = "/opt/python/cp310-cp310" }, { identifier = "cp311-manylinux_s390x", version = "3.11", path_str = "/opt/python/cp311-cp311" }, @@ -40,6 +48,8 @@ python_configurations = [ { identifier = "cp313-manylinux_s390x", version = "3.13", path_str = "/opt/python/cp313-cp313" }, { identifier = "cp314-manylinux_s390x", version = "3.14", path_str = "/opt/python/cp314-cp314" }, { identifier = "cp314t-manylinux_s390x", version = "3.14", path_str = "/opt/python/cp314-cp314t" }, + { identifier = "cp315-manylinux_s390x", version = "3.15", path_str = "/opt/python/cp315-cp315" }, + { identifier = "cp315t-manylinux_s390x", version = "3.15", path_str = "/opt/python/cp315-cp315t" }, { identifier = "cp39-manylinux_armv7l", version = "3.9", path_str = "/opt/python/cp39-cp39" }, { identifier = "cp310-manylinux_armv7l", version = "3.10", path_str = "/opt/python/cp310-cp310" }, { identifier = "cp311-manylinux_armv7l", version = "3.11", path_str = "/opt/python/cp311-cp311" }, @@ -47,6 +57,8 @@ python_configurations = [ { identifier = "cp313-manylinux_armv7l", version = "3.13", path_str = "/opt/python/cp313-cp313" }, { identifier = "cp314-manylinux_armv7l", version = "3.14", path_str = "/opt/python/cp314-cp314" }, { identifier = "cp314t-manylinux_armv7l", version = "3.14", path_str = "/opt/python/cp314-cp314t" }, + { identifier = "cp315-manylinux_armv7l", version = "3.15", path_str = "/opt/python/cp315-cp315" }, + { identifier = "cp315t-manylinux_armv7l", version = "3.15", path_str = "/opt/python/cp315-cp315t" }, { identifier = "cp39-manylinux_riscv64", version = "3.9", path_str = "/opt/python/cp39-cp39" }, { identifier = "cp310-manylinux_riscv64", version = "3.10", path_str = "/opt/python/cp310-cp310" }, { identifier = "cp311-manylinux_riscv64", version = "3.11", path_str = "/opt/python/cp311-cp311" }, @@ -54,6 +66,8 @@ python_configurations = [ { identifier = "cp313-manylinux_riscv64", version = "3.13", path_str = "/opt/python/cp313-cp313" }, { identifier = "cp314-manylinux_riscv64", version = "3.14", path_str = "/opt/python/cp314-cp314" }, { identifier = "cp314t-manylinux_riscv64", version = "3.14", path_str = "/opt/python/cp314-cp314t" }, + { identifier = "cp315-manylinux_riscv64", version = "3.15", path_str = "/opt/python/cp315-cp315" }, + { identifier = "cp315t-manylinux_riscv64", version = "3.15", path_str = "/opt/python/cp315-cp315t" }, { identifier = "pp39-manylinux_aarch64", version = "3.9", path_str = "/opt/python/pp39-pypy39_pp73" }, { identifier = "pp310-manylinux_aarch64", version = "3.10", path_str = "/opt/python/pp310-pypy310_pp73" }, { identifier = "pp311-manylinux_aarch64", version = "3.11", path_str = "/opt/python/pp311-pypy311_pp73" }, @@ -69,6 +83,8 @@ python_configurations = [ { identifier = "cp313-musllinux_x86_64", version = "3.13", path_str = "/opt/python/cp313-cp313" }, { identifier = "cp314-musllinux_x86_64", version = "3.14", path_str = "/opt/python/cp314-cp314" }, { identifier = "cp314t-musllinux_x86_64", version = "3.14", path_str = "/opt/python/cp314-cp314t" }, + { identifier = "cp315-musllinux_x86_64", version = "3.15", path_str = "/opt/python/cp315-cp315" }, + { identifier = "cp315t-musllinux_x86_64", version = "3.15", path_str = "/opt/python/cp315-cp315t" }, { identifier = "cp39-musllinux_i686", version = "3.9", path_str = "/opt/python/cp39-cp39" }, { identifier = "cp310-musllinux_i686", version = "3.10", path_str = "/opt/python/cp310-cp310" }, { identifier = "cp311-musllinux_i686", version = "3.11", path_str = "/opt/python/cp311-cp311" }, @@ -76,6 +92,8 @@ python_configurations = [ { identifier = "cp313-musllinux_i686", version = "3.13", path_str = "/opt/python/cp313-cp313" }, { identifier = "cp314-musllinux_i686", version = "3.14", path_str = "/opt/python/cp314-cp314" }, { identifier = "cp314t-musllinux_i686", version = "3.14", path_str = "/opt/python/cp314-cp314t" }, + { identifier = "cp315-musllinux_i686", version = "3.15", path_str = "/opt/python/cp315-cp315" }, + { identifier = "cp315t-musllinux_i686", version = "3.15", path_str = "/opt/python/cp315-cp315t" }, { identifier = "cp39-musllinux_aarch64", version = "3.9", path_str = "/opt/python/cp39-cp39" }, { identifier = "cp310-musllinux_aarch64", version = "3.10", path_str = "/opt/python/cp310-cp310" }, { identifier = "cp311-musllinux_aarch64", version = "3.11", path_str = "/opt/python/cp311-cp311" }, @@ -83,6 +101,8 @@ python_configurations = [ { identifier = "cp313-musllinux_aarch64", version = "3.13", path_str = "/opt/python/cp313-cp313" }, { identifier = "cp314-musllinux_aarch64", version = "3.14", path_str = "/opt/python/cp314-cp314" }, { identifier = "cp314t-musllinux_aarch64", version = "3.14", path_str = "/opt/python/cp314-cp314t" }, + { identifier = "cp315-musllinux_aarch64", version = "3.15", path_str = "/opt/python/cp315-cp315" }, + { identifier = "cp315t-musllinux_aarch64", version = "3.15", path_str = "/opt/python/cp315-cp315t" }, { identifier = "cp39-musllinux_ppc64le", version = "3.9", path_str = "/opt/python/cp39-cp39" }, { identifier = "cp310-musllinux_ppc64le", version = "3.10", path_str = "/opt/python/cp310-cp310" }, { identifier = "cp311-musllinux_ppc64le", version = "3.11", path_str = "/opt/python/cp311-cp311" }, @@ -90,6 +110,8 @@ python_configurations = [ { identifier = "cp313-musllinux_ppc64le", version = "3.13", path_str = "/opt/python/cp313-cp313" }, { identifier = "cp314-musllinux_ppc64le", version = "3.14", path_str = "/opt/python/cp314-cp314" }, { identifier = "cp314t-musllinux_ppc64le", version = "3.14", path_str = "/opt/python/cp314-cp314t" }, + { identifier = "cp315-musllinux_ppc64le", version = "3.15", path_str = "/opt/python/cp315-cp315" }, + { identifier = "cp315t-musllinux_ppc64le", version = "3.15", path_str = "/opt/python/cp315-cp315t" }, { identifier = "cp39-musllinux_s390x", version = "3.9", path_str = "/opt/python/cp39-cp39" }, { identifier = "cp310-musllinux_s390x", version = "3.10", path_str = "/opt/python/cp310-cp310" }, { identifier = "cp311-musllinux_s390x", version = "3.11", path_str = "/opt/python/cp311-cp311" }, @@ -97,6 +119,8 @@ python_configurations = [ { identifier = "cp313-musllinux_s390x", version = "3.13", path_str = "/opt/python/cp313-cp313" }, { identifier = "cp314-musllinux_s390x", version = "3.14", path_str = "/opt/python/cp314-cp314" }, { identifier = "cp314t-musllinux_s390x", version = "3.14", path_str = "/opt/python/cp314-cp314t" }, + { identifier = "cp315-musllinux_s390x", version = "3.15", path_str = "/opt/python/cp315-cp315" }, + { identifier = "cp315t-musllinux_s390x", version = "3.15", path_str = "/opt/python/cp315-cp315t" }, { identifier = "cp39-musllinux_armv7l", version = "3.9", path_str = "/opt/python/cp39-cp39" }, { identifier = "cp310-musllinux_armv7l", version = "3.10", path_str = "/opt/python/cp310-cp310" }, { identifier = "cp311-musllinux_armv7l", version = "3.11", path_str = "/opt/python/cp311-cp311" }, @@ -104,6 +128,8 @@ python_configurations = [ { identifier = "cp313-musllinux_armv7l", version = "3.13", path_str = "/opt/python/cp313-cp313" }, { identifier = "cp314-musllinux_armv7l", version = "3.14", path_str = "/opt/python/cp314-cp314" }, { identifier = "cp314t-musllinux_armv7l", version = "3.14", path_str = "/opt/python/cp314-cp314t" }, + { identifier = "cp315-musllinux_armv7l", version = "3.15", path_str = "/opt/python/cp315-cp315" }, + { identifier = "cp315t-musllinux_armv7l", version = "3.15", path_str = "/opt/python/cp315-cp315t" }, { identifier = "cp39-musllinux_riscv64", version = "3.9", path_str = "/opt/python/cp39-cp39" }, { identifier = "cp310-musllinux_riscv64", version = "3.10", path_str = "/opt/python/cp310-cp310" }, { identifier = "cp311-musllinux_riscv64", version = "3.11", path_str = "/opt/python/cp311-cp311" }, @@ -111,6 +137,8 @@ python_configurations = [ { identifier = "cp313-musllinux_riscv64", version = "3.13", path_str = "/opt/python/cp313-cp313" }, { identifier = "cp314-musllinux_riscv64", version = "3.14", path_str = "/opt/python/cp314-cp314" }, { identifier = "cp314t-musllinux_riscv64", version = "3.14", path_str = "/opt/python/cp314-cp314t" }, + { identifier = "cp315-musllinux_riscv64", version = "3.15", path_str = "/opt/python/cp315-cp315" }, + { identifier = "cp315t-musllinux_riscv64", version = "3.15", path_str = "/opt/python/cp315-cp315t" }, ] [macos] @@ -136,6 +164,12 @@ python_configurations = [ { identifier = "cp314t-macosx_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.4/python-3.14.4-macos11.pkg" }, { identifier = "cp314t-macosx_arm64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.4/python-3.14.4-macos11.pkg" }, { identifier = "cp314t-macosx_universal2", version = "3.14", url = "https://www.python.org/ftp/python/3.14.4/python-3.14.4-macos11.pkg" }, + { identifier = "cp315-macosx_x86_64", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b1-macos11.pkg" }, + { identifier = "cp315-macosx_arm64", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b1-macos11.pkg" }, + { identifier = "cp315-macosx_universal2", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b1-macos11.pkg" }, + { identifier = "cp315t-macosx_x86_64", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b1-macos11.pkg" }, + { identifier = "cp315t-macosx_arm64", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b1-macos11.pkg" }, + { identifier = "cp315t-macosx_universal2", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b1-macos11.pkg" }, { identifier = "pp39-macosx_x86_64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_x86_64.tar.bz2" }, { identifier = "pp39-macosx_arm64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_arm64.tar.bz2" }, { identifier = "pp310-macosx_x86_64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.19-macos_x86_64.tar.bz2" }, @@ -164,6 +198,10 @@ python_configurations = [ { identifier = "cp314t-win32", version = "3.14.4" }, { identifier = "cp314-win_amd64", version = "3.14.4" }, { identifier = "cp314t-win_amd64", version = "3.14.4" }, + { identifier = "cp315-win32", version = "3.15.0-b1" }, + { identifier = "cp315t-win32", version = "3.15.0-b1" }, + { identifier = "cp315-win_amd64", version = "3.15.0-b1" }, + { identifier = "cp315t-win_amd64", version = "3.15.0-b1" }, { identifier = "cp39-win_arm64", version = "3.9.10" }, { identifier = "cp310-win_arm64", version = "3.10.11" }, { identifier = "cp311-win_arm64", version = "3.11.9" }, @@ -171,6 +209,8 @@ python_configurations = [ { identifier = "cp313-win_arm64", version = "3.13.13" }, { identifier = "cp314-win_arm64", version = "3.14.4" }, { identifier = "cp314t-win_arm64", version = "3.14.4" }, + { identifier = "cp315-win_arm64", version = "3.15.0-b1" }, + { identifier = "cp315t-win_arm64", version = "3.15.0-b1" }, { identifier = "pp39-win_amd64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-win64.zip" }, { identifier = "pp310-win_amd64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.19-win64.zip" }, { identifier = "pp311-win_amd64", version = "3.11", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.22-win64.zip" }, diff --git a/cibuildwheel/resources/constraints-python315.txt b/cibuildwheel/resources/constraints-python315.txt new file mode 100644 index 000000000..84bd6213b --- /dev/null +++ b/cibuildwheel/resources/constraints-python315.txt @@ -0,0 +1,34 @@ +# This file was autogenerated by uv via the following command: +# nox -s update_constraints +altgraph==0.17.5 + # via macholib +build==1.5.0 + # via -r cibuildwheel/resources/constraints.in +delocate==0.13.0 + # via -r cibuildwheel/resources/constraints.in +distlib==0.4.0 + # via virtualenv +filelock==3.29.0 + # via + # python-discovery + # virtualenv +macholib==1.16.4 + # via delocate +packaging==26.2 + # via + # build + # delocate +pip==26.1 + # via -r cibuildwheel/resources/constraints.in +platformdirs==4.9.6 + # via + # python-discovery + # virtualenv +pyproject-hooks==1.2.0 + # via build +python-discovery==1.2.2 + # via virtualenv +typing-extensions==4.15.0 + # via delocate +virtualenv==21.3.0 + # via -r cibuildwheel/resources/constraints.in diff --git a/cibuildwheel/resources/free-threaded-enable-315.xml b/cibuildwheel/resources/free-threaded-enable-315.xml new file mode 100644 index 000000000..9a0d5d9f1 --- /dev/null +++ b/cibuildwheel/resources/free-threaded-enable-315.xml @@ -0,0 +1,14 @@ + + + + + + attributeSetting + 1 + choiceAttribute + selected + choiceIdentifier + org.python.Python.PythonTFramework-3.15 + + + diff --git a/cibuildwheel/resources/pinned_docker_images.cfg b/cibuildwheel/resources/pinned_docker_images.cfg index 2b1b9ef25..fda748e12 100644 --- a/cibuildwheel/resources/pinned_docker_images.cfg +++ b/cibuildwheel/resources/pinned_docker_images.cfg @@ -1,54 +1,54 @@ [x86_64] -manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2026.05.02-2 -manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2026.05.02-2 -manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2026.05.02-2 -musllinux_1_2 = quay.io/pypa/musllinux_1_2_x86_64:2026.05.02-2 +manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2026.05.07-2 +manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2026.05.07-2 +manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2026.05.07-2 +musllinux_1_2 = quay.io/pypa/musllinux_1_2_x86_64:2026.05.07-2 [i686] -manylinux2014 = quay.io/pypa/manylinux2014_i686:2026.05.02-2 -manylinux_2_28 = quay.io/pypa/manylinux_2_28_i686:2026.05.02-2 -manylinux_2_34 = quay.io/pypa/manylinux_2_34_i686:2026.05.02-2 -musllinux_1_2 = quay.io/pypa/musllinux_1_2_i686:2026.05.02-2 +manylinux2014 = quay.io/pypa/manylinux2014_i686:2026.05.07-2 +manylinux_2_28 = quay.io/pypa/manylinux_2_28_i686:2026.05.07-2 +manylinux_2_34 = quay.io/pypa/manylinux_2_34_i686:2026.05.07-2 +musllinux_1_2 = quay.io/pypa/musllinux_1_2_i686:2026.05.07-2 [aarch64] -manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2026.05.02-2 -manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2026.05.02-2 -manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64:2026.05.02-2 -musllinux_1_2 = quay.io/pypa/musllinux_1_2_aarch64:2026.05.02-2 +manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2026.05.07-2 +manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2026.05.07-2 +manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64:2026.05.07-2 +musllinux_1_2 = quay.io/pypa/musllinux_1_2_aarch64:2026.05.07-2 [ppc64le] -manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2026.05.02-2 -manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le:2026.05.02-2 -manylinux_2_34 = quay.io/pypa/manylinux_2_34_ppc64le:2026.05.02-2 -musllinux_1_2 = quay.io/pypa/musllinux_1_2_ppc64le:2026.05.02-2 +manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2026.05.07-2 +manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le:2026.05.07-2 +manylinux_2_34 = quay.io/pypa/manylinux_2_34_ppc64le:2026.05.07-2 +musllinux_1_2 = quay.io/pypa/musllinux_1_2_ppc64le:2026.05.07-2 [s390x] -manylinux2014 = quay.io/pypa/manylinux2014_s390x:2026.05.02-2 -manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x:2026.05.02-2 -manylinux_2_34 = quay.io/pypa/manylinux_2_34_s390x:2026.05.02-2 -musllinux_1_2 = quay.io/pypa/musllinux_1_2_s390x:2026.05.02-2 +manylinux2014 = quay.io/pypa/manylinux2014_s390x:2026.05.07-2 +manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x:2026.05.07-2 +manylinux_2_34 = quay.io/pypa/manylinux_2_34_s390x:2026.05.07-2 +musllinux_1_2 = quay.io/pypa/musllinux_1_2_s390x:2026.05.07-2 [pypy_x86_64] -manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2026.05.02-2 -manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2026.05.02-2 -manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2026.05.02-2 +manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2026.05.07-2 +manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2026.05.07-2 +manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2026.05.07-2 [pypy_i686] -manylinux2014 = quay.io/pypa/manylinux2014_i686:2026.05.02-2 -manylinux_2_28 = quay.io/pypa/manylinux_2_28_i686:2026.05.02-2 -manylinux_2_34 = quay.io/pypa/manylinux_2_34_i686:2026.05.02-2 +manylinux2014 = quay.io/pypa/manylinux2014_i686:2026.05.07-2 +manylinux_2_28 = quay.io/pypa/manylinux_2_28_i686:2026.05.07-2 +manylinux_2_34 = quay.io/pypa/manylinux_2_34_i686:2026.05.07-2 [pypy_aarch64] -manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2026.05.02-2 -manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2026.05.02-2 -manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64:2026.05.02-2 +manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2026.05.07-2 +manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2026.05.07-2 +manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64:2026.05.07-2 [armv7l] -manylinux_2_31 = quay.io/pypa/manylinux_2_31_armv7l:2026.05.02-2 -manylinux_2_35 = quay.io/pypa/manylinux_2_35_armv7l:2026.05.02-2 -musllinux_1_2 = quay.io/pypa/musllinux_1_2_armv7l:2026.05.02-2 +manylinux_2_31 = quay.io/pypa/manylinux_2_31_armv7l:2026.05.07-2 +manylinux_2_35 = quay.io/pypa/manylinux_2_35_armv7l:2026.05.07-2 +musllinux_1_2 = quay.io/pypa/musllinux_1_2_armv7l:2026.05.07-2 [riscv64] -manylinux_2_39 = quay.io/pypa/manylinux_2_39_riscv64:2026.05.02-2 -musllinux_1_2 = quay.io/pypa/musllinux_1_2_riscv64:2026.05.02-2 +manylinux_2_39 = quay.io/pypa/manylinux_2_39_riscv64:2026.05.07-2 +musllinux_1_2 = quay.io/pypa/musllinux_1_2_riscv64:2026.05.07-2 diff --git a/cibuildwheel/util/resources.py b/cibuildwheel/util/resources.py index d06fc058d..37775b188 100644 --- a/cibuildwheel/util/resources.py +++ b/cibuildwheel/util/resources.py @@ -8,6 +8,7 @@ PATH: Final[Path] = Path(__file__).parent.parent / "resources" INSTALL_CERTIFI_SCRIPT: Final[Path] = PATH / "install_certifi.py" FREE_THREAD_ENABLE_314: Final[Path] = PATH / "free-threaded-enable-314.xml" +FREE_THREAD_ENABLE_315: Final[Path] = PATH / "free-threaded-enable-315.xml" NODEJS: Final[Path] = PATH / "nodejs.toml" DEFAULTS: Final[Path] = PATH / "defaults.toml" PINNED_DOCKER_IMAGES: Final[Path] = PATH / "pinned_docker_images.cfg" diff --git a/docs/options.md b/docs/options.md index 9ffc706b5..f9f7d0f84 100644 --- a/docs/options.md +++ b/docs/options.md @@ -60,6 +60,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 | | +| 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 | | | 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 | | | | diff --git a/noxfile.py b/noxfile.py index 738ad3722..319f1b915 100755 --- a/noxfile.py +++ b/noxfile.py @@ -79,7 +79,7 @@ def update_constraints(session: nox.Session) -> None: env = os.environ.copy() env["UV_CUSTOM_COMPILE_COMMAND"] = f"nox -s {session.name}" - for minor_version in range(9, 15): + for minor_version in range(9, 16): python_version = f"3.{minor_version}" output_file = resources / f"constraints-python{python_version.replace('.', '')}.txt" session.run( @@ -94,7 +94,7 @@ def update_constraints(session: nox.Session) -> None: ) shutil.copyfile( - resources / "constraints-python314.txt", + resources / "constraints-python315.txt", resources / "constraints.txt", ) diff --git a/test/utils.py b/test/utils.py index f90ae927f..209b7f5d3 100644 --- a/test/utils.py +++ b/test/utils.py @@ -292,7 +292,10 @@ def _expected_wheels( enable_groups = get_enable_groups() if EnableGroup.CPythonPrerelease in enable_groups: - ... # Add cp315 here when available + python_abi_tags += [ + "cp315-cp315", + "cp315-cp315t", + ] if EnableGroup.PyPyEoL in enable_groups: python_abi_tags += [