99import textwrap
1010import traceback
1111import typing
12- from collections .abc import Iterable , Sequence
12+ from collections .abc import Generator , Iterable , Sequence
1313from pathlib import Path
1414from tempfile import mkdtemp
1515from typing import Any , Literal , TextIO
@@ -369,37 +369,50 @@ def print_preamble(platform: str, options: Options, identifiers: Sequence[str])
369369 print (f"Cache folder: { CIBW_CACHE_PATH } " )
370370 print ()
371371
372- warnings = detect_warnings (options = options , identifiers = identifiers )
372+ warnings = detect_warnings (options = options )
373373 for warning in warnings :
374374 log .warning (warning )
375375
376- print ("Here we go!\n " )
376+ error_list = list (detect_errors (options = options , identifiers = identifiers ))
377+ if error_list :
378+ for error in error_list :
379+ log .error (error )
380+ msg = "\n " .join (error_list )
381+ raise errors .ConfigurationError (msg )
377382
383+ print ("Here we go!\n " )
378384
379- def detect_warnings (* , options : Options , identifiers : Iterable [str ]) -> list [str ]:
380- warnings = []
381385
382- python_version_deprecation = (( 3 , 11 ), 3 )
383- if sys . version_info [: 2 ] < python_version_deprecation [ 0 ]:
384- python_version = "." . join ( map ( str , python_version_deprecation [ 0 ]))
385- msg = (
386- f"cibuildwheel { python_version_deprecation [ 1 ] } will require Python { python_version } +, "
387- "please upgrade the Python version used to run cibuildwheel. "
388- "This does not affect the versions you can target when building wheels. See: https://cibuildwheel.pypa.io/en/stable/#what-does-it-do "
386+ def detect_errors ( * , options : Options , identifiers : Iterable [ str ]) -> Generator [ str , None , None ]:
387+ # Check for deprecated CIBW_FREE_THREADED_SUPPORT environment variable
388+ if "CIBW_FREE_THREADED_SUPPORT" in os . environ :
389+ yield (
390+ "CIBW_FREE_THREADED_SUPPORT environment variable is no longer supported. "
391+ 'Use tool.cibuildwheel.enable = ["cpython-freethreading"] in pyproject.toml '
392+ "or set CIBW_ENABLE=cpython-freethreading instead. "
389393 )
390- warnings .append (msg )
391394
392- # warn about deprecated {python} and {pip}
395+ # Deprecated {python} and {pip}
393396 for option_name in ["test_command" , "before_build" ]:
394397 option_values = [getattr (options .build_options (i ), option_name ) for i in identifiers ]
395398
396399 if any (o and ("{python}" in o or "{pip}" in o ) for o in option_values ):
397400 # Reminder: in an f-string, double braces means literal single brace
398- msg = (
401+ yield (
399402 f"{ option_name } : '{{python}}' and '{{pip}}' are no longer supported "
400403 "and have been removed in cibuildwheel 3. Simply use 'python' or 'pip' instead."
401404 )
402- raise errors .ConfigurationError (msg )
405+
406+
407+ def detect_warnings (* , options : Options ) -> Generator [str , None , None ]:
408+ python_version_deprecation = ((3 , 11 ), 3 )
409+ if sys .version_info [:2 ] < python_version_deprecation [0 ]:
410+ python_version = "." .join (map (str , python_version_deprecation [0 ]))
411+ yield (
412+ f"cibuildwheel { python_version_deprecation [1 ]} will require Python { python_version } +, "
413+ "please upgrade the Python version used to run cibuildwheel. "
414+ "This does not affect the versions you can target when building wheels. See: https://cibuildwheel.pypa.io/en/stable/#what-does-it-do"
415+ )
403416
404417 build_selector = options .globals .build_selector
405418 test_selector = options .globals .test_selector
@@ -417,27 +430,25 @@ def detect_warnings(*, options: Options, identifiers: Iterable[str]) -> list[str
417430 identifier for identifier in all_valid_identifiers if enabled_selector (identifier )
418431 ]
419432
420- warnings += check_for_invalid_selectors (
433+ yield from check_for_invalid_selectors (
421434 selector_name = "build" ,
422435 selector_value = build_selector .build_config ,
423436 all_valid_identifiers = all_valid_identifiers ,
424437 all_enabled_identifiers = all_enabled_identifiers ,
425438 )
426- warnings += check_for_invalid_selectors (
439+ yield from check_for_invalid_selectors (
427440 selector_name = "skip" ,
428441 selector_value = build_selector .skip_config ,
429442 all_valid_identifiers = all_valid_identifiers ,
430443 all_enabled_identifiers = all_enabled_identifiers ,
431444 )
432- warnings += check_for_invalid_selectors (
445+ yield from check_for_invalid_selectors (
433446 selector_name = "test_skip" ,
434447 selector_value = test_selector .skip_config ,
435448 all_valid_identifiers = all_valid_identifiers ,
436449 all_enabled_identifiers = all_enabled_identifiers ,
437450 )
438451
439- return warnings
440-
441452
442453def check_for_invalid_selectors (
443454 * ,
0 commit comments