Merge pull request #1588 from pypa/frontend-flags
Add the ability to pass extra flags to a build frontend through CIBW_BUILD_FRONTEND
This commit is contained in:
@@ -16,9 +16,9 @@ from .options import Options
|
|||||||
from .typing import PathOrStr
|
from .typing import PathOrStr
|
||||||
from .util import (
|
from .util import (
|
||||||
AlreadyBuiltWheelError,
|
AlreadyBuiltWheelError,
|
||||||
|
BuildFrontendConfig,
|
||||||
BuildSelector,
|
BuildSelector,
|
||||||
NonPlatformWheelError,
|
NonPlatformWheelError,
|
||||||
build_frontend_or_default,
|
|
||||||
find_compatible_wheel,
|
find_compatible_wheel,
|
||||||
get_build_verbosity_extra_flags,
|
get_build_verbosity_extra_flags,
|
||||||
prepare_command,
|
prepare_command,
|
||||||
@@ -177,7 +177,7 @@ def build_in_container(
|
|||||||
for config in platform_configs:
|
for config in platform_configs:
|
||||||
log.build_start(config.identifier)
|
log.build_start(config.identifier)
|
||||||
build_options = options.build_options(config.identifier)
|
build_options = options.build_options(config.identifier)
|
||||||
build_frontend = build_frontend_or_default(build_options.build_frontend)
|
build_frontend = build_options.build_frontend or BuildFrontendConfig("pip")
|
||||||
|
|
||||||
dependency_constraint_flags: list[PathOrStr] = []
|
dependency_constraint_flags: list[PathOrStr] = []
|
||||||
|
|
||||||
@@ -243,9 +243,10 @@ def build_in_container(
|
|||||||
container.call(["rm", "-rf", built_wheel_dir])
|
container.call(["rm", "-rf", built_wheel_dir])
|
||||||
container.call(["mkdir", "-p", built_wheel_dir])
|
container.call(["mkdir", "-p", built_wheel_dir])
|
||||||
|
|
||||||
extra_flags = split_config_settings(build_options.config_settings, build_frontend)
|
extra_flags = split_config_settings(build_options.config_settings, build_frontend.name)
|
||||||
|
extra_flags += build_frontend.args
|
||||||
|
|
||||||
if build_frontend == "pip":
|
if build_frontend.name == "pip":
|
||||||
extra_flags += get_build_verbosity_extra_flags(build_options.build_verbosity)
|
extra_flags += get_build_verbosity_extra_flags(build_options.build_verbosity)
|
||||||
container.call(
|
container.call(
|
||||||
[
|
[
|
||||||
@@ -260,7 +261,7 @@ def build_in_container(
|
|||||||
],
|
],
|
||||||
env=env,
|
env=env,
|
||||||
)
|
)
|
||||||
elif build_frontend == "build":
|
elif build_frontend.name == "build":
|
||||||
if not 0 <= build_options.build_verbosity < 2:
|
if not 0 <= build_options.build_verbosity < 2:
|
||||||
msg = f"build_verbosity {build_options.build_verbosity} is not supported for build frontend. Ignoring."
|
msg = f"build_verbosity {build_options.build_verbosity} is not supported for build frontend. Ignoring."
|
||||||
log.warning(msg)
|
log.warning(msg)
|
||||||
|
|||||||
+11
-8
@@ -25,10 +25,10 @@ from .typing import PathOrStr
|
|||||||
from .util import (
|
from .util import (
|
||||||
CIBW_CACHE_PATH,
|
CIBW_CACHE_PATH,
|
||||||
AlreadyBuiltWheelError,
|
AlreadyBuiltWheelError,
|
||||||
BuildFrontend,
|
BuildFrontendConfig,
|
||||||
|
BuildFrontendName,
|
||||||
BuildSelector,
|
BuildSelector,
|
||||||
NonPlatformWheelError,
|
NonPlatformWheelError,
|
||||||
build_frontend_or_default,
|
|
||||||
call,
|
call,
|
||||||
detect_ci_provider,
|
detect_ci_provider,
|
||||||
download,
|
download,
|
||||||
@@ -165,7 +165,7 @@ def setup_python(
|
|||||||
python_configuration: PythonConfiguration,
|
python_configuration: PythonConfiguration,
|
||||||
dependency_constraint_flags: Sequence[PathOrStr],
|
dependency_constraint_flags: Sequence[PathOrStr],
|
||||||
environment: ParsedEnvironment,
|
environment: ParsedEnvironment,
|
||||||
build_frontend: BuildFrontend,
|
build_frontend: BuildFrontendName,
|
||||||
) -> dict[str, str]:
|
) -> dict[str, str]:
|
||||||
tmp.mkdir()
|
tmp.mkdir()
|
||||||
implementation_id = python_configuration.identifier.split("-")[0]
|
implementation_id = python_configuration.identifier.split("-")[0]
|
||||||
@@ -334,7 +334,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
|||||||
|
|
||||||
for config in python_configurations:
|
for config in python_configurations:
|
||||||
build_options = options.build_options(config.identifier)
|
build_options = options.build_options(config.identifier)
|
||||||
build_frontend = build_frontend_or_default(build_options.build_frontend)
|
build_frontend = build_options.build_frontend or BuildFrontendConfig("pip")
|
||||||
log.build_start(config.identifier)
|
log.build_start(config.identifier)
|
||||||
|
|
||||||
identifier_tmp_dir = tmp_path / config.identifier
|
identifier_tmp_dir = tmp_path / config.identifier
|
||||||
@@ -357,7 +357,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
|||||||
config,
|
config,
|
||||||
dependency_constraint_flags,
|
dependency_constraint_flags,
|
||||||
build_options.environment,
|
build_options.environment,
|
||||||
build_frontend,
|
build_frontend.name,
|
||||||
)
|
)
|
||||||
|
|
||||||
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
|
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
|
||||||
@@ -378,9 +378,12 @@ def build(options: Options, tmp_path: Path) -> None:
|
|||||||
log.step("Building wheel...")
|
log.step("Building wheel...")
|
||||||
built_wheel_dir.mkdir()
|
built_wheel_dir.mkdir()
|
||||||
|
|
||||||
extra_flags = split_config_settings(build_options.config_settings, build_frontend)
|
extra_flags = split_config_settings(
|
||||||
|
build_options.config_settings, build_frontend.name
|
||||||
|
)
|
||||||
|
extra_flags += build_frontend.args
|
||||||
|
|
||||||
if build_frontend == "pip":
|
if build_frontend.name == "pip":
|
||||||
extra_flags += get_build_verbosity_extra_flags(build_options.build_verbosity)
|
extra_flags += get_build_verbosity_extra_flags(build_options.build_verbosity)
|
||||||
# Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org
|
# Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org
|
||||||
# see https://github.com/pypa/cibuildwheel/pull/369
|
# see https://github.com/pypa/cibuildwheel/pull/369
|
||||||
@@ -395,7 +398,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
|||||||
*extra_flags,
|
*extra_flags,
|
||||||
env=env,
|
env=env,
|
||||||
)
|
)
|
||||||
elif build_frontend == "build":
|
elif build_frontend.name == "build":
|
||||||
if not 0 <= build_options.build_verbosity < 2:
|
if not 0 <= build_options.build_verbosity < 2:
|
||||||
msg = f"build_verbosity {build_options.build_verbosity} is not supported for build frontend. Ignoring."
|
msg = f"build_verbosity {build_options.build_verbosity} is not supported for build frontend. Ignoring."
|
||||||
log.warning(msg)
|
log.warning(msg)
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ class OCIContainerEngineConfig:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_config_string(config_string: str) -> OCIContainerEngineConfig:
|
def from_config_string(config_string: str) -> OCIContainerEngineConfig:
|
||||||
config_dict = parse_key_value_string(config_string, ["name"])
|
config_dict = parse_key_value_string(
|
||||||
|
config_string, ["name"], ["create_args", "create-args"]
|
||||||
|
)
|
||||||
name = " ".join(config_dict["name"])
|
name = " ".join(config_dict["name"])
|
||||||
if name not in {"docker", "podman"}:
|
if name not in {"docker", "podman"}:
|
||||||
msg = f"unknown container engine {name}"
|
msg = f"unknown container engine {name}"
|
||||||
|
|||||||
+15
-13
@@ -27,7 +27,7 @@ from .typing import PLATFORMS, PlatformName
|
|||||||
from .util import (
|
from .util import (
|
||||||
MANYLINUX_ARCHS,
|
MANYLINUX_ARCHS,
|
||||||
MUSLLINUX_ARCHS,
|
MUSLLINUX_ARCHS,
|
||||||
BuildFrontend,
|
BuildFrontendConfig,
|
||||||
BuildSelector,
|
BuildSelector,
|
||||||
DependencyConstraints,
|
DependencyConstraints,
|
||||||
TestSelector,
|
TestSelector,
|
||||||
@@ -92,7 +92,7 @@ class BuildOptions:
|
|||||||
test_requires: list[str]
|
test_requires: list[str]
|
||||||
test_extras: str
|
test_extras: str
|
||||||
build_verbosity: int
|
build_verbosity: int
|
||||||
build_frontend: BuildFrontend | Literal["default"]
|
build_frontend: BuildFrontendConfig | None
|
||||||
config_settings: str
|
config_settings: str
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -488,7 +488,6 @@ class Options:
|
|||||||
with self.reader.identifier(identifier):
|
with self.reader.identifier(identifier):
|
||||||
before_all = self.reader.get("before-all", sep=" && ")
|
before_all = self.reader.get("before-all", sep=" && ")
|
||||||
|
|
||||||
build_frontend_str = self.reader.get("build-frontend", env_plat=False)
|
|
||||||
environment_config = self.reader.get(
|
environment_config = self.reader.get(
|
||||||
"environment", table={"item": '{k}="{v}"', "sep": " "}
|
"environment", table={"item": '{k}="{v}"', "sep": " "}
|
||||||
)
|
)
|
||||||
@@ -506,17 +505,20 @@ class Options:
|
|||||||
test_extras = self.reader.get("test-extras", sep=",")
|
test_extras = self.reader.get("test-extras", sep=",")
|
||||||
build_verbosity_str = self.reader.get("build-verbosity")
|
build_verbosity_str = self.reader.get("build-verbosity")
|
||||||
|
|
||||||
build_frontend: BuildFrontend | Literal["default"]
|
build_frontend_str = self.reader.get(
|
||||||
if build_frontend_str == "build":
|
"build-frontend",
|
||||||
build_frontend = "build"
|
env_plat=False,
|
||||||
elif build_frontend_str == "pip":
|
table={"item": "{k}:{v}", "sep": "; ", "quote": shlex.quote},
|
||||||
build_frontend = "pip"
|
)
|
||||||
elif build_frontend_str == "default":
|
build_frontend: BuildFrontendConfig | None
|
||||||
build_frontend = "default"
|
if not build_frontend_str or build_frontend_str == "default":
|
||||||
|
build_frontend = None
|
||||||
else:
|
else:
|
||||||
msg = f"cibuildwheel: Unrecognised build frontend {build_frontend_str!r}, only 'pip' and 'build' are supported"
|
try:
|
||||||
print(msg, file=sys.stderr)
|
build_frontend = BuildFrontendConfig.from_config_string(build_frontend_str)
|
||||||
sys.exit(2)
|
except ValueError as e:
|
||||||
|
print(f"cibuildwheel: {e}", file=sys.stderr)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
environment = parse_environment(environment_config)
|
environment = parse_environment(environment_config)
|
||||||
|
|||||||
+38
-11
@@ -57,16 +57,6 @@ install_certifi_script: Final[Path] = resources_dir / "install_certifi.py"
|
|||||||
|
|
||||||
test_fail_cwd_file: Final[Path] = resources_dir / "testing_temp_dir_file.py"
|
test_fail_cwd_file: Final[Path] = resources_dir / "testing_temp_dir_file.py"
|
||||||
|
|
||||||
BuildFrontend = Literal["pip", "build"]
|
|
||||||
|
|
||||||
|
|
||||||
def build_frontend_or_default(
|
|
||||||
setting: BuildFrontend | Literal["default"], default: BuildFrontend = "pip"
|
|
||||||
) -> BuildFrontend:
|
|
||||||
if setting == "default":
|
|
||||||
return default
|
|
||||||
return setting
|
|
||||||
|
|
||||||
|
|
||||||
MANYLINUX_ARCHS: Final[tuple[str, ...]] = (
|
MANYLINUX_ARCHS: Final[tuple[str, ...]] = (
|
||||||
"x86_64",
|
"x86_64",
|
||||||
@@ -376,6 +366,34 @@ class DependencyConstraints:
|
|||||||
return self.base_file_path.name
|
return self.base_file_path.name
|
||||||
|
|
||||||
|
|
||||||
|
BuildFrontendName = Literal["pip", "build"]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class BuildFrontendConfig:
|
||||||
|
name: BuildFrontendName
|
||||||
|
args: Sequence[str] = ()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_config_string(config_string: str) -> BuildFrontendConfig:
|
||||||
|
config_dict = parse_key_value_string(config_string, ["name"], ["args"])
|
||||||
|
name = " ".join(config_dict["name"])
|
||||||
|
if name not in {"pip", "build"}:
|
||||||
|
msg = f"Unrecognised build frontend {name}, only 'pip' and 'build' are supported"
|
||||||
|
raise ValueError(msg)
|
||||||
|
|
||||||
|
name = typing.cast(BuildFrontendName, name)
|
||||||
|
|
||||||
|
args = config_dict.get("args") or []
|
||||||
|
return BuildFrontendConfig(name=name, args=args)
|
||||||
|
|
||||||
|
def options_summary(self) -> str | dict[str, str]:
|
||||||
|
if not self.args:
|
||||||
|
return self.name
|
||||||
|
else:
|
||||||
|
return {"name": self.name, "args": repr(self.args)}
|
||||||
|
|
||||||
|
|
||||||
class NonPlatformWheelError(Exception):
|
class NonPlatformWheelError(Exception):
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
message = textwrap.dedent(
|
message = textwrap.dedent(
|
||||||
@@ -699,13 +717,19 @@ def fix_ansi_codes_for_github_actions(text: str) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def parse_key_value_string(
|
def parse_key_value_string(
|
||||||
key_value_string: str, positional_arg_names: list[str] | None = None
|
key_value_string: str,
|
||||||
|
positional_arg_names: Sequence[str] | None = None,
|
||||||
|
kw_arg_names: Sequence[str] | None = None,
|
||||||
) -> dict[str, list[str]]:
|
) -> dict[str, list[str]]:
|
||||||
"""
|
"""
|
||||||
Parses a string like "docker; create_args: --some-option=value another-option"
|
Parses a string like "docker; create_args: --some-option=value another-option"
|
||||||
"""
|
"""
|
||||||
if positional_arg_names is None:
|
if positional_arg_names is None:
|
||||||
positional_arg_names = []
|
positional_arg_names = []
|
||||||
|
if kw_arg_names is None:
|
||||||
|
kw_arg_names = []
|
||||||
|
|
||||||
|
all_field_names = [*positional_arg_names, *kw_arg_names]
|
||||||
|
|
||||||
shlexer = shlex.shlex(key_value_string, posix=True, punctuation_chars=";:")
|
shlexer = shlex.shlex(key_value_string, posix=True, punctuation_chars=";:")
|
||||||
shlexer.commenters = ""
|
shlexer.commenters = ""
|
||||||
@@ -721,6 +745,9 @@ def parse_key_value_string(
|
|||||||
if len(field) > 1 and field[1] == ":":
|
if len(field) > 1 and field[1] == ":":
|
||||||
field_name = field[0]
|
field_name = field[0]
|
||||||
values = field[2:]
|
values = field[2:]
|
||||||
|
if field_name not in all_field_names:
|
||||||
|
msg = f"Failed to parse {key_value_string!r}. Unknown field name {field_name!r}"
|
||||||
|
raise ValueError(msg)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
field_name = positional_arg_names[field_i]
|
field_name = positional_arg_names[field_i]
|
||||||
|
|||||||
+11
-8
@@ -25,10 +25,10 @@ from .typing import PathOrStr
|
|||||||
from .util import (
|
from .util import (
|
||||||
CIBW_CACHE_PATH,
|
CIBW_CACHE_PATH,
|
||||||
AlreadyBuiltWheelError,
|
AlreadyBuiltWheelError,
|
||||||
BuildFrontend,
|
BuildFrontendConfig,
|
||||||
|
BuildFrontendName,
|
||||||
BuildSelector,
|
BuildSelector,
|
||||||
NonPlatformWheelError,
|
NonPlatformWheelError,
|
||||||
build_frontend_or_default,
|
|
||||||
call,
|
call,
|
||||||
download,
|
download,
|
||||||
find_compatible_wheel,
|
find_compatible_wheel,
|
||||||
@@ -216,7 +216,7 @@ def setup_python(
|
|||||||
python_configuration: PythonConfiguration,
|
python_configuration: PythonConfiguration,
|
||||||
dependency_constraint_flags: Sequence[PathOrStr],
|
dependency_constraint_flags: Sequence[PathOrStr],
|
||||||
environment: ParsedEnvironment,
|
environment: ParsedEnvironment,
|
||||||
build_frontend: BuildFrontend,
|
build_frontend: BuildFrontendName,
|
||||||
) -> dict[str, str]:
|
) -> dict[str, str]:
|
||||||
tmp.mkdir()
|
tmp.mkdir()
|
||||||
implementation_id = python_configuration.identifier.split("-")[0]
|
implementation_id = python_configuration.identifier.split("-")[0]
|
||||||
@@ -369,7 +369,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
|||||||
|
|
||||||
for config in python_configurations:
|
for config in python_configurations:
|
||||||
build_options = options.build_options(config.identifier)
|
build_options = options.build_options(config.identifier)
|
||||||
build_frontend = build_frontend_or_default(build_options.build_frontend)
|
build_frontend = build_options.build_frontend or BuildFrontendConfig("pip")
|
||||||
log.build_start(config.identifier)
|
log.build_start(config.identifier)
|
||||||
|
|
||||||
identifier_tmp_dir = tmp_path / config.identifier
|
identifier_tmp_dir = tmp_path / config.identifier
|
||||||
@@ -390,7 +390,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
|||||||
config,
|
config,
|
||||||
dependency_constraint_flags,
|
dependency_constraint_flags,
|
||||||
build_options.environment,
|
build_options.environment,
|
||||||
build_frontend,
|
build_frontend.name,
|
||||||
)
|
)
|
||||||
|
|
||||||
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
|
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
|
||||||
@@ -414,9 +414,12 @@ def build(options: Options, tmp_path: Path) -> None:
|
|||||||
log.step("Building wheel...")
|
log.step("Building wheel...")
|
||||||
built_wheel_dir.mkdir()
|
built_wheel_dir.mkdir()
|
||||||
|
|
||||||
extra_flags = split_config_settings(build_options.config_settings, build_frontend)
|
extra_flags = split_config_settings(
|
||||||
|
build_options.config_settings, build_frontend.name
|
||||||
|
)
|
||||||
|
extra_flags += build_frontend.args
|
||||||
|
|
||||||
if build_frontend == "pip":
|
if build_frontend.name == "pip":
|
||||||
extra_flags += get_build_verbosity_extra_flags(build_options.build_verbosity)
|
extra_flags += get_build_verbosity_extra_flags(build_options.build_verbosity)
|
||||||
# Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org
|
# Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org
|
||||||
# see https://github.com/pypa/cibuildwheel/pull/369
|
# see https://github.com/pypa/cibuildwheel/pull/369
|
||||||
@@ -431,7 +434,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
|||||||
*extra_flags,
|
*extra_flags,
|
||||||
env=env,
|
env=env,
|
||||||
)
|
)
|
||||||
elif build_frontend == "build":
|
elif build_frontend.name == "build":
|
||||||
if not 0 <= build_options.build_verbosity < 2:
|
if not 0 <= build_options.build_verbosity < 2:
|
||||||
msg = f"build_verbosity {build_options.build_verbosity} is not supported for build frontend. Ignoring."
|
msg = f"build_verbosity {build_options.build_verbosity} is not supported for build frontend. Ignoring."
|
||||||
log.warning(msg)
|
log.warning(msg)
|
||||||
|
|||||||
+17
-1
@@ -504,9 +504,19 @@ This option can also be set using the [command-line option](#command-line) `--pr
|
|||||||
### `CIBW_BUILD_FRONTEND` {: #build-frontend}
|
### `CIBW_BUILD_FRONTEND` {: #build-frontend}
|
||||||
> Set the tool to use to build, either "pip" (default for now) or "build"
|
> Set the tool to use to build, either "pip" (default for now) or "build"
|
||||||
|
|
||||||
Choose which build backend to use. Can either be "pip", which will run
|
Options:
|
||||||
|
|
||||||
|
- `pip[;args: ...]`
|
||||||
|
- `build[;args: ...]`
|
||||||
|
|
||||||
|
Default: `pip`
|
||||||
|
|
||||||
|
Choose which build frontend to use. Can either be "pip", which will run
|
||||||
`python -m pip wheel`, or "build", which will run `python -m build --wheel`.
|
`python -m pip wheel`, or "build", which will run `python -m build --wheel`.
|
||||||
|
|
||||||
|
You can specify extra arguments to pass to `pip wheel` or `build` using the
|
||||||
|
optional `args` option.
|
||||||
|
|
||||||
!!! tip
|
!!! tip
|
||||||
Until v2.0.0, [pip] was the only way to build wheels, and is still the
|
Until v2.0.0, [pip] was the only way to build wheels, and is still the
|
||||||
default. However, we expect that at some point in the future, cibuildwheel
|
default. However, we expect that at some point in the future, cibuildwheel
|
||||||
@@ -526,6 +536,9 @@ Choose which build backend to use. Can either be "pip", which will run
|
|||||||
|
|
||||||
# Ensure pip is used even if the default changes in the future
|
# Ensure pip is used even if the default changes in the future
|
||||||
CIBW_BUILD_FRONTEND: "pip"
|
CIBW_BUILD_FRONTEND: "pip"
|
||||||
|
|
||||||
|
# supply an extra argument to 'pip wheel'
|
||||||
|
CIBW_BUILD_FRONTEND: "pip; args: --no-build-isolation"
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! tab examples "pyproject.toml"
|
!!! tab examples "pyproject.toml"
|
||||||
@@ -537,6 +550,9 @@ Choose which build backend to use. Can either be "pip", which will run
|
|||||||
|
|
||||||
# Ensure pip is used even if the default changes in the future
|
# Ensure pip is used even if the default changes in the future
|
||||||
build-frontend = "pip"
|
build-frontend = "pip"
|
||||||
|
|
||||||
|
# supply an extra argument to 'pip wheel'
|
||||||
|
build-frontend = { name = "pip", args = ["--no-build-isolation"] }
|
||||||
```
|
```
|
||||||
|
|
||||||
### `CIBW_CONFIG_SETTINGS` {: #config-settings}
|
### `CIBW_CONFIG_SETTINGS` {: #config-settings}
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import subprocess
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from . import utils
|
||||||
|
from .test_projects.c import new_c_project
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("frontend_name", ["pip", "build"])
|
||||||
|
def test_build_frontend_args(tmp_path, capfd, frontend_name):
|
||||||
|
project = new_c_project()
|
||||||
|
project_dir = tmp_path / "project"
|
||||||
|
project.generate(project_dir)
|
||||||
|
|
||||||
|
# the build will fail because the frontend is called with '-h' - it prints the help message
|
||||||
|
with pytest.raises(subprocess.CalledProcessError):
|
||||||
|
utils.cibuildwheel_run(
|
||||||
|
project_dir,
|
||||||
|
add_env={
|
||||||
|
"CIBW_BUILD": "cp311-*",
|
||||||
|
"CIBW_BUILD_FRONTEND": f"{frontend_name}; args: -h",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
captured = capfd.readouterr()
|
||||||
|
print(captured.out)
|
||||||
|
|
||||||
|
# check that the help message was printed
|
||||||
|
if frontend_name == "pip":
|
||||||
|
assert "Usage:" in captured.out
|
||||||
|
assert "Wheel Options:" in captured.out
|
||||||
|
else:
|
||||||
|
assert "usage:" in captured.out
|
||||||
|
assert "A simple, correct Python build frontend." in captured.out
|
||||||
@@ -365,7 +365,7 @@ def test_defaults(platform, intercepted_build_args):
|
|||||||
if isinstance(repair_wheel_default, list):
|
if isinstance(repair_wheel_default, list):
|
||||||
repair_wheel_default = " && ".join(repair_wheel_default)
|
repair_wheel_default = " && ".join(repair_wheel_default)
|
||||||
assert build_options.repair_command == repair_wheel_default
|
assert build_options.repair_command == repair_wheel_default
|
||||||
assert build_options.build_frontend == defaults["build-frontend"]
|
assert build_options.build_frontend is None
|
||||||
|
|
||||||
if platform == "linux":
|
if platform == "linux":
|
||||||
assert build_options.manylinux_images
|
assert build_options.manylinux_images
|
||||||
|
|||||||
@@ -253,3 +253,57 @@ def test_container_engine_option(tmp_path: Path, toml_assignment, result_name, r
|
|||||||
|
|
||||||
assert parsed_container_engine.name == result_name
|
assert parsed_container_engine.name == result_name
|
||||||
assert parsed_container_engine.create_args == result_create_args
|
assert parsed_container_engine.create_args == result_create_args
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("toml_assignment", "result_name", "result_args"),
|
||||||
|
[
|
||||||
|
(
|
||||||
|
"",
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'build-frontend = "build"',
|
||||||
|
"build",
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'build-frontend = {name = "build"}',
|
||||||
|
"build",
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'build-frontend = "pip; args: --some-option"',
|
||||||
|
"pip",
|
||||||
|
["--some-option"],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'build-frontend = {name = "pip", args = ["--some-option"]}',
|
||||||
|
"pip",
|
||||||
|
["--some-option"],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_build_frontend_option(tmp_path: Path, toml_assignment, result_name, result_args):
|
||||||
|
args = CommandLineArguments.defaults()
|
||||||
|
args.package_dir = tmp_path
|
||||||
|
|
||||||
|
tmp_path.joinpath("pyproject.toml").write_text(
|
||||||
|
textwrap.dedent(
|
||||||
|
f"""\
|
||||||
|
[tool.cibuildwheel]
|
||||||
|
{toml_assignment}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
options = Options(platform="linux", command_line_arguments=args, env={})
|
||||||
|
parsed_build_frontend = options.build_options(identifier=None).build_frontend
|
||||||
|
|
||||||
|
if toml_assignment:
|
||||||
|
assert parsed_build_frontend is not None
|
||||||
|
assert parsed_build_frontend.name == result_name
|
||||||
|
assert parsed_build_frontend.args == result_args
|
||||||
|
else:
|
||||||
|
assert parsed_build_frontend is None
|
||||||
|
|||||||
Reference in New Issue
Block a user