import sys import pytest from cibuildwheel.__main__ import main from cibuildwheel.architecture import Architecture from cibuildwheel.selector import EnableGroup from cibuildwheel.typing import PlatformName from ..conftest import MOCK_PACKAGE_DIR from .conftest import ArgsInterceptor @pytest.mark.parametrize("option_value", [None, "auto", ""]) def test_platform_unset_or_auto( monkeypatch: pytest.MonkeyPatch, intercepted_build_args: ArgsInterceptor, option_value: str | None, ) -> None: if option_value is None: monkeypatch.delenv("CIBW_PLATFORM", raising=False) else: monkeypatch.setenv("CIBW_PLATFORM", option_value) main() options = intercepted_build_args.args[0] # check that the platform was auto detected to build for the current system if sys.platform.startswith("linux"): assert options.platform == "linux" elif sys.platform == "darwin": assert options.platform == "macos" elif sys.platform == "win32": assert options.platform == "windows" else: pytest.fail(f"Unknown platform: {sys.platform}") def test_unknown_platform_on_ci( monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str] ) -> None: monkeypatch.setenv("CI", "true") monkeypatch.setattr(sys, "platform", "nonexistent") monkeypatch.delenv("CIBW_PLATFORM", raising=False) with pytest.raises(SystemExit) as exit: main() assert exit.value.code == 2 _, err = capsys.readouterr() assert 'Unable to detect platform from "sys.platform"' in err def test_unknown_platform( monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str] ) -> None: monkeypatch.setenv("CIBW_PLATFORM", "nonexistent") with pytest.raises(SystemExit) as exit: main() _, err = capsys.readouterr() assert exit.value.code == 2 assert "Unsupported platform: nonexistent" in err def test_platform_argument( platform: str, intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch ) -> None: monkeypatch.setenv("CIBW_PLATFORM", "nonexistent") monkeypatch.setattr(sys, "argv", [*sys.argv, "--platform", platform]) main() options = intercepted_build_args.args[0] assert options.globals.package_dir == MOCK_PACKAGE_DIR.resolve() @pytest.mark.usefixtures("platform") def test_platform_environment(intercepted_build_args: ArgsInterceptor) -> None: main() options = intercepted_build_args.args[0] assert options.globals.package_dir == MOCK_PACKAGE_DIR.resolve() def test_archs_default(platform: str, intercepted_build_args: ArgsInterceptor) -> None: main() options = intercepted_build_args.args[0] if platform == "linux": assert options.globals.architectures == {Architecture.x86_64} elif platform == "windows": assert options.globals.architectures == {Architecture.AMD64, Architecture.x86} else: assert options.globals.architectures == {Architecture.x86_64} @pytest.mark.parametrize("use_env_var", [False, True]) def test_archs_argument( platform: str, intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch, use_env_var: bool, ) -> None: if use_env_var: monkeypatch.setenv("CIBW_ARCHS", "ppc64le") else: monkeypatch.setenv("CIBW_ARCHS", "unused") monkeypatch.setattr(sys, "argv", [*sys.argv, "--archs", "ppc64le"]) if platform in {"macos", "windows"}: with pytest.raises(SystemExit) as exit: main() assert exit.value.args == (4,) else: main() options = intercepted_build_args.args[0] assert options.globals.architectures == {Architecture.ppc64le} def test_archs_platform_specific( platform: str, intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch ) -> None: monkeypatch.setenv("CIBW_ARCHS", "unused") monkeypatch.setenv("CIBW_ARCHS_LINUX", "ppc64le") monkeypatch.setenv("CIBW_ARCHS_WINDOWS", "x86") monkeypatch.setenv("CIBW_ARCHS_MACOS", "x86_64") main() options = intercepted_build_args.args[0] if platform == "linux": assert options.globals.architectures == {Architecture.ppc64le} elif platform == "windows": assert options.globals.architectures == {Architecture.x86} elif platform == "macos": assert options.globals.architectures == {Architecture.x86_64} def test_archs_platform_native( platform: str, intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch ) -> None: monkeypatch.setenv("CIBW_ARCHS", "native") main() options = intercepted_build_args.args[0] if platform in {"linux", "macos"}: assert options.globals.architectures == {Architecture.x86_64} elif platform == "windows": assert options.globals.architectures == {Architecture.AMD64} def test_archs_platform_auto64( platform: str, intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch ) -> None: monkeypatch.setenv("CIBW_ARCHS", "auto64") main() options = intercepted_build_args.args[0] if platform in {"linux", "macos"}: assert options.globals.architectures == {Architecture.x86_64} elif platform == "windows": assert options.globals.architectures == {Architecture.AMD64} def test_archs_platform_auto32( platform: str, intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch ) -> None: monkeypatch.setenv("CIBW_ARCHS", "auto32") if platform == "macos": with pytest.raises(SystemExit) as exit: main() assert exit.value.args == (4,) else: main() options = intercepted_build_args.args[0] if platform == "linux": assert options.globals.architectures == {Architecture.i686} elif platform == "windows": assert options.globals.architectures == {Architecture.x86} def test_archs_platform_all( platform: str, intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch ) -> None: monkeypatch.setenv("CIBW_ARCHS", "all") main() options = intercepted_build_args.args[0] if platform == "linux": assert options.globals.architectures == { Architecture.x86_64, Architecture.i686, Architecture.aarch64, Architecture.ppc64le, Architecture.s390x, Architecture.armv7l, Architecture.riscv64, } elif platform == "windows": assert options.globals.architectures == { Architecture.x86, Architecture.AMD64, Architecture.ARM64, } elif platform == "macos": assert options.globals.architectures == { Architecture.x86_64, Architecture.arm64, Architecture.universal2, } @pytest.mark.parametrize( ("only", "plat"), ( ("cp311-manylinux_x86_64", "linux"), ("cp310-win_amd64", "windows"), ("cp310-win32", "windows"), ("cp311-macosx_x86_64", "macos"), ), ) def test_only_argument( intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch, only: str, plat: PlatformName, ) -> None: monkeypatch.setenv("CIBW_BUILD", "unused") monkeypatch.setenv("CIBW_SKIP", "unused") monkeypatch.setattr(sys, "argv", [*sys.argv, "--only", only]) main() options = intercepted_build_args.args[0] assert options.globals.build_selector.build_config == only assert options.globals.build_selector.skip_config == "" assert options.platform == plat assert options.globals.architectures == Architecture.all_archs(plat) assert EnableGroup.PyPy in options.globals.build_selector.enable @pytest.mark.parametrize("only", ("cp311-manylxinux_x86_64", "some_linux_thing")) def test_only_failed(monkeypatch: pytest.MonkeyPatch, only: str) -> None: monkeypatch.setattr(sys, "argv", [*sys.argv, "--only", only]) with pytest.raises(SystemExit): main() def test_only_no_platform(monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( sys, "argv", [*sys.argv, "--only", "cp311-manylinux_x86_64", "--platform", "macos"] ) with pytest.raises(SystemExit): main() def test_only_no_archs(monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr( sys, "argv", [*sys.argv, "--only", "cp311-manylinux_x86_64", "--archs", "x86_64"] ) with pytest.raises(SystemExit): main() @pytest.mark.parametrize( ("envvar_name", "envvar_value"), ( ("CIBW_BUILD", "cp310-*"), ("CIBW_SKIP", "cp311-*"), ("CIBW_ARCHS", "auto32"), ("CIBW_PLATFORM", "macos"), ), ) def test_only_overrides_env_vars( monkeypatch: pytest.MonkeyPatch, intercepted_build_args: ArgsInterceptor, envvar_name: str, envvar_value: str, ) -> None: monkeypatch.setattr(sys, "argv", [*sys.argv, "--only", "cp311-manylinux_x86_64"]) monkeypatch.setenv(envvar_name, envvar_value) main() options = intercepted_build_args.args[0] assert options.globals.build_selector.build_config == "cp311-manylinux_x86_64" assert options.globals.build_selector.skip_config == "" assert options.platform == "linux" assert options.globals.architectures == Architecture.all_archs("linux") def test_pyodide_on_windows( monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str] ) -> None: monkeypatch.setattr(sys, "platform", "win32") monkeypatch.setattr(sys, "argv", [*sys.argv, "--only", "cp314-pyodide_wasm32"]) with pytest.raises(SystemExit) as exit: main() _, err = capsys.readouterr() assert exit.value.code == 2 assert "Building for pyodide is not supported on Windows" in err def test_empty_archs_platform( platform: PlatformName, intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch ) -> None: monkeypatch.setenv("CIBW_ARCHS", "") main() options = intercepted_build_args.args[0] assert options.globals.architectures == Architecture.auto_archs(platform)