From 97da90432ebe6e3b642c89cb80737dd2f9bb79a6 Mon Sep 17 00:00:00 2001 From: Matthieu Darbois Date: Sun, 26 May 2024 12:41:20 +0200 Subject: [PATCH] chore: rework single python tests (#1835) * chore: rework single python tests * chore(tests): limit number of builds in test_abi3 * chore(tests): limit number of builds in test_before_all * apply review suggestion use `os.path.samefile` rather than comparing `os.stat` directly. --- test/test_abi_variants.py | 13 +++--- test/test_before_all.py | 29 ++++++++++---- test/test_before_build.py | 3 +- test/test_build_frontend_args.py | 6 +-- test/test_build_skip.py | 20 +++++----- test/test_container_engine.py | 16 ++++---- test/test_cpp_standards.py | 68 +++++++++++++------------------- test/test_environment.py | 7 ++-- test/test_from_sdist.py | 31 +++++---------- test/test_macos_archs.py | 30 +++++++------- test/test_musllinux_X_Y_only.py | 5 ++- test/test_subdir_package.py | 5 +-- test/test_testing.py | 3 +- test/test_wheel_tag.py | 9 ++--- test/test_windows.py | 9 ++--- test/utils.py | 25 +++++++++++- 16 files changed, 143 insertions(+), 136 deletions(-) diff --git a/test/test_abi_variants.py b/test/test_abi_variants.py index 4446ed56..02c75b0e 100644 --- a/test/test_abi_variants.py +++ b/test/test_abi_variants.py @@ -20,7 +20,7 @@ limited_api_project = test_projects.new_c_project( CAN_USE_ABI3 = IS_CPYTHON and not Py_GIL_DISABLED cmdclass = {} extension_kwargs = {} - if CAN_USE_ABI3 and sys.version_info[:2] >= (3, 8): + if CAN_USE_ABI3 and sys.version_info[:2] >= (3, 10): from wheel.bdist_wheel import bdist_wheel as _bdist_wheel class bdist_wheel_abi3(_bdist_wheel): @@ -33,7 +33,7 @@ limited_api_project = test_projects.new_c_project( return python, "abi3", plat cmdclass["bdist_wheel"] = bdist_wheel_abi3 - extension_kwargs["define_macros"] = [("Py_LIMITED_API", "0x03080000")] + extension_kwargs["define_macros"] = [("Py_LIMITED_API", "0x030A0000")] extension_kwargs["py_limited_api"] = True """ ), @@ -53,17 +53,16 @@ def test_abi3(tmp_path): project_dir, add_env={ # free_threaded and PyPy do not have a Py_LIMITED_API equivalent, just build one of those - "CIBW_BUILD": "cp3?-* cp31?-* cp313t-* pp310-*" + # also limit the number of builds for test performance reasons + "CIBW_BUILD": "cp39-* cp310-* pp310-* cp311-* cp313t-*" }, ) # check that the expected wheels are produced expected_wheels = [ - w.replace("cp38-cp38", "cp38-abi3") + w.replace("cp310-cp310", "cp310-abi3") for w in utils.expected_wheels("spam", "0.1.0") - if ("-pp310" in w or "-pp" not in w) - and "-cp39" not in w - and ("-cp313t" in w or "-cp31" not in w) + if "-cp39" in w or "-cp310" in w or "-pp310" in w or "-cp313t" in w ] assert set(actual_wheels) == set(expected_wheels) diff --git a/test/test_before_all.py b/test/test_before_all.py index bad2d4c0..ea59104e 100644 --- a/test/test_before_all.py +++ b/test/test_before_all.py @@ -10,13 +10,22 @@ from . import test_projects, utils project_with_before_build_asserts = test_projects.new_c_project( setup_py_add=textwrap.dedent( r""" - # assert that the Python version as written to text_info.txt in the CIBW_BEFORE_ALL step - # is the same one as is currently running. + import os + with open("text_info.txt") as f: stored_text = f.read() - print("## stored text: " + stored_text) assert stored_text == "sample text 123" + + # assert that the Python version as written to python_prefix.txt in the CIBW_BEFORE_ALL step + # is not the same one as is currently running. + with open('python_prefix.txt') as f: + stored_prefix = f.read() + print('stored_prefix', stored_prefix) + print('sys.prefix', sys.prefix) + # Works around path-comparison bugs caused by short-paths on Windows e.g. + # vssadm~1 instead of vssadministrator + assert not os.path.samefile(stored_prefix, sys.prefix) """ ) ) @@ -30,21 +39,24 @@ def test(tmp_path): print("dummy text", file=ff) # build the wheels - before_all_command = '''python -c "import os;open('{project}/text_info.txt', 'w').write('sample text '+os.environ.get('TEST_VAL', ''))"''' + before_all_command = ( + """python -c "import os, sys;open('{project}/text_info.txt', 'w').write('sample text '+os.environ.get('TEST_VAL', ''))" && """ + '''python -c "import sys; open('{project}/python_prefix.txt', 'w').write(sys.prefix)"''' + ) actual_wheels = utils.cibuildwheel_run( project_dir, add_env={ # write python version information to a temporary file, this is # checked in setup.py "CIBW_BEFORE_ALL": before_all_command, - "CIBW_BEFORE_ALL_LINUX": f'{before_all_command} && python -c "import sys; assert sys.version_info >= (3, 6)"', + "CIBW_BEFORE_ALL_LINUX": f'{before_all_command} && python -c "import sys; assert sys.version_info >= (3, 8)"', "CIBW_ENVIRONMENT": "TEST_VAL='123'", }, + single_python=True, ) # also check that we got the right wheels - (project_dir / "text_info.txt").unlink() - expected_wheels = utils.expected_wheels("spam", "0.1.0") + expected_wheels = utils.expected_wheels("spam", "0.1.0", single_python=True) assert set(actual_wheels) == set(expected_wheels) @@ -72,7 +84,8 @@ def test_cwd(tmp_path): "CIBW_BEFORE_ALL": f'''python -c "import os; assert os.getcwd() == {str(project_dir)!r}"''', "CIBW_BEFORE_ALL_LINUX": '''python -c "import os; assert os.getcwd() == '/project'"''', }, + single_python=True, ) - expected_wheels = utils.expected_wheels("spam", "0.1.0") + expected_wheels = utils.expected_wheels("spam", "0.1.0", single_python=True) assert set(actual_wheels) == set(expected_wheels) diff --git a/test/test_before_build.py b/test/test_before_build.py index e6c5d6d5..b7a9b67b 100644 --- a/test/test_before_build.py +++ b/test/test_before_build.py @@ -82,7 +82,8 @@ def test_cwd(tmp_path): "CIBW_BEFORE_BUILD": f'''python -c "import os; assert os.getcwd() == {str(project_dir)!r}"''', "CIBW_BEFORE_BUILD_LINUX": '''python -c "import os; assert os.getcwd() == '/project'"''', }, + single_python=True, ) - expected_wheels = utils.expected_wheels("spam", "0.1.0") + expected_wheels = utils.expected_wheels("spam", "0.1.0", single_python=True) assert set(actual_wheels) == set(expected_wheels) diff --git a/test/test_build_frontend_args.py b/test/test_build_frontend_args.py index c2b0fc37..4480a087 100644 --- a/test/test_build_frontend_args.py +++ b/test/test_build_frontend_args.py @@ -16,10 +16,8 @@ def test_build_frontend_args(tmp_path, capfd, frontend_name): with pytest.raises(subprocess.CalledProcessError): utils.cibuildwheel_run( project_dir, - add_env={ - "CIBW_BUILD": "cp311-*", - "CIBW_BUILD_FRONTEND": f"{frontend_name}; args: -h", - }, + add_env={"CIBW_BUILD_FRONTEND": f"{frontend_name}; args: -h"}, + single_python=True, ) captured = capfd.readouterr() diff --git a/test/test_build_skip.py b/test/test_build_skip.py index e29d14f1..3bfc3a9c 100644 --- a/test/test_build_skip.py +++ b/test/test_build_skip.py @@ -6,12 +6,12 @@ from . import test_projects, utils project_with_skip_asserts = test_projects.new_c_project( setup_py_add=textwrap.dedent( - r""" - # explode if run on PyPyor Python 3.7 (these should be skipped) + rf""" if sys.implementation.name != "cpython": raise Exception("Only CPython shall be built") - if sys.version_info[0:2] == (3, 7): - raise Exception("CPython 3.7 should be skipped") + expected_version = {"({}, {})".format(*utils.SINGLE_PYTHON_VERSION)} + if sys.version_info[0:2] != expected_version: + raise Exception("CPython {{}}.{{}} should be skipped".format(*sys.version_info[0:2])) """ ) ) @@ -21,17 +21,19 @@ def test(tmp_path): project_dir = tmp_path / "project" project_with_skip_asserts.generate(project_dir) + skip = " ".join( + f"cp3{minor}-*" for minor in range(6, 30) if (3, minor) != utils.SINGLE_PYTHON_VERSION + ) + # build the wheels actual_wheels = utils.cibuildwheel_run( project_dir, add_env={ "CIBW_BUILD": "cp3*-*", - "CIBW_SKIP": "cp37-*", + "CIBW_SKIP": f"*t-* {skip}", }, ) - # check that we got the right wheels. There should be no PyPy or 3.7. - expected_wheels = [ - w for w in utils.expected_wheels("spam", "0.1.0") if ("-cp3" in w) and ("-cp37" not in w) - ] + # check that we got the right wheels. There should be a single version of CPython. + expected_wheels = utils.expected_wheels("spam", "0.1.0", single_python=True) assert set(actual_wheels) == set(expected_wheels) diff --git a/test/test_container_engine.py b/test/test_container_engine.py index 10c09b0d..66bbae1d 100644 --- a/test/test_container_engine.py +++ b/test/test_container_engine.py @@ -21,17 +21,16 @@ def test_podman(tmp_path, capfd, request): actual_wheels = utils.cibuildwheel_run( project_dir, add_env={ - "CIBW_BUILD": "cp310-*{manylinux,musllinux}_x86_64", + "CIBW_ARCHS": "x86_64", "CIBW_BEFORE_ALL": "echo 'test log statement from before-all'", "CIBW_CONTAINER_ENGINE": "podman", }, + single_python=True, ) # check that the expected wheels are produced expected_wheels = [ - w - for w in utils.expected_wheels("spam", "0.1.0") - if ("-cp310-" in w) and ("x86_64" in w) and ("manylinux" in w or "musllinux" in w) + w for w in utils.expected_wheels("spam", "0.1.0", single_python=True) if "x86_64" in w ] assert set(actual_wheels) == set(expected_wheels) @@ -51,15 +50,16 @@ def test_create_args(tmp_path, capfd): actual_wheels = utils.cibuildwheel_run( project_dir, add_env={ - "CIBW_BUILD": "cp310-manylinux_*", + "CIBW_SKIP": "*-musllinux_*", "CIBW_BEFORE_ALL": "echo TEST_CREATE_ARGS is set to $TEST_CREATE_ARGS", "CIBW_CONTAINER_ENGINE": "docker; create_args: --env=TEST_CREATE_ARGS=itworks", }, + single_python=True, ) - expected_wheels = [ - w for w in utils.expected_wheels("spam", "0.1.0") if ("cp310-manylinux" in w) - ] + expected_wheels = utils.expected_wheels( + "spam", "0.1.0", musllinux_versions=[], single_python=True + ) assert set(actual_wheels) == set(expected_wheels) captured = capfd.readouterr() diff --git a/test/test_cpp_standards.py b/test/test_cpp_standards.py index 935e5311..31d2b721 100644 --- a/test/test_cpp_standards.py +++ b/test/test_cpp_standards.py @@ -56,76 +56,62 @@ PyMODINIT_FUNC PyInit_spam(void) cpp_test_project.files["setup.py"] = jinja2.Template(setup_py_template) cpp_test_project.files["spam.cpp"] = jinja2.Template(spam_cpp_template) -cpp11_project = cpp_test_project.copy() -cpp11_project.template_context["extra_compile_args"] = ( - ["/std:c++11"] if utils.platform == "windows" else ["-std=c++11"] -) -cpp11_project.template_context["spam_cpp_top_level_add"] = "#include " - def test_cpp11(tmp_path): # This test checks that the C++11 standard is supported project_dir = tmp_path / "project" - + cpp11_project = cpp_test_project.copy() + cpp11_project.template_context["extra_compile_args"] = ( + ["/std:c++11"] if utils.platform == "windows" else ["-std=c++11"] + ) + cpp11_project.template_context["spam_cpp_top_level_add"] = "#include " cpp11_project.generate(project_dir) - actual_wheels = utils.cibuildwheel_run(project_dir) - expected_wheels = list(utils.expected_wheels("spam", "0.1.0")) + actual_wheels = utils.cibuildwheel_run(project_dir, single_python=True) + expected_wheels = utils.expected_wheels("spam", "0.1.0", single_python=True) assert set(actual_wheels) == set(expected_wheels) -cpp14_project = cpp_test_project.copy() -cpp14_project.template_context["extra_compile_args"] = ( - ["/std:c++14"] if utils.platform == "windows" else ["-std=c++14"] -) -cpp14_project.template_context["spam_cpp_top_level_add"] = "int a = 100'000;" - - def test_cpp14(tmp_path): # This test checks that the C++14 standard is supported project_dir = tmp_path / "project" - + cpp14_project = cpp_test_project.copy() + cpp14_project.template_context["extra_compile_args"] = ( + ["/std:c++14"] if utils.platform == "windows" else ["-std=c++14"] + ) + cpp14_project.template_context["spam_cpp_top_level_add"] = "int a = 100'000;" cpp14_project.generate(project_dir) - actual_wheels = utils.cibuildwheel_run(project_dir) - expected_wheels = list(utils.expected_wheels("spam", "0.1.0")) + actual_wheels = utils.cibuildwheel_run(project_dir, single_python=True) + expected_wheels = utils.expected_wheels("spam", "0.1.0", single_python=True) assert set(actual_wheels) == set(expected_wheels) -cpp17_project = cpp_test_project.copy() - -cpp17_project.template_context["extra_compile_args"] = [ - "/std:c++17" if utils.platform == "windows" else "-std=c++17" -] -cpp17_project.template_context["spam_cpp_top_level_add"] = r""" -#include -auto a = std::pair(5.0, false); -""" - - def test_cpp17(tmp_path): # This test checks that the C++17 standard is supported project_dir = tmp_path / "project" - + cpp17_project = cpp_test_project.copy() + cpp17_project.template_context["extra_compile_args"] = [ + "/std:c++17" if utils.platform == "windows" else "-std=c++17" + ] + cpp17_project.template_context["spam_cpp_top_level_add"] = r""" + #include + auto a = std::pair(5.0, false); + """ cpp17_project.generate(project_dir) if os.environ.get("APPVEYOR_BUILD_WORKER_IMAGE", "") == "Visual Studio 2015": pytest.skip("Visual Studio 2015 does not support C++17") - # Pypy's distutils sets the default compiler to 'msvc9compiler', which - # is too old to support cpp17. - add_env = {"CIBW_SKIP": "pp*"} - + add_env = {} if utils.platform == "macos": add_env["MACOSX_DEPLOYMENT_TARGET"] = "10.13" - actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env) - expected_wheels = [ - w - for w in utils.expected_wheels("spam", "0.1.0", macosx_deployment_target="10.13") - if "-pp" not in w - ] + actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env, single_python=True) + expected_wheels = utils.expected_wheels( + "spam", "0.1.0", macosx_deployment_target="10.13", single_python=True + ) assert set(actual_wheels) == set(expected_wheels) diff --git a/test/test_environment.py b/test/test_environment.py index faaba7f3..b4a0120a 100644 --- a/test/test_environment.py +++ b/test/test_environment.py @@ -49,10 +49,11 @@ def test(tmp_path): "CIBW_ENVIRONMENT": """CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$(echo 'test string 3')" PATH=$PATH:/opt/cibw_test_path""", "CIBW_ENVIRONMENT_WINDOWS": f'''CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$({python_echo} 'test string 3')" PATH="$PATH;/opt/cibw_test_path"''', }, + single_python=True, ) # also check that we got the right wheels built - expected_wheels = utils.expected_wheels("spam", "0.1.0") + expected_wheels = utils.expected_wheels("spam", "0.1.0", single_python=True) assert set(actual_wheels) == set(expected_wheels) @@ -133,12 +134,12 @@ def test_overridden_pip_constraint(tmp_path, build_frontend): actual_wheels = utils.cibuildwheel_run( project_dir, add_env={ - "CIBW_BUILD": "cp312-*", "CIBW_BUILD_FRONTEND": build_frontend, "PIP_CONSTRAINT": str(constraints_file), "CIBW_ENVIRONMENT_LINUX": "PIP_CONSTRAINT=./constraints.txt", }, + single_python=True, ) - expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0") if "cp312" in w] + expected_wheels = utils.expected_wheels("spam", "0.1.0", single_python=True) assert set(actual_wheels) == set(expected_wheels) diff --git a/test/test_from_sdist.py b/test/test_from_sdist.py index f999eaf4..c8a0d6a3 100644 --- a/test/test_from_sdist.py +++ b/test/test_from_sdist.py @@ -33,6 +33,8 @@ def cibuildwheel_from_sdist_run(sdist_path, add_env=None, config_file=None): if add_env: env.update(add_env) + env["CIBW_BUILD"] = "cp{}{}-*".format(*utils.SINGLE_PYTHON_VERSION) + with TemporaryDirectory() as tmp_output_dir: subprocess.run( [ @@ -73,15 +75,11 @@ def test_simple(tmp_path): # build the wheels from sdist actual_wheels = cibuildwheel_from_sdist_run( - sdist_path, - add_env={ - "CIBW_BEFORE_BUILD": setup_py_assertion_cmd, - "CIBW_BUILD": "cp39-*", - }, + sdist_path, add_env={"CIBW_BEFORE_BUILD": setup_py_assertion_cmd} ) # check that the expected wheels are produced - expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0") if "cp39" in w] + expected_wheels = utils.expected_wheels("spam", "0.1.0", single_python=True) assert set(actual_wheels) == set(expected_wheels) @@ -105,14 +103,10 @@ def test_external_config_file_argument(tmp_path, capfd): ) # build the wheels from sdist - actual_wheels = cibuildwheel_from_sdist_run( - sdist_path, - add_env={"CIBW_BUILD": "cp39-*"}, - config_file=str(config_file), - ) + actual_wheels = cibuildwheel_from_sdist_run(sdist_path, config_file=str(config_file)) # check that the expected wheels are produced - expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0") if "cp39" in w] + expected_wheels = utils.expected_wheels("spam", "0.1.0", single_python=True) assert set(actual_wheels) == set(expected_wheels) # check that before-all was run @@ -136,13 +130,10 @@ def test_config_in_pyproject_toml(tmp_path, capfd): sdist_path = make_sdist(project, sdist_dir) # build the wheels from sdist - actual_wheels = cibuildwheel_from_sdist_run( - sdist_path, - add_env={"CIBW_BUILD": "cp39-*"}, - ) + actual_wheels = cibuildwheel_from_sdist_run(sdist_path) # check that the expected wheels are produced - expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0") if "cp39" in w] + expected_wheels = utils.expected_wheels("spam", "0.1.0", single_python=True) assert set(actual_wheels) == set(expected_wheels) # check that before-build was run @@ -174,13 +165,11 @@ def test_internal_config_file_argument(tmp_path, capfd): # build the wheels from sdist, referencing the config file inside actual_wheels = cibuildwheel_from_sdist_run( - sdist_path, - add_env={"CIBW_BUILD": "cp39-*"}, - config_file="{package}/wheel_build_config.toml", + sdist_path, config_file="{package}/wheel_build_config.toml" ) # check that the expected wheels are produced - expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0") if "cp39" in w] + expected_wheels = utils.expected_wheels("spam", "0.1.0", single_python=True) assert set(actual_wheels) == set(expected_wheels) # check that before-all was run diff --git a/test/test_macos_archs.py b/test/test_macos_archs.py index 3f7ceea5..d29118b6 100644 --- a/test/test_macos_archs.py +++ b/test/test_macos_archs.py @@ -42,13 +42,11 @@ def test_cross_compiled_build(tmp_path): actual_wheels = utils.cibuildwheel_run( project_dir, - add_env={ - "CIBW_BUILD": "cp39-*", - "CIBW_ARCHS": "x86_64, universal2, arm64", - }, + add_env={"CIBW_ARCHS": "x86_64, universal2, arm64"}, + single_python=True, ) - - expected_wheels = [w for w in ALL_MACOS_WHEELS if "cp39" in w] + python_tag = "cp{}{}".format(*utils.SINGLE_PYTHON_VERSION) + expected_wheels = [w for w in ALL_MACOS_WHEELS if python_tag in w] assert set(actual_wheels) == set(expected_wheels) @@ -65,7 +63,7 @@ def test_cross_compiled_test(tmp_path, capfd, build_universal2): actual_wheels = utils.cibuildwheel_run( project_dir, add_env={ - "CIBW_BUILD": "cp39-*" if build_universal2 else "*p39-*", + "CIBW_BUILD": "cp310-*" if build_universal2 else "*p310-*", "CIBW_TEST_COMMAND": '''python -c "import platform; print('running tests on ' + platform.machine())"''', "CIBW_ARCHS": "universal2" if build_universal2 else "x86_64 arm64", "CIBW_BUILD_VERBOSITY": "3", @@ -103,11 +101,11 @@ def test_cross_compiled_test(tmp_path, capfd, build_universal2): ) if build_universal2: - expected_wheels = [w for w in ALL_MACOS_WHEELS if "cp39" in w and "universal2" in w] + expected_wheels = [w for w in ALL_MACOS_WHEELS if "cp310" in w and "universal2" in w] else: - expected_wheels = [w for w in ALL_MACOS_WHEELS if "p39-" in w and "universal2" not in w] + expected_wheels = [w for w in ALL_MACOS_WHEELS if "p310-" in w and "universal2" not in w] if platform_machine == "x86_64": - expected_wheels = [w for w in expected_wheels if not ("pp39" in w and "arm64" in w)] + expected_wheels = [w for w in expected_wheels if not ("pp310" in w and "arm64" in w)] assert set(actual_wheels) == set(expected_wheels) @@ -123,11 +121,11 @@ def test_deployment_target_warning_is_firing(tmp_path, capfd): utils.cibuildwheel_run( project_dir, add_env={ - "CIBW_BUILD": "cp39-*", "CIBW_ARCHS": "x86_64", "MACOSX_DEPLOYMENT_TARGET": "10.8", "CIBW_BUILD_VERBOSITY": "3", }, + single_python=True, ) captured = capfd.readouterr() @@ -149,11 +147,11 @@ def test_universal2_testing_on_x86_64(tmp_path, capfd, skip_arm64_test): actual_wheels = utils.cibuildwheel_run( project_dir, add_env={ - "CIBW_BUILD": "cp39-*", "CIBW_TEST_COMMAND": '''python -c "import platform; print('running tests on ' + platform.machine())"''', "CIBW_ARCHS": "universal2", "CIBW_TEST_SKIP": "*_universal2:arm64" if skip_arm64_test else "", }, + single_python=True, ) captured = capfd.readouterr() @@ -168,7 +166,8 @@ def test_universal2_testing_on_x86_64(tmp_path, capfd, skip_arm64_test): else: assert warning_message in captured.err - expected_wheels = [w for w in ALL_MACOS_WHEELS if "cp39" in w and "universal2" in w] + python_tag = "cp{}{}".format(*utils.SINGLE_PYTHON_VERSION) + expected_wheels = [w for w in ALL_MACOS_WHEELS if python_tag in w and "universal2" in w] assert set(actual_wheels) == set(expected_wheels) @@ -186,19 +185,20 @@ def test_universal2_testing_on_arm64(tmp_path, capfd): actual_wheels = utils.cibuildwheel_run( project_dir, add_env={ - "CIBW_BUILD": "cp39-*", "CIBW_ARCHS": "universal2", # check that a native dependency is correctly installed, once per each testing arch "CIBW_TEST_REQUIRES": "numpy", "CIBW_TEST_COMMAND": '''python -c "import numpy, platform; print(f'running tests on {platform.machine()} with numpy {numpy.__version__}')"''', }, + single_python=True, ) captured = capfd.readouterr() assert "running tests on arm64" in captured.out assert "running tests on x86_64" in captured.out - expected_wheels = [w for w in ALL_MACOS_WHEELS if "cp39" in w and "universal2" in w] + python_tag = "cp{}{}".format(*utils.SINGLE_PYTHON_VERSION) + expected_wheels = [w for w in ALL_MACOS_WHEELS if python_tag in w and "universal2" in w] assert set(actual_wheels) == set(expected_wheels) diff --git a/test/test_musllinux_X_Y_only.py b/test/test_musllinux_X_Y_only.py index d05bc9f8..55ceb216 100644 --- a/test/test_musllinux_X_Y_only.py +++ b/test/test_musllinux_X_Y_only.py @@ -38,7 +38,7 @@ def test(musllinux_image, tmp_path): # build the wheels add_env = { - "CIBW_BUILD": "*-musllinux*", + "CIBW_SKIP": "*-manylinux*", "CIBW_MUSLLINUX_X86_64_IMAGE": musllinux_image, "CIBW_MUSLLINUX_I686_IMAGE": musllinux_image, "CIBW_MUSLLINUX_AARCH64_IMAGE": musllinux_image, @@ -46,11 +46,12 @@ def test(musllinux_image, tmp_path): "CIBW_MUSLLINUX_S390X_IMAGE": musllinux_image, } - actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env) + actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env, single_python=True) expected_wheels = utils.expected_wheels( "spam", "0.1.0", manylinux_versions=[], musllinux_versions=[musllinux_image], + single_python=True, ) assert set(actual_wheels) == set(expected_wheels) diff --git a/test/test_subdir_package.py b/test/test_subdir_package.py index cc1abd1b..66533970 100644 --- a/test/test_subdir_package.py +++ b/test/test_subdir_package.py @@ -45,13 +45,12 @@ def test(capfd, tmp_path): add_env={ "CIBW_BEFORE_BUILD": "python {project}/bin/before_build.py", "CIBW_TEST_COMMAND": "python {package}/test/run_tests.py", - # this shouldn't depend on the version of python, so build only CPython 3.10 - "CIBW_BUILD": "cp310-*", }, + single_python=True, ) # check that the expected wheels are produced - expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0") if "cp310" in w] + expected_wheels = utils.expected_wheels("spam", "0.1.0", single_python=True) assert set(actual_wheels) == set(expected_wheels) captured = capfd.readouterr() diff --git a/test/test_testing.py b/test/test_testing.py index 2e9dd7c5..03f6afb0 100644 --- a/test/test_testing.py +++ b/test/test_testing.py @@ -105,10 +105,11 @@ def test_extras_require(tmp_path): "CIBW_TEST_COMMAND": "false || pytest {project}/test", "CIBW_TEST_COMMAND_WINDOWS": "COLOR 00 || pytest {project}/test", }, + single_python=True, ) # also check that we got the right wheels - expected_wheels = utils.expected_wheels("spam", "0.1.0") + expected_wheels = utils.expected_wheels("spam", "0.1.0", single_python=True) assert set(actual_wheels) == set(expected_wheels) diff --git a/test/test_wheel_tag.py b/test/test_wheel_tag.py index 786eaa7a..1f179ffe 100644 --- a/test/test_wheel_tag.py +++ b/test/test_wheel_tag.py @@ -18,17 +18,14 @@ def test_wheel_tag_is_correct_when_using_macosx_deployment_target(tmp_path): deployment_target = "10.11" actual_wheels = utils.cibuildwheel_run( project_dir, - add_env={ - "CIBW_BUILD": "cp39-*", - "MACOSX_DEPLOYMENT_TARGET": deployment_target, - }, + add_env={"MACOSX_DEPLOYMENT_TARGET": deployment_target}, + single_python=True, ) # check that the expected wheels are produced expected_wheels = utils.expected_wheels( - "spam", "0.1.0", macosx_deployment_target=deployment_target + "spam", "0.1.0", macosx_deployment_target=deployment_target, single_python=True ) - expected_wheels = [w for w in expected_wheels if "cp39" in w] print("actual_wheels", actual_wheels) print("expected_wheels", expected_wheels) diff --git a/test/test_windows.py b/test/test_windows.py index 43be80b5..cf9f54c9 100644 --- a/test/test_windows.py +++ b/test/test_windows.py @@ -60,16 +60,13 @@ def test_wheel_tag_is_correct_when_using_windows_cross_compile(tmp_path, use_pyp # build the wheels actual_wheels = utils.cibuildwheel_run( project_dir, - add_env={ - "CIBW_BUILD": "cp310-*", - }, add_args=["--archs", "ARM64"], + single_python=True, ) # check that the expected wheels are produced - expected_wheels = [ - "spam-0.1.0-cp310-cp310-win_arm64.whl", - ] + tag = "cp{}{}".format(*utils.SINGLE_PYTHON_VERSION) + expected_wheels = [f"spam-0.1.0-{tag}-{tag}-win_arm64.whl"] print("actual_wheels", actual_wheels) print("expected_wheels", expected_wheels) diff --git a/test/utils.py b/test/utils.py index 08e2bc93..76c8163b 100644 --- a/test/utils.py +++ b/test/utils.py @@ -11,9 +11,12 @@ import platform as pm import subprocess import sys from tempfile import TemporaryDirectory +from typing import Final from cibuildwheel.util import CIBW_CACHE_PATH +SINGLE_PYTHON_VERSION: Final[tuple[int, int]] = (3, 12) + platform: str if "CIBW_PLATFORM" in os.environ: @@ -67,7 +70,13 @@ def _update_pip_cache_dir(env: dict[str, str]) -> None: def cibuildwheel_run( - project_path, package_dir=".", env=None, add_env=None, output_dir=None, add_args=None + project_path, + package_dir=".", + env=None, + add_env=None, + output_dir=None, + add_args=None, + single_python=False, ): """ Runs cibuildwheel as a subprocess, building the project at project_path. @@ -99,6 +108,9 @@ def cibuildwheel_run( env.setdefault("CIBW_FREE_THREADED_SUPPORT", "1") + if single_python: + env["CIBW_BUILD"] = "cp{}{}-*".format(*SINGLE_PYTHON_VERSION) + with TemporaryDirectory() as tmp_output_dir: subprocess.run( [ @@ -141,6 +153,7 @@ def expected_wheels( machine_arch=None, python_abi_tags=None, include_universal2=False, + single_python=False, ): """ Returns a list of expected wheels from a run of cibuildwheel. @@ -206,6 +219,16 @@ def expected_wheels( "pp310-pypy310_pp73", ] + if single_python: + python_tag = "cp{}{}-".format(*SINGLE_PYTHON_VERSION) + python_abi_tags = [ + next( + tag + for tag in python_abi_tags + if tag.startswith(python_tag) and not tag.endswith("t") + ) + ] + wheels = [] for python_abi_tag in python_abi_tags: