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