diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index 2f6e8d36..ab15f60c 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -441,11 +441,7 @@ def print_preamble(platform: str, options: Options, identifiers: Sequence[str]) def detect_errors(*, options: Options, identifiers: Iterable[str]) -> Generator[str, None, None]: # Check for deprecated CIBW_FREE_THREADED_SUPPORT environment variable if "CIBW_FREE_THREADED_SUPPORT" in os.environ: - yield ( - "CIBW_FREE_THREADED_SUPPORT environment variable is no longer supported. " - 'Use tool.cibuildwheel.enable = ["cpython-freethreading"] in pyproject.toml ' - "or set CIBW_ENABLE=cpython-freethreading instead." - ) + yield "CIBW_FREE_THREADED_SUPPORT environment variable is no longer supported." # Deprecated {python} and {pip} for option_name in ["test_command", "before_build"]: @@ -472,6 +468,13 @@ def detect_warnings(*, options: Options) -> Generator[str, None, None]: build_selector = options.globals.build_selector test_selector = options.globals.test_selector + if EnableGroup.CPythonFreeThreading in build_selector.enable: + yield ( + "'cpython-freethreading' enable is deprecated and will be removed in a future version. " + "It should be removed from tool.cibuildwheel.enable in pyproject.toml " + "or CIBW_ENABLE environment variable." + ) + all_valid_identifiers = [ config.identifier for module in ALL_PLATFORM_MODULES.values() diff --git a/cibuildwheel/options.py b/cibuildwheel/options.py index 705c2db0..972c7b2c 100644 --- a/cibuildwheel/options.py +++ b/cibuildwheel/options.py @@ -686,6 +686,8 @@ class Options: skip_config = "" architectures = Architecture.all_archs(self.platform) enable |= EnableGroup.all_groups() + if args.only.startswith("cp313t-"): + enable.add(EnableGroup.CPythonFreeThreading) build_selector = BuildSelector( build_config=build_config, diff --git a/cibuildwheel/selector.py b/cibuildwheel/selector.py index 299a725e..80dc0309 100644 --- a/cibuildwheel/selector.py +++ b/cibuildwheel/selector.py @@ -38,7 +38,8 @@ class EnableGroup(StrEnum): @classmethod def all_groups(cls) -> frozenset[Self]: - return frozenset(cls) + # see https://github.com/python/mypy/issues/20434 for the reason to type: ignore[arg-type] + return frozenset(set(cls) - {cls.CPythonFreeThreading}) # type: ignore[arg-type] @classmethod def parse_option_value(cls, value: str) -> frozenset[Self]: diff --git a/test/test_abi_variants.py b/test/test_abi_variants.py index e38b3706..25fc9ca5 100644 --- a/test/test_abi_variants.py +++ b/test/test_abi_variants.py @@ -44,7 +44,7 @@ def test_abi3(tmp_path: Path) -> None: add_env={ # free_threaded, GraalPy, and PyPy do not have a Py_LIMITED_API equivalent, just build one of those # also limit the number of builds for test performance reasons - "CIBW_BUILD": "cp39-* cp310-* pp310-* gp312_250-* cp312-* cp313t-*", + "CIBW_BUILD": "cp39-* cp310-* pp310-* gp312_250-* cp312-* cp314t-*", "CIBW_ENABLE": "all", }, ) @@ -65,7 +65,7 @@ def test_abi3(tmp_path: Path) -> None: python_abi_tags=[ "cp39-cp39", "cp310-abi3", # <-- ABI3, works with 3.10 and 3.12 - "cp313-cp313t", + "cp314-cp314t", "pp310-pypy310_pp73", "graalpy312-graalpy250_312_native", ], @@ -192,7 +192,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{}{}-* cp313t-* pp310-*".format(*utils.SINGLE_PYTHON_VERSION), + "CIBW_BUILD": "cp38-* cp{}{}-* cp314t-* pp310-*".format(*utils.SINGLE_PYTHON_VERSION), "CIBW_ENABLE": "all", }, ) diff --git a/unit_test/get_platform_test.py b/unit_test/get_platform_test.py index e0c3e42d..aafc9fad 100644 --- a/unit_test/get_platform_test.py +++ b/unit_test/get_platform_test.py @@ -71,7 +71,7 @@ def test_arm(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: def test_env_set(tmp_path: Path) -> None: environment = {"VSCMD_ARG_TGT_ARCH": "x64"} - configuration = PythonConfiguration(version="irrelevant", identifier="cp313t-win32", url=None) + configuration = PythonConfiguration(version="irrelevant", identifier="cp314t-win32", url=None) with pytest.raises(FatalError, match="VSCMD_ARG_TGT_ARCH"): setup_setuptools_cross_compile(tmp_path, configuration, tmp_path, environment) diff --git a/unit_test/main_tests/main_options_test.py b/unit_test/main_tests/main_options_test.py index 5e9e008a..8e3794d6 100644 --- a/unit_test/main_tests/main_options_test.py +++ b/unit_test/main_tests/main_options_test.py @@ -1,3 +1,4 @@ +import os import sys import tomllib from collections.abc import Mapping @@ -167,6 +168,78 @@ def test_empty_selector(monkeypatch: pytest.MonkeyPatch) -> None: assert e.value.code == 3 +@pytest.mark.usefixtures("platform", "intercepted_build_args") +def test_cp313t_warning1( + monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str] +) -> None: + monkeypatch.setenv("CIBW_ENABLE", "cpython-freethreading") + + main() + + _, err = capsys.readouterr() + print(err) + assert "'cpython-freethreading' enable is deprecated" in err + + +@pytest.mark.usefixtures("platform", "intercepted_build_args") +def test_cp313t_warning2( + monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str], tmp_path: Path +) -> None: + local_path = tmp_path / "tmp_project" + os.mkdir(local_path) # noqa:PTH102 Path.mkdir has been monkeypatched already + local_path.joinpath("setup.py").touch() + + monkeypatch.setattr( + sys, "argv", ["cibuildwheel", "--only", "cp313t-manylinux_x86_64", str(local_path)] + ) + monkeypatch.setenv("CIBW_ENABLE", "cpython-freethreading") + + main() + + _, err = capsys.readouterr() + print(err) + assert "'cpython-freethreading' enable is deprecated" in err + + +@pytest.mark.usefixtures("platform", "intercepted_build_args") +def test_cp313t_warning3( + monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str], tmp_path: Path +) -> None: + local_path = tmp_path / "tmp_project" + os.mkdir(local_path) # noqa:PTH102 Path.mkdir has been monkeypatched already + local_path.joinpath("setup.py").touch() + + monkeypatch.setattr( + sys, "argv", ["cibuildwheel", "--only", "cp313t-manylinux_x86_64", str(local_path)] + ) + + main() + + _, err = capsys.readouterr() + print(err) + assert "'cpython-freethreading' enable is deprecated" in err + + +@pytest.mark.usefixtures("platform", "intercepted_build_args") +def test_cp313t_warning4( + monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str], tmp_path: Path +) -> None: + local_path = tmp_path / "tmp_project" + os.mkdir(local_path) # noqa:PTH102 Path.mkdir has been monkeypatched already + local_path.joinpath("setup.py").touch() + + monkeypatch.setattr( + sys, "argv", ["cibuildwheel", "--only", "cp313t-manylinux_x86_64", str(local_path)] + ) + monkeypatch.setenv("CIBW_ENABLE", "all") + + main() + + _, err = capsys.readouterr() + print(err) + assert "'cpython-freethreading' enable is deprecated" in err + + @pytest.mark.parametrize( ("architecture", "image", "full_image"), [ @@ -579,6 +652,7 @@ def test_enable_all( intercepted_build_args: "ArgsInterceptor", monkeypatch: pytest.MonkeyPatch ) -> None: monkeypatch.setattr(sys, "argv", [*sys.argv, "--enable", "all"]) + monkeypatch.delenv("CIBW_ENABLE", raising=False) main()