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:
co-authored by
pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
parent
643b30c796
commit
097806b6b1
@@ -52,7 +52,7 @@ class Unbuffered:
|
|||||||
self.stream.writelines(data)
|
self.stream.writelines(data)
|
||||||
self.stream.flush()
|
self.stream.flush()
|
||||||
|
|
||||||
def __getattr__(self, attr: str) -> Any:
|
def __getattr__(self, attr: str) -> Any: # noqa: ANN401
|
||||||
return getattr(self.stream, attr)
|
return getattr(self.stream, attr)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ class ParsedEnvironment:
|
|||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"{self.__class__.__name__}({[repr(a) for a in self.assignments]!r})"
|
return f"{self.__class__.__name__}({[repr(a) for a in self.assignments]!r})"
|
||||||
|
|
||||||
def options_summary(self) -> Any:
|
def options_summary(self) -> list[EnvironmentAssignment]:
|
||||||
return self.assignments
|
return self.assignments
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -987,8 +987,8 @@ class Options:
|
|||||||
def option_summary(
|
def option_summary(
|
||||||
self,
|
self,
|
||||||
option_name: str,
|
option_name: str,
|
||||||
option_value: Any,
|
option_value: Any, # noqa: ANN401
|
||||||
default_value: Any,
|
default_value: Any, # noqa: ANN401
|
||||||
overrides: Mapping[str, Any] | None = None,
|
overrides: Mapping[str, Any] | None = None,
|
||||||
skip_unset: bool = False,
|
skip_unset: bool = False,
|
||||||
) -> str | None:
|
) -> str | None:
|
||||||
@@ -1040,7 +1040,7 @@ class Options:
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def option_summary_value(option_value: Any) -> str:
|
def option_summary_value(option_value: Any) -> str: # noqa: ANN401
|
||||||
if hasattr(option_value, "options_summary"):
|
if hasattr(option_value, "options_summary"):
|
||||||
option_value = option_value.options_summary()
|
option_value = option_value.options_summary()
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import dataclasses
|
|||||||
import itertools
|
import itertools
|
||||||
from enum import StrEnum
|
from enum import StrEnum
|
||||||
from fnmatch import fnmatch
|
from fnmatch import fnmatch
|
||||||
from typing import Any, Self
|
from typing import Self
|
||||||
|
|
||||||
import bracex
|
import bracex
|
||||||
from packaging.specifiers import SpecifierSet
|
from packaging.specifiers import SpecifierSet
|
||||||
@@ -113,7 +113,7 @@ class BuildSelector:
|
|||||||
|
|
||||||
return should_build and not should_skip
|
return should_build and not should_skip
|
||||||
|
|
||||||
def options_summary(self) -> Any:
|
def options_summary(self) -> dict[str, str | list[str]]:
|
||||||
return {
|
return {
|
||||||
"build_config": self.build_config,
|
"build_config": self.build_config,
|
||||||
"skip_config": self.skip_config,
|
"skip_config": self.skip_config,
|
||||||
@@ -134,5 +134,5 @@ class TestSelector:
|
|||||||
should_skip = selector_matches(self.skip_config, build_id)
|
should_skip = selector_matches(self.skip_config, build_id)
|
||||||
return not should_skip
|
return not should_skip
|
||||||
|
|
||||||
def options_summary(self) -> Any:
|
def options_summary(self) -> dict[str, str]:
|
||||||
return {"skip_config": self.skip_config}
|
return {"skip_config": self.skip_config}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import shlex
|
|||||||
from collections.abc import Mapping, Sequence
|
from collections.abc import Mapping, Sequence
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from pathlib import Path, PurePath
|
from pathlib import Path, PurePath
|
||||||
from typing import Any, Literal, Self, TypeVar
|
from typing import Literal, Self, TypeVar
|
||||||
|
|
||||||
from packaging.utils import parse_wheel_filename
|
from packaging.utils import parse_wheel_filename
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ class DependencyConstraints:
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def options_summary(self) -> Any:
|
def options_summary(self) -> str | dict[str, str]:
|
||||||
if self == DependencyConstraints.pinned():
|
if self == DependencyConstraints.pinned():
|
||||||
return "pinned"
|
return "pinned"
|
||||||
elif self.packages:
|
elif self.packages:
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ import rich.console
|
|||||||
import rich.text
|
import rich.text
|
||||||
|
|
||||||
|
|
||||||
def define_env(env: Any) -> None:
|
def define_env(env: Any) -> None: # noqa: ANN401
|
||||||
"Hook function for mkdocs-macros"
|
"Hook function for mkdocs-macros"
|
||||||
|
|
||||||
@env.macro # type: ignore[untyped-decorator]
|
@env.macro # type: ignore[untyped-decorator]
|
||||||
|
|||||||
+3
-5
@@ -129,14 +129,9 @@ files = [
|
|||||||
]
|
]
|
||||||
warn_unused_configs = true
|
warn_unused_configs = true
|
||||||
strict = true
|
strict = true
|
||||||
disallow_untyped_defs = false
|
|
||||||
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
|
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
|
||||||
warn_unreachable = false
|
warn_unreachable = false
|
||||||
|
|
||||||
[[tool.mypy.overrides]]
|
|
||||||
module = "cibuildwheel.*"
|
|
||||||
disallow_untyped_defs = true
|
|
||||||
|
|
||||||
[[tool.mypy.overrides]]
|
[[tool.mypy.overrides]]
|
||||||
module = [
|
module = [
|
||||||
"setuptools._distutils", # needed even if only directly import setuptools._distutils.util
|
"setuptools._distutils", # needed even if only directly import setuptools._distutils.util
|
||||||
@@ -196,6 +191,7 @@ extend-select = [
|
|||||||
"B", # flake8-bugbear
|
"B", # flake8-bugbear
|
||||||
"I", # isort
|
"I", # isort
|
||||||
"ARG", # flake8-unused-arguments
|
"ARG", # flake8-unused-arguments
|
||||||
|
"ANN", # flake8-annotations
|
||||||
"C4", # flake8-comprehensions
|
"C4", # flake8-comprehensions
|
||||||
"EM", # flake8-errmsg
|
"EM", # flake8-errmsg
|
||||||
"ICN", # flake8-import-conventions
|
"ICN", # flake8-import-conventions
|
||||||
@@ -236,6 +232,8 @@ ignore = [
|
|||||||
]
|
]
|
||||||
flake8-unused-arguments.ignore-variadic-names = true
|
flake8-unused-arguments.ignore-variadic-names = true
|
||||||
flake8-tidy-imports.ban-relative-imports = "all"
|
flake8-tidy-imports.ban-relative-imports = "all"
|
||||||
|
flake8-annotations.allow-star-arg-any = true
|
||||||
|
flake8-annotations.mypy-init-return = true
|
||||||
|
|
||||||
[tool.ruff.lint.flake8-tidy-imports.banned-api]
|
[tool.ruff.lint.flake8-tidy-imports.banned-api]
|
||||||
"typing.Mapping".msg = "Use collections.abc.Mapping instead."
|
"typing.Mapping".msg = "Use collections.abc.Mapping instead."
|
||||||
|
|||||||
+1
-1
@@ -46,7 +46,7 @@ def pytest_addoption(parser: pytest.Parser) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def pytest_configure(config):
|
def pytest_configure(config: pytest.Config) -> None:
|
||||||
flag_enable = config.getoption("--enable")
|
flag_enable = config.getoption("--enable")
|
||||||
flag_platform = config.getoption("--platform")
|
flag_platform = config.getoption("--platform")
|
||||||
|
|
||||||
|
|||||||
+12
-5
@@ -1,4 +1,5 @@
|
|||||||
import textwrap
|
import textwrap
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import packaging.utils
|
import packaging.utils
|
||||||
import pytest
|
import pytest
|
||||||
@@ -21,7 +22,7 @@ basic_project = test_projects.new_c_project(
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.serial
|
@pytest.mark.serial
|
||||||
def test_dummy_serial():
|
def test_dummy_serial() -> None:
|
||||||
"""A no-op test to ensure that at least one serial test is always found.
|
"""A no-op test to ensure that at least one serial test is always found.
|
||||||
|
|
||||||
Without this no-op test, CI fails on CircleCI because no serial tests are
|
Without this no-op test, CI fails on CircleCI because no serial tests are
|
||||||
@@ -29,7 +30,9 @@ def test_dummy_serial():
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def test(tmp_path, build_frontend_env, capfd):
|
def test(
|
||||||
|
tmp_path: Path, build_frontend_env: dict[str, str], capfd: pytest.CaptureFixture[str]
|
||||||
|
) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
basic_project.generate(project_dir)
|
basic_project.generate(project_dir)
|
||||||
|
|
||||||
@@ -52,7 +55,7 @@ def test(tmp_path, build_frontend_env, capfd):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip(reason="to keep test output clean")
|
@pytest.mark.skip(reason="to keep test output clean")
|
||||||
def test_sample_build(tmp_path, capfd):
|
def test_sample_build(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
basic_project.generate(project_dir)
|
basic_project.generate(project_dir)
|
||||||
|
|
||||||
@@ -70,7 +73,9 @@ def test_sample_build(tmp_path, capfd):
|
|||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"enable_setting", ["", "cpython-prerelease", "pypy", "cpython-freethreading"]
|
"enable_setting", ["", "cpython-prerelease", "pypy", "cpython-freethreading"]
|
||||||
)
|
)
|
||||||
def test_build_identifiers(tmp_path, enable_setting, monkeypatch):
|
def test_build_identifiers(
|
||||||
|
tmp_path: Path, enable_setting: str, monkeypatch: pytest.MonkeyPatch
|
||||||
|
) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
basic_project.generate(project_dir)
|
basic_project.generate(project_dir)
|
||||||
|
|
||||||
@@ -93,7 +98,9 @@ def test_build_identifiers(tmp_path, enable_setting, monkeypatch):
|
|||||||
(None, {"CIBW_ALLOW_EMPTY": "1"}),
|
(None, {"CIBW_ALLOW_EMPTY": "1"}),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_allow_empty(tmp_path, add_args, env_allow_empty):
|
def test_allow_empty(
|
||||||
|
tmp_path: Path, add_args: list[str] | None, env_allow_empty: dict[str, str]
|
||||||
|
) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
basic_project.generate(project_dir)
|
basic_project.generate(project_dir)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
import textwrap
|
import textwrap
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from . import test_projects, utils
|
from . import test_projects, utils
|
||||||
|
|
||||||
@@ -31,7 +34,7 @@ limited_api_project = test_projects.new_c_project(
|
|||||||
limited_api_project.files["pyproject.toml"] = pyproject_toml
|
limited_api_project.files["pyproject.toml"] = pyproject_toml
|
||||||
|
|
||||||
|
|
||||||
def test_abi3(tmp_path):
|
def test_abi3(tmp_path: Path) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
limited_api_project.generate(project_dir)
|
limited_api_project.generate(project_dir)
|
||||||
|
|
||||||
@@ -178,7 +181,7 @@ ctypes_project.files["test/add_test.py"] = textwrap.dedent(
|
|||||||
ctypes_project.files["pyproject.toml"] = pyproject_toml
|
ctypes_project.files["pyproject.toml"] = pyproject_toml
|
||||||
|
|
||||||
|
|
||||||
def test_abi_none(tmp_path, capfd):
|
def test_abi_none(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
ctypes_project.generate(project_dir)
|
ctypes_project.generate(project_dir)
|
||||||
|
|
||||||
|
|||||||
+43
-23
@@ -2,6 +2,8 @@ import os
|
|||||||
import platform
|
import platform
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
import typing
|
||||||
|
from collections.abc import Callable
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from shutil import rmtree, which
|
from shutil import rmtree, which
|
||||||
@@ -52,8 +54,10 @@ if "ANDROID_HOME" not in os.environ:
|
|||||||
# Many CI services don't support running the Android emulator: see platforms.md.
|
# Many CI services don't support running the Android emulator: see platforms.md.
|
||||||
supports_emulator = (not ci) or ("GITHUB_ACTIONS" in os.environ and platform.system() == "Linux")
|
supports_emulator = (not ci) or ("GITHUB_ACTIONS" in os.environ and platform.system() == "Linux")
|
||||||
|
|
||||||
|
T = typing.TypeVar("T", bound=Callable[..., typing.Any])
|
||||||
|
|
||||||
def needs_emulator(test):
|
|
||||||
|
def needs_emulator(test: T) -> T:
|
||||||
# All copies of the testbed app run on the same emulator with the same
|
# All copies of the testbed app run on the same emulator with the same
|
||||||
# application ID, so these tests must be run serially.
|
# application ID, so these tests must be run serially.
|
||||||
test = pytest.mark.serial(test)
|
test = pytest.mark.serial(test)
|
||||||
@@ -85,7 +89,7 @@ cp313_env = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_android_home(tmp_path, capfd):
|
def test_android_home(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
new_c_project().generate(tmp_path)
|
new_c_project().generate(tmp_path)
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
del env["ANDROID_HOME"]
|
del env["ANDROID_HOME"]
|
||||||
@@ -100,7 +104,7 @@ def test_android_home(tmp_path, capfd):
|
|||||||
# a build, which is marked as serial so it will run before the parallel tests, but isn't
|
# a build, which is marked as serial so it will run before the parallel tests, but isn't
|
||||||
# marked as needs_emulator so it will run on all CI platforms.
|
# marked as needs_emulator so it will run on all CI platforms.
|
||||||
@pytest.mark.serial
|
@pytest.mark.serial
|
||||||
def test_expected_wheels(tmp_path, spam_env):
|
def test_expected_wheels(tmp_path: Path, spam_env: dict[str, str]) -> None:
|
||||||
# Since this test covers all Python versions, check the cross venv.
|
# Since this test covers all Python versions, check the cross venv.
|
||||||
test_module = "_cross_venv_test_android"
|
test_module = "_cross_venv_test_android"
|
||||||
project = new_c_project(setup_py_add=f"import {test_module}")
|
project = new_c_project(setup_py_add=f"import {test_module}")
|
||||||
@@ -119,7 +123,7 @@ def test_expected_wheels(tmp_path, spam_env):
|
|||||||
|
|
||||||
|
|
||||||
@needs_emulator
|
@needs_emulator
|
||||||
def test_frontend_good(tmp_path, build_frontend_env):
|
def test_frontend_good(tmp_path: Path, build_frontend_env: dict[str, str]) -> None:
|
||||||
new_c_project().generate(tmp_path)
|
new_c_project().generate(tmp_path)
|
||||||
wheels = cibuildwheel_run(
|
wheels = cibuildwheel_run(
|
||||||
tmp_path,
|
tmp_path,
|
||||||
@@ -129,7 +133,7 @@ def test_frontend_good(tmp_path, build_frontend_env):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("frontend", ["pip"])
|
@pytest.mark.parametrize("frontend", ["pip"])
|
||||||
def test_frontend_bad(frontend, tmp_path, capfd):
|
def test_frontend_bad(frontend: str, tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
new_c_project().generate(tmp_path)
|
new_c_project().generate(tmp_path)
|
||||||
with pytest.raises(CalledProcessError):
|
with pytest.raises(CalledProcessError):
|
||||||
cibuildwheel_run(
|
cibuildwheel_run(
|
||||||
@@ -140,7 +144,7 @@ def test_frontend_bad(frontend, tmp_path, capfd):
|
|||||||
|
|
||||||
|
|
||||||
@needs_emulator
|
@needs_emulator
|
||||||
def test_archs(tmp_path, capfd):
|
def test_archs(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
new_c_project().generate(tmp_path)
|
new_c_project().generate(tmp_path)
|
||||||
|
|
||||||
# Build all architectures while checking the handling of the `before` commands.
|
# Build all architectures while checking the handling of the `before` commands.
|
||||||
@@ -189,7 +193,7 @@ def test_archs(tmp_path, capfd):
|
|||||||
pytest.fail(f"Unexpected line: {line!r}")
|
pytest.fail(f"Unexpected line: {line!r}")
|
||||||
|
|
||||||
|
|
||||||
def test_build_requires(tmp_path, capfd):
|
def test_build_requires(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
# Build-time requirements should be installed for the build platform, not for Android. Prove
|
# Build-time requirements should be installed for the build platform, not for Android. Prove
|
||||||
# this by installing some non-pure-Python requirements and using them in setup.py.
|
# this by installing some non-pure-Python requirements and using them in setup.py.
|
||||||
#
|
#
|
||||||
@@ -226,13 +230,13 @@ def test_build_requires(tmp_path, capfd):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def spam_env(tmp_path):
|
def spam_env(tmp_path: Path) -> dict[str, str]:
|
||||||
project = new_c_project()
|
project = new_c_project()
|
||||||
project.files["test_spam.py"] = dedent(
|
project.files["test_spam.py"] = dedent(
|
||||||
"""\
|
"""\
|
||||||
import spam
|
import spam
|
||||||
|
|
||||||
def test_spam():
|
def test_spam() -> None:
|
||||||
assert spam.filter("ham")
|
assert spam.filter("ham")
|
||||||
assert not spam.filter("spam")
|
assert not spam.filter("spam")
|
||||||
print("Spam test passed")
|
print("Spam test passed")
|
||||||
@@ -240,7 +244,7 @@ def spam_env(tmp_path):
|
|||||||
)
|
)
|
||||||
project.files["test_empty.py"] = dedent(
|
project.files["test_empty.py"] = dedent(
|
||||||
"""\
|
"""\
|
||||||
def test_empty():
|
def test_empty() -> None:
|
||||||
pass
|
pass
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
@@ -265,7 +269,13 @@ def spam_env(tmp_path):
|
|||||||
("pytest test_spam.py", "=== 1 passed in "),
|
("pytest test_spam.py", "=== 1 passed in "),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_test_command_good(command, expected_output, tmp_path, spam_env, capfd):
|
def test_test_command_good(
|
||||||
|
command: str,
|
||||||
|
expected_output: str,
|
||||||
|
tmp_path: Path,
|
||||||
|
spam_env: dict[str, str],
|
||||||
|
capfd: pytest.CaptureFixture[str],
|
||||||
|
) -> None:
|
||||||
cibuildwheel_run(tmp_path, add_env={**spam_env, "CIBW_TEST_COMMAND": command})
|
cibuildwheel_run(tmp_path, add_env={**spam_env, "CIBW_TEST_COMMAND": command})
|
||||||
stdout, stderr = capfd.readouterr()
|
stdout, stderr = capfd.readouterr()
|
||||||
assert expected_output in stdout
|
assert expected_output in stdout
|
||||||
@@ -300,7 +310,13 @@ BAD_PLACEHOLDER_ERROR = (
|
|||||||
("pytest test_ham.py", "not found: test_ham.py"),
|
("pytest test_ham.py", "not found: test_ham.py"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_test_command_bad(command, expected_output, tmp_path, spam_env, capfd):
|
def test_test_command_bad(
|
||||||
|
command: str,
|
||||||
|
expected_output: str,
|
||||||
|
tmp_path: Path,
|
||||||
|
spam_env: dict[str, str],
|
||||||
|
capfd: pytest.CaptureFixture[str],
|
||||||
|
) -> None:
|
||||||
with pytest.raises(CalledProcessError):
|
with pytest.raises(CalledProcessError):
|
||||||
cibuildwheel_run(tmp_path, add_env={**spam_env, "CIBW_TEST_COMMAND": command})
|
cibuildwheel_run(tmp_path, add_env={**spam_env, "CIBW_TEST_COMMAND": command})
|
||||||
assert expected_output in capfd.readouterr().err
|
assert expected_output in capfd.readouterr().err
|
||||||
@@ -314,7 +330,9 @@ def test_test_command_bad(command, expected_output, tmp_path, spam_env, capfd):
|
|||||||
("-E", 1),
|
("-E", 1),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_test_command_python_options(options, expected, tmp_path, capfd):
|
def test_test_command_python_options(
|
||||||
|
options: str, expected: int, tmp_path: Path, capfd: pytest.CaptureFixture[str]
|
||||||
|
) -> None:
|
||||||
project = new_c_project()
|
project = new_c_project()
|
||||||
project.generate(tmp_path)
|
project.generate(tmp_path)
|
||||||
|
|
||||||
@@ -330,7 +348,9 @@ def test_test_command_python_options(options, expected, tmp_path, capfd):
|
|||||||
|
|
||||||
|
|
||||||
@needs_emulator
|
@needs_emulator
|
||||||
def test_package_subdir(tmp_path, spam_env, capfd):
|
def test_package_subdir(
|
||||||
|
tmp_path: Path, spam_env: dict[str, str], capfd: pytest.CaptureFixture[str]
|
||||||
|
) -> None:
|
||||||
spam_paths = list(tmp_path.iterdir())
|
spam_paths = list(tmp_path.iterdir())
|
||||||
package_dir = tmp_path / "package"
|
package_dir = tmp_path / "package"
|
||||||
package_dir.mkdir()
|
package_dir.mkdir()
|
||||||
@@ -345,7 +365,7 @@ def test_package_subdir(tmp_path, spam_env, capfd):
|
|||||||
|
|
||||||
|
|
||||||
@needs_emulator
|
@needs_emulator
|
||||||
def test_no_test_sources(tmp_path, capfd):
|
def test_no_test_sources(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
new_c_project().generate(tmp_path)
|
new_c_project().generate(tmp_path)
|
||||||
with pytest.raises(CalledProcessError):
|
with pytest.raises(CalledProcessError):
|
||||||
cibuildwheel_run(
|
cibuildwheel_run(
|
||||||
@@ -359,17 +379,17 @@ def test_no_test_sources(tmp_path, capfd):
|
|||||||
|
|
||||||
|
|
||||||
@needs_emulator
|
@needs_emulator
|
||||||
def test_environment_markers(tmp_path):
|
def test_environment_markers(tmp_path: Path) -> None:
|
||||||
project = new_c_project()
|
project = new_c_project()
|
||||||
test_filename = "test_environment_markers.py"
|
test_filename = "test_environment_markers.py"
|
||||||
project.files[test_filename] = dedent(
|
project.files[test_filename] = dedent(
|
||||||
"""\
|
"""\
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
def test_android():
|
def test_android() -> None:
|
||||||
import certifi
|
import certifi
|
||||||
|
|
||||||
def test_not_android():
|
def test_not_android() -> None:
|
||||||
try:
|
try:
|
||||||
import platformdirs
|
import platformdirs
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@@ -392,7 +412,7 @@ def test_environment_markers(tmp_path):
|
|||||||
|
|
||||||
|
|
||||||
@needs_emulator
|
@needs_emulator
|
||||||
def test_verbosity(tmp_path, capfd):
|
def test_verbosity(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
new_c_project().generate(tmp_path)
|
new_c_project().generate(tmp_path)
|
||||||
test_env = {
|
test_env = {
|
||||||
**cp313_env,
|
**cp313_env,
|
||||||
@@ -418,7 +438,7 @@ def test_verbosity(tmp_path, capfd):
|
|||||||
|
|
||||||
|
|
||||||
@needs_emulator
|
@needs_emulator
|
||||||
def test_api_level(tmp_path, capfd):
|
def test_api_level(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
project = new_c_project()
|
project = new_c_project()
|
||||||
project.files["pyproject.toml"] = dedent(
|
project.files["pyproject.toml"] = dedent(
|
||||||
"""\
|
"""\
|
||||||
@@ -450,7 +470,7 @@ def test_api_level(tmp_path, capfd):
|
|||||||
|
|
||||||
|
|
||||||
@needs_emulator
|
@needs_emulator
|
||||||
def test_libcxx(tmp_path, capfd):
|
def test_libcxx(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
output_dir = tmp_path / "output"
|
output_dir = tmp_path / "output"
|
||||||
|
|
||||||
@@ -499,7 +519,7 @@ def test_libcxx(tmp_path, capfd):
|
|||||||
|
|
||||||
|
|
||||||
@needs_emulator
|
@needs_emulator
|
||||||
def test_setuptools_rust(tmp_path, capfd):
|
def test_setuptools_rust(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
"""
|
"""
|
||||||
Test Android cross-compilation using the setuptools-rust toolchain.
|
Test Android cross-compilation using the setuptools-rust toolchain.
|
||||||
"""
|
"""
|
||||||
@@ -584,7 +604,7 @@ def test_setuptools_rust(tmp_path, capfd):
|
|||||||
|
|
||||||
|
|
||||||
@needs_emulator
|
@needs_emulator
|
||||||
def test_maturin(tmp_path, capfd):
|
def test_maturin(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
"""
|
"""
|
||||||
Test Android cross-compilation using the maturin backend.
|
Test Android cross-compilation using the maturin backend.
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
import textwrap
|
import textwrap
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -29,7 +30,7 @@ project_with_before_build_asserts = test_projects.new_c_project(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test(tmp_path):
|
def test(tmp_path: Path) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
project_with_before_build_asserts.generate(project_dir)
|
project_with_before_build_asserts.generate(project_dir)
|
||||||
|
|
||||||
@@ -61,7 +62,7 @@ def test(tmp_path):
|
|||||||
assert set(actual_wheels) == set(expected_wheels)
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|
||||||
|
|
||||||
def test_failing_command(tmp_path):
|
def test_failing_command(tmp_path: Path) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
test_projects.new_c_project().generate(project_dir)
|
test_projects.new_c_project().generate(project_dir)
|
||||||
|
|
||||||
@@ -75,7 +76,7 @@ def test_failing_command(tmp_path):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_cwd(tmp_path):
|
def test_cwd(tmp_path: Path) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
test_projects.new_c_project().generate(project_dir)
|
test_projects.new_c_project().generate(project_dir)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
import textwrap
|
import textwrap
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -36,7 +37,7 @@ project_with_before_build_asserts = test_projects.new_c_project(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test(tmp_path):
|
def test(tmp_path: Path) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
project_with_before_build_asserts.generate(project_dir)
|
project_with_before_build_asserts.generate(project_dir)
|
||||||
|
|
||||||
@@ -65,7 +66,7 @@ def test(tmp_path):
|
|||||||
assert set(actual_wheels) == set(expected_wheels)
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|
||||||
|
|
||||||
def test_failing_command(tmp_path):
|
def test_failing_command(tmp_path: Path) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
test_projects.new_c_project().generate(project_dir)
|
test_projects.new_c_project().generate(project_dir)
|
||||||
|
|
||||||
@@ -79,7 +80,7 @@ def test_failing_command(tmp_path):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_cwd(tmp_path):
|
def test_cwd(tmp_path: Path) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
test_projects.new_c_project().generate(project_dir)
|
test_projects.new_c_project().generate(project_dir)
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from . import test_projects, utils
|
from . import test_projects, utils
|
||||||
|
|
||||||
before_test_project = test_projects.new_c_project()
|
before_test_project = test_projects.new_c_project()
|
||||||
@@ -11,7 +13,7 @@ PROJECT_DIR = Path(__file__).parent.parent.resolve()
|
|||||||
|
|
||||||
|
|
||||||
class TestBeforeTest(TestCase):
|
class TestBeforeTest(TestCase):
|
||||||
def test_version(self):
|
def test_version(self) -> None:
|
||||||
# assert that the Python version as written to pythonversion_bt.txt in the CIBW_BEFORE_TEST step
|
# assert that the Python version as written to pythonversion_bt.txt in the CIBW_BEFORE_TEST step
|
||||||
# is the same one as is currently running.
|
# is the same one as is currently running.
|
||||||
# because of use symlinks in MacOS run this test is also need
|
# because of use symlinks in MacOS run this test is also need
|
||||||
@@ -20,7 +22,7 @@ class TestBeforeTest(TestCase):
|
|||||||
print('sys.version', sys.version)
|
print('sys.version', sys.version)
|
||||||
assert stored_version == sys.version
|
assert stored_version == sys.version
|
||||||
|
|
||||||
def test_prefix(self):
|
def test_prefix(self) -> None:
|
||||||
# check that the prefix also was written
|
# check that the prefix also was written
|
||||||
stored_prefix = PROJECT_DIR.joinpath('pythonprefix_bt.txt').read_text()
|
stored_prefix = PROJECT_DIR.joinpath('pythonprefix_bt.txt').read_text()
|
||||||
print('stored_prefix', stored_prefix)
|
print('stored_prefix', stored_prefix)
|
||||||
@@ -32,7 +34,7 @@ class TestBeforeTest(TestCase):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def test(tmp_path, build_frontend_env):
|
def test(tmp_path: Path, build_frontend_env: dict[str, str]) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
before_test_project.generate(project_dir)
|
before_test_project.generate(project_dir)
|
||||||
test_project_dir = project_dir / "dependency"
|
test_project_dir = project_dir / "dependency"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -12,7 +13,9 @@ from . import test_projects, utils
|
|||||||
"build",
|
"build",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_build_frontend_args(tmp_path, capfd, frontend_name):
|
def test_build_frontend_args(
|
||||||
|
tmp_path: Path, capfd: pytest.CaptureFixture[str], frontend_name: str
|
||||||
|
) -> None:
|
||||||
project = test_projects.new_c_project()
|
project = test_projects.new_c_project()
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
project.generate(project_dir)
|
project.generate(project_dir)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import textwrap
|
import textwrap
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from . import test_projects, utils
|
from . import test_projects, utils
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@ project_with_skip_asserts = test_projects.new_c_project(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test(tmp_path):
|
def test(tmp_path: Path) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
project_with_skip_asserts.generate(project_dir)
|
project_with_skip_asserts.generate(project_dir)
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from . import test_projects, utils
|
from . import test_projects, utils
|
||||||
@@ -5,7 +7,9 @@ from . import test_projects, utils
|
|||||||
basic_project = test_projects.new_c_project()
|
basic_project = test_projects.new_c_project()
|
||||||
|
|
||||||
|
|
||||||
def test_podman(tmp_path, capfd, request):
|
def test_podman(
|
||||||
|
tmp_path: Path, capfd: pytest.CaptureFixture[str], request: pytest.FixtureRequest
|
||||||
|
) -> None:
|
||||||
if utils.get_platform() != "linux":
|
if utils.get_platform() != "linux":
|
||||||
pytest.skip("the test is only relevant to the linux build")
|
pytest.skip("the test is only relevant to the linux build")
|
||||||
|
|
||||||
@@ -35,7 +39,7 @@ def test_podman(tmp_path, capfd, request):
|
|||||||
assert "test log statement from before-all" in captured.out
|
assert "test log statement from before-all" in captured.out
|
||||||
|
|
||||||
|
|
||||||
def test_create_args(tmp_path, capfd):
|
def test_create_args(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
if utils.get_platform() != "linux":
|
if utils.get_platform() != "linux":
|
||||||
pytest.skip("the test is only relevant to the linux build")
|
pytest.skip("the test is only relevant to the linux build")
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import platform
|
import platform
|
||||||
import textwrap
|
import textwrap
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -22,7 +23,7 @@ dockcross_only_project = test_projects.new_c_project(
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("docker_cleanup")
|
@pytest.mark.usefixtures("docker_cleanup")
|
||||||
def test(tmp_path):
|
def test(tmp_path: Path) -> None:
|
||||||
if utils.get_platform() != "linux":
|
if utils.get_platform() != "linux":
|
||||||
pytest.skip("the test is only relevant to the linux build")
|
pytest.skip("the test is only relevant to the linux build")
|
||||||
if platform.machine() not in ["x86_64", "i686"]:
|
if platform.machine() not in ["x86_64", "i686"]:
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import jinja2
|
import jinja2
|
||||||
|
|
||||||
from . import utils
|
from . import utils
|
||||||
@@ -52,7 +54,7 @@ cpp_test_project.files["setup.py"] = jinja2.Template(setup_py_template)
|
|||||||
cpp_test_project.files["spam.cpp"] = jinja2.Template(spam_cpp_template)
|
cpp_test_project.files["spam.cpp"] = jinja2.Template(spam_cpp_template)
|
||||||
|
|
||||||
|
|
||||||
def test_cpp11(tmp_path):
|
def test_cpp11(tmp_path: Path) -> None:
|
||||||
# This test checks that the C++11 standard is supported
|
# This test checks that the C++11 standard is supported
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
cpp11_project = cpp_test_project.copy()
|
cpp11_project = cpp_test_project.copy()
|
||||||
@@ -68,7 +70,7 @@ def test_cpp11(tmp_path):
|
|||||||
assert set(actual_wheels) == set(expected_wheels)
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|
||||||
|
|
||||||
def test_cpp14(tmp_path):
|
def test_cpp14(tmp_path: Path) -> None:
|
||||||
# This test checks that the C++14 standard is supported
|
# This test checks that the C++14 standard is supported
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
cpp14_project = cpp_test_project.copy()
|
cpp14_project = cpp_test_project.copy()
|
||||||
@@ -84,7 +86,7 @@ def test_cpp14(tmp_path):
|
|||||||
assert set(actual_wheels) == set(expected_wheels)
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|
||||||
|
|
||||||
def test_cpp17(tmp_path):
|
def test_cpp17(tmp_path: Path) -> None:
|
||||||
# This test checks that the C++17 standard is supported
|
# This test checks that the C++17 standard is supported
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
cpp17_project = cpp_test_project.copy()
|
cpp17_project = cpp_test_project.copy()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
import textwrap
|
import textwrap
|
||||||
from contextlib import nullcontext as does_not_raise
|
from contextlib import nullcontext as does_not_raise
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ shutil.copy(wheel, dest)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def test(tmp_path, capfd):
|
def test(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
# this test checks that a generated wheel name shall be unique in a given cibuildwheel run
|
# this test checks that a generated wheel name shall be unique in a given cibuildwheel run
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
basic_project.generate(project_dir)
|
basic_project.generate(project_dir)
|
||||||
@@ -68,7 +69,7 @@ def test(tmp_path, capfd):
|
|||||||
],
|
],
|
||||||
ids=["no-placeholder", "package-placeholder", "project-placeholder"],
|
ids=["no-placeholder", "package-placeholder", "project-placeholder"],
|
||||||
)
|
)
|
||||||
def test_repair_wheel_command_structure(tmp_path, repair_command):
|
def test_repair_wheel_command_structure(tmp_path: Path, repair_command: str) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
project = test_projects.new_c_project()
|
project = test_projects.new_c_project()
|
||||||
project.files["repair.py"] = textwrap.dedent("""
|
project.files["repair.py"] = textwrap.dedent("""
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ for name, expected_version in expected_versions.items():
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def test_check_versions_script(tmp_path, build_frontend_env_nouv, capfd):
|
def test_check_versions_script(
|
||||||
|
tmp_path: Path, build_frontend_env_nouv: dict[str, str], capfd: pytest.CaptureFixture[str]
|
||||||
|
) -> None:
|
||||||
if utils.get_platform() == "linux":
|
if utils.get_platform() == "linux":
|
||||||
pytest.skip("we don't test dependency versions on linux, refer to other tests")
|
pytest.skip("we don't test dependency versions on linux, refer to other tests")
|
||||||
|
|
||||||
@@ -76,7 +78,9 @@ def get_versions_from_constraint_file(constraint_file: Path) -> dict[str, str]:
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("python_version", ["3.8", "3.12"])
|
@pytest.mark.parametrize("python_version", ["3.8", "3.12"])
|
||||||
def test_pinned_versions(tmp_path, python_version, build_frontend_env_nouv):
|
def test_pinned_versions(
|
||||||
|
tmp_path: Path, python_version: str, build_frontend_env_nouv: dict[str, str]
|
||||||
|
) -> None:
|
||||||
if utils.get_platform() == "linux":
|
if utils.get_platform() == "linux":
|
||||||
pytest.skip("linux doesn't pin individual tool versions, it pins manylinux images instead")
|
pytest.skip("linux doesn't pin individual tool versions, it pins manylinux images instead")
|
||||||
if python_version != "3.12" and utils.get_platform() == "pyodide":
|
if python_version != "3.12" and utils.get_platform() == "pyodide":
|
||||||
@@ -127,7 +131,9 @@ def test_pinned_versions(tmp_path, python_version, build_frontend_env_nouv):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("method", ["inline", "file"])
|
@pytest.mark.parametrize("method", ["inline", "file"])
|
||||||
def test_dependency_constraints(method, tmp_path, build_frontend_env_nouv):
|
def test_dependency_constraints(
|
||||||
|
method: str, tmp_path: Path, build_frontend_env_nouv: dict[str, str]
|
||||||
|
) -> None:
|
||||||
if utils.get_platform() == "linux":
|
if utils.get_platform() == "linux":
|
||||||
pytest.skip("linux doesn't pin individual tool versions, it pins manylinux images instead")
|
pytest.skip("linux doesn't pin individual tool versions, it pins manylinux images instead")
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import itertools
|
import itertools
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -10,13 +11,13 @@ project_with_a_test = test_projects.new_c_project()
|
|||||||
project_with_a_test.files["test/spam_test.py"] = r"""
|
project_with_a_test.files["test/spam_test.py"] = r"""
|
||||||
import spam
|
import spam
|
||||||
|
|
||||||
def test_spam():
|
def test_spam() -> None:
|
||||||
assert spam.filter("spam") == 0
|
assert spam.filter("spam") == 0
|
||||||
assert spam.filter("ham") != 0
|
assert spam.filter("ham") != 0
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def test(tmp_path, request):
|
def test(tmp_path: Path, request: pytest.FixtureRequest) -> None:
|
||||||
archs = request.config.getoption("--run-emulation")
|
archs = request.config.getoption("--run-emulation")
|
||||||
if archs is None:
|
if archs is None:
|
||||||
pytest.skip("needs --run-emulation option to run")
|
pytest.skip("needs --run-emulation option to run")
|
||||||
@@ -45,7 +46,7 @@ def test(tmp_path, request):
|
|||||||
assert set(actual_wheels) == set(expected_wheels)
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|
||||||
|
|
||||||
def test_setting_arch_on_other_platforms(tmp_path, capfd):
|
def test_setting_arch_on_other_platforms(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
if utils.get_platform() == "linux":
|
if utils.get_platform() == "linux":
|
||||||
pytest.skip("this test checks the behaviour on platforms other than linux")
|
pytest.skip("this test checks the behaviour on platforms other than linux")
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import os
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -33,7 +34,7 @@ project_with_environment_asserts = test_projects.new_c_project(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test(tmp_path):
|
def test(tmp_path: Path) -> None:
|
||||||
python_echo = f"'{sys.executable}' -c \"import sys; print(*sys.argv[1:])\""
|
python_echo = f"'{sys.executable}' -c \"import sys; print(*sys.argv[1:])\""
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
project_with_environment_asserts.generate(project_dir)
|
project_with_environment_asserts.generate(project_dir)
|
||||||
@@ -55,7 +56,7 @@ def test(tmp_path):
|
|||||||
assert set(actual_wheels) == set(expected_wheels)
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|
||||||
|
|
||||||
def test_overridden_path(tmp_path, capfd):
|
def test_overridden_path(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
output_dir = tmp_path / "output"
|
output_dir = tmp_path / "output"
|
||||||
|
|
||||||
@@ -108,7 +109,7 @@ def test_overridden_path(tmp_path, capfd):
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_overridden_pip_constraint(tmp_path, build_frontend):
|
def test_overridden_pip_constraint(tmp_path: Path, build_frontend: str) -> None:
|
||||||
"""
|
"""
|
||||||
Verify that users can use PIP_CONSTRAINT to specify a specific version of
|
Verify that users can use PIP_CONSTRAINT to specify a specific version of
|
||||||
a build-system.requires dependency, by asserting the version of pytz in the
|
a build-system.requires dependency, by asserting the version of pytz in the
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ from collections.abc import Mapping
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from tempfile import TemporaryDirectory
|
from tempfile import TemporaryDirectory
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from test.test_projects.base import TestProject
|
from test.test_projects.base import TestProject
|
||||||
|
|
||||||
from . import test_projects, utils
|
from . import test_projects, utils
|
||||||
@@ -59,7 +61,7 @@ def cibuildwheel_from_sdist_run(
|
|||||||
# tests
|
# tests
|
||||||
|
|
||||||
|
|
||||||
def test_simple(tmp_path):
|
def test_simple(tmp_path: Path) -> None:
|
||||||
basic_project = test_projects.new_c_project()
|
basic_project = test_projects.new_c_project()
|
||||||
|
|
||||||
# make an sdist of the project
|
# make an sdist of the project
|
||||||
@@ -87,7 +89,7 @@ def test_simple(tmp_path):
|
|||||||
assert set(actual_wheels) == set(expected_wheels)
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|
||||||
|
|
||||||
def test_external_config_file_argument(tmp_path, capfd):
|
def test_external_config_file_argument(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
basic_project = test_projects.new_c_project()
|
basic_project = test_projects.new_c_project()
|
||||||
|
|
||||||
# make an sdist of the project
|
# make an sdist of the project
|
||||||
@@ -118,7 +120,7 @@ def test_external_config_file_argument(tmp_path, capfd):
|
|||||||
assert "test log statement from before-all" in captured.out
|
assert "test log statement from before-all" in captured.out
|
||||||
|
|
||||||
|
|
||||||
def test_config_in_pyproject_toml(tmp_path, capfd):
|
def test_config_in_pyproject_toml(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
# make a project with a pyproject.toml
|
# make a project with a pyproject.toml
|
||||||
project = test_projects.new_c_project()
|
project = test_projects.new_c_project()
|
||||||
project.files["pyproject.toml"] = textwrap.dedent(
|
project.files["pyproject.toml"] = textwrap.dedent(
|
||||||
@@ -145,7 +147,7 @@ def test_config_in_pyproject_toml(tmp_path, capfd):
|
|||||||
assert "test log statement from before-build 8419" in captured.out
|
assert "test log statement from before-build 8419" in captured.out
|
||||||
|
|
||||||
|
|
||||||
def test_internal_config_file_argument(tmp_path, capfd):
|
def test_internal_config_file_argument(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
# make a project with a config file inside
|
# make a project with a config file inside
|
||||||
project = test_projects.new_c_project(
|
project = test_projects.new_c_project(
|
||||||
setup_cfg_add="include_package_data = True",
|
setup_cfg_add="include_package_data = True",
|
||||||
|
|||||||
+23
-13
@@ -3,6 +3,7 @@ import platform
|
|||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import textwrap
|
import textwrap
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -22,7 +23,7 @@ import platform
|
|||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
class TestPlatform(TestCase):
|
class TestPlatform(TestCase):
|
||||||
def test_platform(self):
|
def test_platform(self) -> None:
|
||||||
self.assertEqual(platform.machine(), "{platform.machine()}")
|
self.assertEqual(platform.machine(), "{platform.machine()}")
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -59,7 +60,12 @@ def skip_if_ios_testing_not_supported() -> None:
|
|||||||
{"CIBW_PLATFORM": "ios", "CIBW_BUILD_FRONTEND": "build"},
|
{"CIBW_PLATFORM": "ios", "CIBW_BUILD_FRONTEND": "build"},
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_ios_platforms(tmp_path, build_config, monkeypatch, capfd):
|
def test_ios_platforms(
|
||||||
|
tmp_path: Path,
|
||||||
|
build_config: dict[str, str],
|
||||||
|
monkeypatch: pytest.MonkeyPatch,
|
||||||
|
capfd: pytest.CaptureFixture[str],
|
||||||
|
) -> None:
|
||||||
skip_if_ios_testing_not_supported()
|
skip_if_ios_testing_not_supported()
|
||||||
|
|
||||||
# Create a temporary "bin" directory, symlink a tool that we know eixsts
|
# Create a temporary "bin" directory, symlink a tool that we know eixsts
|
||||||
@@ -67,7 +73,9 @@ def test_ios_platforms(tmp_path, build_config, monkeypatch, capfd):
|
|||||||
# and add the temp bin directory to the PATH.
|
# and add the temp bin directory to the PATH.
|
||||||
tools_dir = tmp_path / "bin"
|
tools_dir = tmp_path / "bin"
|
||||||
tools_dir.mkdir()
|
tools_dir.mkdir()
|
||||||
tools_dir.joinpath("does-exist").symlink_to(shutil.which("true"))
|
true_app = shutil.which("true")
|
||||||
|
assert true_app is not None
|
||||||
|
tools_dir.joinpath("does-exist").symlink_to(true_app)
|
||||||
|
|
||||||
monkeypatch.setenv("PATH", str(tools_dir), prepend=os.pathsep)
|
monkeypatch.setenv("PATH", str(tools_dir), prepend=os.pathsep)
|
||||||
|
|
||||||
@@ -110,7 +118,7 @@ def test_ios_platforms(tmp_path, build_config, monkeypatch, capfd):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.serial
|
@pytest.mark.serial
|
||||||
def test_no_test_sources(tmp_path, capfd):
|
def test_no_test_sources(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
"""Build will provide a helpful error if pytest is run and test-sources is not defined."""
|
"""Build will provide a helpful error if pytest is run and test-sources is not defined."""
|
||||||
skip_if_ios_testing_not_supported()
|
skip_if_ios_testing_not_supported()
|
||||||
|
|
||||||
@@ -138,7 +146,7 @@ def test_no_test_sources(tmp_path, capfd):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_ios_testing_with_placeholder(tmp_path, capfd):
|
def test_ios_testing_with_placeholder(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
"""
|
"""
|
||||||
Tests with the {project} placeholder are not supported on iOS, because the test command
|
Tests with the {project} placeholder are not supported on iOS, because the test command
|
||||||
is run in the simulator.
|
is run in the simulator.
|
||||||
@@ -168,7 +176,7 @@ def test_ios_testing_with_placeholder(tmp_path, capfd):
|
|||||||
|
|
||||||
@pytest.mark.serial
|
@pytest.mark.serial
|
||||||
@pytest.mark.flaky(reruns=2)
|
@pytest.mark.flaky(reruns=2)
|
||||||
def test_ios_test_command_short_circuit(tmp_path, capfd):
|
def test_ios_test_command_short_circuit(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
skip_if_ios_testing_not_supported()
|
skip_if_ios_testing_not_supported()
|
||||||
|
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
@@ -196,7 +204,7 @@ def test_ios_test_command_short_circuit(tmp_path, capfd):
|
|||||||
assert "Zen of Python" not in captured.out + captured.err
|
assert "Zen of Python" not in captured.out + captured.err
|
||||||
|
|
||||||
|
|
||||||
def test_missing_xbuild_tool(tmp_path, capfd):
|
def test_missing_xbuild_tool(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
"""Build will fail if xbuild-tools references a non-existent tool."""
|
"""Build will fail if xbuild-tools references a non-existent tool."""
|
||||||
skip_if_ios_testing_not_supported()
|
skip_if_ios_testing_not_supported()
|
||||||
|
|
||||||
@@ -220,7 +228,7 @@ def test_missing_xbuild_tool(tmp_path, capfd):
|
|||||||
assert "Could not find a 'does-not-exist' executable on the path." in captured.err
|
assert "Could not find a 'does-not-exist' executable on the path." in captured.err
|
||||||
|
|
||||||
|
|
||||||
def test_no_xbuild_tool_definition(tmp_path, capfd):
|
def test_no_xbuild_tool_definition(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
"""Build will succeed with a warning if there is no xbuild-tools definition."""
|
"""Build will succeed with a warning if there is no xbuild-tools definition."""
|
||||||
skip_if_ios_testing_not_supported()
|
skip_if_ios_testing_not_supported()
|
||||||
|
|
||||||
@@ -254,7 +262,7 @@ def test_no_xbuild_tool_definition(tmp_path, capfd):
|
|||||||
assert "Your project configuration does not define any cross-build tools." in captured.err
|
assert "Your project configuration does not define any cross-build tools." in captured.err
|
||||||
|
|
||||||
|
|
||||||
def test_empty_xbuild_tool_definition(tmp_path, capfd):
|
def test_empty_xbuild_tool_definition(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
"""Build will succeed with no warning if there is an empty xbuild-tools definition."""
|
"""Build will succeed with no warning if there is an empty xbuild-tools definition."""
|
||||||
skip_if_ios_testing_not_supported()
|
skip_if_ios_testing_not_supported()
|
||||||
|
|
||||||
@@ -286,7 +294,9 @@ def test_empty_xbuild_tool_definition(tmp_path, capfd):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.serial
|
@pytest.mark.serial
|
||||||
def test_ios_test_command_without_python_dash_m(tmp_path, capfd):
|
def test_ios_test_command_without_python_dash_m(
|
||||||
|
tmp_path: Path, capfd: pytest.CaptureFixture[str]
|
||||||
|
) -> None:
|
||||||
"""pytest should be able to run without python -m, but it should warn."""
|
"""pytest should be able to run without python -m, but it should warn."""
|
||||||
skip_if_ios_testing_not_supported()
|
skip_if_ios_testing_not_supported()
|
||||||
|
|
||||||
@@ -296,7 +306,7 @@ def test_ios_test_command_without_python_dash_m(tmp_path, capfd):
|
|||||||
project.files["tests/__init__.py"] = ""
|
project.files["tests/__init__.py"] = ""
|
||||||
project.files["tests/test_spam.py"] = textwrap.dedent("""
|
project.files["tests/test_spam.py"] = textwrap.dedent("""
|
||||||
import spam
|
import spam
|
||||||
def test_spam():
|
def test_spam() -> None:
|
||||||
assert spam.filter("spam") == 0
|
assert spam.filter("spam") == 0
|
||||||
assert spam.filter("ham") != 0
|
assert spam.filter("ham") != 0
|
||||||
""")
|
""")
|
||||||
@@ -324,7 +334,7 @@ def test_ios_test_command_without_python_dash_m(tmp_path, capfd):
|
|||||||
assert "iOS tests configured with a test command which doesn't start with 'python -m'" in err
|
assert "iOS tests configured with a test command which doesn't start with 'python -m'" in err
|
||||||
|
|
||||||
|
|
||||||
def test_ios_test_command_invalid(tmp_path, capfd):
|
def test_ios_test_command_invalid(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
"""Test command should raise an error if it's clearly invalid."""
|
"""Test command should raise an error if it's clearly invalid."""
|
||||||
skip_if_ios_testing_not_supported()
|
skip_if_ios_testing_not_supported()
|
||||||
|
|
||||||
@@ -347,7 +357,7 @@ def test_ios_test_command_invalid(tmp_path, capfd):
|
|||||||
assert "iOS tests configured with a test command which doesn't start with 'python -m'" in err
|
assert "iOS tests configured with a test command which doesn't start with 'python -m'" in err
|
||||||
|
|
||||||
|
|
||||||
def test_repair_step(tmp_path):
|
def test_repair_step(tmp_path: Path) -> None:
|
||||||
"""Build will succeed & the custom repair step is called."""
|
"""Build will succeed & the custom repair step is called."""
|
||||||
skip_if_ios_testing_not_supported()
|
skip_if_ios_testing_not_supported()
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import platform
|
import platform
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from . import test_projects, utils
|
from . import test_projects, utils
|
||||||
|
|
||||||
|
|
||||||
def test_python_exist(tmp_path, capfd):
|
def test_python_exist(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
if utils.get_platform() != "linux":
|
if utils.get_platform() != "linux":
|
||||||
pytest.skip("the test is only relevant to the linux build")
|
pytest.skip("the test is only relevant to the linux build")
|
||||||
machine = platform.machine()
|
machine = platform.machine()
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import platform
|
import platform
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -19,7 +20,7 @@ ALL_MACOS_WHEELS = {
|
|||||||
DEPLOYMENT_TARGET_TOO_LOW_WARNING = "Bumping MACOSX_DEPLOYMENT_TARGET"
|
DEPLOYMENT_TARGET_TOO_LOW_WARNING = "Bumping MACOSX_DEPLOYMENT_TARGET"
|
||||||
|
|
||||||
|
|
||||||
def test_cross_compiled_build(tmp_path):
|
def test_cross_compiled_build(tmp_path: Path) -> None:
|
||||||
if utils.get_platform() != "macos":
|
if utils.get_platform() != "macos":
|
||||||
pytest.skip("this test is only relevant to macos")
|
pytest.skip("this test is only relevant to macos")
|
||||||
if utils.get_xcode_version() < (12, 2):
|
if utils.get_xcode_version() < (12, 2):
|
||||||
@@ -51,7 +52,12 @@ def test_cross_compiled_build(tmp_path):
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_cross_compiled_test(tmp_path, capfd, build_universal2, test_config):
|
def test_cross_compiled_test(
|
||||||
|
tmp_path: Path,
|
||||||
|
capfd: pytest.CaptureFixture[str],
|
||||||
|
build_universal2: bool,
|
||||||
|
test_config: dict[str, str],
|
||||||
|
) -> None:
|
||||||
if utils.get_platform() != "macos":
|
if utils.get_platform() != "macos":
|
||||||
pytest.skip("this test is only relevant to macos")
|
pytest.skip("this test is only relevant to macos")
|
||||||
if utils.get_xcode_version() < (12, 2):
|
if utils.get_xcode_version() < (12, 2):
|
||||||
@@ -110,7 +116,9 @@ def test_cross_compiled_test(tmp_path, capfd, build_universal2, test_config):
|
|||||||
assert set(actual_wheels) == set(expected_wheels)
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|
||||||
|
|
||||||
def test_deployment_target_warning_is_firing(tmp_path, capfd):
|
def test_deployment_target_warning_is_firing(
|
||||||
|
tmp_path: Path, capfd: pytest.CaptureFixture[str]
|
||||||
|
) -> None:
|
||||||
# force the warning to check that we can detect it if it happens
|
# force the warning to check that we can detect it if it happens
|
||||||
if utils.get_platform() != "macos":
|
if utils.get_platform() != "macos":
|
||||||
pytest.skip("this test is only relevant to macos")
|
pytest.skip("this test is only relevant to macos")
|
||||||
@@ -133,7 +141,9 @@ def test_deployment_target_warning_is_firing(tmp_path, capfd):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("skip_arm64_test", [False, True])
|
@pytest.mark.parametrize("skip_arm64_test", [False, True])
|
||||||
def test_universal2_testing_on_x86_64(tmp_path, capfd, skip_arm64_test):
|
def test_universal2_testing_on_x86_64(
|
||||||
|
tmp_path: Path, capfd: pytest.CaptureFixture[str], skip_arm64_test: bool
|
||||||
|
) -> None:
|
||||||
if utils.get_platform() != "macos":
|
if utils.get_platform() != "macos":
|
||||||
pytest.skip("this test is only relevant to macos")
|
pytest.skip("this test is only relevant to macos")
|
||||||
if utils.get_xcode_version() < (12, 2):
|
if utils.get_xcode_version() < (12, 2):
|
||||||
@@ -172,7 +182,9 @@ def test_universal2_testing_on_x86_64(tmp_path, capfd, skip_arm64_test):
|
|||||||
assert set(actual_wheels) == set(expected_wheels)
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|
||||||
|
|
||||||
def test_universal2_testing_on_arm64(build_frontend_env, tmp_path, capfd):
|
def test_universal2_testing_on_arm64(
|
||||||
|
build_frontend_env: dict[str, str], tmp_path: Path, capfd: pytest.CaptureFixture[str]
|
||||||
|
) -> None:
|
||||||
# cibuildwheel should test the universal2 wheel on both x86_64 and arm64, when run on arm64
|
# cibuildwheel should test the universal2 wheel on both x86_64 and arm64, when run on arm64
|
||||||
if utils.get_platform() != "macos":
|
if utils.get_platform() != "macos":
|
||||||
pytest.skip("this test is only relevant to macos")
|
pytest.skip("this test is only relevant to macos")
|
||||||
@@ -203,7 +215,9 @@ def test_universal2_testing_on_arm64(build_frontend_env, tmp_path, capfd):
|
|||||||
assert set(actual_wheels) == set(expected_wheels)
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|
||||||
|
|
||||||
def test_cp38_arm64_testing(tmp_path, capfd, request):
|
def test_cp38_arm64_testing(
|
||||||
|
tmp_path: Path, capfd: pytest.CaptureFixture[str], request: pytest.FixtureRequest
|
||||||
|
) -> None:
|
||||||
if utils.get_platform() != "macos":
|
if utils.get_platform() != "macos":
|
||||||
pytest.skip("this test is only relevant to macos")
|
pytest.skip("this test is only relevant to macos")
|
||||||
if utils.get_xcode_version() < (12, 2):
|
if utils.get_xcode_version() < (12, 2):
|
||||||
@@ -238,7 +252,9 @@ def test_cp38_arm64_testing(tmp_path, capfd, request):
|
|||||||
assert set(actual_wheels) == set(expected_wheels)
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|
||||||
|
|
||||||
def test_cp38_arm64_testing_universal2_installer(tmp_path, capfd, request):
|
def test_cp38_arm64_testing_universal2_installer(
|
||||||
|
tmp_path: Path, capfd: pytest.CaptureFixture[str], request: pytest.FixtureRequest
|
||||||
|
) -> None:
|
||||||
if not request.config.getoption("--run-cp38-universal2"):
|
if not request.config.getoption("--run-cp38-universal2"):
|
||||||
pytest.skip("needs --run-cp38-universal2 option to run")
|
pytest.skip("needs --run-cp38-universal2 option to run")
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import platform
|
import platform
|
||||||
import textwrap
|
import textwrap
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -61,7 +62,7 @@ project_with_manylinux_symbols = test_projects.new_c_project(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("docker_cleanup")
|
@pytest.mark.usefixtures("docker_cleanup")
|
||||||
def test(manylinux_image, tmp_path):
|
def test(manylinux_image: str, tmp_path: Path) -> None:
|
||||||
if utils.get_platform() != "linux":
|
if utils.get_platform() != "linux":
|
||||||
pytest.skip("the container image test is only relevant to the linux build")
|
pytest.skip("the container image test is only relevant to the linux build")
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import packaging.utils
|
import packaging.utils
|
||||||
|
|
||||||
from . import test_projects, utils
|
from . import test_projects, utils
|
||||||
@@ -5,7 +7,7 @@ from . import test_projects, utils
|
|||||||
meson_project = test_projects.new_meson_project()
|
meson_project = test_projects.new_meson_project()
|
||||||
|
|
||||||
|
|
||||||
def test_meson_python_basic(tmp_path, build_frontend_env):
|
def test_meson_python_basic(tmp_path: Path, build_frontend_env: dict[str, str]) -> None:
|
||||||
"""Test that cibuildwheel can build a project with meson-python backend."""
|
"""Test that cibuildwheel can build a project with meson-python backend."""
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import textwrap
|
import textwrap
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -27,7 +28,7 @@ project_with_manylinux_symbols = test_projects.new_c_project(
|
|||||||
["musllinux_1_2"],
|
["musllinux_1_2"],
|
||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("docker_cleanup")
|
@pytest.mark.usefixtures("docker_cleanup")
|
||||||
def test(musllinux_image, tmp_path):
|
def test(musllinux_image: str, tmp_path: Path) -> None:
|
||||||
if utils.get_platform() != "linux":
|
if utils.get_platform() != "linux":
|
||||||
pytest.skip("the container image test is only relevant to the linux build")
|
pytest.skip("the container image test is only relevant to the linux build")
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
import textwrap
|
import textwrap
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from . import test_projects, utils
|
from . import test_projects, utils
|
||||||
|
|
||||||
@@ -29,7 +30,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def test_pep518(tmp_path, build_frontend_env):
|
def test_pep518(tmp_path: Path, build_frontend_env: dict[str, str]) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
basic_project.generate(project_dir)
|
basic_project.generate(project_dir)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -23,7 +24,7 @@ def a_function():
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def test(tmp_path, capfd):
|
def test(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
# this test checks that if a pure wheel is generated, the build should
|
# this test checks that if a pure wheel is generated, the build should
|
||||||
# fail.
|
# fail.
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import os
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -48,7 +49,7 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("use_pyproject_toml", [True, False])
|
@pytest.mark.parametrize("use_pyproject_toml", [True, False])
|
||||||
def test_pyodide_build(tmp_path, use_pyproject_toml):
|
def test_pyodide_build(tmp_path: Path, use_pyproject_toml: bool) -> None:
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
pytest.skip("pyodide-build doesn't work correctly on Windows")
|
pytest.skip("pyodide-build doesn't work correctly on Windows")
|
||||||
|
|
||||||
@@ -88,7 +89,7 @@ def test_pyodide_build(tmp_path, use_pyproject_toml):
|
|||||||
assert set(actual_wheels) == set(expected_wheels)
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|
||||||
|
|
||||||
def test_pyodide_version_incompatible(tmp_path, capfd):
|
def test_pyodide_version_incompatible(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
pytest.skip("pyodide-build doesn't work correctly on Windows")
|
pytest.skip("pyodide-build doesn't work correctly on Windows")
|
||||||
|
|
||||||
@@ -110,19 +111,19 @@ def test_pyodide_version_incompatible(tmp_path, capfd):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("expect_failure", [True, False])
|
@pytest.mark.parametrize("expect_failure", [True, False])
|
||||||
def test_pyodide_build_and_test(tmp_path, expect_failure):
|
def test_pyodide_build_and_test(tmp_path: Path, expect_failure: bool) -> None:
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
pytest.skip("pyodide-build doesn't work correctly on Windows")
|
pytest.skip("pyodide-build doesn't work correctly on Windows")
|
||||||
|
|
||||||
if expect_failure:
|
if expect_failure:
|
||||||
basic_project.files["test/spam_test.py"] = textwrap.dedent(r"""
|
basic_project.files["test/spam_test.py"] = textwrap.dedent(r"""
|
||||||
def test_filter():
|
def test_filter() -> None:
|
||||||
assert 0 == 1
|
assert 0 == 1
|
||||||
""")
|
""")
|
||||||
else:
|
else:
|
||||||
basic_project.files["test/spam_test.py"] = textwrap.dedent(r"""
|
basic_project.files["test/spam_test.py"] = textwrap.dedent(r"""
|
||||||
import spam
|
import spam
|
||||||
def test_filter():
|
def test_filter() -> None:
|
||||||
assert spam.filter("spam") == 0
|
assert spam.filter("spam") == 0
|
||||||
""")
|
""")
|
||||||
basic_project.generate(tmp_path)
|
basic_project.generate(tmp_path)
|
||||||
@@ -149,7 +150,7 @@ def test_pyodide_build_and_test(tmp_path, expect_failure):
|
|||||||
assert set(actual_wheels) == set(expected_wheels)
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|
||||||
|
|
||||||
def test_pyodide_repair_wheel(tmp_path):
|
def test_pyodide_repair_wheel(tmp_path: Path) -> None:
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
pytest.skip("pyodide-build doesn't work correctly on Windows")
|
pytest.skip("pyodide-build doesn't work correctly on Windows")
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
import textwrap
|
import textwrap
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -32,7 +33,7 @@ project_with_ssl_tests = test_projects.new_c_project(
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.flaky(reruns=2)
|
@pytest.mark.flaky(reruns=2)
|
||||||
def test(tmp_path):
|
def test(tmp_path: Path) -> None:
|
||||||
# this test checks that SSL is working in the build environment using
|
# this test checks that SSL is working in the build environment using
|
||||||
# some checks in setup.py.
|
# some checks in setup.py.
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import jinja2
|
import jinja2
|
||||||
|
import pytest
|
||||||
|
|
||||||
from . import utils
|
from . import utils
|
||||||
from .test_projects import TestProject
|
from .test_projects import TestProject
|
||||||
@@ -31,7 +32,7 @@ print('before_build.py executed!')
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def test(capfd, tmp_path):
|
def test(capfd: pytest.CaptureFixture[str], tmp_path: Path) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
subdir_package_project.generate(project_dir)
|
subdir_package_project.generate(project_dir)
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -43,11 +43,11 @@ def path_contains(parent, child):
|
|||||||
|
|
||||||
|
|
||||||
class TestSpam(TestCase):
|
class TestSpam(TestCase):
|
||||||
def test_filter(self):
|
def test_filter(self) -> None:
|
||||||
self.assertEqual(0, spam.filter("spam"))
|
self.assertEqual(0, spam.filter("spam"))
|
||||||
self.assertNotEqual(0, spam.filter("ham"))
|
self.assertNotEqual(0, spam.filter("ham"))
|
||||||
|
|
||||||
def test_virtualenv(self):
|
def test_virtualenv(self) -> None:
|
||||||
# sys.prefix is different from sys.base_prefix when running a virtualenv
|
# sys.prefix is different from sys.base_prefix when running a virtualenv
|
||||||
# See https://docs.python.org/3/library/venv.html, which virtualenv seems
|
# See https://docs.python.org/3/library/venv.html, which virtualenv seems
|
||||||
# to honor in recent releases
|
# to honor in recent releases
|
||||||
@@ -58,7 +58,7 @@ class TestSpam(TestCase):
|
|||||||
self.assertTrue(path_contains(sys.prefix, spam.__file__))
|
self.assertTrue(path_contains(sys.prefix, spam.__file__))
|
||||||
self.assertIn("VIRTUAL_ENV", os.environ)
|
self.assertIn("VIRTUAL_ENV", os.environ)
|
||||||
|
|
||||||
def test_uname(self):
|
def test_uname(self) -> None:
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
return
|
return
|
||||||
# if we're running in 32-bit Python, check that the machine is i686.
|
# if we're running in 32-bit Python, check that the machine is i686.
|
||||||
@@ -69,7 +69,7 @@ class TestSpam(TestCase):
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
def test(tmp_path):
|
def test(tmp_path: Path) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
project_with_a_test.generate(project_dir)
|
project_with_a_test.generate(project_dir)
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ def test(tmp_path):
|
|||||||
assert set(actual_wheels) == set(expected_wheels)
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|
||||||
|
|
||||||
def test_extras_require(tmp_path):
|
def test_extras_require(tmp_path: Path) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
project_with_a_test.generate(project_dir)
|
project_with_a_test.generate(project_dir)
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ def test_extras_require(tmp_path):
|
|||||||
assert set(actual_wheels) == set(expected_wheels)
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|
||||||
|
|
||||||
def test_dependency_groups(tmp_path):
|
def test_dependency_groups(tmp_path: Path) -> None:
|
||||||
group_project = project_with_a_test.copy()
|
group_project = project_with_a_test.copy()
|
||||||
group_project.files["pyproject.toml"] = inspect.cleandoc("""
|
group_project.files["pyproject.toml"] = inspect.cleandoc("""
|
||||||
[build-system]
|
[build-system]
|
||||||
@@ -149,12 +149,12 @@ project_with_a_failing_test.files["test/spam_test.py"] = r"""
|
|||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
class TestSpam(TestCase):
|
class TestSpam(TestCase):
|
||||||
def test_something(self):
|
def test_something(self) -> None:
|
||||||
self.fail('this test is supposed to fail')
|
self.fail('this test is supposed to fail')
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def test_failing_test(tmp_path):
|
def test_failing_test(tmp_path: Path) -> None:
|
||||||
"""Ensure a failing test causes cibuildwheel to error out and exit"""
|
"""Ensure a failing test causes cibuildwheel to error out and exit"""
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
output_dir = tmp_path / "output"
|
output_dir = tmp_path / "output"
|
||||||
@@ -215,7 +215,7 @@ def test_bare_pytest_invocation(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_test_sources(tmp_path):
|
def test_test_sources(tmp_path: Path) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
project_with_a_test.generate(project_dir)
|
project_with_a_test.generate(project_dir)
|
||||||
|
|
||||||
@@ -235,7 +235,7 @@ def test_test_sources(tmp_path):
|
|||||||
assert set(actual_wheels) == set(expected_wheels)
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|
||||||
|
|
||||||
def test_test_environment(tmp_path):
|
def test_test_environment(tmp_path: Path) -> None:
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
test_projects.new_c_project().generate(project_dir)
|
test_projects.new_c_project().generate(project_dir)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -9,7 +10,12 @@ SO_FILE_WARNING = "NOTE: Shared object (.so) files found in this project."
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("project_contains_so_files", [False, True])
|
@pytest.mark.parametrize("project_contains_so_files", [False, True])
|
||||||
def test_failed_build_with_so_files(tmp_path, capfd, build_frontend_env, project_contains_so_files):
|
def test_failed_build_with_so_files(
|
||||||
|
tmp_path: Path,
|
||||||
|
capfd: pytest.CaptureFixture[str],
|
||||||
|
build_frontend_env: dict[str, str],
|
||||||
|
project_contains_so_files: bool,
|
||||||
|
) -> None:
|
||||||
project = TestProject()
|
project = TestProject()
|
||||||
project.files["setup.py"] = "raise Exception('this build will fail')\n"
|
project.files["setup.py"] = "raise Exception('this build will fail')\n"
|
||||||
if project_contains_so_files:
|
if project_contains_so_files:
|
||||||
@@ -35,7 +41,11 @@ def test_failed_build_with_so_files(tmp_path, capfd, build_frontend_env, project
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("project_contains_so_files", [False, True])
|
@pytest.mark.parametrize("project_contains_so_files", [False, True])
|
||||||
def test_failed_repair_with_so_files(tmp_path, capfd, project_contains_so_files):
|
def test_failed_repair_with_so_files(
|
||||||
|
tmp_path: Path,
|
||||||
|
capfd: pytest.CaptureFixture[str],
|
||||||
|
project_contains_so_files: bool,
|
||||||
|
) -> None:
|
||||||
if utils.get_platform() != "linux":
|
if utils.get_platform() != "linux":
|
||||||
pytest.skip("this test is only relevant to the linux build")
|
pytest.skip("this test is only relevant to the linux build")
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from . import test_projects, utils
|
from . import test_projects, utils
|
||||||
@@ -5,7 +7,7 @@ from . import test_projects, utils
|
|||||||
basic_project = test_projects.new_c_project()
|
basic_project = test_projects.new_c_project()
|
||||||
|
|
||||||
|
|
||||||
def test_wheel_tag_is_correct_when_using_macosx_deployment_target(tmp_path):
|
def test_wheel_tag_is_correct_when_using_macosx_deployment_target(tmp_path: Path) -> None:
|
||||||
if utils.get_platform() != "macos":
|
if utils.get_platform() != "macos":
|
||||||
pytest.skip("This test is only relevant to MACOSX_DEPLOYMENT_TARGET")
|
pytest.skip("This test is only relevant to MACOSX_DEPLOYMENT_TARGET")
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ def skip_if_no_msvc(arm64: bool = False) -> None:
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("use_pyproject_toml", [True, False])
|
@pytest.mark.parametrize("use_pyproject_toml", [True, False])
|
||||||
def test_wheel_tag_is_correct_when_using_windows_cross_compile(tmp_path, use_pyproject_toml):
|
def test_wheel_tag_is_correct_when_using_windows_cross_compile(
|
||||||
|
tmp_path: Path, use_pyproject_toml: bool
|
||||||
|
) -> None:
|
||||||
if utils.get_platform() != "windows":
|
if utils.get_platform() != "windows":
|
||||||
pytest.skip("This test is only relevant to Windows")
|
pytest.skip("This test is only relevant to Windows")
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -11,7 +11,7 @@ import sys
|
|||||||
from collections.abc import Generator, Mapping, Sequence
|
from collections.abc import Generator, Mapping, Sequence
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from tempfile import TemporaryDirectory
|
from tempfile import TemporaryDirectory
|
||||||
from typing import Any, Final
|
from typing import Final
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -458,7 +458,7 @@ def get_xcode_version() -> tuple[int, int]:
|
|||||||
return (int(version_parts[0]), int(version_parts[1]))
|
return (int(version_parts[0]), int(version_parts[1]))
|
||||||
|
|
||||||
|
|
||||||
def skip_if_pyodide(reason: str) -> Any:
|
def skip_if_pyodide(reason: str) -> pytest.MarkDecorator:
|
||||||
return pytest.mark.skipif(get_platform() == "pyodide", reason=reason)
|
return pytest.mark.skipif(get_platform() == "pyodide", reason=reason)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import pytest
|
|||||||
|
|
||||||
import cibuildwheel.architecture
|
import cibuildwheel.architecture
|
||||||
from cibuildwheel.architecture import Architecture, arch_synonym
|
from cibuildwheel.architecture import Architecture, arch_synonym
|
||||||
|
from cibuildwheel.typing import PlatformName
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(
|
@pytest.fixture(
|
||||||
@@ -20,7 +21,9 @@ from cibuildwheel.architecture import Architecture, arch_synonym
|
|||||||
pytest.param(("windows", "win32", "ARM64", "arm"), id="windows-arm"),
|
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
|
platform_name, platform_value, machine_value, machine_name = request.param
|
||||||
monkeypatch.setattr(sys, "platform", platform_value)
|
monkeypatch.setattr(sys, "platform", platform_value)
|
||||||
monkeypatch.setattr(platform_module, "machine", lambda: machine_value)
|
monkeypatch.setattr(platform_module, "machine", lambda: machine_value)
|
||||||
@@ -28,7 +31,7 @@ def platform_machine(request, monkeypatch):
|
|||||||
return platform_name, machine_name
|
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
|
_, machine_name = platform_machine
|
||||||
|
|
||||||
arch_set = Architecture.auto_archs("linux")
|
arch_set = Architecture.auto_archs("linux")
|
||||||
@@ -52,7 +55,7 @@ def test_arch_auto(platform_machine):
|
|||||||
assert arch_set == expected[machine_name]
|
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
|
_, machine_name = platform_machine
|
||||||
|
|
||||||
arch_set = Architecture.parse_config("auto64", "linux")
|
arch_set = Architecture.parse_config("auto64", "linux")
|
||||||
@@ -68,7 +71,7 @@ def test_arch_auto64(platform_machine):
|
|||||||
assert arch_set == expected[machine_name]
|
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
|
_, machine_name = platform_machine
|
||||||
|
|
||||||
arch_set = Architecture.parse_config("auto32", "linux")
|
arch_set = Architecture.parse_config("auto32", "linux")
|
||||||
@@ -83,7 +86,7 @@ def test_arch_auto32(platform_machine):
|
|||||||
assert arch_set == expected[machine_name]
|
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(sys, "platform", "linux")
|
||||||
monkeypatch.setattr(platform_module, "machine", lambda: "aarch64")
|
monkeypatch.setattr(platform_module, "machine", lambda: "aarch64")
|
||||||
monkeypatch.setattr(shutil, "which", lambda *args, **kwargs: None)
|
monkeypatch.setattr(shutil, "which", lambda *args, **kwargs: None)
|
||||||
@@ -103,14 +106,14 @@ def test_arch_auto_no_aarch32(monkeypatch):
|
|||||||
assert arch_set == set()
|
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(sys, "platform", "darwin")
|
||||||
monkeypatch.setattr(platform_module, "machine", lambda: "arm64")
|
monkeypatch.setattr(platform_module, "machine", lambda: "arm64")
|
||||||
arch_set = Architecture.parse_config("native", platform="ios")
|
arch_set = Architecture.parse_config("native", platform="ios")
|
||||||
assert arch_set == {Architecture.arm64_iphonesimulator}
|
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(sys, "platform", "darwin")
|
||||||
monkeypatch.setattr(platform_module, "machine", lambda: "arm64")
|
monkeypatch.setattr(platform_module, "machine", lambda: "arm64")
|
||||||
arch_set = Architecture.parse_config("auto", platform="ios")
|
arch_set = Architecture.parse_config("auto", platform="ios")
|
||||||
@@ -130,5 +133,7 @@ def test_arch_auto_on_ios(monkeypatch):
|
|||||||
("x86", "windows", "macos", None),
|
("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
|
assert arch_synonym(arch, from_platform, to_platform) == expected
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from cibuildwheel.extra import Printable, dump_python_configurations
|
|||||||
from cibuildwheel.util import resources
|
from cibuildwheel.util import resources
|
||||||
|
|
||||||
|
|
||||||
def test_compare_configs():
|
def test_compare_configs() -> None:
|
||||||
txt = resources.BUILD_PLATFORMS.read_text()
|
txt = resources.BUILD_PLATFORMS.read_text()
|
||||||
|
|
||||||
with resources.BUILD_PLATFORMS.open("rb") as f2:
|
with resources.BUILD_PLATFORMS.open("rb") as f2:
|
||||||
@@ -18,7 +18,7 @@ def test_compare_configs():
|
|||||||
assert new_txt == txt
|
assert new_txt == txt
|
||||||
|
|
||||||
|
|
||||||
def test_dump_with_Version():
|
def test_dump_with_Version() -> None:
|
||||||
# MyPy doesn't understand deeply nested dicts correctly
|
# MyPy doesn't understand deeply nested dicts correctly
|
||||||
example: dict[str, dict[str, list[dict[str, Printable]]]] = {
|
example: dict[str, dict[str, list[dict[str, Printable]]]] = {
|
||||||
"windows": {
|
"windows": {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import cibuildwheel.selector
|
|||||||
from cibuildwheel.selector import BuildSelector, EnableGroup
|
from cibuildwheel.selector import BuildSelector, EnableGroup
|
||||||
|
|
||||||
|
|
||||||
def test_build():
|
def test_build() -> None:
|
||||||
build_selector = BuildSelector(
|
build_selector = BuildSelector(
|
||||||
build_config="cp3*-* *-manylinux*", skip_config="", enable=frozenset([EnableGroup.PyPy])
|
build_config="cp3*-* *-manylinux*", skip_config="", enable=frozenset([EnableGroup.PyPy])
|
||||||
)
|
)
|
||||||
@@ -41,7 +41,7 @@ def test_build():
|
|||||||
assert not build_selector("pp311-win_amd64")
|
assert not build_selector("pp311-win_amd64")
|
||||||
|
|
||||||
|
|
||||||
def test_build_filter_pre():
|
def test_build_filter_pre() -> None:
|
||||||
build_selector = BuildSelector(
|
build_selector = BuildSelector(
|
||||||
build_config="cp3*-* *-manylinux*",
|
build_config="cp3*-* *-manylinux*",
|
||||||
skip_config="",
|
skip_config="",
|
||||||
@@ -55,7 +55,7 @@ def test_build_filter_pre():
|
|||||||
assert not build_selector("cp313t-manylinux_x86_64")
|
assert not build_selector("cp313t-manylinux_x86_64")
|
||||||
|
|
||||||
|
|
||||||
def test_build_filter_pypy():
|
def test_build_filter_pypy() -> None:
|
||||||
build_selector = BuildSelector(
|
build_selector = BuildSelector(
|
||||||
build_config="*",
|
build_config="*",
|
||||||
skip_config="",
|
skip_config="",
|
||||||
@@ -67,7 +67,7 @@ def test_build_filter_pypy():
|
|||||||
assert not build_selector("pp39-manylinux_x86_64")
|
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_selector = BuildSelector(
|
||||||
build_config="*",
|
build_config="*",
|
||||||
skip_config="",
|
skip_config="",
|
||||||
@@ -79,7 +79,7 @@ def test_build_filter_pypy_eol():
|
|||||||
assert build_selector("pp39-manylinux_x86_64")
|
assert build_selector("pp39-manylinux_x86_64")
|
||||||
|
|
||||||
|
|
||||||
def test_build_filter_pypy_all():
|
def test_build_filter_pypy_all() -> None:
|
||||||
build_selector = BuildSelector(
|
build_selector = BuildSelector(
|
||||||
build_config="*",
|
build_config="*",
|
||||||
skip_config="",
|
skip_config="",
|
||||||
@@ -91,7 +91,7 @@ def test_build_filter_pypy_all():
|
|||||||
assert build_selector("pp39-manylinux_x86_64")
|
assert build_selector("pp39-manylinux_x86_64")
|
||||||
|
|
||||||
|
|
||||||
def test_build_filter_pyodide_prerelease():
|
def test_build_filter_pyodide_prerelease() -> None:
|
||||||
build_selector = BuildSelector(
|
build_selector = BuildSelector(
|
||||||
build_config="*",
|
build_config="*",
|
||||||
skip_config="",
|
skip_config="",
|
||||||
@@ -101,7 +101,7 @@ def test_build_filter_pyodide_prerelease():
|
|||||||
assert build_selector("cp313-pyodide_wasm32")
|
assert build_selector("cp313-pyodide_wasm32")
|
||||||
|
|
||||||
|
|
||||||
def test_build_filter_pyodide():
|
def test_build_filter_pyodide() -> None:
|
||||||
build_selector = BuildSelector(
|
build_selector = BuildSelector(
|
||||||
build_config="*",
|
build_config="*",
|
||||||
skip_config="",
|
skip_config="",
|
||||||
@@ -111,7 +111,7 @@ def test_build_filter_pyodide():
|
|||||||
assert build_selector("cp313-pyodide_wasm32")
|
assert build_selector("cp313-pyodide_wasm32")
|
||||||
|
|
||||||
|
|
||||||
def test_skip():
|
def test_skip() -> None:
|
||||||
build_selector = BuildSelector(
|
build_selector = BuildSelector(
|
||||||
build_config="*",
|
build_config="*",
|
||||||
skip_config="pp310-* cp3?-manylinux_i686 cp36-win* *-win32",
|
skip_config="pp310-* cp3?-manylinux_i686 cp36-win* *-win32",
|
||||||
@@ -136,7 +136,7 @@ def test_skip():
|
|||||||
assert build_selector("cp37-win_amd64")
|
assert build_selector("cp37-win_amd64")
|
||||||
|
|
||||||
|
|
||||||
def test_build_and_skip():
|
def test_build_and_skip() -> None:
|
||||||
build_selector = BuildSelector(
|
build_selector = BuildSelector(
|
||||||
build_config="cp36-* cp37-macosx* *-manylinux*",
|
build_config="cp36-* cp37-macosx* *-manylinux*",
|
||||||
skip_config="pp37-* cp37-manylinux_i686",
|
skip_config="pp37-* cp37-manylinux_i686",
|
||||||
@@ -160,7 +160,7 @@ def test_build_and_skip():
|
|||||||
assert not build_selector("cp37-win_amd64")
|
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="")
|
build_selector = BuildSelector(build_config="cp{36,37}*", skip_config="")
|
||||||
|
|
||||||
assert build_selector("cp36-manylinux_x86_64")
|
assert build_selector("cp36-manylinux_x86_64")
|
||||||
@@ -169,7 +169,7 @@ def test_build_braces():
|
|||||||
assert not build_selector("cp39-manylinux_x86_64")
|
assert not build_selector("cp39-manylinux_x86_64")
|
||||||
|
|
||||||
|
|
||||||
def test_build_limited_python():
|
def test_build_limited_python() -> None:
|
||||||
build_selector = BuildSelector(
|
build_selector = BuildSelector(
|
||||||
build_config="*",
|
build_config="*",
|
||||||
skip_config="",
|
skip_config="",
|
||||||
@@ -190,7 +190,7 @@ def test_build_limited_python():
|
|||||||
assert build_selector("gp311_242-win_amd64")
|
assert build_selector("gp311_242-win_amd64")
|
||||||
|
|
||||||
|
|
||||||
def test_build_limited_python_partial():
|
def test_build_limited_python_partial() -> None:
|
||||||
build_selector = BuildSelector(
|
build_selector = BuildSelector(
|
||||||
build_config="*", skip_config="", requires_python=SpecifierSet(">=3.6, !=3.7.*")
|
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")
|
assert build_selector("cp39-manylinux_x86_64")
|
||||||
|
|
||||||
|
|
||||||
def test_build_limited_python_patch():
|
def test_build_limited_python_patch() -> None:
|
||||||
build_selector = BuildSelector(
|
build_selector = BuildSelector(
|
||||||
build_config="*", skip_config="", requires_python=SpecifierSet(">=3.6.8")
|
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")
|
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))
|
build_selector = BuildSelector(build_config="*", skip_config="", enable=frozenset(EnableGroup))
|
||||||
|
|
||||||
assert build_selector("cp313t-manylinux_x86_64")
|
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
|
# This is not a global import to keep pytest from collecting it as a test
|
||||||
test_selector = cibuildwheel.selector.TestSelector(skip_config="cp36-*")
|
test_selector = cibuildwheel.selector.TestSelector(skip_config="cp36-*")
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import pytest
|
|||||||
MOCK_PACKAGE_DIR = Path("some_package_dir")
|
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-docker", action="store_true", default=False, help="run docker tests")
|
||||||
parser.addoption("--run-podman", action="store_true", default=False, help="run podman tests")
|
parser.addoption("--run-podman", action="store_true", default=False, help="run podman tests")
|
||||||
parser.addoption(
|
parser.addoption(
|
||||||
@@ -18,13 +18,13 @@ def pytest_addoption(parser):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@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
|
Monkey-patch enough for the main() function to run
|
||||||
"""
|
"""
|
||||||
real_path_exists = Path.exists
|
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")):
|
if str(path).endswith(str(MOCK_PACKAGE_DIR / "setup.py")):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import ssl
|
import ssl
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import certifi
|
import certifi
|
||||||
import pytest
|
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"
|
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)
|
monkeypatch.delenv("SSL_CERT_FILE", raising=False)
|
||||||
dest = tmp_path / "file.txt"
|
dest = tmp_path / "file.txt"
|
||||||
download(DOWNLOAD_URL, dest)
|
download(DOWNLOAD_URL, dest)
|
||||||
assert len(dest.read_bytes()) == 134
|
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())
|
monkeypatch.setenv("SSL_CERT_FILE", certifi.where())
|
||||||
dest = tmp_path / "file.txt"
|
dest = tmp_path / "file.txt"
|
||||||
download(DOWNLOAD_URL, dest)
|
download(DOWNLOAD_URL, dest)
|
||||||
assert len(dest.read_bytes()) == 134
|
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 = tmp_path / "ca.pem"
|
||||||
bad_cafile.write_text("bad certificates")
|
bad_cafile.write_text("bad certificates")
|
||||||
monkeypatch.setenv("SSL_CERT_FILE", str(bad_cafile))
|
monkeypatch.setenv("SSL_CERT_FILE", str(bad_cafile))
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from cibuildwheel.environment import parse_environment
|
|||||||
PYTHON_ECHO = f"'{sys.executable}' -c \"import sys; print(*sys.argv[1:])\""
|
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_recipe = parse_environment("VAR=1 VBR=2")
|
||||||
|
|
||||||
environment_dict = environment_recipe.as_dictionary(prev_environment={})
|
environment_dict = environment_recipe.as_dictionary(prev_environment={})
|
||||||
@@ -15,7 +15,7 @@ def test_basic_parsing():
|
|||||||
assert environment_dict == {"VAR": "1", "VBR": "2"}
|
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_recipe = parse_environment("A=1 VAR=\"1 NOT_A_VAR=2\" VBR='vbr'")
|
||||||
|
|
||||||
environment_dict = environment_recipe.as_dictionary(prev_environment={})
|
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"}
|
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_recipe = parse_environment("PATH=$PATH:/usr/local/bin")
|
||||||
|
|
||||||
environment_dict = environment_recipe.as_dictionary(prev_environment={"PATH": "/usr/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"}
|
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)"')
|
environment_recipe = parse_environment(f'VAR="$({PYTHON_ECHO} "a test" string)"')
|
||||||
|
|
||||||
env_copy = os.environ.copy()
|
env_copy = os.environ.copy()
|
||||||
@@ -42,7 +42,7 @@ def test_shell_eval():
|
|||||||
assert environment_dict["VAR"] == "a test string"
|
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)"')
|
environment_recipe = parse_environment(f'VAR="$({PYTHON_ECHO} "$PREV_VAR" string)"')
|
||||||
|
|
||||||
prev_environment = {**os.environ, "PREV_VAR": "1 2 3"}
|
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"}
|
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_recipe = parse_environment("CFLAGS=")
|
||||||
|
|
||||||
environment_dict = environment_recipe.as_dictionary(prev_environment={"CFLAGS": "-Wall"})
|
environment_dict = environment_recipe.as_dictionary(prev_environment={"CFLAGS": "-Wall"})
|
||||||
@@ -59,7 +59,7 @@ def test_empty_var():
|
|||||||
assert environment_dict == {"CFLAGS": ""}
|
assert environment_dict == {"CFLAGS": ""}
|
||||||
|
|
||||||
|
|
||||||
def test_no_vars():
|
def test_no_vars() -> None:
|
||||||
environment_recipe = parse_environment("")
|
environment_recipe = parse_environment("")
|
||||||
|
|
||||||
environment_dict = environment_recipe.as_dictionary(prev_environment={})
|
environment_dict = environment_recipe.as_dictionary(prev_environment={})
|
||||||
@@ -67,7 +67,7 @@ def test_no_vars():
|
|||||||
assert environment_dict == {}
|
assert environment_dict == {}
|
||||||
|
|
||||||
|
|
||||||
def test_no_vars_pass_through():
|
def test_no_vars_pass_through() -> None:
|
||||||
environment_recipe = parse_environment("")
|
environment_recipe = parse_environment("")
|
||||||
|
|
||||||
environment_dict = environment_recipe.as_dictionary(
|
environment_dict = environment_recipe.as_dictionary(
|
||||||
@@ -77,7 +77,7 @@ def test_no_vars_pass_through():
|
|||||||
assert environment_dict == {"CIBUILDWHEEL": "awesome"}
|
assert environment_dict == {"CIBUILDWHEEL": "awesome"}
|
||||||
|
|
||||||
|
|
||||||
def test_operators_inside_eval():
|
def test_operators_inside_eval() -> None:
|
||||||
environment_recipe = parse_environment(
|
environment_recipe = parse_environment(
|
||||||
f'SOMETHING="$({PYTHON_ECHO} a; {PYTHON_ECHO} b; {PYTHON_ECHO} c)"'
|
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"
|
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_recipe = parse_environment('PATH2="somewhere_else;$PATH1"')
|
||||||
|
|
||||||
environment_dict = environment_recipe.as_dictionary(prev_environment={"PATH1": "c:\\folder\\"})
|
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\\"
|
assert environment_dict.get("PATH2") == "somewhere_else;c:\\folder\\"
|
||||||
|
|
||||||
|
|
||||||
def test_awkwardly_quoted_variable():
|
def test_awkwardly_quoted_variable() -> None:
|
||||||
environment_recipe = parse_environment(
|
environment_recipe = parse_environment(
|
||||||
f'VAR2=something"like this""$VAR1"$VAR1$({PYTHON_ECHO} "there is more")"$({PYTHON_ECHO} "and more!")"'
|
f'VAR2=something"like this""$VAR1"$VAR1$({PYTHON_ECHO} "there is more")"$({PYTHON_ECHO} "and more!")"'
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import errno
|
import errno
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -8,7 +9,9 @@ import cibuildwheel.__main__ as main_module
|
|||||||
from cibuildwheel.__main__ import main
|
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()
|
fake_cache_dir = (tmp_path / "cibw_cache").resolve()
|
||||||
monkeypatch.setattr(main_module, "CIBW_CACHE_PATH", fake_cache_dir)
|
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()
|
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()
|
fake_cache_dir = (tmp_path / "nonexistent_cache").resolve()
|
||||||
monkeypatch.setattr(main_module, "CIBW_CACHE_PATH", fake_cache_dir)
|
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
|
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()
|
fake_cache_dir = (tmp_path / "cibw_cache").resolve()
|
||||||
monkeypatch.setattr(main_module, "CIBW_CACHE_PATH", fake_cache_dir)
|
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"])
|
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")
|
raise OSError(errno.EACCES, "Permission denied")
|
||||||
|
|
||||||
monkeypatch.setattr(shutil, "rmtree", fake_rmtree)
|
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
|
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()
|
fake_cache_dir = (tmp_path / "not_a_cache").resolve()
|
||||||
monkeypatch.setattr(main_module, "CIBW_CACHE_PATH", fake_cache_dir)
|
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()
|
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()
|
fake_cache_dir = (tmp_path / "fake_cache").resolve()
|
||||||
monkeypatch.setattr(main_module, "CIBW_CACHE_PATH", fake_cache_dir)
|
monkeypatch.setattr(main_module, "CIBW_CACHE_PATH", fake_cache_dir)
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ import contextlib
|
|||||||
import platform as platform_module
|
import platform as platform_module
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
from collections.abc import Generator, Iterator
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -15,27 +17,27 @@ from cibuildwheel.util import file
|
|||||||
class ArgsInterceptor:
|
class ArgsInterceptor:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.call_count = 0
|
self.call_count = 0
|
||||||
self.args: tuple[object, ...] | None = None
|
self.args: tuple[Any, ...] = ()
|
||||||
self.kwargs: dict[str, object] | None = None
|
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.call_count += 1
|
||||||
self.args = args
|
self.args = args
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@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'
|
Ensure that a unit test will never actually run a cibuildwheel 'build'
|
||||||
function, which shouldn't be run on a developer's machine
|
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"
|
msg = "This should never be called"
|
||||||
raise RuntimeError(msg)
|
raise RuntimeError(msg)
|
||||||
|
|
||||||
def ignore_call(*args, **kwargs):
|
def ignore_call(*args: object, **kwargs: object) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
monkeypatch.setattr(subprocess, "Popen", fail_on_call)
|
monkeypatch.setattr(subprocess, "Popen", fail_on_call)
|
||||||
@@ -49,27 +51,27 @@ def mock_protection(monkeypatch):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def fake_package_dir_autouse(fake_package_dir):
|
def fake_package_dir_autouse(fake_package_dir: list[str]) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def disable_print_wheels(monkeypatch):
|
def disable_print_wheels(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def empty_cm(*args, **kwargs):
|
def empty_cm(*args: object, **kwargs: object) -> Generator[None, None, None]:
|
||||||
yield
|
yield
|
||||||
|
|
||||||
monkeypatch.setattr(Logger, "print_summary", empty_cm)
|
monkeypatch.setattr(Logger, "print_summary", empty_cm)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@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"])
|
monkeypatch.setattr(sys, "argv", [*fake_package_dir, "--allow-empty"])
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(params=["linux", "macos", "windows"])
|
@pytest.fixture(params=["linux", "macos", "windows"])
|
||||||
def platform(request, monkeypatch):
|
def platform(request: pytest.FixtureRequest, monkeypatch: pytest.MonkeyPatch) -> str:
|
||||||
platform_value = request.param
|
platform_value: str = request.param
|
||||||
monkeypatch.setenv("CIBW_PLATFORM", platform_value)
|
monkeypatch.setenv("CIBW_PLATFORM", platform_value)
|
||||||
|
|
||||||
if platform_value == "windows":
|
if platform_value == "windows":
|
||||||
@@ -84,7 +86,7 @@ def platform(request, monkeypatch):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def intercepted_build_args(monkeypatch):
|
def intercepted_build_args(monkeypatch: pytest.MonkeyPatch) -> Iterator[ArgsInterceptor]:
|
||||||
intercepted = ArgsInterceptor()
|
intercepted = ArgsInterceptor()
|
||||||
|
|
||||||
monkeypatch.setattr(android, "build", intercepted)
|
monkeypatch.setattr(android, "build", intercepted)
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
|
from collections.abc import Mapping
|
||||||
from fnmatch import fnmatch
|
from fnmatch import fnmatch
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -13,10 +15,15 @@ from cibuildwheel.selector import BuildSelector, EnableGroup
|
|||||||
from cibuildwheel.util import resources
|
from cibuildwheel.util import resources
|
||||||
from cibuildwheel.util.packaging import DependencyConstraints
|
from cibuildwheel.util.packaging import DependencyConstraints
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .conftest import ArgsInterceptor
|
||||||
|
|
||||||
# CIBW_PLATFORM is tested in main_platform_test.py
|
# 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")
|
monkeypatch.setenv("CIBW_FREE_THREADED_SUPPORT", "ON")
|
||||||
|
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
@@ -29,7 +36,9 @@ def test_old_free_threaded(monkeypatch, capsys):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("platform")
|
@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")
|
OUTPUT_DIR = Path("some_output_dir")
|
||||||
|
|
||||||
monkeypatch.setenv("CIBW_OUTPUT_DIR", str(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")
|
@pytest.mark.usefixtures("platform")
|
||||||
def test_output_dir_default(intercepted_build_args):
|
def test_output_dir_default(intercepted_build_args: "ArgsInterceptor") -> None:
|
||||||
main()
|
main()
|
||||||
|
|
||||||
assert intercepted_build_args.args[0].globals.output_dir == Path("wheelhouse").resolve()
|
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.usefixtures("platform")
|
||||||
@pytest.mark.parametrize("also_set_environment", [False, True])
|
@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")
|
OUTPUT_DIR = Path("some_output_dir")
|
||||||
|
|
||||||
monkeypatch.setattr(sys, "argv", [*sys.argv, "--output-dir", str(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")
|
@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_BUILD", "cp313-*")
|
||||||
monkeypatch.setenv("CIBW_SKIP", "cp39-*")
|
monkeypatch.setenv("CIBW_SKIP", "cp39-*")
|
||||||
|
|
||||||
@@ -76,7 +91,9 @@ def test_build_selector(intercepted_build_args, monkeypatch):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("platform", "allow_empty")
|
@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")
|
monkeypatch.setenv("CIBW_BUILD", "invalid")
|
||||||
|
|
||||||
with pytest.raises(SystemExit) as e:
|
with pytest.raises(SystemExit) as e:
|
||||||
@@ -95,7 +112,12 @@ def test_invalid_build_selector(monkeypatch, capsys):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("platform", "intercepted_build_args")
|
@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")
|
monkeypatch.setenv(option_env_var, "invalid")
|
||||||
|
|
||||||
main()
|
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"]
|
"selector", ["*-macosx_universal2:arm64", "*-macosx_universal2:x86_64", "*-macosx_arm64"]
|
||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("platform", "intercepted_build_args")
|
@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)
|
monkeypatch.setenv("CIBW_TEST_SKIP", selector)
|
||||||
|
|
||||||
main()
|
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.parametrize("selector", ["*-macosx_universal2:invalid", "*-macosx_arm64:arm64"])
|
||||||
@pytest.mark.usefixtures("platform", "intercepted_build_args")
|
@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)
|
monkeypatch.setenv("CIBW_TEST_SKIP", selector)
|
||||||
|
|
||||||
main()
|
main()
|
||||||
@@ -132,7 +158,7 @@ def test_invalid_test_skip_selector(monkeypatch, capsys, selector):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("platform", "intercepted_build_args")
|
@pytest.mark.usefixtures("platform", "intercepted_build_args")
|
||||||
def test_empty_selector(monkeypatch):
|
def test_empty_selector(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
monkeypatch.setenv("CIBW_SKIP", "*")
|
monkeypatch.setenv("CIBW_SKIP", "*")
|
||||||
|
|
||||||
with pytest.raises(SystemExit) as e:
|
with pytest.raises(SystemExit) as e:
|
||||||
@@ -161,8 +187,13 @@ def test_empty_selector(monkeypatch):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_manylinux_images(
|
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:
|
if image is not None:
|
||||||
monkeypatch.setenv("CIBW_MANYLINUX_" + architecture.upper() + "_IMAGE", image)
|
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("repair_command", [None, "repair", "repair -w {dest_dir} {wheel}"])
|
||||||
@pytest.mark.parametrize("platform_specific", [False, True])
|
@pytest.mark.parametrize("platform_specific", [False, True])
|
||||||
def test_repair_command(
|
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 repair_command is not None:
|
||||||
if platform_specific:
|
if platform_specific:
|
||||||
monkeypatch.setenv("CIBW_REPAIR_WHEEL_COMMAND_" + platform.upper(), repair_command)
|
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"}],
|
[{}, {"something": "value"}, {"something": "value", "something_else": "other_value"}],
|
||||||
)
|
)
|
||||||
@pytest.mark.parametrize("platform_specific", [False, True])
|
@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())
|
env_string = " ".join(f"{k}={v}" for k, v in environment.items())
|
||||||
if platform_specific:
|
if platform_specific:
|
||||||
monkeypatch.setenv("CIBW_ENVIRONMENT_" + platform.upper(), env_string)
|
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("test_requires", [None, "requirement other_requirement"])
|
||||||
@pytest.mark.parametrize("platform_specific", [False, True])
|
@pytest.mark.parametrize("platform_specific", [False, True])
|
||||||
def test_test_requires(
|
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 test_requires is not None:
|
||||||
if platform_specific:
|
if platform_specific:
|
||||||
monkeypatch.setenv("CIBW_TEST_REQUIRES_" + platform.upper(), test_requires)
|
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("test_extras", [None, "extras"])
|
||||||
@pytest.mark.parametrize("platform_specific", [False, True])
|
@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 test_extras is not None:
|
||||||
if platform_specific:
|
if platform_specific:
|
||||||
monkeypatch.setenv("CIBW_TEST_EXTRAS_" + platform.upper(), test_extras)
|
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("test_command", [None, "test --command"])
|
||||||
@pytest.mark.parametrize("platform_specific", [False, True])
|
@pytest.mark.parametrize("platform_specific", [False, True])
|
||||||
def test_test_command(
|
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 test_command is not None:
|
||||||
if platform_specific:
|
if platform_specific:
|
||||||
monkeypatch.setenv("CIBW_TEST_COMMAND_" + platform.upper(), test_command)
|
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("before_build", [None, "before --build"])
|
||||||
@pytest.mark.parametrize("platform_specific", [False, True])
|
@pytest.mark.parametrize("platform_specific", [False, True])
|
||||||
def test_before_build(
|
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 before_build is not None:
|
||||||
if platform_specific:
|
if platform_specific:
|
||||||
monkeypatch.setenv("CIBW_BEFORE_BUILD_" + platform.upper(), before_build)
|
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("build_verbosity", [None, 0, 2, -2, 4, -4])
|
||||||
@pytest.mark.parametrize("platform_specific", [False, True])
|
@pytest.mark.parametrize("platform_specific", [False, True])
|
||||||
def test_build_verbosity(
|
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 build_verbosity is not None:
|
||||||
if platform_specific:
|
if platform_specific:
|
||||||
monkeypatch.setenv("CIBW_BUILD_VERBOSITY_" + platform.upper(), str(build_verbosity))
|
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])
|
@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 = (
|
config_settings = (
|
||||||
'setting=value setting=value2 triplet=1 triplet=2 triplet=3 other="something else"'
|
'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")
|
@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.setenv(selector, pattern)
|
||||||
monkeypatch.delenv("CIBW_ENABLE", raising=False)
|
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("before_all", ["", None, "test text"])
|
||||||
@pytest.mark.parametrize("platform_specific", [False, True])
|
@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 before_all is not None:
|
||||||
if platform_specific:
|
if platform_specific:
|
||||||
monkeypatch.setenv("CIBW_BEFORE_ALL_" + platform.upper(), before_all)
|
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])
|
@pytest.mark.parametrize("platform_specific", [False, True])
|
||||||
def test_dependency_versions(
|
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
|
option_value = dependency_versions
|
||||||
|
|
||||||
if dependency_versions == "FILE":
|
if dependency_versions == "FILE":
|
||||||
@@ -443,13 +524,16 @@ def test_dependency_versions(
|
|||||||
assert dependency_constraints == DependencyConstraints.latest()
|
assert dependency_constraints == DependencyConstraints.latest()
|
||||||
elif dependency_versions == "FILE":
|
elif dependency_versions == "FILE":
|
||||||
assert dependency_constraints.base_file_path
|
assert dependency_constraints.base_file_path
|
||||||
|
assert option_value is not None
|
||||||
assert dependency_constraints.base_file_path.samefile(Path(option_value))
|
assert dependency_constraints.base_file_path.samefile(Path(option_value))
|
||||||
elif dependency_versions.startswith("packages:"):
|
elif dependency_versions.startswith("packages:"):
|
||||||
assert dependency_constraints.packages == ["pip==21.0.0"]
|
assert dependency_constraints.packages == ["pip==21.0.0"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("method", ["unset", "command_line", "env_var"])
|
@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":
|
if method == "command_line":
|
||||||
monkeypatch.setattr(sys, "argv", [*sys.argv, "--debug-traceback"])
|
monkeypatch.setattr(sys, "argv", [*sys.argv, "--debug-traceback"])
|
||||||
elif method == "env_var":
|
elif method == "env_var":
|
||||||
@@ -471,7 +555,9 @@ def test_debug_traceback(monkeypatch, method, capfd):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("method", ["unset", "command_line", "env_var"])
|
@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)
|
monkeypatch.delenv("CIBW_ENABLE", raising=False)
|
||||||
|
|
||||||
if method == "command_line":
|
if method == "command_line":
|
||||||
@@ -489,7 +575,9 @@ def test_enable(method, intercepted_build_args, monkeypatch):
|
|||||||
assert enable_groups == frozenset([EnableGroup.PyPy, EnableGroup.GraalPy])
|
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"])
|
monkeypatch.setattr(sys, "argv", [*sys.argv, "--enable", "all"])
|
||||||
|
|
||||||
main()
|
main()
|
||||||
@@ -498,7 +586,9 @@ def test_enable_all(intercepted_build_args, monkeypatch):
|
|||||||
assert enable_groups == EnableGroup.all_groups()
|
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.setenv("CIBW_ENABLE", "pypy graalpy")
|
||||||
monkeypatch.setattr(sys, "argv", [*sys.argv, "--enable", "cpython-prerelease"])
|
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"])
|
monkeypatch.setattr(sys, "argv", [*sys.argv, "--enable", "invalid_group"])
|
||||||
|
|
||||||
with pytest.raises(SystemExit) as ex:
|
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
|
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()
|
main()
|
||||||
|
|
||||||
build_options: BuildOptions = intercepted_build_args.args[0].build_options(identifier=None)
|
build_options: BuildOptions = intercepted_build_args.args[0].build_options(identifier=None)
|
||||||
|
|||||||
@@ -5,12 +5,18 @@ import pytest
|
|||||||
from cibuildwheel.__main__ import main
|
from cibuildwheel.__main__ import main
|
||||||
from cibuildwheel.architecture import Architecture
|
from cibuildwheel.architecture import Architecture
|
||||||
from cibuildwheel.selector import EnableGroup
|
from cibuildwheel.selector import EnableGroup
|
||||||
|
from cibuildwheel.typing import PlatformName
|
||||||
|
|
||||||
from ..conftest import MOCK_PACKAGE_DIR
|
from ..conftest import MOCK_PACKAGE_DIR
|
||||||
|
from .conftest import ArgsInterceptor
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("option_value", [None, "auto", ""])
|
@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:
|
if option_value is None:
|
||||||
monkeypatch.delenv("CIBW_PLATFORM", raising=False)
|
monkeypatch.delenv("CIBW_PLATFORM", raising=False)
|
||||||
else:
|
else:
|
||||||
@@ -31,7 +37,9 @@ def test_platform_unset_or_auto(monkeypatch, intercepted_build_args, option_valu
|
|||||||
pytest.fail(f"Unknown platform: {sys.platform}")
|
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.setenv("CI", "true")
|
||||||
monkeypatch.setattr(sys, "platform", "nonexistent")
|
monkeypatch.setattr(sys, "platform", "nonexistent")
|
||||||
monkeypatch.delenv("CIBW_PLATFORM", raising=False)
|
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
|
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")
|
monkeypatch.setenv("CIBW_PLATFORM", "nonexistent")
|
||||||
|
|
||||||
with pytest.raises(SystemExit) as exit:
|
with pytest.raises(SystemExit) as exit:
|
||||||
@@ -55,7 +65,9 @@ def test_unknown_platform(monkeypatch, capsys):
|
|||||||
assert "Unsupported platform: nonexistent" in err
|
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.setenv("CIBW_PLATFORM", "nonexistent")
|
||||||
monkeypatch.setattr(sys, "argv", [*sys.argv, "--platform", platform])
|
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")
|
@pytest.mark.usefixtures("platform")
|
||||||
def test_platform_environment(intercepted_build_args):
|
def test_platform_environment(intercepted_build_args: ArgsInterceptor) -> None:
|
||||||
main()
|
main()
|
||||||
options = intercepted_build_args.args[0]
|
options = intercepted_build_args.args[0]
|
||||||
|
|
||||||
assert options.globals.package_dir == MOCK_PACKAGE_DIR.resolve()
|
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()
|
main()
|
||||||
options = intercepted_build_args.args[0]
|
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])
|
@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:
|
if use_env_var:
|
||||||
monkeypatch.setenv("CIBW_ARCHS", "ppc64le")
|
monkeypatch.setenv("CIBW_ARCHS", "ppc64le")
|
||||||
else:
|
else:
|
||||||
@@ -105,7 +122,9 @@ def test_archs_argument(platform, intercepted_build_args, monkeypatch, use_env_v
|
|||||||
assert options.globals.architectures == {Architecture.ppc64le}
|
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", "unused")
|
||||||
monkeypatch.setenv("CIBW_ARCHS_LINUX", "ppc64le")
|
monkeypatch.setenv("CIBW_ARCHS_LINUX", "ppc64le")
|
||||||
monkeypatch.setenv("CIBW_ARCHS_WINDOWS", "x86")
|
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}
|
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")
|
monkeypatch.setenv("CIBW_ARCHS", "native")
|
||||||
|
|
||||||
main()
|
main()
|
||||||
@@ -134,7 +155,9 @@ def test_archs_platform_native(platform, intercepted_build_args, monkeypatch):
|
|||||||
assert options.globals.architectures == {Architecture.AMD64}
|
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")
|
monkeypatch.setenv("CIBW_ARCHS", "auto64")
|
||||||
|
|
||||||
main()
|
main()
|
||||||
@@ -146,7 +169,9 @@ def test_archs_platform_auto64(platform, intercepted_build_args, monkeypatch):
|
|||||||
assert options.globals.architectures == {Architecture.AMD64}
|
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")
|
monkeypatch.setenv("CIBW_ARCHS", "auto32")
|
||||||
|
|
||||||
if platform == "macos":
|
if platform == "macos":
|
||||||
@@ -165,7 +190,9 @@ def test_archs_platform_auto32(platform, intercepted_build_args, monkeypatch):
|
|||||||
assert options.globals.architectures == {Architecture.x86}
|
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")
|
monkeypatch.setenv("CIBW_ARCHS", "all")
|
||||||
|
|
||||||
main()
|
main()
|
||||||
@@ -204,7 +231,12 @@ def test_archs_platform_all(platform, intercepted_build_args, monkeypatch):
|
|||||||
("cp311-macosx_x86_64", "macos"),
|
("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_BUILD", "unused")
|
||||||
monkeypatch.setenv("CIBW_SKIP", "unused")
|
monkeypatch.setenv("CIBW_SKIP", "unused")
|
||||||
monkeypatch.setattr(sys, "argv", [*sys.argv, "--only", only])
|
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"))
|
@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])
|
monkeypatch.setattr(sys, "argv", [*sys.argv, "--only", only])
|
||||||
|
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|
||||||
def test_only_no_platform(monkeypatch):
|
def test_only_no_platform(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
sys, "argv", [*sys.argv, "--only", "cp311-manylinux_x86_64", "--platform", "macos"]
|
sys, "argv", [*sys.argv, "--only", "cp311-manylinux_x86_64", "--platform", "macos"]
|
||||||
)
|
)
|
||||||
@@ -236,7 +268,7 @@ def test_only_no_platform(monkeypatch):
|
|||||||
main()
|
main()
|
||||||
|
|
||||||
|
|
||||||
def test_only_no_archs(monkeypatch):
|
def test_only_no_archs(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
sys, "argv", [*sys.argv, "--only", "cp311-manylinux_x86_64", "--archs", "x86_64"]
|
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"),
|
("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.setattr(sys, "argv", [*sys.argv, "--only", "cp311-manylinux_x86_64"])
|
||||||
monkeypatch.setenv(envvar_name, envvar_value)
|
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")
|
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, "platform", "win32")
|
||||||
monkeypatch.setattr(sys, "argv", [*sys.argv, "--only", "cp312-pyodide_wasm32"])
|
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
|
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", "")
|
monkeypatch.setenv("CIBW_ARCHS", "")
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from packaging.specifiers import SpecifierSet
|
from packaging.specifiers import SpecifierSet
|
||||||
|
|
||||||
from cibuildwheel.__main__ import main
|
from cibuildwheel.__main__ import main
|
||||||
|
|
||||||
|
from .conftest import ArgsInterceptor
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@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
|
Set up a fake project
|
||||||
"""
|
"""
|
||||||
@@ -24,7 +27,7 @@ def fake_package_dir(monkeypatch, tmp_path):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("platform")
|
@pytest.mark.usefixtures("platform")
|
||||||
def test_no_override(intercepted_build_args):
|
def test_no_override(intercepted_build_args: ArgsInterceptor) -> None:
|
||||||
main()
|
main()
|
||||||
|
|
||||||
options = intercepted_build_args.args[0]
|
options = intercepted_build_args.args[0]
|
||||||
@@ -37,7 +40,9 @@ def test_no_override(intercepted_build_args):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("platform")
|
@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")
|
monkeypatch.setenv("CIBW_PROJECT_REQUIRES_PYTHON", ">=3.8")
|
||||||
|
|
||||||
main()
|
main()
|
||||||
@@ -52,7 +57,9 @@ def test_override_env(monkeypatch, intercepted_build_args):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("platform")
|
@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(
|
fake_package_dir.joinpath("setup.cfg").write_text(
|
||||||
textwrap.dedent(
|
textwrap.dedent(
|
||||||
"""
|
"""
|
||||||
@@ -74,7 +81,9 @@ def test_override_setup_cfg(intercepted_build_args, fake_package_dir):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("platform")
|
@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(
|
fake_package_dir.joinpath("pyproject.toml").write_text(
|
||||||
textwrap.dedent(
|
textwrap.dedent(
|
||||||
"""
|
"""
|
||||||
@@ -96,7 +105,9 @@ def test_override_pyproject_toml(intercepted_build_args, fake_package_dir):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("platform")
|
@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(
|
fake_package_dir.joinpath("setup.py").write_text(
|
||||||
textwrap.dedent(
|
textwrap.dedent(
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import contextlib
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
@@ -6,6 +7,7 @@ import subprocess
|
|||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
import time
|
import time
|
||||||
|
from collections.abc import Iterator
|
||||||
from contextlib import nullcontext
|
from contextlib import nullcontext
|
||||||
from pathlib import Path, PurePath, PurePosixPath
|
from pathlib import Path, PurePath, PurePosixPath
|
||||||
|
|
||||||
@@ -34,7 +36,7 @@ PODMAN = OCIContainerEngineConfig(name="podman")
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture(params=["docker", "podman"], scope="module")
|
@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"):
|
if request.param == "docker" and not request.config.getoption("--run-docker"):
|
||||||
pytest.skip("need --run-docker option to run")
|
pytest.skip("need --run-docker option to run")
|
||||||
if request.param == "podman" and not request.config.getoption("--run-podman"):
|
if request.param == "podman" and not request.config.getoption("--run-podman"):
|
||||||
@@ -63,21 +65,21 @@ def container_engine(request):
|
|||||||
# Tests
|
# Tests
|
||||||
|
|
||||||
|
|
||||||
def test_simple(container_engine):
|
def test_simple(container_engine: OCIContainerEngineConfig) -> None:
|
||||||
with OCIContainer(
|
with OCIContainer(
|
||||||
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=DEFAULT_OCI_PLATFORM
|
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=DEFAULT_OCI_PLATFORM
|
||||||
) as container:
|
) as container:
|
||||||
assert container.call(["echo", "hello"], capture_output=True) == "hello\n"
|
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(
|
with OCIContainer(
|
||||||
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=DEFAULT_OCI_PLATFORM
|
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=DEFAULT_OCI_PLATFORM
|
||||||
) as container:
|
) as container:
|
||||||
assert container.call(["printf", "hello"], capture_output=True) == "hello"
|
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(
|
container = OCIContainer(
|
||||||
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=DEFAULT_OCI_PLATFORM
|
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=DEFAULT_OCI_PLATFORM
|
||||||
)
|
)
|
||||||
@@ -86,7 +88,7 @@ def test_debug_info(container_engine):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def test_environment(container_engine):
|
def test_environment(container_engine: OCIContainerEngineConfig) -> None:
|
||||||
with OCIContainer(
|
with OCIContainer(
|
||||||
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=DEFAULT_OCI_PLATFORM
|
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=DEFAULT_OCI_PLATFORM
|
||||||
) as container:
|
) 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("CIBUILDWHEEL", "1")
|
||||||
monkeypatch.setenv("SOURCE_DATE_EPOCH", "1489957071")
|
monkeypatch.setenv("SOURCE_DATE_EPOCH", "1489957071")
|
||||||
with OCIContainer(
|
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(
|
with OCIContainer(
|
||||||
engine=container_engine,
|
engine=container_engine,
|
||||||
image=DEFAULT_IMAGE,
|
image=DEFAULT_IMAGE,
|
||||||
@@ -122,7 +126,7 @@ def test_cwd(container_engine):
|
|||||||
assert container.call(["pwd"], capture_output=True, cwd="/opt") == "/opt\n"
|
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
|
# test is flaky on some platforms, implement retry for 5 second
|
||||||
timeout = 50 # * 100 ms = 5s
|
timeout = 50 # * 100 ms = 5s
|
||||||
with OCIContainer(
|
with OCIContainer(
|
||||||
@@ -157,7 +161,7 @@ def test_container_removed(container_engine):
|
|||||||
assert container_name not in docker_containers_listing
|
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
|
# max environment variable size is 128kB
|
||||||
long_env_var_length = 127 * 1024
|
long_env_var_length = 127 * 1024
|
||||||
large_environment = {
|
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(
|
with OCIContainer(
|
||||||
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=DEFAULT_OCI_PLATFORM
|
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=DEFAULT_OCI_PLATFORM
|
||||||
) as container:
|
) 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)
|
engine_config = OCIContainerEngineConfig.from_config_string(config)
|
||||||
assert engine_config.name == name
|
assert engine_config.name == name
|
||||||
assert engine_config.create_args == create_args
|
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")
|
@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(
|
with OCIContainer(
|
||||||
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=OCIPlatform.i386
|
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=OCIPlatform.i386
|
||||||
) as container:
|
) as container:
|
||||||
@@ -567,7 +573,7 @@ def test_local_image(
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("platform", list(OCIPlatform))
|
@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 {
|
if detect_ci_provider() == CIProvider.travis_ci and DEFAULT_OCI_PLATFORM not in {
|
||||||
OCIPlatform.AMD64,
|
OCIPlatform.AMD64,
|
||||||
platform,
|
platform,
|
||||||
@@ -657,8 +663,13 @@ def test_multiarch_image(container_engine, platform):
|
|||||||
("podman", '{"Client":{"Version":"2.1.0~rc1"}}', pytest.raises(OCIEngineTooOldError)),
|
("podman", '{"Client":{"Version":"2.1.0~rc1"}}', pytest.raises(OCIEngineTooOldError)),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_engine_version(engine_name, version, context, monkeypatch):
|
def test_engine_version(
|
||||||
def mockcall(*args, **kwargs):
|
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:
|
if version is None:
|
||||||
raise subprocess.CalledProcessError(1, " ".join(str(arg) for arg in args))
|
raise subprocess.CalledProcessError(1, " ".join(str(arg) for arg in args))
|
||||||
return version
|
return version
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import subprocess
|
|||||||
import sys
|
import sys
|
||||||
import typing
|
import typing
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from pathlib import PurePosixPath
|
from pathlib import Path, PurePosixPath
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@@ -18,19 +18,19 @@ ALL_IDS = DEFAULT_IDS | {"cp313t", "pp38", "pp39", "pp310", "pp311", "gp311_242"
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mock_build_container(monkeypatch):
|
def mock_build_container(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
def fail_on_call(*args, **kwargs):
|
def fail_on_call(*args: object, **kwargs: object) -> None:
|
||||||
msg = "This should never be called"
|
msg = "This should never be called"
|
||||||
raise RuntimeError(msg)
|
raise RuntimeError(msg)
|
||||||
|
|
||||||
def ignore_call(*args, **kwargs):
|
def ignore_call(*args: object, **kwargs: object) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def nullcontext(enter_result=None):
|
def nullcontext(enter_result: object = None) -> typing.Generator[object, None, None]:
|
||||||
yield enter_result
|
yield enter_result
|
||||||
|
|
||||||
def ignore_context_call(*args, **kwargs):
|
def ignore_context_call(*args: object, **kwargs: object) -> typing.ContextManager[object]:
|
||||||
return nullcontext(kwargs)
|
return nullcontext(kwargs)
|
||||||
|
|
||||||
monkeypatch.setenv("CIBW_PLATFORM", "linux")
|
monkeypatch.setenv("CIBW_PLATFORM", "linux")
|
||||||
@@ -49,7 +49,7 @@ def mock_build_container(monkeypatch):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("mock_build_container", "fake_package_dir")
|
@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.setattr(sys, "argv", [*sys.argv, "--platform=linux"])
|
||||||
monkeypatch.setenv("CIBW_ARCHS", "auto64 auto32")
|
monkeypatch.setenv("CIBW_ARCHS", "auto64 auto32")
|
||||||
monkeypatch.delenv("CIBW_ENABLE", raising=False)
|
monkeypatch.delenv("CIBW_ENABLE", raising=False)
|
||||||
@@ -95,7 +95,7 @@ def test_build_default_launches(monkeypatch):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("mock_build_container")
|
@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 = tmp_path / "cibw_package"
|
||||||
pkg_dir.mkdir()
|
pkg_dir.mkdir()
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
with tmp_path.joinpath("pyproject.toml").open("w") as f:
|
||||||
f.write(PYPROJECT_1)
|
f.write(PYPROJECT_1)
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ def test_options_1(tmp_path, monkeypatch):
|
|||||||
assert local.pyodide_version == "0.28.0"
|
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:
|
with tmp_path.joinpath("pyproject.toml").open("w") as f:
|
||||||
f.write(PYPROJECT_1)
|
f.write(PYPROJECT_1)
|
||||||
|
|
||||||
@@ -126,7 +126,9 @@ def test_passthrough(tmp_path, monkeypatch):
|
|||||||
"a trailing backslash \\",
|
"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 = CommandLineArguments.defaults()
|
||||||
args.package_dir = tmp_path
|
args.package_dir = tmp_path
|
||||||
|
|
||||||
@@ -157,7 +159,7 @@ xfail_env_parse = pytest.mark.xfail(
|
|||||||
pytest.param("a trailing backslash \\", marks=[xfail_env_parse]),
|
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 = CommandLineArguments.defaults()
|
||||||
args.package_dir = tmp_path
|
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
|
assert parsed_container_engine.disable_host_mount == result_disable_host_mount
|
||||||
|
|
||||||
|
|
||||||
def test_environment_pass_references():
|
def test_environment_pass_references() -> None:
|
||||||
options = Options(
|
options = Options(
|
||||||
platform="linux",
|
platform="linux",
|
||||||
command_line_arguments=CommandLineArguments.defaults(),
|
command_line_arguments=CommandLineArguments.defaults(),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import shlex
|
import shlex
|
||||||
from typing import TYPE_CHECKING
|
from pathlib import Path
|
||||||
|
from typing import Any, cast
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -12,9 +13,7 @@ from cibuildwheel.options import (
|
|||||||
ShlexTableFormat,
|
ShlexTableFormat,
|
||||||
_resolve_cascade,
|
_resolve_cascade,
|
||||||
)
|
)
|
||||||
|
from cibuildwheel.typing import PlatformName
|
||||||
if TYPE_CHECKING:
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
PYPROJECT_1 = """
|
PYPROJECT_1 = """
|
||||||
[tool.cibuildwheel]
|
[tool.cibuildwheel]
|
||||||
@@ -39,12 +38,12 @@ test-requires = ["other", "many"]
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture(params=["linux", "macos", "windows"])
|
@pytest.fixture(params=["linux", "macos", "windows"])
|
||||||
def platform(request):
|
def platform(request: pytest.FixtureRequest) -> PlatformName:
|
||||||
return request.param
|
return cast("PlatformName", request.param)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("fname", ["pyproject.toml", "cibuildwheel.toml"])
|
@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: Path = tmp_path / fname
|
||||||
config_file_path.write_text(PYPROJECT_1)
|
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())
|
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: Path = tmp_path / "pyproject.toml"
|
||||||
config_file_path.write_text(PYPROJECT_1)
|
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"
|
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 = tmp_path / "pyproject.toml"
|
||||||
pyproject_toml.write_text(
|
pyproject_toml.write_text(
|
||||||
"""
|
"""
|
||||||
@@ -140,14 +139,14 @@ repair-wheel-command = "repair-project-global"
|
|||||||
assert options_reader.get("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(
|
options_reader = OptionsReader(
|
||||||
platform=platform, env={"CIBW_REPAIR_WHEEL_COMMAND": "repair-env-global"}
|
platform=platform, env={"CIBW_REPAIR_WHEEL_COMMAND": "repair-env-global"}
|
||||||
)
|
)
|
||||||
assert options_reader.get("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 = tmp_path / "pyproject.toml"
|
||||||
pyproject_toml.write_text(
|
pyproject_toml.write_text(
|
||||||
"""
|
"""
|
||||||
@@ -161,7 +160,7 @@ repair-wheel-command = "repair-project-macos"
|
|||||||
)
|
)
|
||||||
options_reader = OptionsReader(
|
options_reader = OptionsReader(
|
||||||
pyproject_toml,
|
pyproject_toml,
|
||||||
platform=platform,
|
platform=cast("Any", platform),
|
||||||
env={
|
env={
|
||||||
"CIBW_REPAIR_WHEEL_COMMAND": "repair-env-global",
|
"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"
|
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 = tmp_path / "pyproject.toml"
|
||||||
pyproject_toml.write_text(
|
pyproject_toml.write_text(
|
||||||
"""
|
"""
|
||||||
@@ -183,11 +182,11 @@ repair-wheel-command = "repair-project-macos"
|
|||||||
repair-wheel-command = "repair-project-global"
|
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}"
|
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
|
# Note that platform contents are only checked when running
|
||||||
# for that platform.
|
# for that platform.
|
||||||
pyproject_toml = tmp_path / "pyproject.toml"
|
pyproject_toml = tmp_path / "pyproject.toml"
|
||||||
@@ -204,7 +203,7 @@ repairs-wheel-command = "repair-project-linux"
|
|||||||
assert "repair-wheel-command" in str(excinfo.value)
|
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
|
# Note that platform contents are only checked when running
|
||||||
# for that platform.
|
# for that platform.
|
||||||
pyproject_toml = tmp_path / "pyproject.toml"
|
pyproject_toml = tmp_path / "pyproject.toml"
|
||||||
@@ -221,7 +220,7 @@ repair_wheel_command = "repair-project-linux"
|
|||||||
assert "repair-wheel-command" in str(excinfo.value)
|
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 = tmp_path / "pyproject.toml"
|
||||||
pyproject_toml.write_text(
|
pyproject_toml.write_text(
|
||||||
"""
|
"""
|
||||||
@@ -233,7 +232,7 @@ repair-wheel-command = "repair-project-linux"
|
|||||||
OptionsReader(pyproject_toml, platform="linux", env={})
|
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 = tmp_path / "pyproject.toml"
|
||||||
pyproject_toml.write_text(
|
pyproject_toml.write_text(
|
||||||
"""
|
"""
|
||||||
@@ -248,7 +247,7 @@ build = ["1", "2"]
|
|||||||
options_reader.get("build")
|
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 = tmp_path / "pyproject.toml"
|
||||||
pyproject_toml.write_text(
|
pyproject_toml.write_text(
|
||||||
"""
|
"""
|
||||||
@@ -262,7 +261,7 @@ manylinux-x86_64-image = "manylinux1"
|
|||||||
OptionsReader(pyproject_toml, platform="windows", disallow=disallow, env={})
|
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 = tmp_path / "pyproject.toml"
|
||||||
pyproject_toml.write_text(
|
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"])
|
@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(
|
answer = _resolve_cascade(
|
||||||
("not", InheritRule.NONE),
|
("not", InheritRule.NONE),
|
||||||
(None, 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("ignore_empty", [True, False], ids=["ignore_empty", "no_ignore_empty"])
|
||||||
@pytest.mark.parametrize("rule", [InheritRule.PREPEND, InheritRule.NONE, InheritRule.APPEND])
|
@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(
|
answer = _resolve_cascade(
|
||||||
(["a1", "a2"], InheritRule.NONE),
|
(["a1", "a2"], InheritRule.NONE),
|
||||||
([], 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])
|
@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(
|
answer = _resolve_cascade(
|
||||||
({"value": "a1", "base": "b1"}, InheritRule.NONE),
|
({"value": "a1", "base": "b1"}, InheritRule.NONE),
|
||||||
(None, InheritRule.NONE),
|
(None, InheritRule.NONE),
|
||||||
@@ -365,7 +364,7 @@ def test_resolve_cascade_merge_dict(rule):
|
|||||||
assert answer == "value=override base=b1"
|
assert answer == "value=override base=b1"
|
||||||
|
|
||||||
|
|
||||||
def test_resolve_cascade_merge_strings():
|
def test_resolve_cascade_merge_strings() -> None:
|
||||||
answer = _resolve_cascade(
|
answer = _resolve_cascade(
|
||||||
("value=a1 base=b1", InheritRule.NONE),
|
("value=a1 base=b1", InheritRule.NONE),
|
||||||
("value=override", InheritRule.APPEND),
|
("value=override", InheritRule.APPEND),
|
||||||
@@ -374,7 +373,7 @@ def test_resolve_cascade_merge_strings():
|
|||||||
assert answer == "value=override base=b1"
|
assert answer == "value=override base=b1"
|
||||||
|
|
||||||
|
|
||||||
def test_resolve_cascade_merge_different_types():
|
def test_resolve_cascade_merge_different_types() -> None:
|
||||||
answer = _resolve_cascade(
|
answer = _resolve_cascade(
|
||||||
("value=a1 base=b1", InheritRule.NONE),
|
("value=a1 base=b1", InheritRule.NONE),
|
||||||
({"value": "override"}, InheritRule.APPEND),
|
({"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: Path = tmp_path / "pyproject.toml"
|
||||||
pyproject_toml.write_text(PYPROJECT_2)
|
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"
|
assert options_reader.get("test-command", option_format=ListFormat(" && ")) == "pyproject"
|
||||||
|
|
||||||
with options_reader.identifier("random"):
|
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: Path = tmp_path / "pyproject.toml"
|
||||||
|
|
||||||
pyproject_toml.write_text(
|
pyproject_toml.write_text(
|
||||||
@@ -465,10 +466,10 @@ test-command = "pyproject-override"
|
|||||||
)
|
)
|
||||||
|
|
||||||
with pytest.raises(OptionsReaderError):
|
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: Path = tmp_path / "pyproject.toml"
|
||||||
pyproject_toml.write_text(
|
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: Path = tmp_path / "pyproject.toml"
|
||||||
pyproject_toml.write_text(
|
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: Path = tmp_path / "pyproject.toml"
|
||||||
pyproject_toml.write_text(
|
pyproject_toml.write_text(
|
||||||
"""\
|
"""\
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import tomllib
|
import tomllib
|
||||||
|
from pathlib import Path
|
||||||
from textwrap import dedent
|
from textwrap import dedent
|
||||||
|
|
||||||
import pytest
|
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:
|
with open(tmp_path / "setup.py", "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
dedent(
|
dedent(
|
||||||
@@ -31,7 +32,7 @@ def test_read_setup_py_simple(tmp_path):
|
|||||||
assert get_requires_python_str(tmp_path, {}) == "1.23"
|
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:
|
with open(tmp_path / "setup.py", "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
dedent(
|
dedent(
|
||||||
@@ -53,7 +54,7 @@ def test_read_setup_py_if_main(tmp_path):
|
|||||||
assert get_requires_python_str(tmp_path, {}) == "1.23"
|
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:
|
with open(tmp_path / "setup.py", "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
dedent(
|
dedent(
|
||||||
@@ -75,7 +76,7 @@ def test_read_setup_py_if_main_reversed(tmp_path):
|
|||||||
assert get_requires_python_str(tmp_path, {}) == "1.23"
|
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:
|
with open(tmp_path / "setup.py", "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
dedent(
|
dedent(
|
||||||
@@ -97,7 +98,7 @@ def test_read_setup_py_if_invalid(tmp_path):
|
|||||||
assert not get_requires_python_str(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:
|
with open(tmp_path / "setup.py", "w", encoding="utf8") as f:
|
||||||
f.write(
|
f.write(
|
||||||
dedent(
|
dedent(
|
||||||
@@ -123,7 +124,7 @@ def test_read_setup_py_full(tmp_path):
|
|||||||
assert get_requires_python_str(tmp_path, {}) == "1.24"
|
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:
|
with open(tmp_path / "setup.py", "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
dedent(
|
dedent(
|
||||||
@@ -146,7 +147,7 @@ def test_read_setup_py_assign(tmp_path):
|
|||||||
assert get_requires_python_str(tmp_path, {}) is None
|
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:
|
with open(tmp_path / "setup.py", "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
dedent(
|
dedent(
|
||||||
@@ -169,7 +170,7 @@ def test_read_setup_py_None(tmp_path):
|
|||||||
assert get_requires_python_str(tmp_path, {}) is None
|
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:
|
with open(tmp_path / "setup.py", "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
dedent(
|
dedent(
|
||||||
@@ -191,7 +192,7 @@ def test_read_setup_py_empty(tmp_path):
|
|||||||
assert get_requires_python_str(tmp_path, {}) is None
|
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:
|
with open(tmp_path / "setup.cfg", "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
dedent(
|
dedent(
|
||||||
@@ -207,7 +208,7 @@ def test_read_setup_cfg(tmp_path):
|
|||||||
assert get_requires_python_str(tmp_path, {}) == "1.234"
|
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:
|
with open(tmp_path / "setup.cfg", "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
dedent(
|
dedent(
|
||||||
@@ -223,7 +224,7 @@ def test_read_setup_cfg_empty(tmp_path):
|
|||||||
assert get_requires_python_str(tmp_path, {}) is None
|
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:
|
with open(tmp_path / "pyproject.toml", "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
dedent(
|
dedent(
|
||||||
@@ -242,7 +243,7 @@ def test_read_pyproject_toml(tmp_path):
|
|||||||
assert get_requires_python_str(tmp_path, pyproject_toml) == "1.654"
|
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:
|
with open(tmp_path / "pyproject.toml", "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
dedent(
|
dedent(
|
||||||
@@ -258,7 +259,7 @@ def test_read_pyproject_toml_empty(tmp_path):
|
|||||||
assert get_requires_python_str(tmp_path, pyproject_toml) is None
|
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"]}}
|
pyproject_toml = {"dependency-groups": {"group1": ["pkg1", "pkg2"], "group2": ["pkg3"]}}
|
||||||
assert resolve_dependency_groups(pyproject_toml) == ()
|
assert resolve_dependency_groups(pyproject_toml) == ()
|
||||||
assert resolve_dependency_groups(pyproject_toml, "group1") == ("pkg1", "pkg2")
|
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")
|
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"):
|
with pytest.raises(FileNotFoundError, match=r"pyproject\.toml"):
|
||||||
resolve_dependency_groups(None, "test")
|
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"):
|
with pytest.raises(KeyError, match=r"pyproject\.toml"):
|
||||||
resolve_dependency_groups({}, "test")
|
resolve_dependency_groups({}, "test")
|
||||||
|
|||||||
+18
-12
@@ -1,5 +1,5 @@
|
|||||||
import textwrap
|
import textwrap
|
||||||
from pathlib import PurePath
|
from pathlib import Path, PurePath
|
||||||
from unittest.mock import Mock, call
|
from unittest.mock import Mock, call
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@@ -18,7 +18,7 @@ from cibuildwheel.util.helpers import (
|
|||||||
from cibuildwheel.util.packaging import find_compatible_wheel
|
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("{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}"
|
||||||
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"
|
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 {project}", project="project") == "python -m project"
|
||||||
assert prepare_command("python -m {something}", project="project") == "python -m {something}"
|
assert prepare_command("python -m {something}", project="project") == "python -m {something}"
|
||||||
assert (
|
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
|
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(
|
input = textwrap.dedent(
|
||||||
"""
|
"""
|
||||||
This line is normal
|
This line is normal
|
||||||
@@ -131,7 +131,7 @@ def test_fix_ansi_codes_for_github_actions():
|
|||||||
assert output == expected
|
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("bar", positional_arg_names=["foo"]) == {"foo": ["bar"]}
|
||||||
assert parse_key_value_string("foo:bar", kw_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"):
|
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")
|
||||||
assert FlexibleVersion("2.0") < FlexibleVersion("2.1")
|
assert FlexibleVersion("2.0") < FlexibleVersion("2.1")
|
||||||
assert FlexibleVersion("2.1") > FlexibleVersion("2")
|
assert FlexibleVersion("2.1") > FlexibleVersion("2")
|
||||||
@@ -227,7 +227,7 @@ def test_flexible_version_comparisons():
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def sample_project(tmp_path):
|
def sample_project(tmp_path: Path) -> Path:
|
||||||
"""Create a directory structure that contains a range of files."""
|
"""Create a directory structure that contains a range of files."""
|
||||||
project_path = tmp_path / "project"
|
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."""
|
"""Test sources can be copied into the test directory."""
|
||||||
target = tmp_path / "somewhere/test_cwd"
|
target = tmp_path / "somewhere/test_cwd"
|
||||||
copy_test_sources(test_sources, sample_project, target)
|
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()
|
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."""
|
"""If test_sources references a folder that doesn't exist, an error is raised."""
|
||||||
|
|
||||||
with pytest.raises(
|
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."""
|
"""If an alternate copy_into method is provided, it is used."""
|
||||||
|
|
||||||
target = PurePath("/container/test_cwd")
|
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 (
|
assert (
|
||||||
unwrap("""
|
unwrap("""
|
||||||
This is a
|
This is a
|
||||||
@@ -378,7 +384,7 @@ def test_unwrap():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_unwrap_preserving_paragraphs():
|
def test_unwrap_preserving_paragraphs() -> None:
|
||||||
assert (
|
assert (
|
||||||
unwrap("""
|
unwrap("""
|
||||||
This is a
|
This is a
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ OPTIONS_DEFAULTS = Options("linux", CommandLineArguments.defaults(), {}, default
|
|||||||
FILE = Path(__file__)
|
FILE = Path(__file__)
|
||||||
|
|
||||||
|
|
||||||
def test_printout_wheels(capsys):
|
def test_printout_wheels(capsys: pytest.CaptureFixture[str]) -> None:
|
||||||
log = Logger()
|
log = Logger()
|
||||||
log.fold_mode = "disabled"
|
log.fold_mode = "disabled"
|
||||||
log.colors_enabled = False
|
log.colors_enabled = False
|
||||||
@@ -32,7 +32,7 @@ def test_printout_wheels(capsys):
|
|||||||
assert "SHA256=" in captured.out
|
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()
|
log = Logger()
|
||||||
with pytest.raises(RuntimeError), log.print_summary(options=OPTIONS_DEFAULTS):
|
with pytest.raises(RuntimeError), log.print_summary(options=OPTIONS_DEFAULTS):
|
||||||
raise RuntimeError()
|
raise RuntimeError()
|
||||||
|
|||||||
Reference in New Issue
Block a user