diff --git a/cibuildwheel/frontend.py b/cibuildwheel/frontend.py index 8e6a2897f..79796a1be 100644 --- a/cibuildwheel/frontend.py +++ b/cibuildwheel/frontend.py @@ -37,14 +37,19 @@ def options_summary(self) -> str | dict[str, str]: def _get_verbosity_flags(level: int, frontend: BuildFrontendName) -> list[str]: - if frontend == "pip": - if level > 0: - return ["-" + level * "v"] - if level < 0: + if level < 0: + if frontend == "pip": return ["-" + -level * "q"] - elif not 0 <= level < 2: + msg = f"build_verbosity {level} is not supported for {frontend} frontend. Ignoring." log.warning(msg) + + if level > 0: + if frontend == "pip": + return ["-" + level * "v"] + if level > 1: + return ["-" + (level - 1) * "v"] + return [] diff --git a/docs/options.md b/docs/options.md index 0c4ade208..fe2adad84 100644 --- a/docs/options.md +++ b/docs/options.md @@ -1760,9 +1760,27 @@ export CIBW_DEBUG_TRACEBACK=TRUE ``` ### `CIBW_BUILD_VERBOSITY` {: #build-verbosity} -> Increase/decrease the output of pip wheel - -A number from 1 to 3 to increase the level of verbosity (corresponding to invoking pip with `-v`, `-vv`, and `-vvv`), between -1 and -3 (`-q`, `-qq`, and `-qqq`), or just 0 (default verbosity). These flags are useful while debugging a build when the output of the actual build invoked by `pip wheel` is required. Has no effect on the `build` backend, which produces verbose output by default. +> Increase/decrease the output of the build + +This setting controls `-v`/`-q` flags to the build frontend. Since there is +no communication between the build backend and the build frontend, build +messages from the build backend will always be shown with `1`; higher levels +will not produce more logging about the build itself. Other levels only affect +the build frontend output, which is usually things like resolving and +downloading dependencies. The settings are: + +| | build | pip | desc | +|-------------|-------|--------|----------------------------------| +| -2 | N/A | `-qq` | even more quiet, where supported | +| -1 | N/A | `-q` | quiet mode, where supported | +| 0 (default) | | | default for build tool | +| 1 | | `-v` | print backend output | +| 2 | `-v` | `-vv` | print log messages e.g. resolving info | +| 3 | `-vv` | `-vvv` | print even more debug info | + +Settings that are not supported for a specific frontend will log a warning. +The default build frontend is `build`, which does show build backend output by +default. Platform-specific environment variables are also available:
`CIBW_BUILD_VERBOSITY_MACOS` | `CIBW_BUILD_VERBOSITY_WINDOWS` | `CIBW_BUILD_VERBOSITY_LINUX` | `CIBW_BUILD_VERBOSITY_IOS` | `CIBW_BUILD_VERBOSITY_PYODIDE` @@ -1772,7 +1790,7 @@ Platform-specific environment variables are also available:
!!! tab examples "Environment variables" ```yaml - # Increase pip debugging output + # Ensure that the build backend output is present CIBW_BUILD_VERBOSITY: 1 ``` @@ -1780,7 +1798,7 @@ Platform-specific environment variables are also available:
```toml [tool.cibuildwheel] - # Increase pip debugging output + # Ensure that the build backend output is present build-verbosity = 1 ``` diff --git a/unit_test/options_test.py b/unit_test/options_test.py index 143f7fdc0..bcf242916 100644 --- a/unit_test/options_test.py +++ b/unit_test/options_test.py @@ -1,12 +1,16 @@ import os import platform as platform_module import textwrap +import unittest.mock from pathlib import Path +from typing import Literal import pytest from cibuildwheel import errors from cibuildwheel.bashlex_eval import local_environment_executor +from cibuildwheel.frontend import BuildFrontendConfig, get_build_frontend_extra_flags +from cibuildwheel.logger import Logger from cibuildwheel.options import ( CommandLineArguments, Options, @@ -570,3 +574,47 @@ def test_deprecated_image( assert f"{resolved_image!r}" in captured.err else: assert "Deprecated image" not in captured.err + + +@pytest.mark.parametrize( + ("frontend", "verbosity", "result"), + [ + ("pip", 3, ["-Ca", "-Cb", "-1", "-vvv"]), + ("pip", 2, ["-Ca", "-Cb", "-1", "-vv"]), + ("pip", -1, ["-Ca", "-Cb", "-1", "-q"]), + ("build", 0, ["-Ca", "-Cb", "-1"]), + ("build", 1, ["-Ca", "-Cb", "-1"]), + ("build", 2, ["-Ca", "-Cb", "-1", "-v"]), + ("build", 3, ["-Ca", "-Cb", "-1", "-vv"]), + ("build[uv]", 3, ["-Ca", "-Cb", "-1", "-vv"]), + ], +) +def test_get_build_frontend_extra_flags( + frontend: Literal["pip", "build", "build[uv]"], + verbosity: int, + result: list[str], + monkeypatch: pytest.MonkeyPatch, +) -> None: + mock_warning = unittest.mock.MagicMock() + monkeypatch.setattr(Logger, "warning", mock_warning) + build_frontend = BuildFrontendConfig(frontend, ["-1"]) + args = get_build_frontend_extra_flags( + build_frontend=build_frontend, verbosity_level=verbosity, config_settings="a b" + ) + + assert args == result + mock_warning.assert_not_called() + + +@pytest.mark.parametrize("frontend", ["build", "build[uv]"]) +def test_get_build_frontend_extra_flags_warning( + frontend: Literal["build", "build[uv]"], monkeypatch: pytest.MonkeyPatch +) -> None: + mock_warning = unittest.mock.MagicMock() + monkeypatch.setattr(Logger, "warning", mock_warning) + build_frontend = BuildFrontendConfig(frontend, ["-1"]) + args = get_build_frontend_extra_flags( + build_frontend=build_frontend, verbosity_level=-1, config_settings="a b" + ) + assert args == ["-Ca", "-Cb", "-1"] + mock_warning.assert_called_once()