From 6286d9c33d60ae3b2406bafe69efa4d0317b8853 Mon Sep 17 00:00:00 2001 From: mayeut Date: Sun, 25 Sep 2022 10:42:19 +0200 Subject: [PATCH] feature: allow testing cp38-macosx_arm64 wheel Per discussion in https://github.com/pypa/cibuildwheel/pull/1169, the default installer used for cp38 is an Intel installer. It makes sense to skip testing arm64 wheels in this case. However, if the user choose to manually install the universal2 CPython version, then, tests shall be run on arm64. This allows users that either target 11.0+ on intel, universal2 or only build for arm64 to get the arm64 wheel tested on AppleSilicon. --- .cirrus.yml | 16 ++++++++++++++++ cibuildwheel/macos.py | 10 +++++++++- test/conftest.py | 6 ++++++ test/test_macos_archs.py | 30 ++++++++++++++++++++++++++++++ unit_test/conftest.py | 8 +++++++- 5 files changed, 68 insertions(+), 2 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index e85ef479..4ba969ea 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -56,3 +56,19 @@ macos_arm64_task: - brew install python@3.10 - ln -s python3 /opt/homebrew/opt/python@3.10/bin/python <<: *RUN_TESTS + +macos_arm64_cp38_task: + macos_instance: + image: ghcr.io/cirruslabs/macos-monterey-xcode + + env: + PATH: /opt/homebrew/opt/python@3.10/bin:$PATH + PYTEST_ADDOPTS: --run-cp38-universal2 -k 'test_cp38_arm64_testing_universal2_installer or test_arch_auto' + install_pre_requirements_script: + - brew install python@3.10 + - ln -s python3 /opt/homebrew/opt/python@3.10/bin/python + - curl -fsSLO https://www.python.org/ftp/python/3.8.10/python-3.8.10-macos11.pkg + - sudo installer -pkg python-3.8.10-macos11.pkg -target / + - rm python-3.8.10-macos11.pkg + - sh "/Applications/Python 3.8/Install Certificates.command" + <<: *RUN_TESTS diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py index db863504..95bbe268 100644 --- a/cibuildwheel/macos.py +++ b/cibuildwheel/macos.py @@ -425,6 +425,13 @@ def build(options: Options, tmp_path: Path) -> None: if build_options.test_command and build_options.test_selector(config.identifier): machine_arch = platform.machine() + python_arch = call( + "python", + "-sSc", + "import platform; print(platform.machine())", + env=env, + capture_stdout=True, + ).strip() testing_archs: list[Literal["x86_64", "arm64"]] if config_is_arm64: @@ -473,7 +480,8 @@ def build(options: Options, tmp_path: Path) -> None: # skip this test continue - if testing_arch == "arm64" and config.identifier.startswith("cp38-"): + is_cp38 = config.identifier.startswith("cp38-") + if testing_arch == "arm64" and is_cp38 and python_arch != "arm64": log.warning( unwrap( """ diff --git a/test/conftest.py b/test/conftest.py index 872eeb17..07db1c1e 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -8,6 +8,12 @@ def pytest_addoption(parser) -> None: "--run-emulation", action="store_true", default=False, help="run emulation tests" ) parser.addoption("--run-podman", action="store_true", default=False, help="run podman tests") + parser.addoption( + "--run-cp38-universal2", + action="store_true", + default=False, + help="macOS cp38 uses the universal2 installer", + ) @pytest.fixture( diff --git a/test/test_macos_archs.py b/test/test_macos_archs.py index fdd665c0..903c11d1 100644 --- a/test/test_macos_archs.py +++ b/test/test_macos_archs.py @@ -167,3 +167,33 @@ def test_cp38_arm64_testing(tmp_path, capfd): expected_wheels = [w for w in ALL_MACOS_WHEELS if "cp38" in w] assert set(actual_wheels) == set(expected_wheels) + + +def test_cp38_arm64_testing_universal2_installer(tmp_path, capfd, request): + if not request.config.getoption("--run-cp38-universal2"): + pytest.skip("needs --run-cp38-universal2 option to run") + + project_dir = tmp_path / "project" + basic_project.generate(project_dir) + + actual_wheels = utils.cibuildwheel_run( + project_dir, + add_env={ + "CIBW_BUILD": "cp38-*", + "CIBW_TEST_COMMAND": '''python -c "import platform; print('running tests on ' + platform.machine())"''', + "CIBW_ARCHS": "x86_64,universal2,arm64", + "MACOSX_DEPLOYMENT_TARGET": "11.0", + }, + ) + + captured = capfd.readouterr() + + assert "running tests on x86_64" in captured.out + assert "running tests on arm64" in captured.out + + warning_message = "While cibuildwheel can build CPython 3.8 universal2/arm64 wheels, we cannot test the arm64 part of them" + assert warning_message not in captured.err + + expected_wheels = [w.replace("10_9", "11_0") for w in ALL_MACOS_WHEELS if "cp38" in w] + + assert set(actual_wheels) == set(expected_wheels) diff --git a/unit_test/conftest.py b/unit_test/conftest.py index 7e1df1b2..04310334 100644 --- a/unit_test/conftest.py +++ b/unit_test/conftest.py @@ -11,7 +11,13 @@ MOCK_PACKAGE_DIR = Path("some_package_dir") def pytest_addoption(parser): parser.addoption("--run-docker", action="store_true", default=False, help="run docker tests") parser.addoption("--run-podman", action="store_true", default=False, help="run podman tests") - + parser.addoption( + "--run-cp38-universal2", + action="store_true", + default=False, + help="macOS cp38 uses the universal2 installer", + ) + @pytest.fixture def fake_package_dir(tmp_path, monkeypatch):