686 lines
22 KiB
Python
686 lines
22 KiB
Python
from __future__ import annotations
|
|
|
|
import sys
|
|
import tomllib
|
|
from fnmatch import fnmatch
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from cibuildwheel.__main__ import main
|
|
from cibuildwheel.environment import ParsedEnvironment
|
|
from cibuildwheel.frontend import _split_config_settings, parse_config_settings
|
|
from cibuildwheel.options import BuildOptions, _get_pinned_container_images
|
|
from cibuildwheel.selector import BuildSelector, EnableGroup
|
|
from cibuildwheel.util import resources
|
|
from cibuildwheel.util.packaging import DependencyConstraints
|
|
|
|
TYPE_CHECKING = False
|
|
if TYPE_CHECKING:
|
|
from collections.abc import Mapping
|
|
|
|
from .conftest import ArgsInterceptor
|
|
|
|
# CIBW_PLATFORM is tested in main_platform_test.py
|
|
|
|
|
|
def test_old_free_threaded(
|
|
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
|
|
) -> None:
|
|
monkeypatch.setenv("CIBW_FREE_THREADED_SUPPORT", "ON")
|
|
|
|
with pytest.raises(SystemExit):
|
|
main()
|
|
|
|
assert (
|
|
"CIBW_FREE_THREADED_SUPPORT environment variable is no longer supported."
|
|
in capsys.readouterr().err
|
|
)
|
|
|
|
|
|
@pytest.mark.usefixtures("platform")
|
|
def test_output_dir(
|
|
intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
OUTPUT_DIR = Path("some_output_dir")
|
|
|
|
monkeypatch.setenv("CIBW_OUTPUT_DIR", str(OUTPUT_DIR))
|
|
|
|
main()
|
|
|
|
assert intercepted_build_args.args[0].globals.output_dir == OUTPUT_DIR.resolve()
|
|
|
|
|
|
@pytest.mark.usefixtures("platform")
|
|
def test_output_dir_default(intercepted_build_args: ArgsInterceptor) -> None:
|
|
main()
|
|
|
|
assert intercepted_build_args.args[0].globals.output_dir == Path("wheelhouse").resolve()
|
|
|
|
|
|
@pytest.mark.usefixtures("platform")
|
|
@pytest.mark.parametrize("also_set_environment", [False, True])
|
|
def test_output_dir_argument(
|
|
also_set_environment: bool,
|
|
intercepted_build_args: ArgsInterceptor,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
OUTPUT_DIR = Path("some_output_dir")
|
|
|
|
monkeypatch.setattr(sys, "argv", [*sys.argv, "--output-dir", str(OUTPUT_DIR)])
|
|
if also_set_environment:
|
|
monkeypatch.setenv("CIBW_OUTPUT_DIR", "not_this_output_dir")
|
|
|
|
main()
|
|
|
|
assert intercepted_build_args.args[0].globals.output_dir == OUTPUT_DIR.resolve()
|
|
|
|
|
|
@pytest.mark.usefixtures("platform", "allow_empty")
|
|
def test_build_selector(
|
|
intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
monkeypatch.setenv("CIBW_BUILD", "cp313-*")
|
|
monkeypatch.setenv("CIBW_SKIP", "cp39-*")
|
|
|
|
main()
|
|
|
|
intercepted_build_selector = intercepted_build_args.args[0].globals.build_selector
|
|
assert isinstance(intercepted_build_selector, BuildSelector)
|
|
assert intercepted_build_selector("cp313-something-to-build")
|
|
assert not intercepted_build_selector("cp39-something-to-skip")
|
|
# This unit test is just testing the options of 'main'
|
|
# Unit tests for BuildSelector are in build_selector_test.py
|
|
|
|
|
|
@pytest.mark.usefixtures("platform", "allow_empty")
|
|
def test_invalid_build_selector(
|
|
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
|
|
) -> None:
|
|
monkeypatch.setenv("CIBW_BUILD", "invalid")
|
|
|
|
with pytest.raises(SystemExit) as e:
|
|
main()
|
|
|
|
assert e.value.code == 2
|
|
_, err = capsys.readouterr()
|
|
assert "Invalid build selector" in err
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("option_name", "option_env_var"),
|
|
[
|
|
("skip", "CIBW_SKIP"),
|
|
("test_skip", "CIBW_TEST_SKIP"),
|
|
],
|
|
)
|
|
@pytest.mark.usefixtures("platform", "intercepted_build_args")
|
|
def test_invalid_skip_selector(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
capsys: pytest.CaptureFixture[str],
|
|
option_name: str,
|
|
option_env_var: str,
|
|
) -> None:
|
|
monkeypatch.setenv(option_env_var, "invalid")
|
|
|
|
main()
|
|
|
|
_, err = capsys.readouterr()
|
|
print(err)
|
|
assert f"Invalid {option_name} selector" in err
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"selector", ["*-macosx_universal2:arm64", "*-macosx_universal2:x86_64", "*-macosx_arm64"]
|
|
)
|
|
@pytest.mark.usefixtures("platform", "intercepted_build_args")
|
|
def test_valid_test_skip_selector(
|
|
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str], selector: str
|
|
) -> None:
|
|
monkeypatch.setenv("CIBW_TEST_SKIP", selector)
|
|
|
|
main()
|
|
|
|
_, err = capsys.readouterr()
|
|
print(err)
|
|
assert "Invalid test_skip selector" not in err
|
|
|
|
|
|
@pytest.mark.parametrize("selector", ["*-macosx_universal2:invalid", "*-macosx_arm64:arm64"])
|
|
@pytest.mark.usefixtures("platform", "intercepted_build_args")
|
|
def test_invalid_test_skip_selector(
|
|
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str], selector: str
|
|
) -> None:
|
|
monkeypatch.setenv("CIBW_TEST_SKIP", selector)
|
|
|
|
main()
|
|
|
|
_, err = capsys.readouterr()
|
|
print(err)
|
|
assert "Invalid test_skip selector" in err
|
|
|
|
|
|
@pytest.mark.usefixtures("platform", "intercepted_build_args")
|
|
def test_empty_selector(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
monkeypatch.setenv("CIBW_SKIP", "*")
|
|
|
|
with pytest.raises(SystemExit) as e:
|
|
main()
|
|
|
|
assert e.value.code == 3
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("architecture", "image", "full_image"),
|
|
[
|
|
("x86_64", None, "quay.io/pypa/manylinux_2_28_x86_64@*"),
|
|
("x86_64", "manylinux2014", "quay.io/pypa/manylinux2014_x86_64@*"),
|
|
("x86_64", "manylinux_2_28", "quay.io/pypa/manylinux_2_28_x86_64@*"),
|
|
("x86_64", "manylinux_2_34", "quay.io/pypa/manylinux_2_34_x86_64@*"),
|
|
("x86_64", "custom_image", "custom_image"),
|
|
("i686", None, "quay.io/pypa/manylinux_2_28_i686@*"),
|
|
("i686", "manylinux2014", "quay.io/pypa/manylinux2014_i686@*"),
|
|
("i686", "manylinux_2_28", "quay.io/pypa/manylinux_2_28_i686@*"),
|
|
("i686", "custom_image", "custom_image"),
|
|
("pypy_x86_64", None, "quay.io/pypa/manylinux_2_28_x86_64@*"),
|
|
("pypy_x86_64", "manylinux2014", "quay.io/pypa/manylinux2014_x86_64@*"),
|
|
("pypy_x86_64", "manylinux_2_28", "quay.io/pypa/manylinux_2_28_x86_64@*"),
|
|
("pypy_x86_64", "manylinux_2_34", "quay.io/pypa/manylinux_2_34_x86_64@*"),
|
|
("pypy_x86_64", "custom_image", "custom_image"),
|
|
],
|
|
)
|
|
def test_manylinux_images(
|
|
architecture: str,
|
|
image: str | None,
|
|
full_image: str,
|
|
platform: str,
|
|
intercepted_build_args: ArgsInterceptor,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
if image is not None:
|
|
monkeypatch.setenv("CIBW_MANYLINUX_" + architecture.upper() + "_IMAGE", image)
|
|
|
|
main()
|
|
|
|
build_options = intercepted_build_args.args[0].build_options(identifier=None)
|
|
|
|
if platform == "linux":
|
|
assert fnmatch(
|
|
build_options.manylinux_images[architecture],
|
|
full_image,
|
|
)
|
|
else:
|
|
assert build_options.manylinux_images is None
|
|
|
|
|
|
def get_default_repair_command(platform: str) -> str:
|
|
if platform == "linux":
|
|
return "auditwheel repair -w {dest_dir} {wheel}"
|
|
elif platform == "macos":
|
|
return "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}"
|
|
elif platform == "windows":
|
|
return "delvewheel repair -w {dest_dir} -v {wheel}"
|
|
elif platform == "pyodide":
|
|
return ""
|
|
else:
|
|
msg = f"Unknown platform: {platform!r}"
|
|
raise ValueError(msg)
|
|
|
|
|
|
@pytest.mark.parametrize("repair_command", [None, "", "repair", "repair -w {dest_dir} {wheel}"])
|
|
@pytest.mark.parametrize("platform_specific", [False, True])
|
|
def test_repair_command(
|
|
repair_command: str | None,
|
|
platform_specific: bool,
|
|
platform: str,
|
|
intercepted_build_args: ArgsInterceptor,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
if repair_command is not None:
|
|
if platform_specific:
|
|
monkeypatch.setenv("CIBW_REPAIR_WHEEL_COMMAND_" + platform.upper(), repair_command)
|
|
monkeypatch.setenv("CIBW_REPAIR_WHEEL_COMMAND", "overwritten")
|
|
else:
|
|
monkeypatch.setenv("CIBW_REPAIR_WHEEL_COMMAND", repair_command)
|
|
|
|
main()
|
|
|
|
build_options = intercepted_build_args.args[0].build_options(identifier=None)
|
|
|
|
expected_repair = (
|
|
get_default_repair_command(platform) if repair_command is None else repair_command
|
|
)
|
|
assert build_options.repair_command == expected_repair
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"environment",
|
|
[{}, {"something": "value"}, {"something": "value", "something_else": "other_value"}],
|
|
)
|
|
@pytest.mark.parametrize("platform_specific", [False, True])
|
|
def test_environment(
|
|
environment: Mapping[str, str],
|
|
platform_specific: bool,
|
|
platform: str,
|
|
intercepted_build_args: ArgsInterceptor,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
env_string = " ".join(f"{k}={v}" for k, v in environment.items())
|
|
if platform_specific:
|
|
monkeypatch.setenv("CIBW_ENVIRONMENT_" + platform.upper(), env_string)
|
|
monkeypatch.setenv("CIBW_ENVIRONMENT", "overwritten")
|
|
else:
|
|
monkeypatch.setenv("CIBW_ENVIRONMENT", env_string)
|
|
|
|
main()
|
|
|
|
build_options = intercepted_build_args.args[0].build_options(identifier=None)
|
|
intercepted_environment = build_options.environment
|
|
|
|
assert isinstance(intercepted_environment, ParsedEnvironment)
|
|
assert intercepted_environment.as_dictionary(prev_environment={}) == environment
|
|
|
|
|
|
@pytest.mark.parametrize("test_requires", [None, "requirement other_requirement"])
|
|
@pytest.mark.parametrize("platform_specific", [False, True])
|
|
def test_test_requires(
|
|
test_requires: str | None,
|
|
platform_specific: bool,
|
|
platform: str,
|
|
intercepted_build_args: ArgsInterceptor,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
if test_requires is not None:
|
|
if platform_specific:
|
|
monkeypatch.setenv("CIBW_TEST_REQUIRES_" + platform.upper(), test_requires)
|
|
monkeypatch.setenv("CIBW_TEST_REQUIRES", "overwritten")
|
|
else:
|
|
monkeypatch.setenv("CIBW_TEST_REQUIRES", test_requires)
|
|
|
|
main()
|
|
|
|
build_options = intercepted_build_args.args[0].build_options(identifier=None)
|
|
|
|
assert build_options.test_requires == (test_requires or "").split()
|
|
|
|
|
|
@pytest.mark.parametrize("audit_requires", [None, "abi3audit", "abi3audit custom-audit-tool"])
|
|
@pytest.mark.parametrize("platform_specific", [False, True])
|
|
def test_audit_requires(
|
|
audit_requires: str | None,
|
|
platform_specific: bool,
|
|
platform: str,
|
|
intercepted_build_args: ArgsInterceptor,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
if audit_requires is not None:
|
|
if platform_specific:
|
|
monkeypatch.setenv("CIBW_AUDIT_REQUIRES_" + platform.upper(), audit_requires)
|
|
monkeypatch.setenv("CIBW_AUDIT_REQUIRES", "overwritten")
|
|
else:
|
|
monkeypatch.setenv("CIBW_AUDIT_REQUIRES", audit_requires)
|
|
|
|
main()
|
|
|
|
build_options = intercepted_build_args.args[0].build_options(identifier=None)
|
|
|
|
expected = (audit_requires or "abi3audit").split()
|
|
assert build_options.audit_requires == expected
|
|
|
|
|
|
@pytest.mark.parametrize("test_extras", [None, "extras"])
|
|
@pytest.mark.parametrize("platform_specific", [False, True])
|
|
def test_test_extras(
|
|
test_extras: str | None,
|
|
platform_specific: bool,
|
|
platform: str,
|
|
intercepted_build_args: ArgsInterceptor,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
if test_extras is not None:
|
|
if platform_specific:
|
|
monkeypatch.setenv("CIBW_TEST_EXTRAS_" + platform.upper(), test_extras)
|
|
monkeypatch.setenv("CIBW_TEST_EXTRAS", "overwritten")
|
|
else:
|
|
monkeypatch.setenv("CIBW_TEST_EXTRAS", test_extras)
|
|
|
|
main()
|
|
|
|
build_options = intercepted_build_args.args[0].build_options(identifier=None)
|
|
|
|
assert build_options.test_extras == ("[" + test_extras + "]" if test_extras else "")
|
|
|
|
|
|
@pytest.mark.parametrize("test_command", [None, "test --command"])
|
|
@pytest.mark.parametrize("platform_specific", [False, True])
|
|
def test_test_command(
|
|
test_command: str | None,
|
|
platform_specific: bool,
|
|
platform: str,
|
|
intercepted_build_args: ArgsInterceptor,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
if test_command is not None:
|
|
if platform_specific:
|
|
monkeypatch.setenv("CIBW_TEST_COMMAND_" + platform.upper(), test_command)
|
|
monkeypatch.setenv("CIBW_TEST_COMMAND", "overwritten")
|
|
else:
|
|
monkeypatch.setenv("CIBW_TEST_COMMAND", test_command)
|
|
|
|
main()
|
|
|
|
build_options = intercepted_build_args.args[0].build_options(identifier=None)
|
|
|
|
assert build_options.test_command == (test_command or "")
|
|
|
|
|
|
@pytest.mark.parametrize("before_build", [None, "before --build"])
|
|
@pytest.mark.parametrize("platform_specific", [False, True])
|
|
def test_before_build(
|
|
before_build: str | None,
|
|
platform_specific: bool,
|
|
platform: str,
|
|
intercepted_build_args: ArgsInterceptor,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
if before_build is not None:
|
|
if platform_specific:
|
|
monkeypatch.setenv("CIBW_BEFORE_BUILD_" + platform.upper(), before_build)
|
|
monkeypatch.setenv("CIBW_BEFORE_BUILD", "overwritten")
|
|
else:
|
|
monkeypatch.setenv("CIBW_BEFORE_BUILD", before_build)
|
|
|
|
main()
|
|
|
|
build_options = intercepted_build_args.args[0].build_options(identifier=None)
|
|
assert build_options.before_build == (before_build or "")
|
|
|
|
|
|
@pytest.mark.parametrize("build_verbosity", [None, 0, 2, -2, 4, -4])
|
|
@pytest.mark.parametrize("platform_specific", [False, True])
|
|
def test_build_verbosity(
|
|
build_verbosity: int | None,
|
|
platform_specific: bool,
|
|
platform: str,
|
|
intercepted_build_args: ArgsInterceptor,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
if build_verbosity is not None:
|
|
if platform_specific:
|
|
monkeypatch.setenv("CIBW_BUILD_VERBOSITY_" + platform.upper(), str(build_verbosity))
|
|
monkeypatch.setenv("CIBW_BUILD_VERBOSITY", "overwritten")
|
|
else:
|
|
monkeypatch.setenv("CIBW_BUILD_VERBOSITY", str(build_verbosity))
|
|
|
|
main()
|
|
build_options = intercepted_build_args.args[0].build_options(identifier=None)
|
|
|
|
expected_verbosity = max(-3, min(3, int(build_verbosity or 0)))
|
|
assert build_options.build_verbosity == expected_verbosity
|
|
|
|
|
|
@pytest.mark.parametrize("platform_specific", [False, True])
|
|
def test_config_settings(
|
|
platform_specific: bool,
|
|
platform: str,
|
|
intercepted_build_args: ArgsInterceptor,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
config_settings = (
|
|
'setting=value setting=value2 triplet=1 triplet=2 triplet=3 other="something else"'
|
|
)
|
|
if platform_specific:
|
|
monkeypatch.setenv("CIBW_CONFIG_SETTINGS_" + platform.upper(), config_settings)
|
|
monkeypatch.setenv("CIBW_CONFIG_SETTINGS", "a=b")
|
|
else:
|
|
monkeypatch.setenv("CIBW_CONFIG_SETTINGS", config_settings)
|
|
|
|
main()
|
|
build_options = intercepted_build_args.args[0].build_options(identifier=None)
|
|
|
|
assert build_options.config_settings == config_settings
|
|
|
|
assert _split_config_settings(config_settings) == [
|
|
"-Csetting=value",
|
|
"-Csetting=value2",
|
|
"-Ctriplet=1",
|
|
"-Ctriplet=2",
|
|
"-Ctriplet=3",
|
|
"-Cother=something else",
|
|
]
|
|
assert parse_config_settings(config_settings) == {
|
|
"setting": ["value", "value2"],
|
|
"triplet": ["1", "2", "3"],
|
|
"other": "something else",
|
|
}
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"selector",
|
|
[
|
|
"CIBW_BUILD",
|
|
"CIBW_SKIP",
|
|
"CIBW_TEST_SKIP",
|
|
],
|
|
)
|
|
@pytest.mark.parametrize(
|
|
("pattern", "series"),
|
|
[
|
|
("cp27-*", 1),
|
|
("cp35-*", 1),
|
|
("?p36-*", 2),
|
|
("?p37-*", 2),
|
|
("?p38-*", 3),
|
|
("?p27*", 1),
|
|
("?p2*", 1),
|
|
("?p35*", 1),
|
|
("cp313t*", None),
|
|
],
|
|
)
|
|
@pytest.mark.usefixtures("platform", "intercepted_build_args", "allow_empty")
|
|
def test_build_selector_deprecated_error(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
selector: str,
|
|
pattern: str,
|
|
series: int,
|
|
capsys: pytest.CaptureFixture[str],
|
|
) -> None:
|
|
monkeypatch.setenv(selector, pattern)
|
|
monkeypatch.delenv("CIBW_ENABLE", raising=False)
|
|
|
|
if selector == "CIBW_BUILD":
|
|
with pytest.raises(SystemExit) as ex:
|
|
main()
|
|
assert ex.value.code == 4
|
|
|
|
else:
|
|
main()
|
|
|
|
stderr = capsys.readouterr().err
|
|
if pattern == "cp313t*":
|
|
msg = "cibuildwheel 4.x no longer supports Python 3.13 free-threading. Please use the 3.x series or update"
|
|
else:
|
|
msg = f"cibuildwheel 4.x no longer supports Python < 3.9. Please use the {series}.x series or update"
|
|
assert msg in stderr
|
|
|
|
|
|
@pytest.mark.parametrize("before_all", ["", None, "test text"])
|
|
@pytest.mark.parametrize("platform_specific", [False, True])
|
|
def test_before_all(
|
|
before_all: str | None,
|
|
platform_specific: bool,
|
|
platform: str,
|
|
intercepted_build_args: ArgsInterceptor,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
if before_all is not None:
|
|
if platform_specific:
|
|
monkeypatch.setenv("CIBW_BEFORE_ALL_" + platform.upper(), before_all)
|
|
monkeypatch.setenv("CIBW_BEFORE_ALL", "overwritten")
|
|
else:
|
|
monkeypatch.setenv("CIBW_BEFORE_ALL", before_all)
|
|
|
|
main()
|
|
|
|
build_options = intercepted_build_args.args[0].build_options(identifier=None)
|
|
|
|
assert build_options.before_all == (before_all or "")
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"dependency_versions",
|
|
[None, "pinned", "latest", "FILE", "packages: pip==21.0.0"],
|
|
)
|
|
@pytest.mark.parametrize("platform_specific", [False, True])
|
|
def test_dependency_versions(
|
|
dependency_versions: str | None,
|
|
platform_specific: bool,
|
|
platform: str,
|
|
intercepted_build_args: ArgsInterceptor,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
option_value = dependency_versions
|
|
|
|
if dependency_versions == "FILE":
|
|
constraints_file = tmp_path / "constraints.txt"
|
|
constraints_file.write_text("foo==1.2.3\nbar==4.5.6")
|
|
option_value = str(constraints_file)
|
|
|
|
if option_value is not None:
|
|
if platform_specific:
|
|
monkeypatch.setenv("CIBW_DEPENDENCY_VERSIONS_" + platform.upper(), option_value)
|
|
monkeypatch.setenv("CIBW_DEPENDENCY_VERSIONS", "overwritten")
|
|
else:
|
|
monkeypatch.setenv("CIBW_DEPENDENCY_VERSIONS", option_value)
|
|
|
|
main()
|
|
|
|
build_options: BuildOptions = intercepted_build_args.args[0].build_options(identifier=None)
|
|
dependency_constraints = build_options.dependency_constraints
|
|
if dependency_versions is None or dependency_versions == "pinned":
|
|
assert dependency_constraints == DependencyConstraints.pinned()
|
|
elif dependency_versions == "latest":
|
|
assert dependency_constraints == DependencyConstraints.latest()
|
|
elif dependency_versions == "FILE":
|
|
assert dependency_constraints.base_file_path
|
|
assert option_value is not None
|
|
assert dependency_constraints.base_file_path.samefile(Path(option_value))
|
|
elif dependency_versions.startswith("packages:"):
|
|
assert dependency_constraints.packages == ["pip==21.0.0"]
|
|
|
|
|
|
@pytest.mark.parametrize("method", ["unset", "command_line", "env_var"])
|
|
def test_debug_traceback(
|
|
monkeypatch: pytest.MonkeyPatch, method: str, capfd: pytest.CaptureFixture[str]
|
|
) -> None:
|
|
if method == "command_line":
|
|
monkeypatch.setattr(sys, "argv", [*sys.argv, "--debug-traceback"])
|
|
elif method == "env_var":
|
|
monkeypatch.setenv("CIBW_DEBUG_TRACEBACK", "TRUE")
|
|
|
|
# set an option that produces a configuration error
|
|
monkeypatch.setenv("CIBW_BUILD_FRONTEND", "invalid_value")
|
|
|
|
with pytest.raises(SystemExit) as exit:
|
|
main()
|
|
assert exit.value.code == 2
|
|
|
|
_, err = capfd.readouterr()
|
|
|
|
if method == "unset":
|
|
assert "Traceback (most recent call last)" not in err
|
|
else:
|
|
assert "Traceback (most recent call last)" in err
|
|
|
|
|
|
@pytest.mark.parametrize("method", ["unset", "command_line", "env_var"])
|
|
def test_enable(
|
|
method: str, intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
monkeypatch.delenv("CIBW_ENABLE", raising=False)
|
|
|
|
if method == "command_line":
|
|
monkeypatch.setattr(sys, "argv", [*sys.argv, "--enable", "pypy", "--enable", "graalpy"])
|
|
elif method == "env_var":
|
|
monkeypatch.setenv("CIBW_ENABLE", "pypy graalpy")
|
|
|
|
main()
|
|
|
|
enable_groups = intercepted_build_args.args[0].globals.build_selector.enable
|
|
|
|
if method == "unset":
|
|
assert enable_groups == frozenset()
|
|
else:
|
|
assert enable_groups == frozenset([EnableGroup.PyPy, EnableGroup.GraalPy])
|
|
|
|
|
|
def test_enable_all(
|
|
intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
monkeypatch.setattr(sys, "argv", [*sys.argv, "--enable", "all"])
|
|
monkeypatch.delenv("CIBW_ENABLE", raising=False)
|
|
|
|
main()
|
|
|
|
enable_groups = intercepted_build_args.args[0].globals.build_selector.enable
|
|
assert enable_groups == EnableGroup.all_groups()
|
|
|
|
|
|
def test_enable_arg_inherits(
|
|
intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
monkeypatch.setenv("CIBW_ENABLE", "pypy graalpy")
|
|
monkeypatch.setattr(sys, "argv", [*sys.argv, "--enable", "cpython-prerelease"])
|
|
|
|
main()
|
|
|
|
enable_groups = intercepted_build_args.args[0].globals.build_selector.enable
|
|
|
|
assert enable_groups == frozenset(
|
|
(EnableGroup.PyPy, EnableGroup.GraalPy, EnableGroup.CPythonPrerelease)
|
|
)
|
|
|
|
|
|
def test_enable_arg_error_message(
|
|
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
|
|
) -> None:
|
|
monkeypatch.setattr(sys, "argv", [*sys.argv, "--enable", "invalid_group"])
|
|
|
|
with pytest.raises(SystemExit) as ex:
|
|
main()
|
|
assert ex.value.code == 2
|
|
|
|
_, err = capsys.readouterr()
|
|
assert "Valid group names are:" in err
|
|
|
|
|
|
def test_defaults(platform: str, intercepted_build_args: ArgsInterceptor) -> None:
|
|
main()
|
|
|
|
build_options: BuildOptions = intercepted_build_args.args[0].build_options(identifier=None)
|
|
with resources.DEFAULTS.open("rb") as f:
|
|
defaults_toml = tomllib.load(f)
|
|
|
|
root_defaults = defaults_toml["tool"]["cibuildwheel"]
|
|
platform_defaults = defaults_toml["tool"]["cibuildwheel"][platform]
|
|
|
|
defaults = {}
|
|
defaults.update(root_defaults)
|
|
defaults.update(platform_defaults)
|
|
|
|
# test a few options
|
|
assert build_options.before_all == defaults["before-all"]
|
|
repair_wheel_default = defaults["repair-wheel-command"]
|
|
if isinstance(repair_wheel_default, list):
|
|
repair_wheel_default = " && ".join(repair_wheel_default)
|
|
assert build_options.repair_command == repair_wheel_default
|
|
assert build_options.build_frontend.name == "build"
|
|
assert build_options.build_frontend.args == ()
|
|
|
|
if platform == "linux":
|
|
assert build_options.manylinux_images
|
|
pinned_images = _get_pinned_container_images()
|
|
default_x86_64_image = pinned_images["x86_64"][defaults["manylinux-x86_64-image"]]
|
|
assert build_options.manylinux_images["x86_64"] == default_x86_64_image
|