chore: use kw_only (Python 3.10+) on most dataclasses (#2422)
* chore: use kw_only (Python 3.10+) on many dataclasses Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> * fix: expose windows file to type checker Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> --------- Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import configparser
|
||||
from dataclasses import dataclass
|
||||
import dataclasses
|
||||
from pathlib import Path
|
||||
|
||||
import requests
|
||||
@@ -11,7 +11,7 @@ DIR = Path(__file__).parent.resolve()
|
||||
RESOURCES = DIR.parent / "cibuildwheel/resources"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class Image:
|
||||
manylinux_version: str
|
||||
platforms: list[str]
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
|
||||
import dataclasses
|
||||
import difflib
|
||||
import logging
|
||||
import tomllib
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Final
|
||||
|
||||
@@ -27,7 +27,7 @@ NODEJS_DIST: Final[str] = "https://nodejs.org/dist/"
|
||||
NODEJS_INDEX: Final[str] = f"{NODEJS_DIST}index.json"
|
||||
|
||||
|
||||
@dataclass(frozen=True, order=True)
|
||||
@dataclasses.dataclass(frozen=True, order=True)
|
||||
class VersionTuple:
|
||||
version: Version
|
||||
version_string: str
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
|
||||
import dataclasses
|
||||
import difflib
|
||||
import logging
|
||||
import subprocess
|
||||
import tomllib
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Final
|
||||
|
||||
@@ -28,7 +28,7 @@ GET_VIRTUALENV_URL_TEMPLATE: Final[str] = (
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True, order=True)
|
||||
@dataclasses.dataclass(frozen=True, order=True)
|
||||
class VersionTuple:
|
||||
version: Version
|
||||
version_string: str
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import dataclasses
|
||||
import subprocess
|
||||
from collections.abc import (
|
||||
Callable,
|
||||
@@ -5,7 +6,6 @@ from collections.abc import (
|
||||
Mapping,
|
||||
Sequence,
|
||||
)
|
||||
from dataclasses import dataclass
|
||||
|
||||
import bashlex
|
||||
|
||||
@@ -17,7 +17,7 @@ def local_environment_executor(command: Sequence[str], env: Mapping[str, str]) -
|
||||
return subprocess.run(command, env=env, text=True, stdout=subprocess.PIPE, check=True).stdout
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@dataclasses.dataclass(frozen=True, kw_only=True)
|
||||
class NodeExecutionContext:
|
||||
environment: dict[str, str]
|
||||
input: str
|
||||
|
||||
@@ -102,7 +102,7 @@ class EnvironmentAssignmentBash:
|
||||
return False
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
@dataclasses.dataclass(kw_only=True)
|
||||
class ParsedEnvironment:
|
||||
assignments: list[EnvironmentAssignment]
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import dataclasses
|
||||
import shlex
|
||||
import typing
|
||||
from collections.abc import Sequence
|
||||
from dataclasses import dataclass
|
||||
from typing import Literal, Self, get_args
|
||||
|
||||
from .logger import log
|
||||
@@ -10,7 +10,7 @@ from .util.helpers import parse_key_value_string
|
||||
BuildFrontendName = Literal["pip", "build", "build[uv]"]
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class BuildFrontendConfig:
|
||||
name: BuildFrontendName
|
||||
args: Sequence[str] = ()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import dataclasses
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
@@ -10,7 +11,6 @@ import textwrap
|
||||
import typing
|
||||
import uuid
|
||||
from collections.abc import Mapping, Sequence
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from pathlib import Path, PurePath, PurePosixPath
|
||||
from types import TracebackType
|
||||
@@ -37,10 +37,11 @@ class OCIPlatform(Enum):
|
||||
S390X = "linux/s390x"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class OCIContainerEngineConfig:
|
||||
name: ContainerEngineName
|
||||
create_args: tuple[str, ...] = field(default_factory=tuple)
|
||||
_: dataclasses.KW_ONLY
|
||||
create_args: tuple[str, ...] = dataclasses.field(default_factory=tuple)
|
||||
disable_host_mount: bool = False
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -51,7 +51,7 @@ MUSLLINUX_ARCHS: Final[tuple[str, ...]] = (
|
||||
)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
@dataclasses.dataclass(kw_only=True)
|
||||
class CommandLineArguments:
|
||||
platform: Literal["auto", "linux", "macos", "windows"] | None
|
||||
archs: str | None
|
||||
@@ -80,7 +80,7 @@ class CommandLineArguments:
|
||||
)
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
@dataclasses.dataclass(frozen=True, kw_only=True)
|
||||
class GlobalOptions:
|
||||
package_dir: Path
|
||||
output_dir: Path
|
||||
@@ -90,7 +90,7 @@ class GlobalOptions:
|
||||
allow_empty: bool
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
@dataclasses.dataclass(frozen=True, kw_only=True)
|
||||
class BuildOptions:
|
||||
globals: GlobalOptions
|
||||
environment: ParsedEnvironment
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import dataclasses
|
||||
import os
|
||||
import shlex
|
||||
import shutil
|
||||
@@ -7,7 +8,6 @@ import subprocess
|
||||
import sys
|
||||
import textwrap
|
||||
from collections.abc import Sequence, Set
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import assert_never
|
||||
|
||||
@@ -42,7 +42,7 @@ from ..venv import constraint_flags, virtualenv
|
||||
from .macos import install_cpython as install_build_cpython
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@dataclasses.dataclass(frozen=True, kw_only=True)
|
||||
class PythonConfiguration:
|
||||
version: str
|
||||
identifier: str
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import contextlib
|
||||
import dataclasses
|
||||
import subprocess
|
||||
import sys
|
||||
import textwrap
|
||||
from collections import OrderedDict
|
||||
from collections.abc import Iterable, Iterator, Sequence, Set
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path, PurePath, PurePosixPath
|
||||
from typing import assert_never
|
||||
|
||||
@@ -32,7 +32,7 @@ ARCHITECTURE_OCI_PLATFORM_MAP = {
|
||||
}
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@dataclasses.dataclass(frozen=True, kw_only=True)
|
||||
class PythonConfiguration:
|
||||
version: str
|
||||
identifier: str
|
||||
@@ -43,7 +43,7 @@ class PythonConfiguration:
|
||||
return PurePosixPath(self.path_str)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@dataclasses.dataclass(frozen=True, kw_only=True)
|
||||
class BuildStep:
|
||||
platform_configs: list[PythonConfiguration]
|
||||
platform_tag: str
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import dataclasses
|
||||
import functools
|
||||
import inspect
|
||||
import os
|
||||
@@ -8,7 +9,6 @@ import subprocess
|
||||
import sys
|
||||
import typing
|
||||
from collections.abc import Set
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Literal, assert_never
|
||||
|
||||
@@ -76,7 +76,7 @@ def get_macos_sdks() -> list[str]:
|
||||
return [m.group(1) for m in re.finditer(r"-sdk (macosx\S+)", output)]
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@dataclasses.dataclass(frozen=True, kw_only=True)
|
||||
class PythonConfiguration:
|
||||
version: str
|
||||
identifier: str
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import dataclasses
|
||||
import functools
|
||||
import json
|
||||
import os
|
||||
@@ -6,7 +7,6 @@ import sys
|
||||
import tomllib
|
||||
import typing
|
||||
from collections.abc import Set
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
from typing import Final, TypedDict
|
||||
@@ -41,7 +41,7 @@ from ..venv import constraint_flags, virtualenv
|
||||
IS_WIN: Final[bool] = sys.platform.startswith("win")
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@dataclasses.dataclass(frozen=True, kw_only=True)
|
||||
class PythonConfiguration:
|
||||
version: str
|
||||
identifier: str
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import dataclasses
|
||||
import json
|
||||
import os
|
||||
import platform as platform_module
|
||||
@@ -5,7 +6,6 @@ import shutil
|
||||
import subprocess
|
||||
import textwrap
|
||||
from collections.abc import MutableMapping, Set
|
||||
from dataclasses import dataclass
|
||||
from functools import cache
|
||||
from pathlib import Path
|
||||
from typing import assert_never
|
||||
@@ -51,7 +51,7 @@ def get_nuget_args(
|
||||
]
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@dataclasses.dataclass(frozen=True, kw_only=True)
|
||||
class PythonConfiguration:
|
||||
version: str
|
||||
arch: str
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import dataclasses
|
||||
import itertools
|
||||
from dataclasses import dataclass
|
||||
from enum import StrEnum
|
||||
from fnmatch import fnmatch
|
||||
from typing import Any
|
||||
@@ -58,7 +58,7 @@ class EnableGroup(StrEnum):
|
||||
return frozenset(result)
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
@dataclasses.dataclass(frozen=True, kw_only=True)
|
||||
class BuildSelector:
|
||||
"""
|
||||
This class holds a set of build/skip patterns. You call an instance with a
|
||||
@@ -113,7 +113,7 @@ class BuildSelector:
|
||||
}
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@dataclasses.dataclass(frozen=True, kw_only=True)
|
||||
class TestSelector:
|
||||
"""
|
||||
A build selector that can only skip tests according to a skip pattern.
|
||||
|
||||
@@ -11,7 +11,7 @@ from .cmd import call
|
||||
from .helpers import parse_key_value_string, unwrap
|
||||
|
||||
|
||||
@dataclass()
|
||||
@dataclass(kw_only=True)
|
||||
class DependencyConstraints:
|
||||
base_file_path: Path | None = None
|
||||
packages: list[str] = field(default_factory=list)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import contextlib
|
||||
import sys
|
||||
from collections.abc import Generator
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import pytest
|
||||
import setuptools._distutils.util
|
||||
@@ -10,23 +12,27 @@ from cibuildwheel.errors import FatalError
|
||||
from cibuildwheel.platforms.windows import PythonConfiguration, setup_setuptools_cross_compile
|
||||
|
||||
# monkeypatching os.name is too flaky. E.g. It works on my machine, but fails in pipeline
|
||||
if not sys.platform.startswith("win"):
|
||||
if not sys.platform.startswith("win") and not TYPE_CHECKING:
|
||||
pytest.skip("Windows-only tests", allow_module_level=True)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def patched_environment(monkeypatch: pytest.MonkeyPatch, environment: dict[str, str]):
|
||||
def patched_environment(
|
||||
monkeypatch: pytest.MonkeyPatch, environment: dict[str, str]
|
||||
) -> Generator[None, None, None]:
|
||||
with monkeypatch.context() as mp:
|
||||
for envvar, val in environment.items():
|
||||
mp.setenv(name=envvar, value=val)
|
||||
yield
|
||||
|
||||
|
||||
def test_x86(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
|
||||
def test_x86(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
arch = "32"
|
||||
environment: dict[str, str] = {}
|
||||
|
||||
configuration = PythonConfiguration("irrelevant", arch, "irrelevant", None)
|
||||
configuration = PythonConfiguration(
|
||||
version="irrelevant", arch=arch, identifier="irrelevant", url=None
|
||||
)
|
||||
|
||||
setup_setuptools_cross_compile(tmp_path, configuration, tmp_path, environment)
|
||||
with patched_environment(monkeypatch, environment):
|
||||
@@ -36,11 +42,13 @@ def test_x86(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
|
||||
assert target_platform == "win32"
|
||||
|
||||
|
||||
def test_x64(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
|
||||
def test_x64(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
arch = "64"
|
||||
environment: dict[str, str] = {}
|
||||
|
||||
configuration = PythonConfiguration("irrelevant", arch, "irrelevant", None)
|
||||
configuration = PythonConfiguration(
|
||||
version="irrelevant", arch=arch, identifier="irrelevant", url=None
|
||||
)
|
||||
|
||||
setup_setuptools_cross_compile(tmp_path, configuration, tmp_path, environment)
|
||||
with patched_environment(monkeypatch, environment):
|
||||
@@ -53,11 +61,13 @@ def test_x64(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
|
||||
@pytest.mark.skipif(
|
||||
detect_ci_provider() == CIProvider.azure_pipelines, reason="arm64 not recognised on azure"
|
||||
)
|
||||
def test_arm(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
|
||||
def test_arm(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
arch = "ARM64"
|
||||
environment: dict[str, str] = {}
|
||||
|
||||
configuration = PythonConfiguration("irrelevant", arch, "irrelevant", None)
|
||||
configuration = PythonConfiguration(
|
||||
version="irrelevant", arch=arch, identifier="irrelevant", url=None
|
||||
)
|
||||
|
||||
setup_setuptools_cross_compile(tmp_path, configuration, tmp_path, environment)
|
||||
with patched_environment(monkeypatch, environment):
|
||||
@@ -67,21 +77,25 @@ def test_arm(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
|
||||
assert target_platform == "win-arm64"
|
||||
|
||||
|
||||
def test_env_set(tmp_path: Path):
|
||||
def test_env_set(tmp_path: Path) -> None:
|
||||
arch = "32"
|
||||
environment = {"VSCMD_ARG_TGT_ARCH": "x64"}
|
||||
|
||||
configuration = PythonConfiguration("irrelevant", arch, "irrelevant", None)
|
||||
configuration = PythonConfiguration(
|
||||
version="irrelevant", arch=arch, identifier="irrelevant", url=None
|
||||
)
|
||||
|
||||
with pytest.raises(FatalError, match="VSCMD_ARG_TGT_ARCH"):
|
||||
setup_setuptools_cross_compile(tmp_path, configuration, tmp_path, environment)
|
||||
|
||||
|
||||
def test_env_blank(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
|
||||
def test_env_blank(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
arch = "32"
|
||||
environment = {"VSCMD_ARG_TGT_ARCH": ""}
|
||||
|
||||
configuration = PythonConfiguration("irrelevant", arch, "irrelevant", None)
|
||||
configuration = PythonConfiguration(
|
||||
version="irrelevant", arch=arch, identifier="irrelevant", url=None
|
||||
)
|
||||
|
||||
setup_setuptools_cross_compile(tmp_path, configuration, tmp_path, environment)
|
||||
with patched_environment(monkeypatch, environment):
|
||||
|
||||
Reference in New Issue
Block a user