diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0e2b2c41..bd1b6e9d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: - id: isort - repo: https://github.com/psf/black - rev: 21.4b0 + rev: 21.4b1 hooks: - id: black files: ^bin/update_pythons.py|setup.py$ diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index 7fe64eaf..d64f02b6 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -73,19 +73,22 @@ def main() -> None: Python. Default: auto. ''') + arch_list_str = ", ".join(a.name for a in Architecture) parser.add_argument('--archs', default=None, - help=''' + help=f''' Comma-separated list of CPU architectures to build for. When set to 'auto', builds the architectures natively supported on this machine. Set this option to build an architecture via emulation, for example, using binfmt_misc and QEMU. Default: auto. - Choices: auto, auto64, auto32, native, all, {} - '''.format(", ".join(a.name for a in Architecture))) + Choices: auto, auto64, auto32, native, all, {arch_list_str} + ''') + parser.add_argument('--output-dir', default=os.environ.get('CIBW_OUTPUT_DIR', 'wheelhouse'), help='Destination folder for the wheels.') + parser.add_argument('package_dir', default='.', nargs='?', @@ -99,6 +102,7 @@ def main() -> None: parser.add_argument('--print-build-identifiers', action='store_true', help='Print the build identifiers matched by the current invocation and exit.') + parser.add_argument('--allow-empty', action='store_true', help='Do not report an error code if the build does not match any wheels.') @@ -368,7 +372,12 @@ def detect_warnings(platform: str, build_options: BuildOptions) -> List[str]: option_value = getattr(build_options, option_name) if option_value and ('{python}' in option_value or '{pip}' in option_value): - warnings.append(option_name + ": '{python}' and '{pip}' are no longer needed, and will be removed in a future release. Simply use 'python' or 'pip' instead.") + # Reminder: in an f-string, double braces means literal single brace + msg = ( + f"{option_name}: '{{python}}' and '{{pip}}' are no longer needed, " + "and will be removed in a future release. Simply use 'python' or 'pip' instead." + ) + warnings.append(msg) return warnings diff --git a/cibuildwheel/bashlex_eval.py b/cibuildwheel/bashlex_eval.py index 79386531..05dd46af 100644 --- a/cibuildwheel/bashlex_eval.py +++ b/cibuildwheel/bashlex_eval.py @@ -58,9 +58,8 @@ def evaluate_word_node(node: bashlex.ast.node, context: NodeExecutionContext) -> if part_string not in value: raise RuntimeError( - 'bash parse failed. part "{}" not found in "{}". Word was "{}". Full input was "{}"'.format( - part_string, value, node.word, context.input, - ) + f'bash parse failed. part "{part_string}" not found in "{value}". ' + f'Word was "{node.word}". Full input was "{context.input}"' ) value = value.replace(part_string, part_value, 1) diff --git a/cibuildwheel/docker_container.py b/cibuildwheel/docker_container.py index e18eed8c..204a0d2a 100644 --- a/cibuildwheel/docker_container.py +++ b/cibuildwheel/docker_container.py @@ -45,10 +45,10 @@ class DockerContainer: subprocess.run( [ 'docker', 'create', - '--env', 'CIBUILDWHEEL', - '--name', self.name, - '-i', - '-v', '/:/host', # ignored on CircleCI + '--env=CIBUILDWHEEL', + f'--name={self.name}', + '--interactive', + '--volume=/:/host', # ignored on CircleCI *cwd_args, self.docker_image, *shell_args @@ -169,13 +169,15 @@ class DockerContainer: while True: line = self.bash_stdout.readline() - if line.endswith(b'%s\n' % (bytes(end_of_message, encoding='utf8'))): + if line.endswith(bytes(end_of_message, encoding='utf8') + b'\n'): + # fmt: off footer_offset = ( len(line) - 1 # newline character - len(end_of_message) # delimiter - 4 # 4 returncode decimals ) + # fmt: on returncode_str = line[footer_offset:footer_offset+4] returncode = int(returncode_str) # add the last line to output, without the footer diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 7ba4f5cc..3e99e467 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -31,7 +31,7 @@ class PythonConfiguration(NamedTuple): def get_python_configurations( build_selector: BuildSelector, - architectures: Set[Architecture] + architectures: Set[Architecture], ) -> List[PythonConfiguration]: full_python_configs = read_python_configs('linux') @@ -159,7 +159,7 @@ def build(options: BuildOptions) -> None: docker.call([ 'pip', 'wheel', container_package_dir, - '-w', built_wheel_dir, + '--wheel-dir', built_wheel_dir, '--no-deps', *get_build_verbosity_extra_flags(options.build_verbosity) ], env=env) diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py index bce16706..b58d8a95 100644 --- a/cibuildwheel/macos.py +++ b/cibuildwheel/macos.py @@ -233,6 +233,9 @@ def setup_python(python_configuration: PythonConfiguration, # inconsistencies if it's left unset. env.setdefault('MACOSX_DEPLOYMENT_TARGET', '10.9') + config_is_arm64 = python_configuration.identifier.endswith('arm64') + config_is_universal2 = python_configuration.identifier.endswith('universal2') + if python_configuration.version == '3.5': # Cross-compilation platform override - CPython 3.5 has an # i386/x86_64 version of Python, but we only want a x64_64 build @@ -246,18 +249,18 @@ def setup_python(python_configuration: PythonConfiguration, # compatible back to 10.9. env.setdefault('_PYTHON_HOST_PLATFORM', 'macosx-10.9-x86_64') env.setdefault('ARCHFLAGS', '-arch x86_64') - elif python_configuration.identifier.endswith('arm64'): + elif config_is_arm64: # macOS 11 is the first OS with arm64 support, so the wheels # have that as a minimum. env.setdefault('_PYTHON_HOST_PLATFORM', 'macosx-11.0-arm64') env.setdefault('ARCHFLAGS', '-arch arm64') - elif python_configuration.identifier.endswith('universal2'): + elif config_is_universal2: if get_macos_version() < (10, 16): # we can do universal2 builds on macos 10.15, but we need to # set ARCHFLAGS otherwise CPython sets it to `-arch x86_64` env.setdefault('ARCHFLAGS', '-arch arm64 -arch x86_64') - building_arm64 = python_configuration.identifier.endswith('arm64') or python_configuration.identifier.endswith('universal2') + building_arm64 = config_is_arm64 or config_is_universal2 if building_arm64 and get_macos_version() < (10, 16) and 'SDKROOT' not in env: # xcode 12.2 or higher can build arm64 on macos 10.15 or below, but # needs the correct SDK selected. @@ -299,6 +302,9 @@ def build(options: BuildOptions) -> None: for config in python_configurations: log.build_start(config.identifier) + config_is_arm64 = config.identifier.endswith('arm64') + config_is_universal2 = config.identifier.endswith('universal2') + dependency_constraint_flags: Sequence[PathOrStr] = [] if options.dependency_constraints: dependency_constraint_flags = [ @@ -322,7 +328,7 @@ def build(options: BuildOptions) -> None: call([ 'pip', 'wheel', options.package_dir.resolve(), - '-w', built_wheel_dir, + '--wheel-dir', built_wheel_dir, '--no-deps', *get_build_verbosity_extra_flags(options.build_verbosity) ], env=env) @@ -339,9 +345,9 @@ def build(options: BuildOptions) -> None: if options.repair_command: log.step('Repairing wheel...') - if config.identifier.endswith('universal2'): + if config_is_universal2: delocate_archs = 'x86_64,arm64' - elif config.identifier.endswith('arm64'): + elif config_is_arm64: delocate_archs = 'arm64' else: delocate_archs = 'x86_64' @@ -364,28 +370,28 @@ def build(options: BuildOptions) -> None: machine_arch = platform.machine() testing_archs: List[Literal['x86_64', 'arm64']] = [] - if config.identifier.endswith('_arm64'): + if config_is_arm64: testing_archs = ['arm64'] - elif config.identifier.endswith('_universal2'): + elif config_is_universal2: testing_archs = ['x86_64', 'arm64'] else: testing_archs = ['x86_64'] for testing_arch in testing_archs: - if config.identifier.endswith('_universal2'): + if config_is_universal2: arch_specific_identifier = f'{config.identifier}:{testing_arch}' if not options.test_selector(arch_specific_identifier): continue if machine_arch == 'x86_64' and testing_arch == 'arm64': - if config.identifier.endswith('_arm64'): + if config_is_arm64: log.warning(unwrap(''' While arm64 wheels can be built on x86_64, they cannot be tested. The ability to test the arm64 wheels will be added in a future release of cibuildwheel, once Apple Silicon CI runners are widely available. To silence this warning, set `CIBW_TEST_SKIP: *-macosx_arm64`. ''')) - elif config.identifier.endswith('_universal2'): + elif config_is_universal2: log.warning(unwrap(''' While universal2 wheels can be built on x86_64, the arm64 part of them cannot currently be tested. The ability to test the arm64 part of a @@ -440,7 +446,7 @@ def build(options: BuildOptions) -> None: call_with_arch(before_test_prepared, env=virtualenv_env, shell=True) # install the wheel - call_with_arch(['pip', 'install', str(repaired_wheel) + options.test_extras], env=virtualenv_env) + call_with_arch(['pip', 'install', f"{repaired_wheel}{options.test_extras}"], env=virtualenv_env) # test the wheel if options.test_requires: diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py index d91d1984..cff10794 100644 --- a/cibuildwheel/windows.py +++ b/cibuildwheel/windows.py @@ -299,7 +299,7 @@ def build(options: BuildOptions) -> None: before_test_prepared = prepare_command( options.before_test, project='.', - package=options.package_dir + package=options.package_dir, ) shell(before_test_prepared, env=virtualenv_env) @@ -316,7 +316,7 @@ def build(options: BuildOptions) -> None: test_command_prepared = prepare_command( options.test_command, project=Path('.').resolve(), - package=options.package_dir.resolve() + package=options.package_dir.resolve(), ) shell(test_command_prepared, cwd='c:\\', env=virtualenv_env) diff --git a/test/test_before_all.py b/test/test_before_all.py index 1b9ff240..2306fb27 100644 --- a/test/test_before_all.py +++ b/test/test_before_all.py @@ -31,7 +31,7 @@ def test(tmp_path): # write python version information to a temporary file, this is # checked in setup.py 'CIBW_BEFORE_ALL': before_all_command, - 'CIBW_BEFORE_ALL_LINUX': before_all_command + ''' && python -c "import sys; assert sys.version_info >= (3, 6)"''', + 'CIBW_BEFORE_ALL_LINUX': f'{before_all_command} && python -c "import sys; assert sys.version_info >= (3, 6)"', 'CIBW_ENVIRONMENT': "TEST_VAL='123'" })