tests: fully type the test suite (#2794)

* tests: fully type the test suite

* chore: require more typing

Signed-off-by: Henry Schreiner <henryfs@princeton.edu>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Signed-off-by: Henry Schreiner <henryfs@princeton.edu>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Henry Schreiner
2026-04-01 15:23:02 +01:00
committed by GitHub
co-authored by pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
parent 643b30c796
commit 097806b6b1
58 changed files with 627 additions and 339 deletions
+13 -8
View File
@@ -6,6 +6,7 @@ import pytest
import cibuildwheel.architecture
from cibuildwheel.architecture import Architecture, arch_synonym
from cibuildwheel.typing import PlatformName
@pytest.fixture(
@@ -20,7 +21,9 @@ from cibuildwheel.architecture import Architecture, arch_synonym
pytest.param(("windows", "win32", "ARM64", "arm"), id="windows-arm"),
]
)
def platform_machine(request, monkeypatch):
def platform_machine(
request: pytest.FixtureRequest, monkeypatch: pytest.MonkeyPatch
) -> tuple[str, str]:
platform_name, platform_value, machine_value, machine_name = request.param
monkeypatch.setattr(sys, "platform", platform_value)
monkeypatch.setattr(platform_module, "machine", lambda: machine_value)
@@ -28,7 +31,7 @@ def platform_machine(request, monkeypatch):
return platform_name, machine_name
def test_arch_auto(platform_machine):
def test_arch_auto(platform_machine: tuple[str, str]) -> None:
_, machine_name = platform_machine
arch_set = Architecture.auto_archs("linux")
@@ -52,7 +55,7 @@ def test_arch_auto(platform_machine):
assert arch_set == expected[machine_name]
def test_arch_auto64(platform_machine):
def test_arch_auto64(platform_machine: tuple[str, str]) -> None:
_, machine_name = platform_machine
arch_set = Architecture.parse_config("auto64", "linux")
@@ -68,7 +71,7 @@ def test_arch_auto64(platform_machine):
assert arch_set == expected[machine_name]
def test_arch_auto32(platform_machine):
def test_arch_auto32(platform_machine: tuple[str, str]) -> None:
_, machine_name = platform_machine
arch_set = Architecture.parse_config("auto32", "linux")
@@ -83,7 +86,7 @@ def test_arch_auto32(platform_machine):
assert arch_set == expected[machine_name]
def test_arch_auto_no_aarch32(monkeypatch):
def test_arch_auto_no_aarch32(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(sys, "platform", "linux")
monkeypatch.setattr(platform_module, "machine", lambda: "aarch64")
monkeypatch.setattr(shutil, "which", lambda *args, **kwargs: None)
@@ -103,14 +106,14 @@ def test_arch_auto_no_aarch32(monkeypatch):
assert arch_set == set()
def test_arch_native_on_ios(monkeypatch):
def test_arch_native_on_ios(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(sys, "platform", "darwin")
monkeypatch.setattr(platform_module, "machine", lambda: "arm64")
arch_set = Architecture.parse_config("native", platform="ios")
assert arch_set == {Architecture.arm64_iphonesimulator}
def test_arch_auto_on_ios(monkeypatch):
def test_arch_auto_on_ios(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(sys, "platform", "darwin")
monkeypatch.setattr(platform_module, "machine", lambda: "arm64")
arch_set = Architecture.parse_config("auto", platform="ios")
@@ -130,5 +133,7 @@ def test_arch_auto_on_ios(monkeypatch):
("x86", "windows", "macos", None),
],
)
def test_arch_synonym(arch, from_platform, to_platform, expected):
def test_arch_synonym(
arch: str, from_platform: PlatformName, to_platform: PlatformName, expected: str | None
) -> None:
assert arch_synonym(arch, from_platform, to_platform) == expected
+2 -2
View File
@@ -6,7 +6,7 @@ from cibuildwheel.extra import Printable, dump_python_configurations
from cibuildwheel.util import resources
def test_compare_configs():
def test_compare_configs() -> None:
txt = resources.BUILD_PLATFORMS.read_text()
with resources.BUILD_PLATFORMS.open("rb") as f2:
@@ -18,7 +18,7 @@ def test_compare_configs():
assert new_txt == txt
def test_dump_with_Version():
def test_dump_with_Version() -> None:
# MyPy doesn't understand deeply nested dicts correctly
example: dict[str, dict[str, list[dict[str, Printable]]]] = {
"windows": {
+15 -15
View File
@@ -4,7 +4,7 @@ import cibuildwheel.selector
from cibuildwheel.selector import BuildSelector, EnableGroup
def test_build():
def test_build() -> None:
build_selector = BuildSelector(
build_config="cp3*-* *-manylinux*", skip_config="", enable=frozenset([EnableGroup.PyPy])
)
@@ -41,7 +41,7 @@ def test_build():
assert not build_selector("pp311-win_amd64")
def test_build_filter_pre():
def test_build_filter_pre() -> None:
build_selector = BuildSelector(
build_config="cp3*-* *-manylinux*",
skip_config="",
@@ -55,7 +55,7 @@ def test_build_filter_pre():
assert not build_selector("cp313t-manylinux_x86_64")
def test_build_filter_pypy():
def test_build_filter_pypy() -> None:
build_selector = BuildSelector(
build_config="*",
skip_config="",
@@ -67,7 +67,7 @@ def test_build_filter_pypy():
assert not build_selector("pp39-manylinux_x86_64")
def test_build_filter_pypy_eol():
def test_build_filter_pypy_eol() -> None:
build_selector = BuildSelector(
build_config="*",
skip_config="",
@@ -79,7 +79,7 @@ def test_build_filter_pypy_eol():
assert build_selector("pp39-manylinux_x86_64")
def test_build_filter_pypy_all():
def test_build_filter_pypy_all() -> None:
build_selector = BuildSelector(
build_config="*",
skip_config="",
@@ -91,7 +91,7 @@ def test_build_filter_pypy_all():
assert build_selector("pp39-manylinux_x86_64")
def test_build_filter_pyodide_prerelease():
def test_build_filter_pyodide_prerelease() -> None:
build_selector = BuildSelector(
build_config="*",
skip_config="",
@@ -101,7 +101,7 @@ def test_build_filter_pyodide_prerelease():
assert build_selector("cp313-pyodide_wasm32")
def test_build_filter_pyodide():
def test_build_filter_pyodide() -> None:
build_selector = BuildSelector(
build_config="*",
skip_config="",
@@ -111,7 +111,7 @@ def test_build_filter_pyodide():
assert build_selector("cp313-pyodide_wasm32")
def test_skip():
def test_skip() -> None:
build_selector = BuildSelector(
build_config="*",
skip_config="pp310-* cp3?-manylinux_i686 cp36-win* *-win32",
@@ -136,7 +136,7 @@ def test_skip():
assert build_selector("cp37-win_amd64")
def test_build_and_skip():
def test_build_and_skip() -> None:
build_selector = BuildSelector(
build_config="cp36-* cp37-macosx* *-manylinux*",
skip_config="pp37-* cp37-manylinux_i686",
@@ -160,7 +160,7 @@ def test_build_and_skip():
assert not build_selector("cp37-win_amd64")
def test_build_braces():
def test_build_braces() -> None:
build_selector = BuildSelector(build_config="cp{36,37}*", skip_config="")
assert build_selector("cp36-manylinux_x86_64")
@@ -169,7 +169,7 @@ def test_build_braces():
assert not build_selector("cp39-manylinux_x86_64")
def test_build_limited_python():
def test_build_limited_python() -> None:
build_selector = BuildSelector(
build_config="*",
skip_config="",
@@ -190,7 +190,7 @@ def test_build_limited_python():
assert build_selector("gp311_242-win_amd64")
def test_build_limited_python_partial():
def test_build_limited_python_partial() -> None:
build_selector = BuildSelector(
build_config="*", skip_config="", requires_python=SpecifierSet(">=3.6, !=3.7.*")
)
@@ -201,7 +201,7 @@ def test_build_limited_python_partial():
assert build_selector("cp39-manylinux_x86_64")
def test_build_limited_python_patch():
def test_build_limited_python_patch() -> None:
build_selector = BuildSelector(
build_config="*", skip_config="", requires_python=SpecifierSet(">=3.6.8")
)
@@ -210,13 +210,13 @@ def test_build_limited_python_patch():
assert build_selector("cp37-manylinux_x86_64")
def test_build_free_threaded_python():
def test_build_free_threaded_python() -> None:
build_selector = BuildSelector(build_config="*", skip_config="", enable=frozenset(EnableGroup))
assert build_selector("cp313t-manylinux_x86_64")
def test_testing_selector():
def test_testing_selector() -> None:
# This is not a global import to keep pytest from collecting it as a test
test_selector = cibuildwheel.selector.TestSelector(skip_config="cp36-*")
+3 -3
View File
@@ -6,7 +6,7 @@ import pytest
MOCK_PACKAGE_DIR = Path("some_package_dir")
def pytest_addoption(parser):
def pytest_addoption(parser: pytest.Parser) -> None:
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(
@@ -18,13 +18,13 @@ def pytest_addoption(parser):
@pytest.fixture
def fake_package_dir(tmp_path, monkeypatch):
def fake_package_dir(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> list[str]:
"""
Monkey-patch enough for the main() function to run
"""
real_path_exists = Path.exists
def mock_path_exists(path):
def mock_path_exists(path: Path) -> bool:
if str(path).endswith(str(MOCK_PACKAGE_DIR / "setup.py")):
return True
else:
+4 -3
View File
@@ -1,4 +1,5 @@
import ssl
from pathlib import Path
import certifi
import pytest
@@ -8,21 +9,21 @@ from cibuildwheel.util.file import download
DOWNLOAD_URL = "https://cdn.jsdelivr.net/gh/pypa/cibuildwheel@v1.6.3/requirements-dev.txt"
def test_download(monkeypatch, tmp_path):
def test_download(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
monkeypatch.delenv("SSL_CERT_FILE", raising=False)
dest = tmp_path / "file.txt"
download(DOWNLOAD_URL, dest)
assert len(dest.read_bytes()) == 134
def test_download_good_ssl_cert_file(monkeypatch, tmp_path):
def test_download_good_ssl_cert_file(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
monkeypatch.setenv("SSL_CERT_FILE", certifi.where())
dest = tmp_path / "file.txt"
download(DOWNLOAD_URL, dest)
assert len(dest.read_bytes()) == 134
def test_download_bad_ssl_cert_file(monkeypatch, tmp_path):
def test_download_bad_ssl_cert_file(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
bad_cafile = tmp_path / "ca.pem"
bad_cafile.write_text("bad certificates")
monkeypatch.setenv("SSL_CERT_FILE", str(bad_cafile))
+11 -11
View File
@@ -7,7 +7,7 @@ from cibuildwheel.environment import parse_environment
PYTHON_ECHO = f"'{sys.executable}' -c \"import sys; print(*sys.argv[1:])\""
def test_basic_parsing():
def test_basic_parsing() -> None:
environment_recipe = parse_environment("VAR=1 VBR=2")
environment_dict = environment_recipe.as_dictionary(prev_environment={})
@@ -15,7 +15,7 @@ def test_basic_parsing():
assert environment_dict == {"VAR": "1", "VBR": "2"}
def test_quotes():
def test_quotes() -> None:
environment_recipe = parse_environment("A=1 VAR=\"1 NOT_A_VAR=2\" VBR='vbr'")
environment_dict = environment_recipe.as_dictionary(prev_environment={})
@@ -23,7 +23,7 @@ def test_quotes():
assert environment_dict == {"A": "1", "VAR": "1 NOT_A_VAR=2", "VBR": "vbr"}
def test_inheritance():
def test_inheritance() -> None:
environment_recipe = parse_environment("PATH=$PATH:/usr/local/bin")
environment_dict = environment_recipe.as_dictionary(prev_environment={"PATH": "/usr/bin"})
@@ -31,7 +31,7 @@ def test_inheritance():
assert environment_dict == {"PATH": "/usr/bin:/usr/local/bin"}
def test_shell_eval():
def test_shell_eval() -> None:
environment_recipe = parse_environment(f'VAR="$({PYTHON_ECHO} "a test" string)"')
env_copy = os.environ.copy()
@@ -42,7 +42,7 @@ def test_shell_eval():
assert environment_dict["VAR"] == "a test string"
def test_shell_eval_and_env():
def test_shell_eval_and_env() -> None:
environment_recipe = parse_environment(f'VAR="$({PYTHON_ECHO} "$PREV_VAR" string)"')
prev_environment = {**os.environ, "PREV_VAR": "1 2 3"}
@@ -51,7 +51,7 @@ def test_shell_eval_and_env():
assert environment_dict == {**prev_environment, "VAR": "1 2 3 string"}
def test_empty_var():
def test_empty_var() -> None:
environment_recipe = parse_environment("CFLAGS=")
environment_dict = environment_recipe.as_dictionary(prev_environment={"CFLAGS": "-Wall"})
@@ -59,7 +59,7 @@ def test_empty_var():
assert environment_dict == {"CFLAGS": ""}
def test_no_vars():
def test_no_vars() -> None:
environment_recipe = parse_environment("")
environment_dict = environment_recipe.as_dictionary(prev_environment={})
@@ -67,7 +67,7 @@ def test_no_vars():
assert environment_dict == {}
def test_no_vars_pass_through():
def test_no_vars_pass_through() -> None:
environment_recipe = parse_environment("")
environment_dict = environment_recipe.as_dictionary(
@@ -77,7 +77,7 @@ def test_no_vars_pass_through():
assert environment_dict == {"CIBUILDWHEEL": "awesome"}
def test_operators_inside_eval():
def test_operators_inside_eval() -> None:
environment_recipe = parse_environment(
f'SOMETHING="$({PYTHON_ECHO} a; {PYTHON_ECHO} b; {PYTHON_ECHO} c)"'
)
@@ -88,7 +88,7 @@ def test_operators_inside_eval():
assert environment_dict.get("SOMETHING") == "a\nb\nc"
def test_substitution_with_backslash():
def test_substitution_with_backslash() -> None:
environment_recipe = parse_environment('PATH2="somewhere_else;$PATH1"')
environment_dict = environment_recipe.as_dictionary(prev_environment={"PATH1": "c:\\folder\\"})
@@ -96,7 +96,7 @@ def test_substitution_with_backslash():
assert environment_dict.get("PATH2") == "somewhere_else;c:\\folder\\"
def test_awkwardly_quoted_variable():
def test_awkwardly_quoted_variable() -> None:
environment_recipe = parse_environment(
f'VAR2=something"like this""$VAR1"$VAR1$({PYTHON_ECHO} "there is more")"$({PYTHON_ECHO} "and more!")"'
)
+17 -6
View File
@@ -1,6 +1,7 @@
import errno
import shutil
import sys
from pathlib import Path
import pytest
@@ -8,7 +9,9 @@ import cibuildwheel.__main__ as main_module
from cibuildwheel.__main__ import main
def test_clean_cache_when_cache_exists(tmp_path, monkeypatch, capfd):
def test_clean_cache_when_cache_exists(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capfd: pytest.CaptureFixture[str]
) -> None:
fake_cache_dir = (tmp_path / "cibw_cache").resolve()
monkeypatch.setattr(main_module, "CIBW_CACHE_PATH", fake_cache_dir)
@@ -40,7 +43,9 @@ def test_clean_cache_when_cache_exists(tmp_path, monkeypatch, capfd):
assert not fake_cache_dir.exists()
def test_clean_cache_when_cache_does_not_exist(tmp_path, monkeypatch, capfd):
def test_clean_cache_when_cache_does_not_exist(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capfd: pytest.CaptureFixture[str]
) -> None:
fake_cache_dir = (tmp_path / "nonexistent_cache").resolve()
monkeypatch.setattr(main_module, "CIBW_CACHE_PATH", fake_cache_dir)
@@ -55,7 +60,9 @@ def test_clean_cache_when_cache_does_not_exist(tmp_path, monkeypatch, capfd):
assert f"Cache directory does not exist: {fake_cache_dir}" in out
def test_clean_cache_with_error(tmp_path, monkeypatch, capfd):
def test_clean_cache_with_error(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capfd: pytest.CaptureFixture[str]
) -> None:
fake_cache_dir = (tmp_path / "cibw_cache").resolve()
monkeypatch.setattr(main_module, "CIBW_CACHE_PATH", fake_cache_dir)
@@ -73,7 +80,7 @@ def test_clean_cache_with_error(tmp_path, monkeypatch, capfd):
monkeypatch.setattr(sys, "argv", ["cibuildwheel", "--clean-cache"])
def fake_rmtree(path): # noqa: ARG001
def fake_rmtree(path: Path) -> None: # noqa: ARG001
raise OSError(errno.EACCES, "Permission denied")
monkeypatch.setattr(shutil, "rmtree", fake_rmtree)
@@ -88,7 +95,9 @@ def test_clean_cache_with_error(tmp_path, monkeypatch, capfd):
assert "Error clearing cache:" in err
def test_clean_cache_without_sentinel(tmp_path, monkeypatch, capfd):
def test_clean_cache_without_sentinel(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capfd: pytest.CaptureFixture[str]
) -> None:
fake_cache_dir = (tmp_path / "not_a_cache").resolve()
monkeypatch.setattr(main_module, "CIBW_CACHE_PATH", fake_cache_dir)
@@ -106,7 +115,9 @@ def test_clean_cache_without_sentinel(tmp_path, monkeypatch, capfd):
assert fake_cache_dir.exists()
def test_clean_cache_with_invalid_signature(tmp_path, monkeypatch, capfd):
def test_clean_cache_with_invalid_signature(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capfd: pytest.CaptureFixture[str]
) -> None:
fake_cache_dir = (tmp_path / "fake_cache").resolve()
monkeypatch.setattr(main_module, "CIBW_CACHE_PATH", fake_cache_dir)
+15 -13
View File
@@ -2,7 +2,9 @@ import contextlib
import platform as platform_module
import subprocess
import sys
from collections.abc import Generator, Iterator
from pathlib import Path
from typing import Any
import pytest
@@ -15,27 +17,27 @@ from cibuildwheel.util import file
class ArgsInterceptor:
def __init__(self) -> None:
self.call_count = 0
self.args: tuple[object, ...] | None = None
self.kwargs: dict[str, object] | None = None
self.args: tuple[Any, ...] = ()
self.kwargs: dict[str, Any] = {}
def __call__(self, *args: object, **kwargs: object) -> None:
def __call__(self, *args: Any, **kwargs: Any) -> None:
self.call_count += 1
self.args = args
self.kwargs = kwargs
@pytest.fixture(autouse=True)
def mock_protection(monkeypatch):
def mock_protection(monkeypatch: pytest.MonkeyPatch) -> None:
"""
Ensure that a unit test will never actually run a cibuildwheel 'build'
function, which shouldn't be run on a developer's machine
"""
def fail_on_call(*args, **kwargs):
def fail_on_call(*args: object, **kwargs: object) -> None:
msg = "This should never be called"
raise RuntimeError(msg)
def ignore_call(*args, **kwargs):
def ignore_call(*args: object, **kwargs: object) -> None:
pass
monkeypatch.setattr(subprocess, "Popen", fail_on_call)
@@ -49,27 +51,27 @@ def mock_protection(monkeypatch):
@pytest.fixture(autouse=True)
def fake_package_dir_autouse(fake_package_dir):
def fake_package_dir_autouse(fake_package_dir: list[str]) -> None:
pass
@pytest.fixture(autouse=True)
def disable_print_wheels(monkeypatch):
def disable_print_wheels(monkeypatch: pytest.MonkeyPatch) -> None:
@contextlib.contextmanager
def empty_cm(*args, **kwargs):
def empty_cm(*args: object, **kwargs: object) -> Generator[None, None, None]:
yield
monkeypatch.setattr(Logger, "print_summary", empty_cm)
@pytest.fixture
def allow_empty(monkeypatch, fake_package_dir):
def allow_empty(monkeypatch: pytest.MonkeyPatch, fake_package_dir: list[str]) -> None:
monkeypatch.setattr(sys, "argv", [*fake_package_dir, "--allow-empty"])
@pytest.fixture(params=["linux", "macos", "windows"])
def platform(request, monkeypatch):
platform_value = request.param
def platform(request: pytest.FixtureRequest, monkeypatch: pytest.MonkeyPatch) -> str:
platform_value: str = request.param
monkeypatch.setenv("CIBW_PLATFORM", platform_value)
if platform_value == "windows":
@@ -84,7 +86,7 @@ def platform(request, monkeypatch):
@pytest.fixture
def intercepted_build_args(monkeypatch):
def intercepted_build_args(monkeypatch: pytest.MonkeyPatch) -> Iterator[ArgsInterceptor]:
intercepted = ArgsInterceptor()
monkeypatch.setattr(android, "build", intercepted)
+127 -35
View File
@@ -1,7 +1,9 @@
import sys
import tomllib
from collections.abc import Mapping
from fnmatch import fnmatch
from pathlib import Path
from typing import TYPE_CHECKING
import pytest
@@ -13,10 +15,15 @@ from cibuildwheel.selector import BuildSelector, EnableGroup
from cibuildwheel.util import resources
from cibuildwheel.util.packaging import DependencyConstraints
if TYPE_CHECKING:
from .conftest import ArgsInterceptor
# CIBW_PLATFORM is tested in main_platform_test.py
def test_old_free_threaded(monkeypatch, capsys):
def test_old_free_threaded(
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
) -> None:
monkeypatch.setenv("CIBW_FREE_THREADED_SUPPORT", "ON")
with pytest.raises(SystemExit):
@@ -29,7 +36,9 @@ def test_old_free_threaded(monkeypatch, capsys):
@pytest.mark.usefixtures("platform")
def test_output_dir(intercepted_build_args, monkeypatch):
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))
@@ -40,7 +49,7 @@ def test_output_dir(intercepted_build_args, monkeypatch):
@pytest.mark.usefixtures("platform")
def test_output_dir_default(intercepted_build_args):
def test_output_dir_default(intercepted_build_args: "ArgsInterceptor") -> None:
main()
assert intercepted_build_args.args[0].globals.output_dir == Path("wheelhouse").resolve()
@@ -48,7 +57,11 @@ def test_output_dir_default(intercepted_build_args):
@pytest.mark.usefixtures("platform")
@pytest.mark.parametrize("also_set_environment", [False, True])
def test_output_dir_argument(also_set_environment, intercepted_build_args, monkeypatch):
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)])
@@ -61,7 +74,9 @@ def test_output_dir_argument(also_set_environment, intercepted_build_args, monke
@pytest.mark.usefixtures("platform", "allow_empty")
def test_build_selector(intercepted_build_args, monkeypatch):
def test_build_selector(
intercepted_build_args: "ArgsInterceptor", monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("CIBW_BUILD", "cp313-*")
monkeypatch.setenv("CIBW_SKIP", "cp39-*")
@@ -76,7 +91,9 @@ def test_build_selector(intercepted_build_args, monkeypatch):
@pytest.mark.usefixtures("platform", "allow_empty")
def test_invalid_build_selector(monkeypatch, capsys):
def test_invalid_build_selector(
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
) -> None:
monkeypatch.setenv("CIBW_BUILD", "invalid")
with pytest.raises(SystemExit) as e:
@@ -95,7 +112,12 @@ def test_invalid_build_selector(monkeypatch, capsys):
],
)
@pytest.mark.usefixtures("platform", "intercepted_build_args")
def test_invalid_skip_selector(monkeypatch, capsys, option_name, option_env_var):
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()
@@ -109,7 +131,9 @@ def test_invalid_skip_selector(monkeypatch, capsys, option_name, option_env_var)
"selector", ["*-macosx_universal2:arm64", "*-macosx_universal2:x86_64", "*-macosx_arm64"]
)
@pytest.mark.usefixtures("platform", "intercepted_build_args")
def test_valid_test_skip_selector(monkeypatch, capsys, selector):
def test_valid_test_skip_selector(
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str], selector: str
) -> None:
monkeypatch.setenv("CIBW_TEST_SKIP", selector)
main()
@@ -121,7 +145,9 @@ def test_valid_test_skip_selector(monkeypatch, capsys, selector):
@pytest.mark.parametrize("selector", ["*-macosx_universal2:invalid", "*-macosx_arm64:arm64"])
@pytest.mark.usefixtures("platform", "intercepted_build_args")
def test_invalid_test_skip_selector(monkeypatch, capsys, selector):
def test_invalid_test_skip_selector(
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str], selector: str
) -> None:
monkeypatch.setenv("CIBW_TEST_SKIP", selector)
main()
@@ -132,7 +158,7 @@ def test_invalid_test_skip_selector(monkeypatch, capsys, selector):
@pytest.mark.usefixtures("platform", "intercepted_build_args")
def test_empty_selector(monkeypatch):
def test_empty_selector(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("CIBW_SKIP", "*")
with pytest.raises(SystemExit) as e:
@@ -161,8 +187,13 @@ def test_empty_selector(monkeypatch):
],
)
def test_manylinux_images(
architecture, image, full_image, platform, intercepted_build_args, monkeypatch
):
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)
@@ -194,8 +225,12 @@ def get_default_repair_command(platform: str) -> str:
@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, platform_specific, platform, intercepted_build_args, monkeypatch
):
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)
@@ -216,7 +251,13 @@ def test_repair_command(
[{}, {"something": "value"}, {"something": "value", "something_else": "other_value"}],
)
@pytest.mark.parametrize("platform_specific", [False, True])
def test_environment(environment, platform_specific, platform, intercepted_build_args, monkeypatch):
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)
@@ -236,8 +277,12 @@ def test_environment(environment, platform_specific, platform, intercepted_build
@pytest.mark.parametrize("test_requires", [None, "requirement other_requirement"])
@pytest.mark.parametrize("platform_specific", [False, True])
def test_test_requires(
test_requires, platform_specific, platform, intercepted_build_args, monkeypatch
):
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)
@@ -254,7 +299,13 @@ def test_test_requires(
@pytest.mark.parametrize("test_extras", [None, "extras"])
@pytest.mark.parametrize("platform_specific", [False, True])
def test_test_extras(test_extras, platform_specific, platform, intercepted_build_args, monkeypatch):
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)
@@ -272,8 +323,12 @@ def test_test_extras(test_extras, platform_specific, platform, intercepted_build
@pytest.mark.parametrize("test_command", [None, "test --command"])
@pytest.mark.parametrize("platform_specific", [False, True])
def test_test_command(
test_command, platform_specific, platform, intercepted_build_args, monkeypatch
):
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)
@@ -291,8 +346,12 @@ def test_test_command(
@pytest.mark.parametrize("before_build", [None, "before --build"])
@pytest.mark.parametrize("platform_specific", [False, True])
def test_before_build(
before_build, platform_specific, platform, intercepted_build_args, monkeypatch
):
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)
@@ -309,8 +368,12 @@ def test_before_build(
@pytest.mark.parametrize("build_verbosity", [None, 0, 2, -2, 4, -4])
@pytest.mark.parametrize("platform_specific", [False, True])
def test_build_verbosity(
build_verbosity, platform_specific, platform, intercepted_build_args, monkeypatch
):
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))
@@ -326,7 +389,12 @@ def test_build_verbosity(
@pytest.mark.parametrize("platform_specific", [False, True])
def test_config_settings(platform_specific, platform, intercepted_build_args, monkeypatch):
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"'
)
@@ -376,7 +444,9 @@ def test_config_settings(platform_specific, platform, intercepted_build_args, mo
],
)
@pytest.mark.usefixtures("platform", "intercepted_build_args", "allow_empty")
def test_build_selector_deprecated_error(monkeypatch, selector, pattern, capsys):
def test_build_selector_deprecated_error(
monkeypatch: pytest.MonkeyPatch, selector: str, pattern: str, capsys: pytest.CaptureFixture[str]
) -> None:
monkeypatch.setenv(selector, pattern)
monkeypatch.delenv("CIBW_ENABLE", raising=False)
@@ -396,7 +466,13 @@ def test_build_selector_deprecated_error(monkeypatch, selector, pattern, capsys)
@pytest.mark.parametrize("before_all", ["", None, "test text"])
@pytest.mark.parametrize("platform_specific", [False, True])
def test_before_all(before_all, platform_specific, platform, intercepted_build_args, monkeypatch):
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)
@@ -417,8 +493,13 @@ def test_before_all(before_all, platform_specific, platform, intercepted_build_a
)
@pytest.mark.parametrize("platform_specific", [False, True])
def test_dependency_versions(
dependency_versions, platform_specific, platform, intercepted_build_args, monkeypatch, tmp_path
):
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":
@@ -443,13 +524,16 @@ def test_dependency_versions(
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, method, capfd):
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":
@@ -471,7 +555,9 @@ def test_debug_traceback(monkeypatch, method, capfd):
@pytest.mark.parametrize("method", ["unset", "command_line", "env_var"])
def test_enable(method, intercepted_build_args, monkeypatch):
def test_enable(
method: str, intercepted_build_args: "ArgsInterceptor", monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.delenv("CIBW_ENABLE", raising=False)
if method == "command_line":
@@ -489,7 +575,9 @@ def test_enable(method, intercepted_build_args, monkeypatch):
assert enable_groups == frozenset([EnableGroup.PyPy, EnableGroup.GraalPy])
def test_enable_all(intercepted_build_args, monkeypatch):
def test_enable_all(
intercepted_build_args: "ArgsInterceptor", monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setattr(sys, "argv", [*sys.argv, "--enable", "all"])
main()
@@ -498,7 +586,9 @@ def test_enable_all(intercepted_build_args, monkeypatch):
assert enable_groups == EnableGroup.all_groups()
def test_enable_arg_inherits(intercepted_build_args, monkeypatch):
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"])
@@ -511,7 +601,9 @@ def test_enable_arg_inherits(intercepted_build_args, monkeypatch):
)
def test_enable_arg_error_message(monkeypatch, capsys):
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:
@@ -522,7 +614,7 @@ def test_enable_arg_error_message(monkeypatch, capsys):
assert "Valid group names are:" in err
def test_defaults(platform, intercepted_build_args):
def test_defaults(platform: str, intercepted_build_args: "ArgsInterceptor") -> None:
main()
build_options: BuildOptions = intercepted_build_args.args[0].build_options(identifier=None)
+60 -19
View File
@@ -5,12 +5,18 @@ 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, intercepted_build_args, option_value):
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:
@@ -31,7 +37,9 @@ def test_platform_unset_or_auto(monkeypatch, intercepted_build_args, option_valu
pytest.fail(f"Unknown platform: {sys.platform}")
def test_unknown_platform_on_ci(monkeypatch, capsys):
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)
@@ -44,7 +52,9 @@ def test_unknown_platform_on_ci(monkeypatch, capsys):
assert 'Unable to detect platform from "sys.platform"' in err
def test_unknown_platform(monkeypatch, capsys):
def test_unknown_platform(
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
) -> None:
monkeypatch.setenv("CIBW_PLATFORM", "nonexistent")
with pytest.raises(SystemExit) as exit:
@@ -55,7 +65,9 @@ def test_unknown_platform(monkeypatch, capsys):
assert "Unsupported platform: nonexistent" in err
def test_platform_argument(platform, intercepted_build_args, monkeypatch):
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])
@@ -67,14 +79,14 @@ def test_platform_argument(platform, intercepted_build_args, monkeypatch):
@pytest.mark.usefixtures("platform")
def test_platform_environment(intercepted_build_args):
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, intercepted_build_args):
def test_archs_default(platform: str, intercepted_build_args: ArgsInterceptor) -> None:
main()
options = intercepted_build_args.args[0]
@@ -87,7 +99,12 @@ def test_archs_default(platform, intercepted_build_args):
@pytest.mark.parametrize("use_env_var", [False, True])
def test_archs_argument(platform, intercepted_build_args, monkeypatch, use_env_var):
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:
@@ -105,7 +122,9 @@ def test_archs_argument(platform, intercepted_build_args, monkeypatch, use_env_v
assert options.globals.architectures == {Architecture.ppc64le}
def test_archs_platform_specific(platform, intercepted_build_args, monkeypatch):
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")
@@ -122,7 +141,9 @@ def test_archs_platform_specific(platform, intercepted_build_args, monkeypatch):
assert options.globals.architectures == {Architecture.x86_64}
def test_archs_platform_native(platform, intercepted_build_args, monkeypatch):
def test_archs_platform_native(
platform: str, intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("CIBW_ARCHS", "native")
main()
@@ -134,7 +155,9 @@ def test_archs_platform_native(platform, intercepted_build_args, monkeypatch):
assert options.globals.architectures == {Architecture.AMD64}
def test_archs_platform_auto64(platform, intercepted_build_args, monkeypatch):
def test_archs_platform_auto64(
platform: str, intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("CIBW_ARCHS", "auto64")
main()
@@ -146,7 +169,9 @@ def test_archs_platform_auto64(platform, intercepted_build_args, monkeypatch):
assert options.globals.architectures == {Architecture.AMD64}
def test_archs_platform_auto32(platform, intercepted_build_args, monkeypatch):
def test_archs_platform_auto32(
platform: str, intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("CIBW_ARCHS", "auto32")
if platform == "macos":
@@ -165,7 +190,9 @@ def test_archs_platform_auto32(platform, intercepted_build_args, monkeypatch):
assert options.globals.architectures == {Architecture.x86}
def test_archs_platform_all(platform, intercepted_build_args, monkeypatch):
def test_archs_platform_all(
platform: str, intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("CIBW_ARCHS", "all")
main()
@@ -204,7 +231,12 @@ def test_archs_platform_all(platform, intercepted_build_args, monkeypatch):
("cp311-macosx_x86_64", "macos"),
),
)
def test_only_argument(intercepted_build_args, monkeypatch, only, plat):
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])
@@ -220,14 +252,14 @@ def test_only_argument(intercepted_build_args, monkeypatch, only, plat):
@pytest.mark.parametrize("only", ("cp311-manylxinux_x86_64", "some_linux_thing"))
def test_only_failed(monkeypatch, only):
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):
def test_only_no_platform(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(
sys, "argv", [*sys.argv, "--only", "cp311-manylinux_x86_64", "--platform", "macos"]
)
@@ -236,7 +268,7 @@ def test_only_no_platform(monkeypatch):
main()
def test_only_no_archs(monkeypatch):
def test_only_no_archs(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(
sys, "argv", [*sys.argv, "--only", "cp311-manylinux_x86_64", "--archs", "x86_64"]
)
@@ -254,7 +286,12 @@ def test_only_no_archs(monkeypatch):
("CIBW_PLATFORM", "macos"),
),
)
def test_only_overrides_env_vars(monkeypatch, intercepted_build_args, envvar_name, envvar_value):
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)
@@ -267,7 +304,9 @@ def test_only_overrides_env_vars(monkeypatch, intercepted_build_args, envvar_nam
assert options.globals.architectures == Architecture.all_archs("linux")
def test_pyodide_on_windows(monkeypatch, capsys):
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", "cp312-pyodide_wasm32"])
@@ -280,7 +319,9 @@ def test_pyodide_on_windows(monkeypatch, capsys):
assert "Building for pyodide is not supported on Windows" in err
def test_empty_archs_platform(platform, intercepted_build_args, monkeypatch):
def test_empty_archs_platform(
platform: PlatformName, intercepted_build_args: ArgsInterceptor, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("CIBW_ARCHS", "")
main()
@@ -1,14 +1,17 @@
import sys
import textwrap
from pathlib import Path
import pytest
from packaging.specifiers import SpecifierSet
from cibuildwheel.__main__ import main
from .conftest import ArgsInterceptor
@pytest.fixture(autouse=True)
def fake_package_dir(monkeypatch, tmp_path):
def fake_package_dir(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> Path:
"""
Set up a fake project
"""
@@ -24,7 +27,7 @@ def fake_package_dir(monkeypatch, tmp_path):
@pytest.mark.usefixtures("platform")
def test_no_override(intercepted_build_args):
def test_no_override(intercepted_build_args: ArgsInterceptor) -> None:
main()
options = intercepted_build_args.args[0]
@@ -37,7 +40,9 @@ def test_no_override(intercepted_build_args):
@pytest.mark.usefixtures("platform")
def test_override_env(monkeypatch, intercepted_build_args):
def test_override_env(
monkeypatch: pytest.MonkeyPatch, intercepted_build_args: ArgsInterceptor
) -> None:
monkeypatch.setenv("CIBW_PROJECT_REQUIRES_PYTHON", ">=3.8")
main()
@@ -52,7 +57,9 @@ def test_override_env(monkeypatch, intercepted_build_args):
@pytest.mark.usefixtures("platform")
def test_override_setup_cfg(intercepted_build_args, fake_package_dir):
def test_override_setup_cfg(
intercepted_build_args: ArgsInterceptor, fake_package_dir: Path
) -> None:
fake_package_dir.joinpath("setup.cfg").write_text(
textwrap.dedent(
"""
@@ -74,7 +81,9 @@ def test_override_setup_cfg(intercepted_build_args, fake_package_dir):
@pytest.mark.usefixtures("platform")
def test_override_pyproject_toml(intercepted_build_args, fake_package_dir):
def test_override_pyproject_toml(
intercepted_build_args: ArgsInterceptor, fake_package_dir: Path
) -> None:
fake_package_dir.joinpath("pyproject.toml").write_text(
textwrap.dedent(
"""
@@ -96,7 +105,9 @@ def test_override_pyproject_toml(intercepted_build_args, fake_package_dir):
@pytest.mark.usefixtures("platform")
def test_override_setup_py_simple(intercepted_build_args, fake_package_dir):
def test_override_setup_py_simple(
intercepted_build_args: ArgsInterceptor, fake_package_dir: Path
) -> None:
fake_package_dir.joinpath("setup.py").write_text(
textwrap.dedent(
"""
+26 -15
View File
@@ -1,3 +1,4 @@
import contextlib
import json
import os
import random
@@ -6,6 +7,7 @@ import subprocess
import sys
import textwrap
import time
from collections.abc import Iterator
from contextlib import nullcontext
from pathlib import Path, PurePath, PurePosixPath
@@ -34,7 +36,7 @@ PODMAN = OCIContainerEngineConfig(name="podman")
@pytest.fixture(params=["docker", "podman"], scope="module")
def container_engine(request):
def container_engine(request: pytest.FixtureRequest) -> Iterator[OCIContainerEngineConfig]:
if request.param == "docker" and not request.config.getoption("--run-docker"):
pytest.skip("need --run-docker option to run")
if request.param == "podman" and not request.config.getoption("--run-podman"):
@@ -63,21 +65,21 @@ def container_engine(request):
# Tests
def test_simple(container_engine):
def test_simple(container_engine: OCIContainerEngineConfig) -> None:
with OCIContainer(
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=DEFAULT_OCI_PLATFORM
) as container:
assert container.call(["echo", "hello"], capture_output=True) == "hello\n"
def test_no_lf(container_engine):
def test_no_lf(container_engine: OCIContainerEngineConfig) -> None:
with OCIContainer(
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=DEFAULT_OCI_PLATFORM
) as container:
assert container.call(["printf", "hello"], capture_output=True) == "hello"
def test_debug_info(container_engine):
def test_debug_info(container_engine: OCIContainerEngineConfig) -> None:
container = OCIContainer(
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=DEFAULT_OCI_PLATFORM
)
@@ -86,7 +88,7 @@ def test_debug_info(container_engine):
pass
def test_environment(container_engine):
def test_environment(container_engine: OCIContainerEngineConfig) -> None:
with OCIContainer(
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=DEFAULT_OCI_PLATFORM
) as container:
@@ -98,7 +100,9 @@ def test_environment(container_engine):
)
def test_environment_pass(container_engine, monkeypatch):
def test_environment_pass(
container_engine: OCIContainerEngineConfig, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("CIBUILDWHEEL", "1")
monkeypatch.setenv("SOURCE_DATE_EPOCH", "1489957071")
with OCIContainer(
@@ -111,7 +115,7 @@ def test_environment_pass(container_engine, monkeypatch):
)
def test_cwd(container_engine):
def test_cwd(container_engine: OCIContainerEngineConfig) -> None:
with OCIContainer(
engine=container_engine,
image=DEFAULT_IMAGE,
@@ -122,7 +126,7 @@ def test_cwd(container_engine):
assert container.call(["pwd"], capture_output=True, cwd="/opt") == "/opt\n"
def test_container_removed(container_engine):
def test_container_removed(container_engine: OCIContainerEngineConfig) -> None:
# test is flaky on some platforms, implement retry for 5 second
timeout = 50 # * 100 ms = 5s
with OCIContainer(
@@ -157,7 +161,7 @@ def test_container_removed(container_engine):
assert container_name not in docker_containers_listing
def test_large_environment(container_engine):
def test_large_environment(container_engine: OCIContainerEngineConfig) -> None:
# max environment variable size is 128kB
long_env_var_length = 127 * 1024
large_environment = {
@@ -177,7 +181,7 @@ def test_large_environment(container_engine):
)
def test_binary_output(container_engine):
def test_binary_output(container_engine: OCIContainerEngineConfig) -> None:
with OCIContainer(
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=DEFAULT_OCI_PLATFORM
) as container:
@@ -472,7 +476,9 @@ def test_create_args_volume(tmp_path: Path, container_engine: OCIContainerEngine
),
],
)
def test_parse_engine_config(config, name, create_args, capsys):
def test_parse_engine_config(
config: str, name: str, create_args: tuple[str, ...], capsys: pytest.CaptureFixture[str]
) -> None:
engine_config = OCIContainerEngineConfig.from_config_string(config)
assert engine_config.name == name
assert engine_config.create_args == create_args
@@ -485,7 +491,7 @@ def test_parse_engine_config(config, name, create_args, capsys):
@pytest.mark.skipif(DEFAULT_OCI_PLATFORM != OCIPlatform.AMD64, reason="Only runs on x86_64")
def test_enforce_32_bit(container_engine):
def test_enforce_32_bit(container_engine: OCIContainerEngineConfig) -> None:
with OCIContainer(
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=OCIPlatform.i386
) as container:
@@ -567,7 +573,7 @@ def test_local_image(
@pytest.mark.parametrize("platform", list(OCIPlatform))
def test_multiarch_image(container_engine, platform):
def test_multiarch_image(container_engine: OCIContainerEngineConfig, platform: OCIPlatform) -> None:
if detect_ci_provider() == CIProvider.travis_ci and DEFAULT_OCI_PLATFORM not in {
OCIPlatform.AMD64,
platform,
@@ -657,8 +663,13 @@ def test_multiarch_image(container_engine, platform):
("podman", '{"Client":{"Version":"2.1.0~rc1"}}', pytest.raises(OCIEngineTooOldError)),
],
)
def test_engine_version(engine_name, version, context, monkeypatch):
def mockcall(*args, **kwargs):
def test_engine_version(
engine_name: str,
version: str | None,
context: contextlib.AbstractContextManager[None],
monkeypatch: pytest.MonkeyPatch,
) -> None:
def mockcall(*args: object, **kwargs: object) -> str:
if version is None:
raise subprocess.CalledProcessError(1, " ".join(str(arg) for arg in args))
return version
+8 -8
View File
@@ -3,7 +3,7 @@ import subprocess
import sys
import typing
from contextlib import contextmanager
from pathlib import PurePosixPath
from pathlib import Path, PurePosixPath
from unittest import mock
import pytest
@@ -18,19 +18,19 @@ ALL_IDS = DEFAULT_IDS | {"cp313t", "pp38", "pp39", "pp310", "pp311", "gp311_242"
@pytest.fixture
def mock_build_container(monkeypatch):
def fail_on_call(*args, **kwargs):
def mock_build_container(monkeypatch: pytest.MonkeyPatch) -> None:
def fail_on_call(*args: object, **kwargs: object) -> None:
msg = "This should never be called"
raise RuntimeError(msg)
def ignore_call(*args, **kwargs):
def ignore_call(*args: object, **kwargs: object) -> None:
pass
@contextmanager
def nullcontext(enter_result=None):
def nullcontext(enter_result: object = None) -> typing.Generator[object, None, None]:
yield enter_result
def ignore_context_call(*args, **kwargs):
def ignore_context_call(*args: object, **kwargs: object) -> typing.ContextManager[object]:
return nullcontext(kwargs)
monkeypatch.setenv("CIBW_PLATFORM", "linux")
@@ -49,7 +49,7 @@ def mock_build_container(monkeypatch):
@pytest.mark.usefixtures("mock_build_container", "fake_package_dir")
def test_build_default_launches(monkeypatch):
def test_build_default_launches(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(sys, "argv", [*sys.argv, "--platform=linux"])
monkeypatch.setenv("CIBW_ARCHS", "auto64 auto32")
monkeypatch.delenv("CIBW_ENABLE", raising=False)
@@ -95,7 +95,7 @@ def test_build_default_launches(monkeypatch):
@pytest.mark.usefixtures("mock_build_container")
def test_build_with_override_launches(monkeypatch, tmp_path):
def test_build_with_override_launches(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
pkg_dir = tmp_path / "cibw_package"
pkg_dir.mkdir()
+7 -5
View File
@@ -48,7 +48,7 @@ manylinux-x86_64-image = "manylinux_2_34"
"""
def test_options_1(tmp_path, monkeypatch):
def test_options_1(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
with tmp_path.joinpath("pyproject.toml").open("w") as f:
f.write(PYPROJECT_1)
@@ -96,7 +96,7 @@ def test_options_1(tmp_path, monkeypatch):
assert local.pyodide_version == "0.28.0"
def test_passthrough(tmp_path, monkeypatch):
def test_passthrough(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
with tmp_path.joinpath("pyproject.toml").open("w") as f:
f.write(PYPROJECT_1)
@@ -126,7 +126,9 @@ def test_passthrough(tmp_path, monkeypatch):
"a trailing backslash \\",
],
)
def test_passthrough_evil(tmp_path, monkeypatch, env_var_value):
def test_passthrough_evil(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch, env_var_value: str
) -> None:
args = CommandLineArguments.defaults()
args.package_dir = tmp_path
@@ -157,7 +159,7 @@ xfail_env_parse = pytest.mark.xfail(
pytest.param("a trailing backslash \\", marks=[xfail_env_parse]),
],
)
def test_toml_environment_evil(tmp_path, env_var_value):
def test_toml_environment_evil(tmp_path: Path, env_var_value: str) -> None:
args = CommandLineArguments.defaults()
args.package_dir = tmp_path
@@ -296,7 +298,7 @@ def test_container_engine_option(
assert parsed_container_engine.disable_host_mount == result_disable_host_mount
def test_environment_pass_references():
def test_environment_pass_references() -> None:
options = Options(
platform="linux",
command_line_arguments=CommandLineArguments.defaults(),
+33 -32
View File
@@ -1,5 +1,6 @@
import shlex
from typing import TYPE_CHECKING
from pathlib import Path
from typing import Any, cast
import pytest
@@ -12,9 +13,7 @@ from cibuildwheel.options import (
ShlexTableFormat,
_resolve_cascade,
)
if TYPE_CHECKING:
from pathlib import Path
from cibuildwheel.typing import PlatformName
PYPROJECT_1 = """
[tool.cibuildwheel]
@@ -39,12 +38,12 @@ test-requires = ["other", "many"]
@pytest.fixture(params=["linux", "macos", "windows"])
def platform(request):
return request.param
def platform(request: pytest.FixtureRequest) -> PlatformName:
return cast("PlatformName", request.param)
@pytest.mark.parametrize("fname", ["pyproject.toml", "cibuildwheel.toml"])
def test_simple_settings(tmp_path, platform, fname):
def test_simple_settings(tmp_path: Path, platform: PlatformName, fname: str) -> None:
config_file_path: Path = tmp_path / fname
config_file_path.write_text(PYPROJECT_1)
@@ -83,7 +82,7 @@ def test_simple_settings(tmp_path, platform, fname):
options_reader.get("test-extras", option_format=ShlexTableFormat())
def test_envvar_override(tmp_path, platform):
def test_envvar_override(tmp_path: Path, platform: PlatformName) -> None:
config_file_path: Path = tmp_path / "pyproject.toml"
config_file_path.write_text(PYPROJECT_1)
@@ -128,7 +127,7 @@ def test_envvar_override(tmp_path, platform):
assert options_reader.get("test-command") == "mytest"
def test_project_global_override_default_platform(tmp_path, platform):
def test_project_global_override_default_platform(tmp_path: Path, platform: PlatformName) -> None:
pyproject_toml = tmp_path / "pyproject.toml"
pyproject_toml.write_text(
"""
@@ -140,14 +139,14 @@ repair-wheel-command = "repair-project-global"
assert options_reader.get("repair-wheel-command") == "repair-project-global"
def test_env_global_override_default_platform(platform):
def test_env_global_override_default_platform(platform: PlatformName) -> None:
options_reader = OptionsReader(
platform=platform, env={"CIBW_REPAIR_WHEEL_COMMAND": "repair-env-global"}
)
assert options_reader.get("repair-wheel-command") == "repair-env-global"
def test_env_global_override_project_platform(tmp_path, platform):
def test_env_global_override_project_platform(tmp_path: Path, platform: PlatformName) -> None:
pyproject_toml = tmp_path / "pyproject.toml"
pyproject_toml.write_text(
"""
@@ -161,7 +160,7 @@ repair-wheel-command = "repair-project-macos"
)
options_reader = OptionsReader(
pyproject_toml,
platform=platform,
platform=cast("Any", platform),
env={
"CIBW_REPAIR_WHEEL_COMMAND": "repair-env-global",
},
@@ -169,7 +168,7 @@ repair-wheel-command = "repair-project-macos"
assert options_reader.get("repair-wheel-command") == "repair-env-global"
def test_global_platform_order(tmp_path, platform):
def test_global_platform_order(tmp_path: Path, platform: str) -> None:
pyproject_toml = tmp_path / "pyproject.toml"
pyproject_toml.write_text(
"""
@@ -183,11 +182,11 @@ repair-wheel-command = "repair-project-macos"
repair-wheel-command = "repair-project-global"
"""
)
options_reader = OptionsReader(pyproject_toml, platform=platform, env={})
options_reader = OptionsReader(pyproject_toml, platform=cast("Any", platform), env={})
assert options_reader.get("repair-wheel-command") == f"repair-project-{platform}"
def test_unexpected_key(tmp_path):
def test_unexpected_key(tmp_path: Path) -> None:
# Note that platform contents are only checked when running
# for that platform.
pyproject_toml = tmp_path / "pyproject.toml"
@@ -204,7 +203,7 @@ repairs-wheel-command = "repair-project-linux"
assert "repair-wheel-command" in str(excinfo.value)
def test_underscores_in_key(tmp_path):
def test_underscores_in_key(tmp_path: Path) -> None:
# Note that platform contents are only checked when running
# for that platform.
pyproject_toml = tmp_path / "pyproject.toml"
@@ -221,7 +220,7 @@ repair_wheel_command = "repair-project-linux"
assert "repair-wheel-command" in str(excinfo.value)
def test_unexpected_table(tmp_path):
def test_unexpected_table(tmp_path: Path) -> None:
pyproject_toml = tmp_path / "pyproject.toml"
pyproject_toml.write_text(
"""
@@ -233,7 +232,7 @@ repair-wheel-command = "repair-project-linux"
OptionsReader(pyproject_toml, platform="linux", env={})
def test_unsupported_join(tmp_path):
def test_unsupported_join(tmp_path: Path) -> None:
pyproject_toml = tmp_path / "pyproject.toml"
pyproject_toml.write_text(
"""
@@ -248,7 +247,7 @@ build = ["1", "2"]
options_reader.get("build")
def test_disallowed_a(tmp_path):
def test_disallowed_a(tmp_path: Path) -> None:
pyproject_toml = tmp_path / "pyproject.toml"
pyproject_toml.write_text(
"""
@@ -262,7 +261,7 @@ manylinux-x86_64-image = "manylinux1"
OptionsReader(pyproject_toml, platform="windows", disallow=disallow, env={})
def test_environment_override_empty(tmp_path):
def test_environment_override_empty(tmp_path: Path) -> None:
pyproject_toml = tmp_path / "pyproject.toml"
pyproject_toml.write_text(
"""
@@ -296,7 +295,7 @@ manylinux-x86_64-image = ""
@pytest.mark.parametrize("ignore_empty", [True, False], ids=["ignore_empty", "no_ignore_empty"])
def test_resolve_cascade(ignore_empty):
def test_resolve_cascade(ignore_empty: bool) -> None:
answer = _resolve_cascade(
("not", InheritRule.NONE),
(None, InheritRule.NONE),
@@ -327,7 +326,7 @@ def test_resolve_cascade(ignore_empty):
@pytest.mark.parametrize("ignore_empty", [True, False], ids=["ignore_empty", "no_ignore_empty"])
@pytest.mark.parametrize("rule", [InheritRule.PREPEND, InheritRule.NONE, InheritRule.APPEND])
def test_resolve_cascade_merge_list(ignore_empty, rule):
def test_resolve_cascade_merge_list(ignore_empty: bool, rule: InheritRule) -> None:
answer = _resolve_cascade(
(["a1", "a2"], InheritRule.NONE),
([], InheritRule.NONE),
@@ -348,7 +347,7 @@ def test_resolve_cascade_merge_list(ignore_empty, rule):
@pytest.mark.parametrize("rule", [InheritRule.PREPEND, InheritRule.NONE, InheritRule.APPEND])
def test_resolve_cascade_merge_dict(rule):
def test_resolve_cascade_merge_dict(rule: InheritRule) -> None:
answer = _resolve_cascade(
({"value": "a1", "base": "b1"}, InheritRule.NONE),
(None, InheritRule.NONE),
@@ -365,7 +364,7 @@ def test_resolve_cascade_merge_dict(rule):
assert answer == "value=override base=b1"
def test_resolve_cascade_merge_strings():
def test_resolve_cascade_merge_strings() -> None:
answer = _resolve_cascade(
("value=a1 base=b1", InheritRule.NONE),
("value=override", InheritRule.APPEND),
@@ -374,7 +373,7 @@ def test_resolve_cascade_merge_strings():
assert answer == "value=override base=b1"
def test_resolve_cascade_merge_different_types():
def test_resolve_cascade_merge_different_types() -> None:
answer = _resolve_cascade(
("value=a1 base=b1", InheritRule.NONE),
({"value": "override"}, InheritRule.APPEND),
@@ -420,11 +419,13 @@ test-command = ["extra-prepend"]
"""
def test_pyproject_2(tmp_path, platform):
def test_pyproject_2(tmp_path: Path, platform: str) -> None:
pyproject_toml: Path = tmp_path / "pyproject.toml"
pyproject_toml.write_text(PYPROJECT_2)
options_reader = OptionsReader(config_file_path=pyproject_toml, platform=platform, env={})
options_reader = OptionsReader(
config_file_path=pyproject_toml, platform=cast("Any", platform), env={}
)
assert options_reader.get("test-command", option_format=ListFormat(" && ")) == "pyproject"
with options_reader.identifier("random"):
@@ -451,7 +452,7 @@ def test_pyproject_2(tmp_path, platform):
)
def test_overrides_not_a_list(tmp_path, platform):
def test_overrides_not_a_list(tmp_path: Path, platform: str) -> None:
pyproject_toml: Path = tmp_path / "pyproject.toml"
pyproject_toml.write_text(
@@ -465,10 +466,10 @@ test-command = "pyproject-override"
)
with pytest.raises(OptionsReaderError):
OptionsReader(config_file_path=pyproject_toml, platform=platform, env={})
OptionsReader(config_file_path=pyproject_toml, platform=cast("Any", platform), env={})
def test_config_settings(tmp_path):
def test_config_settings(tmp_path: Path) -> None:
pyproject_toml: Path = tmp_path / "pyproject.toml"
pyproject_toml.write_text(
"""\
@@ -485,7 +486,7 @@ other = ["two", "three"]
)
def test_pip_config_settings(tmp_path):
def test_pip_config_settings(tmp_path: Path) -> None:
pyproject_toml: Path = tmp_path / "pyproject.toml"
pyproject_toml.write_text(
"""\
@@ -501,7 +502,7 @@ def test_pip_config_settings(tmp_path):
)
def test_overrides_inherit(tmp_path):
def test_overrides_inherit(tmp_path: Path) -> None:
pyproject_toml: Path = tmp_path / "pyproject.toml"
pyproject_toml.write_text(
"""\
+16 -15
View File
@@ -1,4 +1,5 @@
import tomllib
from pathlib import Path
from textwrap import dedent
import pytest
@@ -10,7 +11,7 @@ from cibuildwheel.projectfiles import (
)
def test_read_setup_py_simple(tmp_path):
def test_read_setup_py_simple(tmp_path: Path) -> None:
with open(tmp_path / "setup.py", "w") as f:
f.write(
dedent(
@@ -31,7 +32,7 @@ def test_read_setup_py_simple(tmp_path):
assert get_requires_python_str(tmp_path, {}) == "1.23"
def test_read_setup_py_if_main(tmp_path):
def test_read_setup_py_if_main(tmp_path: Path) -> None:
with open(tmp_path / "setup.py", "w") as f:
f.write(
dedent(
@@ -53,7 +54,7 @@ def test_read_setup_py_if_main(tmp_path):
assert get_requires_python_str(tmp_path, {}) == "1.23"
def test_read_setup_py_if_main_reversed(tmp_path):
def test_read_setup_py_if_main_reversed(tmp_path: Path) -> None:
with open(tmp_path / "setup.py", "w") as f:
f.write(
dedent(
@@ -75,7 +76,7 @@ def test_read_setup_py_if_main_reversed(tmp_path):
assert get_requires_python_str(tmp_path, {}) == "1.23"
def test_read_setup_py_if_invalid(tmp_path):
def test_read_setup_py_if_invalid(tmp_path: Path) -> None:
with open(tmp_path / "setup.py", "w") as f:
f.write(
dedent(
@@ -97,7 +98,7 @@ def test_read_setup_py_if_invalid(tmp_path):
assert not get_requires_python_str(tmp_path, {})
def test_read_setup_py_full(tmp_path):
def test_read_setup_py_full(tmp_path: Path) -> None:
with open(tmp_path / "setup.py", "w", encoding="utf8") as f:
f.write(
dedent(
@@ -123,7 +124,7 @@ def test_read_setup_py_full(tmp_path):
assert get_requires_python_str(tmp_path, {}) == "1.24"
def test_read_setup_py_assign(tmp_path):
def test_read_setup_py_assign(tmp_path: Path) -> None:
with open(tmp_path / "setup.py", "w") as f:
f.write(
dedent(
@@ -146,7 +147,7 @@ def test_read_setup_py_assign(tmp_path):
assert get_requires_python_str(tmp_path, {}) is None
def test_read_setup_py_None(tmp_path):
def test_read_setup_py_None(tmp_path: Path) -> None:
with open(tmp_path / "setup.py", "w") as f:
f.write(
dedent(
@@ -169,7 +170,7 @@ def test_read_setup_py_None(tmp_path):
assert get_requires_python_str(tmp_path, {}) is None
def test_read_setup_py_empty(tmp_path):
def test_read_setup_py_empty(tmp_path: Path) -> None:
with open(tmp_path / "setup.py", "w") as f:
f.write(
dedent(
@@ -191,7 +192,7 @@ def test_read_setup_py_empty(tmp_path):
assert get_requires_python_str(tmp_path, {}) is None
def test_read_setup_cfg(tmp_path):
def test_read_setup_cfg(tmp_path: Path) -> None:
with open(tmp_path / "setup.cfg", "w") as f:
f.write(
dedent(
@@ -207,7 +208,7 @@ def test_read_setup_cfg(tmp_path):
assert get_requires_python_str(tmp_path, {}) == "1.234"
def test_read_setup_cfg_empty(tmp_path):
def test_read_setup_cfg_empty(tmp_path: Path) -> None:
with open(tmp_path / "setup.cfg", "w") as f:
f.write(
dedent(
@@ -223,7 +224,7 @@ def test_read_setup_cfg_empty(tmp_path):
assert get_requires_python_str(tmp_path, {}) is None
def test_read_pyproject_toml(tmp_path):
def test_read_pyproject_toml(tmp_path: Path) -> None:
with open(tmp_path / "pyproject.toml", "w") as f:
f.write(
dedent(
@@ -242,7 +243,7 @@ def test_read_pyproject_toml(tmp_path):
assert get_requires_python_str(tmp_path, pyproject_toml) == "1.654"
def test_read_pyproject_toml_empty(tmp_path):
def test_read_pyproject_toml_empty(tmp_path: Path) -> None:
with open(tmp_path / "pyproject.toml", "w") as f:
f.write(
dedent(
@@ -258,7 +259,7 @@ def test_read_pyproject_toml_empty(tmp_path):
assert get_requires_python_str(tmp_path, pyproject_toml) is None
def test_read_dep_groups():
def test_read_dep_groups() -> None:
pyproject_toml = {"dependency-groups": {"group1": ["pkg1", "pkg2"], "group2": ["pkg3"]}}
assert resolve_dependency_groups(pyproject_toml) == ()
assert resolve_dependency_groups(pyproject_toml, "group1") == ("pkg1", "pkg2")
@@ -266,11 +267,11 @@ def test_read_dep_groups():
assert resolve_dependency_groups(pyproject_toml, "group1", "group2") == ("pkg1", "pkg2", "pkg3")
def test_dep_group_no_file_error():
def test_dep_group_no_file_error() -> None:
with pytest.raises(FileNotFoundError, match=r"pyproject\.toml"):
resolve_dependency_groups(None, "test")
def test_dep_group_no_section_error():
def test_dep_group_no_section_error() -> None:
with pytest.raises(KeyError, match=r"pyproject\.toml"):
resolve_dependency_groups({}, "test")
+18 -12
View File
@@ -1,5 +1,5 @@
import textwrap
from pathlib import PurePath
from pathlib import Path, PurePath
from unittest.mock import Mock, call
import pytest
@@ -18,7 +18,7 @@ from cibuildwheel.util.helpers import (
from cibuildwheel.util.packaging import find_compatible_wheel
def test_format_safe():
def test_format_safe() -> None:
assert format_safe("{wheel}", wheel="filename.whl") == "filename.whl"
assert format_safe("command #{wheel}", wheel="filename.whl") == "command {wheel}"
assert format_safe("{command #{wheel}}", wheel="filename.whl") == "{command {wheel}}"
@@ -37,7 +37,7 @@ def test_format_safe():
assert format_safe("#{not_a_param} {param}", param="1") == "#{not_a_param} 1"
def test_prepare_command():
def test_prepare_command() -> None:
assert prepare_command("python -m {project}", project="project") == "python -m project"
assert prepare_command("python -m {something}", project="project") == "python -m {something}"
assert (
@@ -103,7 +103,7 @@ def test_find_compatible_wheel_not_found(wheel: str, identifier: str) -> None:
assert find_compatible_wheel([PurePath(wheel)], identifier) is None
def test_fix_ansi_codes_for_github_actions():
def test_fix_ansi_codes_for_github_actions() -> None:
input = textwrap.dedent(
"""
This line is normal
@@ -131,7 +131,7 @@ def test_fix_ansi_codes_for_github_actions():
assert output == expected
def test_parse_key_value_string():
def test_parse_key_value_string() -> None:
assert parse_key_value_string("bar", positional_arg_names=["foo"]) == {"foo": ["bar"]}
assert parse_key_value_string("foo:bar", kw_arg_names=["foo"]) == {"foo": ["bar"]}
with pytest.raises(ValueError, match="Too many positional arguments"):
@@ -212,7 +212,7 @@ def test_parse_key_value_string():
}
def test_flexible_version_comparisons():
def test_flexible_version_comparisons() -> None:
assert FlexibleVersion("2.0") == FlexibleVersion("2")
assert FlexibleVersion("2.0") < FlexibleVersion("2.1")
assert FlexibleVersion("2.1") > FlexibleVersion("2")
@@ -227,7 +227,7 @@ def test_flexible_version_comparisons():
@pytest.fixture
def sample_project(tmp_path):
def sample_project(tmp_path: Path) -> Path:
"""Create a directory structure that contains a range of files."""
project_path = tmp_path / "project"
@@ -324,7 +324,13 @@ def sample_project(tmp_path):
),
],
)
def test_copy_test_sources(tmp_path, sample_project, test_sources, expected, not_expected):
def test_copy_test_sources(
tmp_path: Path,
sample_project: Path,
test_sources: list[str],
expected: list[str],
not_expected: list[str],
) -> None:
"""Test sources can be copied into the test directory."""
target = tmp_path / "somewhere/test_cwd"
copy_test_sources(test_sources, sample_project, target)
@@ -336,7 +342,7 @@ def test_copy_test_sources(tmp_path, sample_project, test_sources, expected, not
assert not (tmp_path / "somewhere/test_cwd" / path).exists()
def test_copy_test_sources_missing_file(tmp_path, sample_project):
def test_copy_test_sources_missing_file(tmp_path: Path, sample_project: Path) -> None:
"""If test_sources references a folder that doesn't exist, an error is raised."""
with pytest.raises(
@@ -350,7 +356,7 @@ def test_copy_test_sources_missing_file(tmp_path, sample_project):
)
def test_copy_test_sources_alternate_copy_into(sample_project):
def test_copy_test_sources_alternate_copy_into(sample_project: Path) -> None:
"""If an alternate copy_into method is provided, it is used."""
target = PurePath("/container/test_cwd")
@@ -367,7 +373,7 @@ def test_copy_test_sources_alternate_copy_into(sample_project):
)
def test_unwrap():
def test_unwrap() -> None:
assert (
unwrap("""
This is a
@@ -378,7 +384,7 @@ def test_unwrap():
)
def test_unwrap_preserving_paragraphs():
def test_unwrap_preserving_paragraphs() -> None:
assert (
unwrap("""
This is a
+2 -2
View File
@@ -9,7 +9,7 @@ OPTIONS_DEFAULTS = Options("linux", CommandLineArguments.defaults(), {}, default
FILE = Path(__file__)
def test_printout_wheels(capsys):
def test_printout_wheels(capsys: pytest.CaptureFixture[str]) -> None:
log = Logger()
log.fold_mode = "disabled"
log.colors_enabled = False
@@ -32,7 +32,7 @@ def test_printout_wheels(capsys):
assert "SHA256=" in captured.out
def test_no_printout_on_error(capsys):
def test_no_printout_on_error(capsys: pytest.CaptureFixture[str]) -> None:
log = Logger()
with pytest.raises(RuntimeError), log.print_summary(options=OPTIONS_DEFAULTS):
raise RuntimeError()