From 1512427455dd17ade2b412b797b80ecd47f12b27 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 18 Apr 2023 12:00:35 -0400 Subject: [PATCH 1/4] chore: touch up Ruff, add exe check Signed-off-by: Henry Schreiner --- bin/projects.py | 0 bin/update_how_it_works_image.py | 0 pyproject.toml | 38 +++++++++++++++++--------------- 3 files changed, 20 insertions(+), 18 deletions(-) mode change 100644 => 100755 bin/projects.py mode change 100644 => 100755 bin/update_how_it_works_image.py diff --git a/bin/projects.py b/bin/projects.py old mode 100644 new mode 100755 diff --git a/bin/update_how_it_works_image.py b/bin/update_how_it_works_image.py old mode 100644 new mode 100755 diff --git a/pyproject.toml b/pyproject.toml index d4224d4fd..0234b137f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -120,26 +120,28 @@ messages_control.disable = [ [tool.ruff] select = [ - "E", "F", "W", # flake8 - "B", "B904", # flake8-bugbear - "I", # isort - "ARG", # flake8-unused-arguments - "C4", # flake8-comprehensions - "EM", # flake8-errmsg - "ICN", # flake8-import-conventions - "ISC", # flake8-implicit-str-concat - "PGH", # pygrep-hooks - "PIE", # flake8-pie - "PLC", "PLE", "PLW", # pylint - "PT", # flake8-pytest-style - "RET", # flake8-return - "RUF", # Ruff-specific - "SIM", # flake8-simplify - "UP", # pyupgrade - "YTT", # flake8-2020 + "E", "F", "W", # flake8 + "B", # flake8-bugbear + "I", # isort + "ARG", # flake8-unused-arguments + "C4", # flake8-comprehensions + "EM", # flake8-errmsg + "ICN", # flake8-import-conventions + "ISC", # flake8-implicit-str-concat + "PGH", # pygrep-hooks + "PIE", # flake8-pie + "PL", # pylint + "PT", # flake8-pytest-style + "RET", # flake8-return + "RUF", # Ruff-specific + "SIM", # flake8-simplify + "UP", # pyupgrade + "YTT", # flake8-2020 + "EXE", # flake8-executable ] extend-ignore = [ - "PLR2004", "E501", + "PLR", # Design related pylint codes + "E501", # Line too long "RET504", "RET505", "RET508", # else after control flow "PT004", # Rename suggested for returnless fixtures "PT007", # False positive (fixed upstream) From ec9919a088c47cd7b219592636be06a7cbb37d3b Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 18 Apr 2023 12:01:08 -0400 Subject: [PATCH 2/4] chore: add Ruff logging format check Signed-off-by: Henry Schreiner --- bin/update_pythons.py | 6 +++--- bin/update_virtualenv.py | 6 +++--- pyproject.toml | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/bin/update_pythons.py b/bin/update_pythons.py index 930b13dfb..bfa10ba75 100755 --- a/bin/update_pythons.py +++ b/bin/update_pythons.py @@ -93,7 +93,7 @@ def update_version_windows(self, spec: Specifier) -> ConfigWinCP | None: unsorted_versions = spec.filter(self.version_dict) versions = sorted(unsorted_versions, reverse=True) - log.debug(f"Windows {self.arch} {spec} has {', '.join(str(v) for v in versions)}") + log.debug("Windows %s %s has %s", self.arch, spec, ", ".join(str(v) for v in versions)) if not versions: return None @@ -254,7 +254,7 @@ def update_config(self, config: dict[str, str]) -> None: identifier = config["identifier"] version = Version(config["version"]) spec = Specifier(f"=={version.major}.{version.minor}.*") - log.info(f"Reading in '{identifier}' -> {spec} @ {version}") + log.info("Reading in %r -> %s @ %s", str(identifier), spec, version) orig_config = copy.copy(config) config_update: AnyConfig | None = None @@ -282,7 +282,7 @@ def update_config(self, config: dict[str, str]) -> None: config.update(**config_update) if config != orig_config: - log.info(f" Updated {orig_config} to {config}") + log.info(" Updated %s to %s", orig_config, config) @click.command() diff --git a/bin/update_virtualenv.py b/bin/update_virtualenv.py index ef1fec806..d7c7dc8ae 100755 --- a/bin/update_virtualenv.py +++ b/bin/update_virtualenv.py @@ -54,14 +54,14 @@ def git_ls_remote_versions(url) -> list[VersionTuple]: try: version = Version(version_string) if version.is_devrelease: - log.info(f"Ignoring development release '{version}'") + log.info("Ignoring development release %r", str(version)) continue if version.is_prerelease: - log.info(f"Ignoring pre-release '{version}'") + log.info("Ignoring pre-release %r", str(version)) continue versions.append(VersionTuple(version, version_string)) except InvalidVersion: - log.warning(f"Ignoring ref '{ref}'") + log.warning("Ignoring ref %r", ref) versions.sort(reverse=True) return versions diff --git a/pyproject.toml b/pyproject.toml index 0234b137f..c71a1ae4a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -128,6 +128,7 @@ select = [ "EM", # flake8-errmsg "ICN", # flake8-import-conventions "ISC", # flake8-implicit-str-concat + "G", # flake8-logging-format "PGH", # pygrep-hooks "PIE", # flake8-pie "PL", # pylint From 6d038dfbdfca459e39ad4642bde682b23435b0e8 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 18 Apr 2023 12:38:21 -0400 Subject: [PATCH 3/4] chore: update typing to collections.abc Signed-off-by: Henry Schreiner --- bin/inspect_all_known_projects.py | 2 +- cibuildwheel/architecture.py | 3 ++- cibuildwheel/bashlex_eval.py | 3 ++- cibuildwheel/environment.py | 3 ++- cibuildwheel/functools_cached_property_38.py | 8 +++++--- cibuildwheel/linux.py | 4 ++-- cibuildwheel/macos.py | 7 ++++--- cibuildwheel/oci_container.py | 6 ++++-- cibuildwheel/options.py | 8 +++++--- cibuildwheel/util.py | 20 ++++++-------------- cibuildwheel/windows.py | 3 +-- pyproject.toml | 7 +++++++ unit_test/option_prepare_test.py | 6 +++--- 13 files changed, 44 insertions(+), 36 deletions(-) diff --git a/bin/inspect_all_known_projects.py b/bin/inspect_all_known_projects.py index 3f91b2b56..684b7ff11 100755 --- a/bin/inspect_all_known_projects.py +++ b/bin/inspect_all_known_projects.py @@ -15,8 +15,8 @@ from __future__ import annotations import ast +from collections.abc import Iterator from pathlib import Path -from typing import Iterator import click import yaml diff --git a/cibuildwheel/architecture.py b/cibuildwheel/architecture.py index e1c8482ac..8c4b22939 100644 --- a/cibuildwheel/architecture.py +++ b/cibuildwheel/architecture.py @@ -4,6 +4,7 @@ import platform as platform_module import re import sys +from collections.abc import Set from enum import Enum from .typing import Final, Literal, PlatformName, assert_never @@ -132,7 +133,7 @@ def bitness_archs(platform: PlatformName, bitness: Literal["64", "32"]) -> set[A def allowed_architectures_check( platform: PlatformName, - architectures: set[Architecture], + architectures: Set[Architecture], ) -> None: allowed_architectures = Architecture.all_archs(platform) diff --git a/cibuildwheel/bashlex_eval.py b/cibuildwheel/bashlex_eval.py index 01093a623..3a167890a 100644 --- a/cibuildwheel/bashlex_eval.py +++ b/cibuildwheel/bashlex_eval.py @@ -1,8 +1,9 @@ from __future__ import annotations import subprocess +from collections.abc import Sequence from dataclasses import dataclass -from typing import Callable, Dict, List, Sequence +from typing import Callable, Dict, List # noqa: TID251 import bashlex diff --git a/cibuildwheel/environment.py b/cibuildwheel/environment.py index 74bfd78a5..625529e95 100644 --- a/cibuildwheel/environment.py +++ b/cibuildwheel/environment.py @@ -1,7 +1,8 @@ from __future__ import annotations import dataclasses -from typing import Any, Mapping, Sequence +from collections.abc import Mapping, Sequence +from typing import Any import bashlex import bashlex.errors diff --git a/cibuildwheel/functools_cached_property_38.py b/cibuildwheel/functools_cached_property_38.py index 879cdb620..134564b5c 100644 --- a/cibuildwheel/functools_cached_property_38.py +++ b/cibuildwheel/functools_cached_property_38.py @@ -1,7 +1,9 @@ from __future__ import annotations +import typing +from collections.abc import Callable from threading import RLock -from typing import Any, Callable, Generic, TypeVar, overload +from typing import Any, Generic, TypeVar __all__ = ["cached_property"] @@ -24,11 +26,11 @@ def __set_name__(self, owner: type[Any], name: str) -> None: msg = f"Cannot assign the same cached_property to two different names ({self.attrname!r} and {name!r})." raise TypeError(msg) - @overload + @typing.overload def __get__(self, instance: None, owner: type[Any] | None = ...) -> cached_property[_T]: ... - @overload + @typing.overload def __get__(self, instance: object, owner: type[Any] | None = ...) -> _T: ... diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index eb878d8d7..37ef5c8f0 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -3,10 +3,10 @@ import subprocess import sys import textwrap -from collections.abc import Set +from collections.abc import Iterator, Set from dataclasses import dataclass from pathlib import Path, PurePath, PurePosixPath -from typing import Iterator, Tuple +from typing import Tuple from .architecture import Architecture from .logger import log diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py index 24d22e46a..75614449b 100644 --- a/cibuildwheel/macos.py +++ b/cibuildwheel/macos.py @@ -8,10 +8,11 @@ import shutil import subprocess import sys -from collections.abc import Set +import typing +from collections.abc import Sequence, Set from dataclasses import dataclass from pathlib import Path -from typing import Sequence, Tuple, cast +from typing import Tuple from filelock import FileLock @@ -55,7 +56,7 @@ def get_macos_version() -> tuple[int, int]: """ version_str, _, _ = platform.mac_ver() version = tuple(map(int, version_str.split(".")[:2])) - return cast(Tuple[int, int], version) + return typing.cast(Tuple[int, int], version) def get_macos_sdks() -> list[str]: diff --git a/cibuildwheel/oci_container.py b/cibuildwheel/oci_container.py index df6af6c97..8da216a2e 100644 --- a/cibuildwheel/oci_container.py +++ b/cibuildwheel/oci_container.py @@ -8,10 +8,12 @@ import shutil import subprocess import sys +import typing import uuid +from collections.abc import Sequence from pathlib import Path, PurePath, PurePosixPath from types import TracebackType -from typing import IO, Dict, Sequence, cast +from typing import IO, Dict from cibuildwheel.util import CIProvider, detect_ci_provider @@ -329,7 +331,7 @@ def get_environment(self) -> dict[str, str]: capture_output=True, ) ) - return cast(Dict[str, str], env) + return typing.cast(Dict[str, str], env) def environment_executor(self, command: list[str], environment: dict[str, str]) -> str: # used as an EnvironmentExecutor to evaluate commands and capture output diff --git a/cibuildwheel/options.py b/cibuildwheel/options.py index 3469dce89..974470c63 100644 --- a/cibuildwheel/options.py +++ b/cibuildwheel/options.py @@ -10,8 +10,10 @@ import sys import textwrap import traceback +import typing +from collections.abc import Callable, Generator, Iterator, Mapping, Set from pathlib import Path -from typing import Any, Callable, Dict, Generator, Iterator, List, Mapping, Union, cast +from typing import Any, Dict, List, Union if sys.version_info >= (3, 11): import tomllib @@ -193,7 +195,7 @@ def __init__( *, platform: PlatformName, env: Mapping[str, str], - disallow: dict[str, set[str]] | None = None, + disallow: Mapping[str, Set[str]] | None = None, ) -> None: self.platform = platform self.env = env @@ -462,7 +464,7 @@ def globals(self) -> GlobalOptions: print(msg, file=sys.stderr) sys.exit(2) - container_engine = cast(ContainerEngine, container_engine_str) + container_engine = typing.cast(ContainerEngine, container_engine_str) return GlobalOptions( package_dir=package_dir, diff --git a/cibuildwheel/util.py b/cibuildwheel/util.py index 38622c707..53cb22a61 100644 --- a/cibuildwheel/util.py +++ b/cibuildwheel/util.py @@ -11,23 +11,15 @@ import sys import textwrap import time +import typing import urllib.request +from collections.abc import Generator, Iterable, Sequence from dataclasses import dataclass from enum import Enum from functools import lru_cache from pathlib import Path, PurePath from time import sleep -from typing import ( - Any, - ClassVar, - Generator, - Iterable, - Sequence, - TextIO, - TypeVar, - cast, - overload, -) +from typing import Any, ClassVar, TextIO, TypeVar import bracex import certifi @@ -107,7 +99,7 @@ def build_frontend_or_default( IS_WIN: Final[bool] = sys.platform.startswith("win") -@overload +@typing.overload def call( *args: PathOrStr, env: dict[str, str] | None = None, @@ -117,7 +109,7 @@ def call( ... -@overload +@typing.overload def call( *args: PathOrStr, env: dict[str, str] | None = None, @@ -149,7 +141,7 @@ def call( result = subprocess.run(args_, check=True, shell=IS_WIN, env=env, cwd=cwd, **kwargs) if not capture_stdout: return None - return cast(str, result.stdout) + return typing.cast(str, result.stdout) def shell(*commands: str, env: dict[str, str] | None = None, cwd: PathOrStr | None = None) -> None: diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py index 2c0df37ff..5ab8827a2 100644 --- a/cibuildwheel/windows.py +++ b/cibuildwheel/windows.py @@ -6,12 +6,11 @@ import subprocess import sys import textwrap -from collections.abc import Set +from collections.abc import Sequence, Set from contextlib import suppress from dataclasses import dataclass from functools import lru_cache from pathlib import Path -from typing import Sequence from zipfile import ZipFile from filelock import FileLock diff --git a/pyproject.toml b/pyproject.toml index c71a1ae4a..570772db4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -136,6 +136,7 @@ select = [ "RET", # flake8-return "RUF", # Ruff-specific "SIM", # flake8-simplify + "TID251", # flake8-tidy-imports.banned-api "UP", # pyupgrade "YTT", # flake8-2020 "EXE", # flake8-executable @@ -151,6 +152,12 @@ target-version = "py37" typing-modules = ["cibuildwheel.typing"] flake8-unused-arguments.ignore-variadic-names = true +[tool.ruff.flake8-tidy-imports.banned-api] +"typing.Mapping".msg = "Use collections.abc.Mapping instead." +"typing.Callable".msg = "Use collections.abc.Callable instead." +"typing.Iterator".msg = "Use collections.abc.Iterator instead." +"typing.Sequence".msg = "Use collections.abc.Sequence instead." +"typing.Set".msg = "Use collections.abc.Set instead." [tool.ruff.per-file-ignores] "unit_test/*" = ["PLC1901"] diff --git a/unit_test/option_prepare_test.py b/unit_test/option_prepare_test.py index 5cf585694..b5c361b27 100644 --- a/unit_test/option_prepare_test.py +++ b/unit_test/option_prepare_test.py @@ -3,9 +3,9 @@ import platform as platform_module import subprocess import sys +import typing from contextlib import contextmanager from pathlib import PurePosixPath -from typing import cast from unittest import mock import pytest @@ -52,7 +52,7 @@ def test_build_default_launches(monkeypatch): main() - build_in_container = cast(mock.Mock, linux.build_in_container) + build_in_container = typing.cast(mock.Mock, linux.build_in_container) assert build_in_container.call_count == 4 @@ -120,7 +120,7 @@ def test_build_with_override_launches(monkeypatch, tmp_path): main() - build_in_container = cast(mock.Mock, linux.build_in_container) + build_in_container = typing.cast(mock.Mock, linux.build_in_container) assert build_in_container.call_count == 6 From 8c5f89c035ba6ac81794ed5a5d6cd2110957f181 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 18 Apr 2023 13:06:17 -0400 Subject: [PATCH 4/4] chore: update typing to be generic on function args Signed-off-by: Henry Schreiner --- bin/inspect_all_known_projects.py | 4 ++-- bin/projects.py | 9 +++++---- bin/update_pythons.py | 5 +++-- cibuildwheel/__main__.py | 6 +++--- cibuildwheel/bashlex_eval.py | 12 +++++++----- cibuildwheel/environment.py | 4 ++-- cibuildwheel/extra.py | 5 ++++- cibuildwheel/linux.py | 8 ++++---- cibuildwheel/oci_container.py | 6 +++--- cibuildwheel/options.py | 8 ++++---- cibuildwheel/util.py | 14 ++++++++------ cibuildwheel/windows.py | 6 +++--- 12 files changed, 48 insertions(+), 39 deletions(-) diff --git a/bin/inspect_all_known_projects.py b/bin/inspect_all_known_projects.py index 684b7ff11..a2c68a6bd 100755 --- a/bin/inspect_all_known_projects.py +++ b/bin/inspect_all_known_projects.py @@ -15,7 +15,7 @@ from __future__ import annotations import ast -from collections.abc import Iterator +from collections.abc import Iterable, Iterator from pathlib import Path import click @@ -97,7 +97,7 @@ def save(self, filename: Path | str) -> None: with open(filename, "w") as f: yaml.safe_dump(self.contents, f, default_flow_style=False) - def on_each(self, repos: list[str]) -> Iterator[tuple[str, str, str | None]]: + def on_each(self, repos: Iterable[str]) -> Iterator[tuple[str, str, str | None]]: for repo in repos: print(f"[bold]{repo}:") for filename in sorted(self.contents, reverse=True): diff --git a/bin/projects.py b/bin/projects.py index 6b577189e..546a10c82 100755 --- a/bin/projects.py +++ b/bin/projects.py @@ -16,6 +16,7 @@ import textwrap import urllib.request import xml.dom.minidom +from collections.abc import Iterable, Mapping, Sequence from datetime import datetime from io import StringIO from pathlib import Path @@ -42,7 +43,7 @@ class Project: NAME: int = 0 - def __init__(self, config: dict[str, Any], github: Github | None = None): + def __init__(self, config: Mapping[str, Any], github: Github | None = None): try: self.name: str = config["name"] self.gh: str = config["gh"] @@ -149,7 +150,7 @@ def path_for_icon(icon_name: str, relative_to: Path | None = None) -> Path: def get_projects( - config: list[dict[str, Any]], + config: Iterable[Mapping[str, Any]], *, online: bool = True, auth: str | None = None, @@ -163,7 +164,7 @@ def get_projects( return sorted((Project(item, github) for item in config), reverse=online) -def render_projects(projects: list[Project], *, dest_path: Path, include_info: bool = True): +def render_projects(projects: Sequence[Project], *, dest_path: Path, include_info: bool = True): io = StringIO() print = functools.partial(builtins.print, file=io) @@ -191,7 +192,7 @@ def render_projects(projects: list[Project], *, dest_path: Path, include_info: b def insert_projects_table( file: Path, *, - projects: list[Project], + projects: Sequence[Project], input_filename: str, include_info: bool = True, ): diff --git a/bin/update_pythons.py b/bin/update_pythons.py index bfa10ba75..35f6a76ed 100755 --- a/bin/update_pythons.py +++ b/bin/update_pythons.py @@ -6,6 +6,7 @@ import difflib import logging import sys +from collections.abc import Mapping, MutableMapping from pathlib import Path from typing import Any, Union @@ -124,7 +125,7 @@ def __init__(self, arch_str: ArchStr): ] self.arch = arch_str - def get_arch_file(self, release: dict[str, Any]) -> str: + def get_arch_file(self, release: Mapping[str, Any]) -> str: urls: list[str] = [ rf["download_url"] for rf in release["files"] @@ -250,7 +251,7 @@ def __init__(self) -> None: self.macos_pypy = PyPyVersions("64") self.macos_pypy_arm64 = PyPyVersions("ARM64") - def update_config(self, config: dict[str, str]) -> None: + def update_config(self, config: MutableMapping[str, str]) -> None: identifier = config["identifier"] version = Version(config["version"]) spec = Specifier(f"=={version.major}.{version.minor}.*") diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index e29156963..9dfba1512 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -7,7 +7,7 @@ import tarfile import textwrap import typing -from collections.abc import Sequence, Set +from collections.abc import Iterable, Sequence, Set from pathlib import Path from tempfile import mkdtemp @@ -337,7 +337,7 @@ def build_in_directory(args: CommandLineArguments) -> None: log.warning(f"Can't delete temporary folder '{tmp_path}'") -def print_preamble(platform: str, options: Options, identifiers: list[str]) -> None: +def print_preamble(platform: str, options: Options, identifiers: Sequence[str]) -> None: print( textwrap.dedent( """ @@ -377,7 +377,7 @@ def get_build_identifiers( return [config.identifier for config in python_configurations] -def detect_warnings(*, options: Options, identifiers: list[str]) -> list[str]: +def detect_warnings(*, options: Options, identifiers: Iterable[str]) -> list[str]: warnings = [] # warn about deprecated {python} and {pip} diff --git a/cibuildwheel/bashlex_eval.py b/cibuildwheel/bashlex_eval.py index 3a167890a..c5f805372 100644 --- a/cibuildwheel/bashlex_eval.py +++ b/cibuildwheel/bashlex_eval.py @@ -1,7 +1,7 @@ from __future__ import annotations import subprocess -from collections.abc import Sequence +from collections.abc import Iterable, Mapping, Sequence from dataclasses import dataclass from typing import Callable, Dict, List # noqa: TID251 @@ -11,7 +11,7 @@ EnvironmentExecutor = Callable[[List[str], Dict[str, str]], str] -def local_environment_executor(command: list[str], env: dict[str, str]) -> str: +def local_environment_executor(command: Sequence[str], env: Mapping[str, str]) -> str: return subprocess.run(command, env=env, text=True, stdout=subprocess.PIPE, check=True).stdout @@ -23,7 +23,7 @@ class NodeExecutionContext: def evaluate( - value: str, environment: dict[str, str], executor: EnvironmentExecutor | None = None + value: str, environment: Mapping[str, str], executor: EnvironmentExecutor | None = None ) -> str: if not value: # empty string evaluates to empty string @@ -41,7 +41,9 @@ def evaluate( return evaluate_node( value_word_node, context=NodeExecutionContext( - environment=environment, input=value, executor=executor or local_environment_executor + environment=dict(environment), + input=value, + executor=executor or local_environment_executor, ), ) @@ -106,7 +108,7 @@ def evaluate_nodes_as_compound_command( def evaluate_nodes_as_simple_command( - nodes: list[bashlex.ast.node], context: NodeExecutionContext + nodes: Iterable[bashlex.ast.node], context: NodeExecutionContext ) -> str: command = [evaluate_node(part, context=context) for part in nodes] return context.executor(command, context.environment) diff --git a/cibuildwheel/environment.py b/cibuildwheel/environment.py index 625529e95..2a7b99a2a 100644 --- a/cibuildwheel/environment.py +++ b/cibuildwheel/environment.py @@ -55,7 +55,7 @@ class EnvironmentAssignment(Protocol): def evaluated_value( self, *, - environment: dict[str, str], + environment: Mapping[str, str], executor: bashlex_eval.EnvironmentExecutor | None = None, ) -> str: """Returns the value of this assignment, as evaluated in the environment""" @@ -92,7 +92,7 @@ def __init__(self, assignment: str): def evaluated_value( self, - environment: dict[str, str], + environment: Mapping[str, str], executor: bashlex_eval.EnvironmentExecutor | None = None, ) -> str: return bashlex_eval.evaluate(self.value, environment=environment, executor=executor) diff --git a/cibuildwheel/extra.py b/cibuildwheel/extra.py index 36389e6f7..03e3ce6f0 100644 --- a/cibuildwheel/extra.py +++ b/cibuildwheel/extra.py @@ -4,6 +4,7 @@ from __future__ import annotations +from collections.abc import Mapping, Sequence from io import StringIO from .typing import Protocol @@ -16,7 +17,9 @@ def __str__(self) -> str: ... -def dump_python_configurations(inp: dict[str, dict[str, list[dict[str, Printable]]]]) -> str: +def dump_python_configurations( + inp: Mapping[str, Mapping[str, Sequence[Mapping[str, Printable]]]] +) -> str: output = StringIO() for header, values in inp.items(): output.write(f"[{header}]\n") diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 37ef5c8f0..4f019ac34 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -3,7 +3,7 @@ import subprocess import sys import textwrap -from collections.abc import Iterator, Set +from collections.abc import Iterable, Iterator, Sequence, Set from dataclasses import dataclass from pathlib import Path, PurePath, PurePosixPath from typing import Tuple @@ -113,7 +113,7 @@ def get_build_steps( def check_all_python_exist( - *, platform_configs: list[PythonConfiguration], container: OCIContainer + *, platform_configs: Iterable[PythonConfiguration], container: OCIContainer ) -> None: exist = True messages = [] @@ -138,7 +138,7 @@ def check_all_python_exist( def build_in_container( *, options: Options, - platform_configs: list[PythonConfiguration], + platform_configs: Sequence[PythonConfiguration], container: OCIContainer, container_project_path: PurePath, container_package_dir: PurePath, @@ -438,7 +438,7 @@ def build(options: Options, tmp_path: Path) -> None: # noqa: ARG001 sys.exit(1) -def _matches_prepared_command(error_cmd: list[str], command_template: str) -> bool: +def _matches_prepared_command(error_cmd: Sequence[str], command_template: str) -> bool: if len(error_cmd) < 3 or error_cmd[0:2] != ["sh", "-c"]: return False command_prefix = command_template.split("{", maxsplit=1)[0].strip() diff --git a/cibuildwheel/oci_container.py b/cibuildwheel/oci_container.py index 8da216a2e..aa54eefbf 100644 --- a/cibuildwheel/oci_container.py +++ b/cibuildwheel/oci_container.py @@ -10,7 +10,7 @@ import sys import typing import uuid -from collections.abc import Sequence +from collections.abc import Mapping, Sequence from pathlib import Path, PurePath, PurePosixPath from types import TracebackType from typing import IO, Dict @@ -241,7 +241,7 @@ def glob(self, path: PurePosixPath, pattern: str) -> list[PurePosixPath]: def call( self, args: Sequence[PathOrStr], - env: dict[str, str] | None = None, + env: Mapping[str, str] | None = None, capture_output: bool = False, cwd: PathOrStr | None = None, ) -> str: @@ -333,7 +333,7 @@ def get_environment(self) -> dict[str, str]: ) return typing.cast(Dict[str, str], env) - def environment_executor(self, command: list[str], environment: dict[str, str]) -> str: + def environment_executor(self, command: Sequence[str], environment: dict[str, str]) -> str: # used as an EnvironmentExecutor to evaluate commands and capture output return self.call(command, env=environment, capture_output=True) diff --git a/cibuildwheel/options.py b/cibuildwheel/options.py index 974470c63..d28e76214 100644 --- a/cibuildwheel/options.py +++ b/cibuildwheel/options.py @@ -11,7 +11,7 @@ import textwrap import traceback import typing -from collections.abc import Callable, Generator, Iterator, Mapping, Set +from collections.abc import Callable, Generator, Iterable, Iterator, Mapping, Set from pathlib import Path from typing import Any, Dict, List, Union @@ -601,7 +601,7 @@ def build_options(self, identifier: str | None) -> BuildOptions: config_settings=config_settings, ) - def check_for_invalid_configuration(self, identifiers: list[str]) -> None: + def check_for_invalid_configuration(self, identifiers: Iterable[str]) -> None: if self.platform in {"macos", "windows"}: before_all_values = {self.build_options(i).before_all for i in identifiers} @@ -633,7 +633,7 @@ def defaults(self) -> Options: read_config_file=False, ) - def summary(self, identifiers: list[str]) -> str: + def summary(self, identifiers: Iterable[str]) -> str: lines = [] global_option_names = sorted(f.name for f in dataclasses.fields(self.globals)) @@ -671,7 +671,7 @@ def option_summary( option_name: str, option_value: Any, default_value: Any, - overrides: dict[str, Any] | None = None, + overrides: Mapping[str, Any] | None = None, ) -> str: """ Return a summary of the option value, including any overrides, with diff --git a/cibuildwheel/util.py b/cibuildwheel/util.py index 53cb22a61..2ba4fe6a1 100644 --- a/cibuildwheel/util.py +++ b/cibuildwheel/util.py @@ -13,7 +13,7 @@ import time import typing import urllib.request -from collections.abc import Generator, Iterable, Sequence +from collections.abc import Generator, Iterable, Mapping, Sequence from dataclasses import dataclass from enum import Enum from functools import lru_cache @@ -102,7 +102,7 @@ def build_frontend_or_default( @typing.overload def call( *args: PathOrStr, - env: dict[str, str] | None = None, + env: Mapping[str, str] | None = None, cwd: PathOrStr | None = None, capture_stdout: Literal[False] = ..., ) -> None: @@ -112,7 +112,7 @@ def call( @typing.overload def call( *args: PathOrStr, - env: dict[str, str] | None = None, + env: Mapping[str, str] | None = None, cwd: PathOrStr | None = None, capture_stdout: Literal[True], ) -> str: @@ -121,7 +121,7 @@ def call( def call( *args: PathOrStr, - env: dict[str, str] | None = None, + env: Mapping[str, str] | None = None, cwd: PathOrStr | None = None, capture_stdout: bool = False, ) -> str | None: @@ -144,7 +144,9 @@ def call( return typing.cast(str, result.stdout) -def shell(*commands: str, env: dict[str, str] | None = None, cwd: PathOrStr | None = None) -> None: +def shell( + *commands: str, env: Mapping[str, str] | None = None, cwd: PathOrStr | None = None +) -> None: command = " ".join(commands) print(f"+ {command}") subprocess.run(command, env=env, cwd=cwd, shell=True, check=True) @@ -499,7 +501,7 @@ def print_new_wheels(msg: str, output_dir: Path) -> Generator[None, None, None]: ) -def get_pip_version(env: dict[str, str]) -> str: +def get_pip_version(env: Mapping[str, str]) -> str: versions_output_text = call( "python", "-m", "pip", "freeze", "--all", capture_stdout=True, env=env ) diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py index 5ab8827a2..caee9ce69 100644 --- a/cibuildwheel/windows.py +++ b/cibuildwheel/windows.py @@ -6,7 +6,7 @@ import subprocess import sys import textwrap -from collections.abc import Sequence, Set +from collections.abc import MutableMapping, Sequence, Set from contextlib import suppress from dataclasses import dataclass from functools import lru_cache @@ -137,7 +137,7 @@ def setup_setuptools_cross_compile( tmp: Path, python_configuration: PythonConfiguration, python_libs_base: Path, - env: dict[str, str], + env: MutableMapping[str, str], ) -> None: distutils_cfg = tmp / "extra-setup.cfg" env["DIST_EXTRA_CONFIG"] = str(distutils_cfg) @@ -185,7 +185,7 @@ def setup_rust_cross_compile( tmp: Path, # noqa: ARG001 python_configuration: PythonConfiguration, python_libs_base: Path, # noqa: ARG001 - env: dict[str, str], + env: MutableMapping[str, str], ) -> None: # Assume that MSVC will be used, because we already know that we are # cross-compiling. MinGW users can set CARGO_BUILD_TARGET themselves