From 10c727eed9fc962f75d33d472272e3ad78c3e707 Mon Sep 17 00:00:00 2001
From: "cibuildwheel-bot[bot]"
<83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
Date: Wed, 23 Jul 2025 20:59:02 -0400
Subject: [PATCH] feat: Python 3.14rc1 build by default (#2507)
---
README.md | 4 +-
cibuildwheel/resources/build-platforms.toml | 24 +++----
.../resources/pinned_docker_images.cfg | 66 +++++++++----------
cibuildwheel/selector.py | 2 +-
pyproject.toml | 1 +
test/utils.py | 5 +-
unit_test/build_selector_test.py | 2 +
unit_test/linux_build_steps_test.py | 6 +-
unit_test/option_prepare_test.py | 6 +-
9 files changed, 63 insertions(+), 53 deletions(-)
diff --git a/README.md b/README.md
index 6ac4156f..feaaf542 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ While cibuildwheel itself requires a recent Python version to run (we support th
| CPython 3.11 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A | N/A | N/A |
| CPython 3.12 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A | N/A | ✅⁴ |
| CPython 3.13³ | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | ✅ | ✅ | N/A |
-| CPython 3.14³ | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A | N/A | N/A |
+| CPython 3.14 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A | N/A | N/A |
| PyPy 3.8 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | N/A | N/A | N/A |
| PyPy 3.9 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | N/A | N/A | N/A |
| PyPy 3.10 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | N/A | N/A | N/A |
@@ -40,7 +40,7 @@ While cibuildwheel itself requires a recent Python version to run (we support th
¹ PyPy & GraalPy are only supported for manylinux wheels.
² Windows arm64 support is experimental.
-³ Free-threaded mode requires opt-in using [`enable`](https://cibuildwheel.pypa.io/en/stable/options/#enable).
+³ Free-threaded mode requires opt-in on 3.13 using [`enable`](https://cibuildwheel.pypa.io/en/stable/options/#enable).
⁴ Experimental, not yet supported on PyPI, but can be used directly in web deployment. Use `--platform pyodide` to build.
⁵ manylinux armv7l support is experimental. As there are no RHEL based image for this architecture, it's using an Ubuntu based image instead.
diff --git a/cibuildwheel/resources/build-platforms.toml b/cibuildwheel/resources/build-platforms.toml
index 6f5b7c79..fa0a2fac 100644
--- a/cibuildwheel/resources/build-platforms.toml
+++ b/cibuildwheel/resources/build-platforms.toml
@@ -165,12 +165,12 @@ python_configurations = [
{ identifier = "cp313t-macosx_x86_64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.5/python-3.13.5-macos11.pkg" },
{ identifier = "cp313t-macosx_arm64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.5/python-3.13.5-macos11.pkg" },
{ identifier = "cp313t-macosx_universal2", version = "3.13", url = "https://www.python.org/ftp/python/3.13.5/python-3.13.5-macos11.pkg" },
- { identifier = "cp314-macosx_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.0/python-3.14.0b4-macos11.pkg" },
- { identifier = "cp314-macosx_arm64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.0/python-3.14.0b4-macos11.pkg" },
- { identifier = "cp314-macosx_universal2", version = "3.14", url = "https://www.python.org/ftp/python/3.14.0/python-3.14.0b4-macos11.pkg" },
- { identifier = "cp314t-macosx_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.0/python-3.14.0b4-macos11.pkg" },
- { identifier = "cp314t-macosx_arm64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.0/python-3.14.0b4-macos11.pkg" },
- { identifier = "cp314t-macosx_universal2", version = "3.14", url = "https://www.python.org/ftp/python/3.14.0/python-3.14.0b4-macos11.pkg" },
+ { identifier = "cp314-macosx_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.0/python-3.14.0rc1-macos11.pkg" },
+ { identifier = "cp314-macosx_arm64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.0/python-3.14.0rc1-macos11.pkg" },
+ { identifier = "cp314-macosx_universal2", version = "3.14", url = "https://www.python.org/ftp/python/3.14.0/python-3.14.0rc1-macos11.pkg" },
+ { identifier = "cp314t-macosx_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.0/python-3.14.0rc1-macos11.pkg" },
+ { identifier = "cp314t-macosx_arm64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.0/python-3.14.0rc1-macos11.pkg" },
+ { identifier = "cp314t-macosx_universal2", version = "3.14", url = "https://www.python.org/ftp/python/3.14.0/python-3.14.0rc1-macos11.pkg" },
{ identifier = "pp38-macosx_x86_64", version = "3.8", url = "https://downloads.python.org/pypy/pypy3.8-v7.3.11-macos_x86_64.tar.bz2" },
{ identifier = "pp38-macosx_arm64", version = "3.8", url = "https://downloads.python.org/pypy/pypy3.8-v7.3.11-macos_arm64.tar.bz2" },
{ identifier = "pp39-macosx_x86_64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_x86_64.tar.bz2" },
@@ -199,18 +199,18 @@ python_configurations = [
{ identifier = "cp313t-win32", version = "3.13.5", arch = "32" },
{ identifier = "cp313-win_amd64", version = "3.13.5", arch = "64" },
{ identifier = "cp313t-win_amd64", version = "3.13.5", arch = "64" },
- { identifier = "cp314-win32", version = "3.14.0-b4", arch = "32" },
- { identifier = "cp314t-win32", version = "3.14.0-b4", arch = "32" },
- { identifier = "cp314-win_amd64", version = "3.14.0-b4", arch = "64" },
- { identifier = "cp314t-win_amd64", version = "3.14.0-b4", arch = "64" },
+ { identifier = "cp314-win32", version = "3.14.0-rc1", arch = "32" },
+ { identifier = "cp314t-win32", version = "3.14.0-rc1", arch = "32" },
+ { identifier = "cp314-win_amd64", version = "3.14.0-rc1", arch = "64" },
+ { identifier = "cp314t-win_amd64", version = "3.14.0-rc1", arch = "64" },
{ identifier = "cp39-win_arm64", version = "3.9.10", arch = "ARM64" },
{ identifier = "cp310-win_arm64", version = "3.10.11", arch = "ARM64" },
{ identifier = "cp311-win_arm64", version = "3.11.9", arch = "ARM64" },
{ identifier = "cp312-win_arm64", version = "3.12.10", arch = "ARM64" },
{ identifier = "cp313-win_arm64", version = "3.13.5", arch = "ARM64" },
{ identifier = "cp313t-win_arm64", version = "3.13.5", arch = "ARM64" },
- { identifier = "cp314-win_arm64", version = "3.14.0-b4", arch = "ARM64" },
- { identifier = "cp314t-win_arm64", version = "3.14.0-b4", arch = "ARM64" },
+ { identifier = "cp314-win_arm64", version = "3.14.0-rc1", arch = "ARM64" },
+ { identifier = "cp314t-win_arm64", version = "3.14.0-rc1", arch = "ARM64" },
{ identifier = "pp38-win_amd64", version = "3.8", arch = "64", url = "https://downloads.python.org/pypy/pypy3.8-v7.3.11-win64.zip" },
{ identifier = "pp39-win_amd64", version = "3.9", arch = "64", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-win64.zip" },
{ identifier = "pp310-win_amd64", version = "3.10", arch = "64", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.19-win64.zip" },
diff --git a/cibuildwheel/resources/pinned_docker_images.cfg b/cibuildwheel/resources/pinned_docker_images.cfg
index e4bab3e8..452c58d7 100644
--- a/cibuildwheel/resources/pinned_docker_images.cfg
+++ b/cibuildwheel/resources/pinned_docker_images.cfg
@@ -1,53 +1,53 @@
[x86_64]
-manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2025.07.20-2
-manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2025.07.20-2
-manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2025.07.20-2
-musllinux_1_2 = quay.io/pypa/musllinux_1_2_x86_64:2025.07.20-2
+manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2025.07.23-1
+manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2025.07.23-1
+manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2025.07.23-1
+musllinux_1_2 = quay.io/pypa/musllinux_1_2_x86_64:2025.07.23-1
[i686]
-manylinux2014 = quay.io/pypa/manylinux2014_i686:2025.07.20-2
-manylinux_2_28 = quay.io/pypa/manylinux_2_28_i686:2025.07.20-2
-manylinux_2_34 = quay.io/pypa/manylinux_2_34_i686:2025.07.20-2
-musllinux_1_2 = quay.io/pypa/musllinux_1_2_i686:2025.07.20-2
+manylinux2014 = quay.io/pypa/manylinux2014_i686:2025.07.23-1
+manylinux_2_28 = quay.io/pypa/manylinux_2_28_i686:2025.07.23-1
+manylinux_2_34 = quay.io/pypa/manylinux_2_34_i686:2025.07.23-1
+musllinux_1_2 = quay.io/pypa/musllinux_1_2_i686:2025.07.23-1
[aarch64]
-manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2025.07.20-2
-manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2025.07.20-2
-manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64:2025.07.20-2
-musllinux_1_2 = quay.io/pypa/musllinux_1_2_aarch64:2025.07.20-2
+manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2025.07.23-1
+manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2025.07.23-1
+manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64:2025.07.23-1
+musllinux_1_2 = quay.io/pypa/musllinux_1_2_aarch64:2025.07.23-1
[ppc64le]
-manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2025.07.20-2
-manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le:2025.07.20-2
-manylinux_2_34 = quay.io/pypa/manylinux_2_34_ppc64le:2025.07.20-2
-musllinux_1_2 = quay.io/pypa/musllinux_1_2_ppc64le:2025.07.20-2
+manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2025.07.23-1
+manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le:2025.07.23-1
+manylinux_2_34 = quay.io/pypa/manylinux_2_34_ppc64le:2025.07.23-1
+musllinux_1_2 = quay.io/pypa/musllinux_1_2_ppc64le:2025.07.23-1
[s390x]
-manylinux2014 = quay.io/pypa/manylinux2014_s390x:2025.07.20-2
-manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x:2025.07.20-2
-manylinux_2_34 = quay.io/pypa/manylinux_2_34_s390x:2025.07.20-2
-musllinux_1_2 = quay.io/pypa/musllinux_1_2_s390x:2025.07.20-2
+manylinux2014 = quay.io/pypa/manylinux2014_s390x:2025.07.23-1
+manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x:2025.07.23-1
+manylinux_2_34 = quay.io/pypa/manylinux_2_34_s390x:2025.07.23-1
+musllinux_1_2 = quay.io/pypa/musllinux_1_2_s390x:2025.07.23-1
[pypy_x86_64]
-manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2025.07.20-2
-manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2025.07.20-2
-manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2025.07.20-2
+manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2025.07.23-1
+manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2025.07.23-1
+manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2025.07.23-1
[pypy_i686]
-manylinux2014 = quay.io/pypa/manylinux2014_i686:2025.07.20-2
-manylinux_2_28 = quay.io/pypa/manylinux_2_28_i686:2025.07.20-2
-manylinux_2_34 = quay.io/pypa/manylinux_2_34_i686:2025.07.20-2
+manylinux2014 = quay.io/pypa/manylinux2014_i686:2025.07.23-1
+manylinux_2_28 = quay.io/pypa/manylinux_2_28_i686:2025.07.23-1
+manylinux_2_34 = quay.io/pypa/manylinux_2_34_i686:2025.07.23-1
[pypy_aarch64]
-manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2025.07.20-2
-manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2025.07.20-2
-manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64:2025.07.20-2
+manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2025.07.23-1
+manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2025.07.23-1
+manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64:2025.07.23-1
[armv7l]
-manylinux_2_31 = quay.io/pypa/manylinux_2_31_armv7l:2025.07.20-2
-musllinux_1_2 = quay.io/pypa/musllinux_1_2_armv7l:2025.07.20-2
+manylinux_2_31 = quay.io/pypa/manylinux_2_31_armv7l:2025.07.23-1
+musllinux_1_2 = quay.io/pypa/musllinux_1_2_armv7l:2025.07.23-1
[riscv64]
-manylinux_2_39 = quay.io/pypa/manylinux_2_39_riscv64:2025.07.20-2
-musllinux_1_2 = quay.io/pypa/musllinux_1_2_riscv64:2025.07.20-2
+manylinux_2_39 = quay.io/pypa/manylinux_2_39_riscv64:2025.07.23-1
+musllinux_1_2 = quay.io/pypa/musllinux_1_2_riscv64:2025.07.23-1
diff --git a/cibuildwheel/selector.py b/cibuildwheel/selector.py
index 0b986e69..fefa939d 100644
--- a/cibuildwheel/selector.py
+++ b/cibuildwheel/selector.py
@@ -87,7 +87,7 @@ class BuildSelector:
# filter out groups that are not enabled
if EnableGroup.CPythonFreeThreading not in self.enable and fnmatch(build_id, "cp313t-*"):
return False
- if EnableGroup.CPythonPrerelease not in self.enable and fnmatch(build_id, "cp314*"):
+ if EnableGroup.CPythonPrerelease not in self.enable and fnmatch(build_id, "cp315*"):
return False
if EnableGroup.PyPy not in self.enable and fnmatch(build_id, "pp31*"):
return False
diff --git a/pyproject.toml b/pyproject.toml
index abe0a92e..e1101920 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -148,6 +148,7 @@ py-version = "3.11"
jobs = "0"
fail-on = ["E", "F"]
fail-under = "9.8"
+max-positional-arguments = "7"
reports.output-format = "colorized"
messages_control.enable = [
"useless-suppression",
diff --git a/test/utils.py b/test/utils.py
index 4773ad21..ef8ad81a 100644
--- a/test/utils.py
+++ b/test/utils.py
@@ -272,6 +272,8 @@ def _expected_wheels(
"cp311-cp311",
"cp312-cp312",
"cp313-cp313",
+ "cp314-cp314",
+ "cp314-cp314t",
]
enable_groups = get_enable_groups()
@@ -279,8 +281,7 @@ def _expected_wheels(
python_abi_tags.append("cp313-cp313t")
if EnableGroup.CPythonPrerelease in enable_groups:
- python_abi_tags.append("cp314-cp314")
- python_abi_tags.append("cp314-cp314t")
+ ... # Add cp315 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 4c723244..2a05f13a 100644
--- a/unit_test/build_selector_test.py
+++ b/unit_test/build_selector_test.py
@@ -15,6 +15,7 @@ def test_build():
assert build_selector("cp311-manylinux_x86_64")
assert build_selector("cp312-manylinux_x86_64")
assert build_selector("cp313-manylinux_x86_64")
+ assert build_selector("cp314-manylinux_x86_64")
assert build_selector("pp310-manylinux_x86_64")
assert build_selector("pp311-manylinux_x86_64")
assert build_selector("cp36-manylinux_i686")
@@ -36,6 +37,7 @@ def test_build():
assert build_selector("cp311-win_amd64")
assert build_selector("cp312-win_amd64")
assert build_selector("cp313-win_amd64")
+ assert build_selector("cp314-win_amd64")
assert not build_selector("pp310-win_amd64")
assert not build_selector("pp311-win_amd64")
diff --git a/unit_test/linux_build_steps_test.py b/unit_test/linux_build_steps_test.py
index aa4363c1..0595a684 100644
--- a/unit_test/linux_build_steps_test.py
+++ b/unit_test/linux_build_steps_test.py
@@ -90,6 +90,8 @@ def test_linux_container_split(tmp_path: Path, monkeypatch: pytest.MonkeyPatch)
"cp311-manylinux_x86_64",
"cp312-manylinux_x86_64",
"cp313-manylinux_x86_64",
+ "cp314-manylinux_x86_64",
+ "cp314t-manylinux_x86_64",
]
- assert before_alls(build_steps[3]) == [""] * 3
- assert container_engines(build_steps[3]) == [default_container_engine] * 3
+ assert before_alls(build_steps[3]) == [""] * 5
+ assert container_engines(build_steps[3]) == [default_container_engine] * 5
diff --git a/unit_test/option_prepare_test.py b/unit_test/option_prepare_test.py
index 39d6058a..9412d085 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 = {"cp38", "cp39", "cp310", "cp311", "cp312", "cp313"}
+DEFAULT_IDS = {"cp38", "cp39", "cp310", "cp311", "cp312", "cp313", "cp314", "cp314t"}
ALL_IDS = DEFAULT_IDS | {"cp313t", "pp38", "pp39", "pp310", "pp311", "gp311_242"}
@@ -155,6 +155,8 @@ before-all = "true"
"cp312",
"cp313",
"cp313t",
+ "cp314",
+ "cp314t",
"pp38",
"pp39",
"pp310",
@@ -177,6 +179,8 @@ before-all = "true"
"cp312",
"cp313",
"cp313t",
+ "cp314",
+ "cp314t",
"pp38",
"pp39",
"pp310",