diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index a409d725b..6c04e4c93 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -334,7 +334,7 @@ def build_in_directory(args: CommandLineArguments) -> None: if not identifiers: message = f"No build identifiers selected: {options.globals.build_selector}" - if args.allow_empty: + if options.globals.allow_empty: print(f"cibuildwheel: {message}", file=sys.stderr) else: raise errors.NothingToDoError(message) diff --git a/cibuildwheel/options.py b/cibuildwheel/options.py index 62094e94d..cb3606798 100644 --- a/cibuildwheel/options.py +++ b/cibuildwheel/options.py @@ -75,6 +75,7 @@ class GlobalOptions: build_selector: BuildSelector test_selector: TestSelector architectures: set[Architecture] + allow_empty: bool @dataclasses.dataclass(frozen=True) @@ -520,6 +521,8 @@ def globals(self) -> GlobalOptions: self.reader.get("free-threaded-support", env_plat=False, ignore_empty=True) ) + allow_empty = args.allow_empty or strtobool(self.env.get("CIBW_ALLOW_EMPTY", "0")) + prerelease_pythons = args.prerelease_pythons or strtobool( self.env.get("CIBW_PRERELEASE_PYTHONS", "0") ) @@ -557,6 +560,7 @@ def globals(self) -> GlobalOptions: build_selector=build_selector, test_selector=test_selector, architectures=architectures, + allow_empty=allow_empty, ) def build_options(self, identifier: str | None) -> BuildOptions: diff --git a/docs/options.md b/docs/options.md index 0906d923b..5cb238784 100644 --- a/docs/options.md +++ b/docs/options.md @@ -621,6 +621,28 @@ This option can also be set using the [command-line option](#command-line) `--pr CIBW_PRERELEASE_PYTHONS: True ``` +### `CIBW_ALLOW_EMPTY` {: #allow-empty} +> Suppress the error code if no wheels match the specified build identifiers + +When none of the specified build identifiers match any available versions, +cibuildwheel will typically return error code 3, indicating that there are +no wheels to build. Enabling this option will suppress this error, allowing +the build process to complete without signaling an error. + +Default: Off (0). Error code 3 is returned when no builds are selected. + +This option can also be set using the [command-line option](#command-line) +`--allow-empty`. This option is not available in the `pyproject.toml` config. + +#### Examples + +!!! tab examples "Environment variables" + + ```yaml + # Prevent an error code if the build does not match any wheels + CIBW_ALLOW_EMPTY: True + ``` + ## Build customization ### `CIBW_BUILD_FRONTEND` {: #build-frontend} @@ -1667,7 +1689,7 @@ cibuildwheel exits 0 on success, or >0 if an error occurs. Specific error codes are defined: - 2 means a configuration error -- 3 means no builds are selected (and --allow-empty wasn't passed) +- 3 means no builds are selected (and [`--allow-empty`](#allow-empty) wasn't passed) - 4 means you specified an option that has been deprecated. diff --git a/test/test_0_basic.py b/test/test_0_basic.py index 0a4a0f046..6663b2da9 100644 --- a/test/test_0_basic.py +++ b/test/test_0_basic.py @@ -69,7 +69,15 @@ def test_build_identifiers(tmp_path): ), f"{expected_wheels} vs {build_identifiers}" -def test_allow_empty(tmp_path): +@pytest.mark.parametrize( + ("add_args", "env_allow_empty"), + [ + (["--allow-empty"], {}), + (["--allow-empty"], {"CIBW_ALLOW_EMPTY": "0"}), + (None, {"CIBW_ALLOW_EMPTY": "1"}), + ], +) +def test_allow_empty(tmp_path, add_args, env_allow_empty): project_dir = tmp_path / "project" basic_project.generate(project_dir) @@ -77,8 +85,8 @@ def test_allow_empty(tmp_path): # without error actual_wheels = utils.cibuildwheel_run( project_dir, - add_env={"CIBW_BUILD": "BUILD_NOTHING_AT_ALL"}, - add_args=["--allow-empty"], + add_env={"CIBW_BUILD": "BUILD_NOTHING_AT_ALL", **env_allow_empty}, + add_args=add_args, ) # check that nothing was built