From 8bdb703302031321146b1fd54c52c4e5828fc4bf Mon Sep 17 00:00:00 2001 From: Matthieu Darbois Date: Mon, 11 May 2026 03:19:36 +0200 Subject: [PATCH] break: drop Python 3.8 (#2686) --- README.md | 25 +++--- cibuildwheel/__main__.py | 7 +- cibuildwheel/frontend.py | 11 +-- cibuildwheel/platforms/android.py | 2 - cibuildwheel/platforms/ios.py | 1 - cibuildwheel/platforms/linux.py | 1 - cibuildwheel/platforms/macos.py | 47 +--------- cibuildwheel/platforms/pyodide.py | 1 - cibuildwheel/platforms/windows.py | 11 +-- cibuildwheel/resources/build-platforms.toml | 25 ------ .../resources/constraints-python38.txt | 42 --------- docs/configuration.md | 8 +- docs/contributing.md | 26 ------ docs/faq.md | 28 ------ docs/options.md | 88 +++++++++---------- docs/platforms.md | 5 +- examples/circleci-minimal.yml | 2 +- noxfile.py | 2 +- test/conftest.py | 6 -- test/test_abi_variants.py | 2 +- test/test_container_images.py | 2 +- test/test_dependency_versions.py | 9 +- test/test_macos_archs.py | 69 --------------- test/test_testing.py | 8 -- test/utils.py | 13 +-- unit_test/conftest.py | 6 -- unit_test/linux_build_steps_test.py | 21 +++-- unit_test/main_tests/main_options_test.py | 27 +++--- unit_test/option_prepare_test.py | 24 +++-- unit_test/options_test.py | 16 +--- 30 files changed, 115 insertions(+), 420 deletions(-) delete mode 100644 cibuildwheel/resources/constraints-python38.txt diff --git a/README.md b/README.md index e6f6b4aa..b841e9ac 100644 --- a/README.md +++ b/README.md @@ -24,19 +24,18 @@ While cibuildwheel itself requires a recent Python version to run (we support th | | 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.8 | ✅ | ✅ | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | N/A | N/A | N/A | -| 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 | +| 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 | **1** PyPy & GraalPy are only supported for manylinux wheels.
**2** Windows arm64 support is experimental.
diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index 0584e77a..02fb4663 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -533,10 +533,13 @@ def check_for_invalid_selectors( msg += "This selector matches a group that wasn't enabled. Enable it using the `enable` option or remove this selector. " if "p2" in selector_ or "p35" in selector_: - msg += f"cibuildwheel 3.x no longer supports Python < 3.8. Please use the 1.x series or update `{selector_name}`. " + msg += f"cibuildwheel 4.x no longer supports Python < 3.9. Please use the 1.x series or update `{selector_name}`. " error_type = errors.DeprecationError if "p36" in selector_ or "p37" in selector_: - msg += f"cibuildwheel 3.x no longer supports Python < 3.8. Please use the 2.x series or update `{selector_name}`. " + msg += f"cibuildwheel 4.x no longer supports Python < 3.9. Please use the 2.x series or update `{selector_name}`. " + error_type = errors.DeprecationError + if "p38" in selector_: + msg += f"cibuildwheel 4.x no longer supports Python < 3.9. Please use the 3.x series or update `{selector_name}`. " error_type = errors.DeprecationError if "cp313t" in selector_: msg += f"cibuildwheel 4.x no longer supports Python 3.13 free-threading. Please use the 3.x series or update `{selector_name}`. " diff --git a/cibuildwheel/frontend.py b/cibuildwheel/frontend.py index e6808c0f..11c3e93d 100644 --- a/cibuildwheel/frontend.py +++ b/cibuildwheel/frontend.py @@ -4,7 +4,6 @@ import typing from collections.abc import Sequence from typing import Literal, Self, get_args -from cibuildwheel.logger import log from cibuildwheel.typing import PathOrStr from cibuildwheel.util.helpers import parse_key_value_string, prepare_command @@ -37,12 +36,8 @@ class BuildFrontendConfig: return {"name": self.name, "args": repr(self.args)} -def _get_verbosity_flags(level: int, frontend: BuildFrontendName, *, py38: bool) -> list[str]: +def _get_verbosity_flags(level: int, frontend: BuildFrontendName) -> list[str]: if level < 0: - if frontend.startswith("build") and py38: - msg = f"build_verbosity {level} is not supported for {frontend} frontend. Ignoring." - log.warning(msg) - return [] return ["-" + -level * "q"] if level > 0: @@ -80,10 +75,10 @@ def parse_config_settings(config_settings_str: str) -> dict[str, str | list[str] def get_build_frontend_extra_flags( - build_frontend: BuildFrontendConfig, verbosity_level: int, config_settings: str, *, py38: bool + build_frontend: BuildFrontendConfig, verbosity_level: int, config_settings: str ) -> list[str]: return [ *_split_config_settings(config_settings), *build_frontend.args, - *_get_verbosity_flags(verbosity_level, build_frontend.name, py38=py38), + *_get_verbosity_flags(verbosity_level, build_frontend.name), ] diff --git a/cibuildwheel/platforms/android.py b/cibuildwheel/platforms/android.py index b7be5a6f..94a5de1c 100644 --- a/cibuildwheel/platforms/android.py +++ b/cibuildwheel/platforms/android.py @@ -475,7 +475,6 @@ def build_wheel(state: BuildState) -> Path: project=".", package=state.options.package_dir, ), - py38=False, ), env=state.android_env, ) @@ -497,7 +496,6 @@ def build_wheel(state: BuildState) -> Path: project=".", package=state.options.package_dir, ), - py38=False, ), env=state.android_env, ) diff --git a/cibuildwheel/platforms/ios.py b/cibuildwheel/platforms/ios.py index 8b4e3d98..217b4ddf 100644 --- a/cibuildwheel/platforms/ios.py +++ b/cibuildwheel/platforms/ios.py @@ -486,7 +486,6 @@ def build(options: Options, tmp_path: Path) -> None: project=".", package=build_options.package_dir, ), - py38=False, ) match build_frontend.name: diff --git a/cibuildwheel/platforms/linux.py b/cibuildwheel/platforms/linux.py index a5bbabab..437e4dc7 100644 --- a/cibuildwheel/platforms/linux.py +++ b/cibuildwheel/platforms/linux.py @@ -291,7 +291,6 @@ def build_in_container( project=container_project_path, package=container_package_dir, ), - py38=config.identifier[1:].startswith("p38"), ) match build_frontend.name: diff --git a/cibuildwheel/platforms/macos.py b/cibuildwheel/platforms/macos.py index 4688263d..4fe894cf 100644 --- a/cibuildwheel/platforms/macos.py +++ b/cibuildwheel/platforms/macos.py @@ -483,7 +483,6 @@ def build(options: Options, tmp_path: Path) -> None: project=".", package=build_options.package_dir, ), - py38=config.identifier[1:].startswith("p38"), ) build_env = env.copy() @@ -576,13 +575,6 @@ def build(options: Options, tmp_path: Path) -> None: if build_options.test_command and build_options.test_selector(config.identifier): machine_arch = platform.machine() - python_arch = call( - "python", - "-sSc", - "import platform; print(platform.machine())", - env=env, - capture_stdout=True, - ).strip() testing_archs: list[Literal["x86_64", "arm64"]] if config_is_arm64: @@ -630,24 +622,6 @@ def build(options: Options, tmp_path: Path) -> None: # skip this test continue - is_cp38 = config.identifier.startswith("cp38-") - if testing_arch == "arm64" and is_cp38 and python_arch != "arm64": - log.warning( - unwrap( - """ - While cibuildwheel can build CPython 3.8 universal2/arm64 wheels, we - cannot test the arm64 part of them, even when running on an Apple - Silicon machine. This is because we use the x86_64 installer of - CPython 3.8. See the discussion in - https://github.com/pypa/cibuildwheel/pull/1169 for the details. To - silence this warning, set `CIBW_TEST_SKIP: "cp38-macosx_*:arm64"`. - """ - ) - ) - - # skip this test - continue - log.step( "Testing wheel..." if testing_arch == machine_arch @@ -704,33 +678,16 @@ def build(options: Options, tmp_path: Path) -> None: shell_with_arch(before_test_prepared, env=virtualenv_env) # install the wheel - if is_cp38 and python_arch == "x86_64": - virtualenv_env_install_wheel = virtualenv_env.copy() - virtualenv_env_install_wheel["SYSTEM_VERSION_COMPAT"] = "0" - log.notice( - unwrap( - """ - Setting SYSTEM_VERSION_COMPAT=0 to ensure CPython 3.8 can get - correct macOS version and allow installation of wheels with - MACOSX_DEPLOYMENT_TARGET >= 11.0. - See https://github.com/pypa/cibuildwheel/issues/1767 for the - details. - """ - ) - ) - else: - virtualenv_env_install_wheel = virtualenv_env - pip_install( f"{repaired_wheel}{build_options.test_extras}", - env=virtualenv_env_install_wheel, + env=virtualenv_env, ) # test the wheel if build_options.test_requires: pip_install( *build_options.test_requires, - env=virtualenv_env_install_wheel, + env=virtualenv_env, ) # run the tests from a temp dir, with an absolute path in the command diff --git a/cibuildwheel/platforms/pyodide.py b/cibuildwheel/platforms/pyodide.py index 60f4a656..2c2e9082 100644 --- a/cibuildwheel/platforms/pyodide.py +++ b/cibuildwheel/platforms/pyodide.py @@ -428,7 +428,6 @@ def build(options: Options, tmp_path: Path) -> None: project=".", package=build_options.package_dir, ), - py38=False, ) call( diff --git a/cibuildwheel/platforms/windows.py b/cibuildwheel/platforms/windows.py index 0eced5c9..3f2c74fc 100644 --- a/cibuildwheel/platforms/windows.py +++ b/cibuildwheel/platforms/windows.py @@ -242,11 +242,6 @@ def setup_rust_cross_compile( ) -def can_use_uv(python_configuration: PythonConfiguration) -> bool: - conditions = (not python_configuration.identifier.startswith("pp38-"),) - return all(conditions) - - def setup_python( tmp: Path, python_configuration: PythonConfiguration, @@ -278,9 +273,6 @@ def setup_python( raise ValueError(msg) assert base_python.exists() - if build_frontend == "build[uv]" and not can_use_uv(python_configuration): - build_frontend = "build" - use_uv = build_frontend in {"build[uv]", "uv"} uv_path = find_uv() @@ -419,7 +411,7 @@ def build(options: Options, tmp_path: Path) -> None: for config in python_configurations: build_options = options.build_options(config.identifier) build_frontend = build_options.build_frontend - use_uv = build_frontend.name in {"build[uv]", "uv"} and can_use_uv(config) + use_uv = build_frontend.name in {"build[uv]", "uv"} log.build_start(config.identifier) identifier_tmp_dir = tmp_path / config.identifier @@ -471,7 +463,6 @@ def build(options: Options, tmp_path: Path) -> None: project=".", package=options.globals.package_dir, ), - py38=config.identifier[1:].startswith("p38"), ) if ( diff --git a/cibuildwheel/resources/build-platforms.toml b/cibuildwheel/resources/build-platforms.toml index 60e440d1..03abceff 100644 --- a/cibuildwheel/resources/build-platforms.toml +++ b/cibuildwheel/resources/build-platforms.toml @@ -1,6 +1,5 @@ [linux] python_configurations = [ - { identifier = "cp38-manylinux_x86_64", version = "3.8", path_str = "/opt/python/cp38-cp38" }, { identifier = "cp39-manylinux_x86_64", version = "3.9", path_str = "/opt/python/cp39-cp39" }, { identifier = "cp310-manylinux_x86_64", version = "3.10", path_str = "/opt/python/cp310-cp310" }, { identifier = "cp311-manylinux_x86_64", version = "3.11", path_str = "/opt/python/cp311-cp311" }, @@ -8,7 +7,6 @@ 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 = "cp38-manylinux_i686", version = "3.8", path_str = "/opt/python/cp38-cp38" }, { 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" }, @@ -16,13 +14,11 @@ 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 = "pp38-manylinux_x86_64", version = "3.8", path_str = "/opt/python/pp38-pypy38_pp73" }, { 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" }, { identifier = "gp311_242-manylinux_x86_64", version = "3.11", path_str = "/opt/python/graalpy311-graalpy242_311_native" }, { identifier = "gp312_250-manylinux_x86_64", version = "3.12", path_str = "/opt/python/graalpy312-graalpy250_312_native" }, - { identifier = "cp38-manylinux_aarch64", version = "3.8", path_str = "/opt/python/cp38-cp38" }, { identifier = "cp39-manylinux_aarch64", version = "3.9", path_str = "/opt/python/cp39-cp39" }, { identifier = "cp310-manylinux_aarch64", version = "3.10", path_str = "/opt/python/cp310-cp310" }, { identifier = "cp311-manylinux_aarch64", version = "3.11", path_str = "/opt/python/cp311-cp311" }, @@ -30,7 +26,6 @@ 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 = "cp38-manylinux_ppc64le", version = "3.8", path_str = "/opt/python/cp38-cp38" }, { 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" }, @@ -38,7 +33,6 @@ 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 = "cp38-manylinux_s390x", version = "3.8", path_str = "/opt/python/cp38-cp38" }, { 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" }, @@ -46,7 +40,6 @@ 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 = "cp38-manylinux_armv7l", version = "3.8", path_str = "/opt/python/cp38-cp38" }, { 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" }, @@ -54,7 +47,6 @@ 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 = "cp38-manylinux_riscv64", version = "3.8", path_str = "/opt/python/cp38-cp38" }, { 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" }, @@ -62,17 +54,14 @@ 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 = "pp38-manylinux_aarch64", version = "3.8", path_str = "/opt/python/pp38-pypy38_pp73" }, { 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" }, { identifier = "gp311_242-manylinux_aarch64", version = "3.11", path_str = "/opt/python/graalpy311-graalpy242_311_native" }, { identifier = "gp312_250-manylinux_aarch64", version = "3.12", path_str = "/opt/python/graalpy312-graalpy250_312_native" }, - { identifier = "pp38-manylinux_i686", version = "3.8", path_str = "/opt/python/pp38-pypy38_pp73" }, { identifier = "pp39-manylinux_i686", version = "3.9", path_str = "/opt/python/pp39-pypy39_pp73" }, { identifier = "pp310-manylinux_i686", version = "3.10", path_str = "/opt/python/pp310-pypy310_pp73" }, { identifier = "pp311-manylinux_i686", version = "3.11", path_str = "/opt/python/pp311-pypy311_pp73" }, - { identifier = "cp38-musllinux_x86_64", version = "3.8", path_str = "/opt/python/cp38-cp38" }, { identifier = "cp39-musllinux_x86_64", version = "3.9", path_str = "/opt/python/cp39-cp39" }, { identifier = "cp310-musllinux_x86_64", version = "3.10", path_str = "/opt/python/cp310-cp310" }, { identifier = "cp311-musllinux_x86_64", version = "3.11", path_str = "/opt/python/cp311-cp311" }, @@ -80,7 +69,6 @@ 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 = "cp38-musllinux_i686", version = "3.8", path_str = "/opt/python/cp38-cp38" }, { 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" }, @@ -88,7 +76,6 @@ 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 = "cp38-musllinux_aarch64", version = "3.8", path_str = "/opt/python/cp38-cp38" }, { 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" }, @@ -96,7 +83,6 @@ 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 = "cp38-musllinux_ppc64le", version = "3.8", path_str = "/opt/python/cp38-cp38" }, { 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" }, @@ -104,7 +90,6 @@ 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 = "cp38-musllinux_s390x", version = "3.8", path_str = "/opt/python/cp38-cp38" }, { 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" }, @@ -112,7 +97,6 @@ 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 = "cp38-musllinux_armv7l", version = "3.8", path_str = "/opt/python/cp38-cp38" }, { 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" }, @@ -120,7 +104,6 @@ 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 = "cp38-musllinux_riscv64", version = "3.8", path_str = "/opt/python/cp38-cp38" }, { 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" }, @@ -132,9 +115,6 @@ python_configurations = [ [macos] python_configurations = [ - { identifier = "cp38-macosx_x86_64", version = "3.8", url = "https://www.python.org/ftp/python/3.8.10/python-3.8.10-macosx10.9.pkg" }, - { identifier = "cp38-macosx_arm64", version = "3.8", url = "https://www.python.org/ftp/python/3.8.10/python-3.8.10-macosx10.9.pkg" }, - { identifier = "cp38-macosx_universal2", version = "3.8", url = "https://www.python.org/ftp/python/3.8.10/python-3.8.10-macosx10.9.pkg" }, { identifier = "cp39-macosx_x86_64", version = "3.9", url = "https://www.python.org/ftp/python/3.9.13/python-3.9.13-macos11.pkg" }, { identifier = "cp39-macosx_arm64", version = "3.9", url = "https://www.python.org/ftp/python/3.9.13/python-3.9.13-macos11.pkg" }, { identifier = "cp39-macosx_universal2", version = "3.9", url = "https://www.python.org/ftp/python/3.9.13/python-3.9.13-macos11.pkg" }, @@ -156,8 +136,6 @@ 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 = "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" }, { 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" }, @@ -172,8 +150,6 @@ python_configurations = [ [windows] python_configurations = [ - { identifier = "cp38-win32", version = "3.8.10" }, - { identifier = "cp38-win_amd64", version = "3.8.10" }, { identifier = "cp39-win32", version = "3.9.13" }, { identifier = "cp39-win_amd64", version = "3.9.13" }, { identifier = "cp310-win32", version = "3.10.11" }, @@ -195,7 +171,6 @@ 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 = "pp38-win_amd64", version = "3.8", url = "https://downloads.python.org/pypy/pypy3.8-v7.3.11-win64.zip" }, { 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-python38.txt b/cibuildwheel/resources/constraints-python38.txt deleted file mode 100644 index e53d1481..00000000 --- a/cibuildwheel/resources/constraints-python38.txt +++ /dev/null @@ -1,42 +0,0 @@ -# This file was autogenerated by uv via the following command: -# nox -s update_constraints -altgraph==0.17.5 - # via macholib -build==1.2.2.post1 - # via -r cibuildwheel/resources/constraints.in -delocate==0.12.0 - # via -r cibuildwheel/resources/constraints.in -distlib==0.4.0 - # via virtualenv -filelock==3.16.1 - # via - # python-discovery - # virtualenv -importlib-metadata==8.5.0 - # via build -macholib==1.16.4 - # via delocate -packaging==26.2 - # via - # build - # delocate -pip==25.0.1 - # via -r cibuildwheel/resources/constraints.in -platformdirs==4.3.6 - # via - # python-discovery - # virtualenv -pyproject-hooks==1.2.0 - # via build -python-discovery==1.2.2 - # via virtualenv -tomli==2.4.1 - # via build -typing-extensions==4.13.2 - # via - # delocate - # virtualenv -virtualenv==21.2.1 - # via -r cibuildwheel/resources/constraints.in -zipp==3.20.2 - # via importlib-metadata diff --git a/docs/configuration.md b/docs/configuration.md index c35c697f..62bef786 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -132,17 +132,17 @@ which means it can be given multiple times. manylinux-x86_64-image = "manylinux_2_34" [[tool.cibuildwheel.overrides]] -select = "cp38-*" +select = "cp39-*" manylinux-x86_64-image = "manylinux2014" [[tool.cibuildwheel.overrides]] -select = "cp3{9,10}-*" +select = "cp3{10,11}-*" manylinux-x86_64-image = "manylinux_2_28" ``` -This example will build CPython 3.8 wheels on manylinux2014, CPython 3.9-3.10 +This example will build CPython 3.9 wheels on manylinux2014, CPython 3.10-3.11 wheels on manylinux_2_28, and manylinux_2_34 wheels for any newer Python -(like 3.10). +(like 3.14). ```toml [tool.cibuildwheel] diff --git a/docs/contributing.md b/docs/contributing.md index 36abbf8f..f5693cf2 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -161,32 +161,6 @@ bin/run_example_ci_configs.py examples/github-with-qemu.yml The script then outputs a Markdown table that can be copy/pasted into a PR to monitor and record the test. -### Preparing environments - -This has been moved to using docker, so you only need the following instructions if you add `--no-docker` to avoid using docker. - -The dependency update script in the next section requires multiple python versions installed. One way to do this is to use `pyenv`: - -```bash -pyenv install 3.7.8 -# Optionally add 3.8 and make it the local version; -# otherwise assuming 3.8+ already is your current python version -``` - -Then, you need to make the required virtual environments: - -```bash -$(pyenv prefix 3.7.8)/bin/python -m venv env37 -``` - - - -And, you need to install the requirements into each environment: - -```bash -for f in env*/bin/pip; do $f install pip-tools; done -``` - ### Making a release Before making a release, ensure pinned dependencies are up-to-date. Autoupdates are run weekly, with a PR being raised with any changes as required, so just make sure the latest one is merged before continuing. diff --git a/docs/faq.md b/docs/faq.md index db574127..db3d7cc6 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -344,34 +344,6 @@ To work around this, use a different environment variable such as `REPAIR_LIBRAR See [#816](https://github.com/pypa/cibuildwheel/issues/816), thanks to @phoerious for reporting. -### macOS: Building CPython 3.8 wheels on arm64 - -If you're building on an arm64 runner, you might notice something strange about CPython 3.8 - unlike Python 3.9+, it's cross-compiled to arm64 from an x86_64 version of Python running under Rosetta emulation. This is because (despite the prevalence of arm64 versions of Python 3.8 from Apple and Homebrew) there is no officially supported Python.org installer of Python 3.8 for arm64. - -This is fine for simple C extensions, but for more complicated builds on arm64 it becomes an issue. - -So, if you want to build macOS arm64 wheels on an arm64 runner (e.g., `macos-14`) on Python 3.8, before invoking cibuildwheel, you should install a native arm64 Python 3.8 interpreter on the runner: - - -!!! tab "GitHub Actions" - - ```yaml - - uses: actions/setup-python@v5 - with: - python-version: 3.8 - if: runner.os == 'macOS' && runner.arch == 'ARM64' - ``` - -!!! tab "Generic" - - ```bash - curl -o /tmp/Python38.pkg https://www.python.org/ftp/python/3.8.10/python-3.8.10-macos11.pkg - sudo installer -pkg /tmp/Python38.pkg -target / - sh "/Applications/Python 3.8/Install Certificates.command" - ``` - -Then cibuildwheel will detect that it's installed and use it instead. However, you probably don't want to build x86_64 wheels on this Python, unless you're happy with them only supporting macOS 11+. - ### macOS: Library dependencies do not satisfy target MacOS Since delocate 0.11.0 there is added verification that the library binary dependencies match the target macOS version. This is to prevent the situation where a wheel platform tag is lower than the actual minimum macOS version required by the library. To resolve this error you need to build the library to the same macOS version as the target wheel (for example using `MACOSX_DEPLOYMENT_TARGET` environment variable). diff --git a/docs/options.md b/docs/options.md index 917d1c5c..9ffc706b 100644 --- a/docs/options.md +++ b/docs/options.md @@ -45,7 +45,7 @@ This option can also be set using the [command-line option](#command-line) `--pl > Choose the Python versions to build -List of builds to build and skip. Each build has an identifier like `cp38-manylinux_x86_64` or `cp37-macosx_x86_64` - you can list specific ones to build and cibuildwheel will only build those, and/or list ones to skip and cibuildwheel won't try to build them. +List of builds to build and skip. Each build has an identifier like `cp314-manylinux_x86_64` or `cp313-macosx_x86_64` - you can list specific ones to build and cibuildwheel will only build those, and/or list ones to skip and cibuildwheel won't try to build them. When both options are specified, both conditions are applied and only builds with a tag that matches `build` and does not match `skip` will be built. @@ -54,14 +54,12 @@ When setting the options, you can use shell-style globbing syntax, as per [fnmat
| | macOS | Windows | Linux Intel | Linux Other | Android | iOS | pyodide (WASM) | |---------------|------------------------------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------|---------------------------------------------------------------------------------------------------|----------------------| -| Python 3.8 | cp38-macosx_x86_64
cp38-macosx_universal2
cp38-macosx_arm64 | cp38-win_amd64
cp38-win32 | cp38-manylinux_x86_64
cp38-manylinux_i686
cp38-musllinux_x86_64
cp38-musllinux_i686 | cp38-manylinux_aarch64
cp38-manylinux_ppc64le
cp38-manylinux_s390x
cp38-manylinux_armv7l
cp38-manylinux_riscv64
cp38-musllinux_aarch64
cp38-musllinux_ppc64le
cp38-musllinux_s390x
cp38-musllinux_armv7l
cp38-musllinux_riscv64 | | | | | Python 3.9 | cp39-macosx_x86_64
cp39-macosx_universal2
cp39-macosx_arm64 | cp39-win_amd64
cp39-win32
cp39-win_arm64 | cp39-manylinux_x86_64
cp39-manylinux_i686
cp39-musllinux_x86_64
cp39-musllinux_i686 | cp39-manylinux_aarch64
cp39-manylinux_ppc64le
cp39-manylinux_s390x
cp39-manylinux_armv7l
cp39-manylinux_riscv64
cp39-musllinux_aarch64
cp39-musllinux_ppc64le
cp39-musllinux_s390x
cp39-musllinux_armv7l
cp39-musllinux_riscv64 | | | | | Python 3.10 | cp310-macosx_x86_64
cp310-macosx_universal2
cp310-macosx_arm64 | cp310-win_amd64
cp310-win32
cp310-win_arm64 | cp310-manylinux_x86_64
cp310-manylinux_i686
cp310-musllinux_x86_64
cp310-musllinux_i686 | cp310-manylinux_aarch64
cp310-manylinux_ppc64le
cp310-manylinux_s390x
cp310-manylinux_armv7l
cp310-manylinux_riscv64
cp310-musllinux_aarch64
cp310-musllinux_ppc64le
cp310-musllinux_s390x
cp310-musllinux_armv7l
cp310-musllinux_riscv64 | | | | | Python 3.11 | cp311-macosx_x86_64
cp311-macosx_universal2
cp311-macosx_arm64 | cp311-win_amd64
cp311-win32
cp311-win_arm64 | cp311-manylinux_x86_64
cp311-manylinux_i686
cp311-musllinux_x86_64
cp311-musllinux_i686 | cp311-manylinux_aarch64
cp311-manylinux_ppc64le
cp311-manylinux_s390x
cp311-manylinux_armv7l
cp311-manylinux_riscv64
cp311-musllinux_aarch64
cp311-musllinux_ppc64le
cp311-musllinux_s390x
cp311-musllinux_armv7l
cp311-musllinux_riscv64 | | | | | 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 | | -| PyPy3.8 v7.3 | pp38-macosx_x86_64
pp38-macosx_arm64 | pp38-win_amd64 | pp38-manylinux_x86_64
pp38-manylinux_i686 | pp38-manylinux_aarch64 | | | | | 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 | | | | @@ -81,29 +79,29 @@ See the [cibuildwheel 2 documentation](https://cibuildwheel.pypa.io/en/2.x/) for ```toml [tool.cibuildwheel] - # Only build on CPython 3.8 - build = "cp38-*" + # Only build on CPython 3.14 + build = "cp314-*" - # Skip building on CPython 3.8 on the Mac - skip = "cp38-macosx_x86_64" + # Skip building on CPython 3.9 on the Mac + skip = "cp39-macosx_x86_64" - # Skip building on CPython 3.8 on all platforms - skip = "cp38-*" + # Skip building on CPython 3.9 on all platforms + skip = "cp39-*" - # Skip CPython 3.8 on Windows - skip = "cp38-win*" + # Skip CPython 3.9 on Windows + skip = "cp39-win*" - # Skip CPython 3.8 on 32-bit Windows - skip = "cp38-win32" + # Skip CPython 3.9 on 32-bit Windows + skip = "cp39-win32" - # Skip CPython 3.8 and CPython 3.9 - skip = ["cp38-*", "cp39-*"] + # Skip CPython 3.9 and CPython 3.10 + skip = ["cp39-*", "cp310-*"] - # Skip Python 3.8 on Linux - skip = "cp38-manylinux*" + # Skip Python 3.9 on Linux + skip = "cp39-*linux*" # Skip 32-bit builds - skip = ["*-win32", "*-manylinux_i686"] + skip = ["*-win32", "*-*linux_i686"] # Disable building PyPy wheels on all platforms skip = "pp*" @@ -118,29 +116,29 @@ See the [cibuildwheel 2 documentation](https://cibuildwheel.pypa.io/en/2.x/) for !!! tab examples "Environment variables" ```yaml - # Only build on CPython 3.8 - CIBW_BUILD: cp38-* + # Only build on CPython 3.14 + CIBW_BUILD: cp314-* - # Skip building on CPython 3.8 on the Mac - CIBW_SKIP: cp38-macosx_x86_64 + # Skip building on CPython 3.9 on the Mac + CIBW_SKIP: cp39-macosx_x86_64 - # Skip building on CPython 3.8 on all platforms - CIBW_SKIP: cp38-* + # Skip building on CPython 3.9 on all platforms + CIBW_SKIP: cp39-* - # Skip CPython 3.8 on Windows - CIBW_SKIP: cp38-win* + # Skip CPython 3.9 on Windows + CIBW_SKIP: cp39-win* - # Skip CPython 3.8 on 32-bit Windows - CIBW_SKIP: cp38-win32 + # Skip CPython 3.9 on 32-bit Windows + CIBW_SKIP: cp39-win32 - # Skip CPython 3.8 and CPython 3.9 - CIBW_SKIP: cp38-* cp39-* + # Skip CPython 3.9 and CPython 3.10 + CIBW_SKIP: cp39-* cp310-* - # Skip Python 3.8 on Linux - CIBW_SKIP: cp38-manylinux* + # Skip Python 3.9 on Linux + CIBW_SKIP: cp39-*linux* # Skip 32-bit builds - CIBW_SKIP: "*-win32 *-manylinux_i686" + CIBW_SKIP: "*-win32 *-*linux_i686" # Disable building PyPy wheels on all platforms CIBW_SKIP: pp* @@ -304,7 +302,7 @@ simple keyword assignment in a top level function call. If you need to override this behaviour for some reason, you can use this option. When setting this option, the syntax is the same as `project.requires-python`, -using 'version specifiers' like `>=3.8`, according to +using 'version specifiers' like `>=3.12`, according to [PEP440](https://www.python.org/dev/peps/pep-0440/#version-specifiers). Default: reads your package's Python compatibility from `pyproject.toml` @@ -325,7 +323,7 @@ the package is compatible with all versions of Python that it can build. ```toml [project] ... - requires-python = ">=3.8" + requires-python = ">=3.12" ``` Note that not all build backends fully support using a `[project]` table yet; @@ -341,7 +339,7 @@ the package is compatible with all versions of Python that it can build. !!! tab examples "Environment variables" ```yaml - CIBW_PROJECT_REQUIRES_PYTHON: ">=3.8" + CIBW_PROJECT_REQUIRES_PYTHON: ">=3.12" ``` ### `enable` {: #enable toml env-var} @@ -1238,7 +1236,7 @@ specifiers inline with the `packages: SPECIFIER...` syntax. If you need different dependencies for each python version, provide them in the same folder with a `-pythonXY` suffix. e.g. if your `dependency-versions="./constraints.txt"`, cibuildwheel will use - `./constraints-python38.txt` on Python 3.8, or fallback to + `./constraints-python314.txt` on Python 3.14, or fallback to `./constraints.txt` if that's not found. Platform-specific environment variables are also available:
@@ -1780,16 +1778,14 @@ will not produce more logging about the build itself. Other levels only affect the build frontend output, which is usually things like resolving and downloading dependencies. The settings are: -| | build | pip | uv | desc | -|-------------|-------|--------|-------|----------------------------------| -| -2 | `-qq`[^1] | `-qq` | `-qq` | even more quiet, where supported | -| -1 | `-q`[^1] | `-q` | `-q` | quiet mode, where supported | -| 0 (default) | | | | default for build tool | -| 1 | | `-v` | | print backend output | +| | build | pip | uv | desc | +|-------------|-------|--------|-------|----------------------------------------| +| -2 | `-qq` | `-qq` | `-qq` | even more quiet, where supported | +| -1 | `-q` | `-q` | `-q` | quiet mode, where supported | +| 0 (default) | | | | default for build tool | +| 1 | | `-v` | | print backend output | | 2 | `-v` | `-vv` | `-v` | print log messages e.g. resolving info | -| 3 | `-vv` | `-vvv` | `-vv` | print even more debug info | - -[^1]: Not supported on Python 3.8, will be ignored with a warning. +| 3 | `-vv` | `-vvv` | `-vv` | print even more debug info | Settings that are not supported for a specific frontend will log a warning. The default build frontend is `build`, which does show build backend output by diff --git a/docs/platforms.md b/docs/platforms.md index 1780c118..33d82e21 100644 --- a/docs/platforms.md +++ b/docs/platforms.md @@ -62,11 +62,10 @@ macOS builds will honor the `MACOSX_DEPLOYMENT_TARGET` environment variable to c | Arch | Python version range | Minimum target | |-------|----------------------|----------------| -| Intel | CPython 3.8-3.11 | 10.9 | +| Intel | CPython 3.9-3.11 | 10.9 | | Intel | CPython 3.12-3.13 | 10.13 | | Intel | CPython 3.14+ | 10.15 | | AS | CPython or PyPy | 11 | -| Intel | PyPy 3.8 | 10.13 | | Intel | PyPy 3.9+ | 10.15 | If you set the value lower, cibuildwheel will cap it to the lowest supported value for each target as needed. @@ -74,7 +73,7 @@ If you set the value lower, cibuildwheel will cap it to the lowest supported val !!! note For Rust-based extensions, `Rustc` requires `MACOSX_DEPLOYMENT_TARGET` to be at least 10.12. However, `cibuildwheel` defaults to 10.9 for - **Intel / CPython 3.8-3.11** builds. Users must manually set + **Intel / CPython 3.9-3.11** builds. Users must manually set `MACOSX_DEPLOYMENT_TARGET` to 10.12 or higher when building Rust extensions. ### macOS architectures diff --git a/examples/circleci-minimal.yml b/examples/circleci-minimal.yml index 19215082..4678eeba 100644 --- a/examples/circleci-minimal.yml +++ b/examples/circleci-minimal.yml @@ -43,7 +43,7 @@ jobs: - run: name: Build the OS X wheels. command: | - sudo softwareupdate --install-rosetta --agree-to-license # for python<=3.8 or x86_64/universal2 tests + sudo softwareupdate --install-rosetta --agree-to-license # for x86_64/universal2 tests pip3 install cibuildwheel==3.4.1 cibuildwheel --output-dir wheelhouse - store_artifacts: diff --git a/noxfile.py b/noxfile.py index 5644369b..738ad372 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(8, 15): + for minor_version in range(9, 15): python_version = f"3.{minor_version}" output_file = resources / f"constraints-python{python_version.replace('.', '')}.txt" session.run( diff --git a/test/conftest.py b/test/conftest.py index 64c3208a..8949dc80 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -26,12 +26,6 @@ def pytest_addoption(parser: pytest.Parser) -> None: choices=("all", *EMULATED_ARCHS), ) parser.addoption("--run-podman", action="store_true", default=False, help="run podman tests") - parser.addoption( - "--run-cp38-universal2", - action="store_true", - default=False, - help="macOS cp38 uses the universal2 installer", - ) parser.addoption( "--enable", action="store", diff --git a/test/test_abi_variants.py b/test/test_abi_variants.py index fdf797be..3fd44ee6 100644 --- a/test/test_abi_variants.py +++ b/test/test_abi_variants.py @@ -197,7 +197,7 @@ def test_abi_none(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None: "CIBW_TEST_REQUIRES": "pytest", "CIBW_TEST_COMMAND": f"{utils.invoke_pytest()} {{project}}/test", # limit the number of builds for test performance reasons - "CIBW_BUILD": "cp38-* cp{}{}-* cp314t-* pp310-*".format(*utils.SINGLE_PYTHON_VERSION), + "CIBW_BUILD": "cp39-* cp{}{}-* cp314t-* pp310-*".format(*utils.SINGLE_PYTHON_VERSION), "CIBW_ENABLE": "all", }, ) diff --git a/test/test_container_images.py b/test/test_container_images.py index 5a32bd4a..fa8bc518 100644 --- a/test/test_container_images.py +++ b/test/test_container_images.py @@ -50,6 +50,6 @@ def test(tmp_path: Path) -> None: for w in utils.expected_wheels( "spam", "0.1.0", manylinux_versions=manylinux_versions, musllinux_versions=[] ) - if "-cp38-" in w or "-cp39-" in w + if "-cp39-" in w ] assert set(actual_wheels) == set(expected_wheels) diff --git a/test/test_dependency_versions.py b/test/test_dependency_versions.py index 32cfc6ca..c7d11e5b 100644 --- a/test/test_dependency_versions.py +++ b/test/test_dependency_versions.py @@ -1,5 +1,4 @@ import json -import platform import re import subprocess import textwrap @@ -77,7 +76,7 @@ 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.13"]) +@pytest.mark.parametrize("python_version", ["3.9", "3.13"]) def test_pinned_versions( tmp_path: Path, python_version: str, build_frontend_env_nouv: dict[str, str] ) -> None: @@ -85,12 +84,6 @@ def test_pinned_versions( pytest.skip("linux doesn't pin individual tool versions, it pins manylinux images instead") 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" - and utils.get_platform() == "windows" - and platform.machine() == "ARM64" - ): - pytest.skip(f"Windows ARM64 does not support Python {python_version}") project_dir = tmp_path / "project" test_projects.new_c_project().generate(project_dir) diff --git a/test/test_macos_archs.py b/test/test_macos_archs.py index 7137be2d..b5274bc6 100644 --- a/test/test_macos_archs.py +++ b/test/test_macos_archs.py @@ -213,72 +213,3 @@ def test_universal2_testing_on_arm64( 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) - - -def test_cp38_arm64_testing( - tmp_path: Path, capfd: pytest.CaptureFixture[str], request: pytest.FixtureRequest -) -> None: - if utils.get_platform() != "macos": - pytest.skip("this test is only relevant to macos") - if utils.get_xcode_version() < (12, 2): - pytest.skip("this test only works with Xcode 12.2 or greater") - if platform.machine() != "arm64": - pytest.skip("this test only works on arm64") - if request.config.getoption("--run-cp38-universal2"): - pytest.skip("--run-cp38-universal2 option skips this test") - - project_dir = tmp_path / "project" - basic_project.generate(project_dir) - - actual_wheels = utils.cibuildwheel_run( - project_dir, - add_env={ - "CIBW_BUILD": "cp38-*", - "CIBW_TEST_COMMAND": '''python -c "import platform; print('running tests on ' + platform.machine())"''', - "CIBW_ARCHS": "x86_64,universal2,arm64", - }, - ) - - captured = capfd.readouterr() - - assert "running tests on x86_64" in captured.out - assert "running tests on arm64" not in captured.out - - warning_message = "While cibuildwheel can build CPython 3.8 universal2/arm64 wheels, we cannot test the arm64 part of them" - assert warning_message in captured.err - - expected_wheels = [w for w in ALL_MACOS_WHEELS if "cp38" in w] - - assert set(actual_wheels) == set(expected_wheels) - - -def test_cp38_arm64_testing_universal2_installer( - tmp_path: Path, capfd: pytest.CaptureFixture[str], request: pytest.FixtureRequest -) -> None: - if not request.config.getoption("--run-cp38-universal2"): - pytest.skip("needs --run-cp38-universal2 option to run") - - project_dir = tmp_path / "project" - basic_project.generate(project_dir) - - actual_wheels = utils.cibuildwheel_run( - project_dir, - add_env={ - "CIBW_BUILD": "cp38-*", - "CIBW_TEST_COMMAND": '''python -c "import platform; print('running tests on ' + platform.machine())"''', - "CIBW_ARCHS": "x86_64,universal2,arm64", - "MACOSX_DEPLOYMENT_TARGET": "11.0", - }, - ) - - captured = capfd.readouterr() - - assert "running tests on x86_64" in captured.out - assert "running tests on arm64" in captured.out - - warning_message = "While cibuildwheel can build CPython 3.8 universal2/arm64 wheels, we cannot test the arm64 part of them" - assert warning_message not in captured.err - - expected_wheels = [w.replace("10_9", "11_0") for w in ALL_MACOS_WHEELS if "cp38" in w] - - assert set(actual_wheels) == set(expected_wheels) diff --git a/test/test_testing.py b/test/test_testing.py index 6305cffc..39e6cd3f 100644 --- a/test/test_testing.py +++ b/test/test_testing.py @@ -167,11 +167,6 @@ def test_failing_test(tmp_path: Path) -> None: add_env={ "CIBW_TEST_REQUIRES": "pytest", "CIBW_TEST_COMMAND": f"{utils.invoke_pytest()} {{project}}/test", - # CPython 3.8 when running on macOS arm64 is unusual. The build - # always runs in x86_64, so the arm64 tests are not run. See - # #1169 for reasons why. That means the build succeeds, which - # we don't want. So we skip that build. - "CIBW_SKIP": "cp38-macosx_arm64", }, ) @@ -199,9 +194,6 @@ def test_bare_pytest_invocation( "CIBW_TEST_COMMAND": ( "python -m pytest" if test_runner == "pytest" else "python -m unittest" ), - # Skip CPython 3.8 on macOS arm64, see comment above in - # 'test_failing_test' - "CIBW_SKIP": "cp38-macosx_arm64", }, ) diff --git a/test/utils.py b/test/utils.py index 69b2e1b4..f90ae927 100644 --- a/test/utils.py +++ b/test/utils.py @@ -280,7 +280,6 @@ def _expected_wheels( ] elif python_abi_tags is None: python_abi_tags = [ - "cp38-cp38", "cp39-cp39", "cp310-cp310", "cp311-cp311", @@ -297,7 +296,6 @@ def _expected_wheels( if EnableGroup.PyPyEoL in enable_groups: python_abi_tags += [ - "pp38-pypy38_pp73", "pp39-pypy39_pp73", "pp310-pypy310_pp73", ] @@ -312,10 +310,6 @@ def _expected_wheels( "graalpy312-graalpy250_312_native", ] - if machine_arch == "ARM64" and platform == "windows": - # no CPython 3.8 on Windows ARM64 - python_abi_tags = [t for t in python_abi_tags if not t.startswith("cp38")] - if machine_arch not in PYPY_ARCHS: python_abi_tags = [tag for tag in python_abi_tags if not tag.startswith("pp")] @@ -360,12 +354,9 @@ def _expected_wheels( elif platform == "macos": if python_abi_tag.startswith("pp"): - if python_abi_tag.startswith("pp38"): - min_macosx = macosx_deployment_target - else: - min_macosx = _floor_macosx(macosx_deployment_target, "10.15") + min_macosx = _floor_macosx(macosx_deployment_target, "10.15") elif python_abi_tag.startswith("cp"): - if python_abi_tag.startswith(("cp38", "cp39", "cp310", "cp311")): + if python_abi_tag.startswith(("cp39", "cp310", "cp311")): min_macosx = macosx_deployment_target elif python_abi_tag.startswith(("cp312", "cp313")): min_macosx = _floor_macosx(macosx_deployment_target, "10.13") diff --git a/unit_test/conftest.py b/unit_test/conftest.py index bb1533e0..2ab3b44d 100644 --- a/unit_test/conftest.py +++ b/unit_test/conftest.py @@ -9,12 +9,6 @@ MOCK_PACKAGE_DIR = Path("some_package_dir") def pytest_addoption(parser: pytest.Parser) -> None: parser.addoption("--run-docker", action="store_true", default=False, help="run docker tests") parser.addoption("--run-podman", action="store_true", default=False, help="run podman tests") - parser.addoption( - "--run-cp38-universal2", - action="store_true", - default=False, - help="macOS cp38 uses the universal2 installer", - ) @pytest.fixture diff --git a/unit_test/linux_build_steps_test.py b/unit_test/linux_build_steps_test.py index 0595a684..237ab171 100644 --- a/unit_test/linux_build_steps_test.py +++ b/unit_test/linux_build_steps_test.py @@ -28,16 +28,16 @@ def test_linux_container_split(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) archs = "x86_64 i686" [[tool.cibuildwheel.overrides]] - select = "cp{38,39,310}-*" + select = "cp{39,310,311}-*" manylinux-x86_64-image = "other_container_image" manylinux-i686-image = "other_container_image" [[tool.cibuildwheel.overrides]] - select = "cp39-*" - before-all = "echo 'a cp39-only command'" + select = "cp310-*" + before-all = "echo 'a cp310-only command'" [[tool.cibuildwheel.overrides]] - select = "cp310-*" + select = "cp311-*" container-engine = "docker; create_args: --privileged" """ ) @@ -69,17 +69,17 @@ def test_linux_container_split(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) default_container_engine = OCIContainerEngineConfig(name="docker") assert build_steps[0].container_image == "other_container_image" - assert identifiers(build_steps[0]) == ["cp38-manylinux_x86_64"] + assert identifiers(build_steps[0]) == ["cp39-manylinux_x86_64"] assert before_alls(build_steps[0]) == [""] assert container_engines(build_steps[0]) == [default_container_engine] assert build_steps[1].container_image == "other_container_image" - assert identifiers(build_steps[1]) == ["cp39-manylinux_x86_64"] - assert before_alls(build_steps[1]) == ["echo 'a cp39-only command'"] + assert identifiers(build_steps[1]) == ["cp310-manylinux_x86_64"] + assert before_alls(build_steps[1]) == ["echo 'a cp310-only command'"] assert container_engines(build_steps[1]) == [default_container_engine] assert build_steps[2].container_image == "other_container_image" - assert identifiers(build_steps[2]) == ["cp310-manylinux_x86_64"] + assert identifiers(build_steps[2]) == ["cp311-manylinux_x86_64"] assert before_alls(build_steps[2]) == [""] assert container_engines(build_steps[2]) == [ OCIContainerEngineConfig(name="docker", create_args=("--privileged",)) @@ -87,11 +87,10 @@ def test_linux_container_split(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) assert build_steps[3].container_image == "normal_container_image" assert identifiers(build_steps[3]) == [ - "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]) == [""] * 5 - assert container_engines(build_steps[3]) == [default_container_engine] * 5 + assert before_alls(build_steps[3]) == [""] * 4 + assert container_engines(build_steps[3]) == [default_container_engine] * 4 diff --git a/unit_test/main_tests/main_options_test.py b/unit_test/main_tests/main_options_test.py index 7f2706fb..463cd20f 100644 --- a/unit_test/main_tests/main_options_test.py +++ b/unit_test/main_tests/main_options_test.py @@ -433,20 +433,26 @@ def test_config_settings( ], ) @pytest.mark.parametrize( - "pattern", + ("pattern", "series"), [ - "cp27-*", - "cp35-*", - "?p36-*", - "?p27*", - "?p2*", - "?p35*", - "cp313t*", + ("cp27-*", 1), + ("cp35-*", 1), + ("?p36-*", 2), + ("?p37-*", 2), + ("?p38-*", 3), + ("?p27*", 1), + ("?p2*", 1), + ("?p35*", 1), + ("cp313t*", None), ], ) @pytest.mark.usefixtures("platform", "intercepted_build_args", "allow_empty") def test_build_selector_deprecated_error( - monkeypatch: pytest.MonkeyPatch, selector: str, pattern: str, capsys: pytest.CaptureFixture[str] + monkeypatch: pytest.MonkeyPatch, + selector: str, + pattern: str, + series: int, + capsys: pytest.CaptureFixture[str], ) -> None: monkeypatch.setenv(selector, pattern) monkeypatch.delenv("CIBW_ENABLE", raising=False) @@ -463,8 +469,7 @@ def test_build_selector_deprecated_error( if pattern == "cp313t*": msg = "cibuildwheel 4.x no longer supports Python 3.13 free-threading. Please use the 3.x series or update" else: - series = "2" if "6" in pattern else "1" - msg = f"cibuildwheel 3.x no longer supports Python < 3.8. Please use the {series}.x series or update" + msg = f"cibuildwheel 4.x no longer supports Python < 3.9. Please use the {series}.x series or update" assert msg in stderr diff --git a/unit_test/option_prepare_test.py b/unit_test/option_prepare_test.py index 0c23edf9..abc2009e 100644 --- a/unit_test/option_prepare_test.py +++ b/unit_test/option_prepare_test.py @@ -13,8 +13,8 @@ from cibuildwheel.__main__ import main from cibuildwheel.oci_container import OCIPlatform from cibuildwheel.util import file -DEFAULT_IDS = {"cp38", "cp39", "cp310", "cp311", "cp312", "cp313", "cp314", "cp314t"} -ALL_IDS = DEFAULT_IDS | {"pp38", "pp39", "pp310", "pp311", "gp311_242", "gp312_250"} +DEFAULT_IDS = {"cp39", "cp310", "cp311", "cp312", "cp313", "cp314", "cp314t"} +ALL_IDS = DEFAULT_IDS | {"pp39", "pp310", "pp311", "gp311_242", "gp312_250"} @pytest.fixture @@ -110,12 +110,12 @@ archs = ["auto64", "auto32"] # Before Python 3.10, use manylinux2014 [[tool.cibuildwheel.overrides]] -select = "cp3?-*" +select = "cp3?-* cp310-*" manylinux-x86_64-image = "manylinux2014" manylinux-i686-image = "manylinux2014" [[tool.cibuildwheel.overrides]] -select = "cp38-manylinux_x86_64" +select = "cp39-manylinux_x86_64" before-all = "true" """ ) @@ -136,8 +136,8 @@ before-all = "true" assert kwargs["container"]["oci_platform"] == OCIPlatform.AMD64 identifiers = {x.identifier for x in kwargs["platform_configs"]} - assert identifiers == {"cp38-manylinux_x86_64"} - assert kwargs["options"].build_options("cp38-manylinux_x86_64").before_all == "true" + assert identifiers == {"cp39-manylinux_x86_64"} + assert kwargs["options"].build_options("cp39-manylinux_x86_64").before_all == "true" kwargs = build_in_container.call_args_list[1][1] assert "quay.io/pypa/manylinux2014_x86_64" in kwargs["container"]["image"] @@ -149,14 +149,12 @@ before-all = "true" f"{x}-manylinux_x86_64" for x in ALL_IDS - { - "cp38", - "cp310", + "cp39", "cp311", "cp312", "cp313", "cp314", "cp314t", - "pp38", "pp39", "pp310", "pp311", @@ -164,7 +162,7 @@ before-all = "true" "gp312_250", } } - assert kwargs["options"].build_options("cp39-manylinux_x86_64").before_all == "" + assert kwargs["options"].build_options("cp310-manylinux_x86_64").before_all == "" kwargs = build_in_container.call_args_list[2][1] assert "quay.io/pypa/manylinux_2_28_x86_64" in kwargs["container"]["image"] @@ -174,13 +172,11 @@ before-all = "true" assert identifiers == { f"{x}-manylinux_x86_64" for x in [ - "cp310", "cp311", "cp312", "cp313", "cp314", "cp314t", - "pp38", "pp39", "pp310", "pp311", @@ -194,7 +190,7 @@ before-all = "true" assert kwargs["container"]["cwd"] == PurePosixPath("/project") assert kwargs["container"]["oci_platform"] == OCIPlatform.i386 identifiers = {x.identifier for x in kwargs["platform_configs"]} - assert identifiers == {"cp38-manylinux_i686", "cp39-manylinux_i686"} + assert identifiers == {"cp39-manylinux_i686", "cp310-manylinux_i686"} kwargs = build_in_container.call_args_list[4][1] assert "quay.io/pypa/manylinux_2_28_i686" in kwargs["container"]["image"] @@ -202,7 +198,7 @@ before-all = "true" assert kwargs["container"]["oci_platform"] == OCIPlatform.i386 identifiers = {x.identifier for x in kwargs["platform_configs"]} assert identifiers == { - f"{x}-manylinux_i686" for x in ALL_IDS - {"cp38", "cp39"} if "gp" not in x + f"{x}-manylinux_i686" for x in ALL_IDS - {"cp39", "cp310"} if "gp" not in x } kwargs = build_in_container.call_args_list[5][1] diff --git a/unit_test/options_test.py b/unit_test/options_test.py index 278a28f4..4beb9c2d 100644 --- a/unit_test/options_test.py +++ b/unit_test/options_test.py @@ -576,27 +576,13 @@ def test_get_build_frontend_extra_flags( monkeypatch.setattr(Logger, "warning", mock_warning) build_frontend = BuildFrontendConfig(frontend, ["-1"]) args = get_build_frontend_extra_flags( - build_frontend=build_frontend, verbosity_level=verbosity, config_settings="a b", py38=False + build_frontend=build_frontend, verbosity_level=verbosity, config_settings="a b" ) assert args == result mock_warning.assert_not_called() -@pytest.mark.parametrize("frontend", ["build", "build[uv]"]) -def test_get_build_frontend_extra_flags_warning( - frontend: Literal["build", "build[uv]"], monkeypatch: pytest.MonkeyPatch -) -> None: - mock_warning = unittest.mock.MagicMock() - monkeypatch.setattr(Logger, "warning", mock_warning) - build_frontend = BuildFrontendConfig(frontend, ["-1"]) - args = get_build_frontend_extra_flags( - build_frontend=build_frontend, verbosity_level=-1, config_settings="a b", py38=True - ) - assert args == ["-Ca", "-Cb", "-1"] - mock_warning.assert_called_once() - - @pytest.mark.parametrize( ("config_settings", "expected"), [