fix: error on CIBW_FREE_THREADED_SUPPORT set (#2520)

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
This commit is contained in:
Henry Schreiner
2025-07-26 19:09:26 +02:00
committed by GitHub
parent c89609aaf2
commit 55fcb25edc
2 changed files with 44 additions and 21 deletions
+32 -21
View File
@@ -9,7 +9,7 @@ import tarfile
import textwrap import textwrap
import traceback import traceback
import typing import typing
from collections.abc import Iterable, Sequence from collections.abc import Generator, Iterable, Sequence
from pathlib import Path from pathlib import Path
from tempfile import mkdtemp from tempfile import mkdtemp
from typing import Any, Literal, TextIO from typing import Any, Literal, TextIO
@@ -369,37 +369,50 @@ def print_preamble(platform: str, options: Options, identifiers: Sequence[str])
print(f"Cache folder: {CIBW_CACHE_PATH}") print(f"Cache folder: {CIBW_CACHE_PATH}")
print() print()
warnings = detect_warnings(options=options, identifiers=identifiers) warnings = detect_warnings(options=options)
for warning in warnings: for warning in warnings:
log.warning(warning) log.warning(warning)
error_list = list(detect_errors(options=options, identifiers=identifiers))
if error_list:
for error in error_list:
log.error(error)
msg = "\n".join(error_list)
raise errors.ConfigurationError(msg)
print("Here we go!\n") print("Here we go!\n")
def detect_warnings(*, options: Options, identifiers: Iterable[str]) -> list[str]: def detect_errors(*, options: Options, identifiers: Iterable[str]) -> Generator[str, None, None]:
warnings = [] # Check for deprecated CIBW_FREE_THREADED_SUPPORT environment variable
if "CIBW_FREE_THREADED_SUPPORT" in os.environ:
python_version_deprecation = ((3, 11), 3) yield (
if sys.version_info[:2] < python_version_deprecation[0]: "CIBW_FREE_THREADED_SUPPORT environment variable is no longer supported. "
python_version = ".".join(map(str, python_version_deprecation[0])) 'Use tool.cibuildwheel.enable = ["cpython-freethreading"] in pyproject.toml '
msg = ( "or set CIBW_ENABLE=cpython-freethreading instead."
f"cibuildwheel {python_version_deprecation[1]} will require Python {python_version}+, "
"please upgrade the Python version used to run cibuildwheel. "
"This does not affect the versions you can target when building wheels. See: https://cibuildwheel.pypa.io/en/stable/#what-does-it-do"
) )
warnings.append(msg)
# warn about deprecated {python} and {pip} # Deprecated {python} and {pip}
for option_name in ["test_command", "before_build"]: for option_name in ["test_command", "before_build"]:
option_values = [getattr(options.build_options(i), option_name) for i in identifiers] option_values = [getattr(options.build_options(i), option_name) for i in identifiers]
if any(o and ("{python}" in o or "{pip}" in o) for o in option_values): if any(o and ("{python}" in o or "{pip}" in o) for o in option_values):
# Reminder: in an f-string, double braces means literal single brace # Reminder: in an f-string, double braces means literal single brace
msg = ( yield (
f"{option_name}: '{{python}}' and '{{pip}}' are no longer supported " f"{option_name}: '{{python}}' and '{{pip}}' are no longer supported "
"and have been removed in cibuildwheel 3. Simply use 'python' or 'pip' instead." "and have been removed in cibuildwheel 3. Simply use 'python' or 'pip' instead."
) )
raise errors.ConfigurationError(msg)
def detect_warnings(*, options: Options) -> Generator[str, None, None]:
python_version_deprecation = ((3, 11), 3)
if sys.version_info[:2] < python_version_deprecation[0]:
python_version = ".".join(map(str, python_version_deprecation[0]))
yield (
f"cibuildwheel {python_version_deprecation[1]} will require Python {python_version}+, "
"please upgrade the Python version used to run cibuildwheel. "
"This does not affect the versions you can target when building wheels. See: https://cibuildwheel.pypa.io/en/stable/#what-does-it-do"
)
build_selector = options.globals.build_selector build_selector = options.globals.build_selector
test_selector = options.globals.test_selector test_selector = options.globals.test_selector
@@ -417,27 +430,25 @@ def detect_warnings(*, options: Options, identifiers: Iterable[str]) -> list[str
identifier for identifier in all_valid_identifiers if enabled_selector(identifier) identifier for identifier in all_valid_identifiers if enabled_selector(identifier)
] ]
warnings += check_for_invalid_selectors( yield from check_for_invalid_selectors(
selector_name="build", selector_name="build",
selector_value=build_selector.build_config, selector_value=build_selector.build_config,
all_valid_identifiers=all_valid_identifiers, all_valid_identifiers=all_valid_identifiers,
all_enabled_identifiers=all_enabled_identifiers, all_enabled_identifiers=all_enabled_identifiers,
) )
warnings += check_for_invalid_selectors( yield from check_for_invalid_selectors(
selector_name="skip", selector_name="skip",
selector_value=build_selector.skip_config, selector_value=build_selector.skip_config,
all_valid_identifiers=all_valid_identifiers, all_valid_identifiers=all_valid_identifiers,
all_enabled_identifiers=all_enabled_identifiers, all_enabled_identifiers=all_enabled_identifiers,
) )
warnings += check_for_invalid_selectors( yield from check_for_invalid_selectors(
selector_name="test_skip", selector_name="test_skip",
selector_value=test_selector.skip_config, selector_value=test_selector.skip_config,
all_valid_identifiers=all_valid_identifiers, all_valid_identifiers=all_valid_identifiers,
all_enabled_identifiers=all_enabled_identifiers, all_enabled_identifiers=all_enabled_identifiers,
) )
return warnings
def check_for_invalid_selectors( def check_for_invalid_selectors(
*, *,
+12
View File
@@ -16,6 +16,18 @@ from cibuildwheel.util.packaging import DependencyConstraints
# CIBW_PLATFORM is tested in main_platform_test.py # CIBW_PLATFORM is tested in main_platform_test.py
def test_old_free_threaded(monkeypatch, capsys):
monkeypatch.setenv("CIBW_FREE_THREADED_SUPPORT", "ON")
with pytest.raises(SystemExit):
main()
assert (
"CIBW_FREE_THREADED_SUPPORT environment variable is no longer supported."
in capsys.readouterr().err
)
@pytest.mark.usefixtures("platform") @pytest.mark.usefixtures("platform")
def test_output_dir(intercepted_build_args, monkeypatch): def test_output_dir(intercepted_build_args, monkeypatch):
OUTPUT_DIR = Path("some_output_dir") OUTPUT_DIR = Path("some_output_dir")