refactor: use dataclasses vs. NamedTuples
This commit is contained in:
@@ -27,7 +27,7 @@ repos:
|
|||||||
|
|
||||||
# Autoremoves unused imports
|
# Autoremoves unused imports
|
||||||
- repo: https://github.com/hadialqattan/pycln
|
- repo: https://github.com/hadialqattan/pycln
|
||||||
rev: v1.3.1
|
rev: v1.3.2
|
||||||
hooks:
|
hooks:
|
||||||
- id: pycln
|
- id: pycln
|
||||||
args: [--all]
|
args: [--all]
|
||||||
@@ -49,7 +49,7 @@ repos:
|
|||||||
- id: setup-cfg-fmt
|
- id: setup-cfg-fmt
|
||||||
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||||
rev: v0.942
|
rev: v0.950
|
||||||
hooks:
|
hooks:
|
||||||
- id: mypy
|
- id: mypy
|
||||||
name: mypy 3.6 on cibuildwheel/
|
name: mypy 3.6 on cibuildwheel/
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import configparser
|
import configparser
|
||||||
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import NamedTuple
|
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
@@ -11,7 +11,8 @@ DIR = Path(__file__).parent.resolve()
|
|||||||
RESOURCES = DIR.parent / "cibuildwheel/resources"
|
RESOURCES = DIR.parent / "cibuildwheel/resources"
|
||||||
|
|
||||||
|
|
||||||
class Image(NamedTuple):
|
@dataclass(frozen=True)
|
||||||
|
class Image:
|
||||||
manylinux_version: str
|
manylinux_version: str
|
||||||
platform: str
|
platform: str
|
||||||
image_name: str
|
image_name: str
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import difflib
|
|||||||
import logging
|
import logging
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import NamedTuple
|
|
||||||
|
|
||||||
import click
|
import click
|
||||||
import rich
|
import rich
|
||||||
@@ -36,7 +36,8 @@ GET_VIRTUALENV_URL_TEMPLATE: Final[
|
|||||||
] = f"{GET_VIRTUALENV_GITHUB}/blob/{{version}}/public/virtualenv.pyz?raw=true"
|
] = f"{GET_VIRTUALENV_GITHUB}/blob/{{version}}/public/virtualenv.pyz?raw=true"
|
||||||
|
|
||||||
|
|
||||||
class VersionTuple(NamedTuple):
|
@dataclass(frozen=True)
|
||||||
|
class VersionTuple:
|
||||||
version: Version
|
version: Version
|
||||||
version_string: str
|
version_string: str
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ def main() -> None:
|
|||||||
help="Enable pre-release Python versions if available.",
|
help="Enable pre-release Python versions if available.",
|
||||||
)
|
)
|
||||||
|
|
||||||
args = parser.parse_args(namespace=CommandLineArguments())
|
args = CommandLineArguments(**vars(parser.parse_args()))
|
||||||
|
|
||||||
if args.platform != "auto":
|
if args.platform != "auto":
|
||||||
platform = args.platform
|
platform = args.platform
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
from typing import Callable, Dict, List, NamedTuple, Optional, Sequence
|
from dataclasses import dataclass
|
||||||
|
from typing import Callable, Dict, List, Optional, Sequence
|
||||||
|
|
||||||
import bashlex
|
import bashlex
|
||||||
|
|
||||||
@@ -13,7 +14,8 @@ def local_environment_executor(command: List[str], env: Dict[str, str]) -> str:
|
|||||||
).stdout
|
).stdout
|
||||||
|
|
||||||
|
|
||||||
class NodeExecutionContext(NamedTuple):
|
@dataclass(frozen=True)
|
||||||
|
class NodeExecutionContext:
|
||||||
environment: Dict[str, str]
|
environment: Dict[str, str]
|
||||||
input: str
|
input: str
|
||||||
executor: EnvironmentExecutor
|
executor: EnvironmentExecutor
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
|
from dataclasses import dataclass
|
||||||
from pathlib import Path, PurePath
|
from pathlib import Path, PurePath
|
||||||
from typing import Iterator, List, NamedTuple, Set, Tuple
|
from typing import Iterator, List, Set, Tuple
|
||||||
|
|
||||||
from .architecture import Architecture
|
from .architecture import Architecture
|
||||||
from .docker_container import DockerContainer
|
from .docker_container import DockerContainer
|
||||||
@@ -18,7 +19,8 @@ from .util import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class PythonConfiguration(NamedTuple):
|
@dataclass(frozen=True)
|
||||||
|
class PythonConfiguration:
|
||||||
version: str
|
version: str
|
||||||
identifier: str
|
identifier: str
|
||||||
path_str: str
|
path_str: str
|
||||||
@@ -28,7 +30,8 @@ class PythonConfiguration(NamedTuple):
|
|||||||
return PurePath(self.path_str)
|
return PurePath(self.path_str)
|
||||||
|
|
||||||
|
|
||||||
class BuildStep(NamedTuple):
|
@dataclass(frozen=True)
|
||||||
|
class BuildStep:
|
||||||
platform_configs: List[PythonConfiguration]
|
platform_configs: List[PythonConfiguration]
|
||||||
platform_tag: str
|
platform_tag: str
|
||||||
docker_image: str
|
docker_image: str
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ import re
|
|||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, List, NamedTuple, Sequence, Set, Tuple, cast
|
from typing import Dict, List, Sequence, Set, Tuple, cast
|
||||||
|
|
||||||
from filelock import FileLock
|
from filelock import FileLock
|
||||||
|
|
||||||
@@ -53,7 +54,8 @@ def get_macos_sdks() -> List[str]:
|
|||||||
return [m.group(1) for m in re.finditer(r"-sdk (macosx\S+)", output)]
|
return [m.group(1) for m in re.finditer(r"-sdk (macosx\S+)", output)]
|
||||||
|
|
||||||
|
|
||||||
class PythonConfiguration(NamedTuple):
|
@dataclass(frozen=True)
|
||||||
|
class PythonConfiguration:
|
||||||
version: str
|
version: str
|
||||||
identifier: str
|
identifier: str
|
||||||
url: str
|
url: str
|
||||||
|
|||||||
+13
-18
@@ -4,24 +4,15 @@ import sys
|
|||||||
import traceback
|
import traceback
|
||||||
from configparser import ConfigParser
|
from configparser import ConfigParser
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
from dataclasses import asdict, dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import (
|
from typing import Any, Dict, Iterator, List, Mapping, Optional, Set, Tuple, Union
|
||||||
Any,
|
|
||||||
Dict,
|
|
||||||
Iterator,
|
|
||||||
List,
|
|
||||||
Mapping,
|
|
||||||
NamedTuple,
|
|
||||||
Optional,
|
|
||||||
Set,
|
|
||||||
Tuple,
|
|
||||||
Union,
|
|
||||||
)
|
|
||||||
|
|
||||||
if sys.version_info >= (3, 11):
|
if sys.version_info >= (3, 11):
|
||||||
import tomllib
|
import tomllib
|
||||||
else:
|
else:
|
||||||
import tomli as tomllib
|
import tomli as tomllib
|
||||||
|
|
||||||
from packaging.specifiers import SpecifierSet
|
from packaging.specifiers import SpecifierSet
|
||||||
|
|
||||||
from .architecture import Architecture
|
from .architecture import Architecture
|
||||||
@@ -43,6 +34,7 @@ from .util import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
class CommandLineArguments:
|
class CommandLineArguments:
|
||||||
platform: Literal["auto", "linux", "macos", "windows"]
|
platform: Literal["auto", "linux", "macos", "windows"]
|
||||||
archs: Optional[str]
|
archs: Optional[str]
|
||||||
@@ -54,7 +46,8 @@ class CommandLineArguments:
|
|||||||
prerelease_pythons: bool
|
prerelease_pythons: bool
|
||||||
|
|
||||||
|
|
||||||
class GlobalOptions(NamedTuple):
|
@dataclass(frozen=True)
|
||||||
|
class GlobalOptions:
|
||||||
package_dir: Path
|
package_dir: Path
|
||||||
output_dir: Path
|
output_dir: Path
|
||||||
build_selector: BuildSelector
|
build_selector: BuildSelector
|
||||||
@@ -62,7 +55,8 @@ class GlobalOptions(NamedTuple):
|
|||||||
architectures: Set[Architecture]
|
architectures: Set[Architecture]
|
||||||
|
|
||||||
|
|
||||||
class BuildOptions(NamedTuple):
|
@dataclass(frozen=True)
|
||||||
|
class BuildOptions:
|
||||||
globals: GlobalOptions
|
globals: GlobalOptions
|
||||||
environment: ParsedEnvironment
|
environment: ParsedEnvironment
|
||||||
before_all: str
|
before_all: str
|
||||||
@@ -102,7 +96,8 @@ class BuildOptions(NamedTuple):
|
|||||||
Setting = Union[Dict[str, str], List[str], str, int]
|
Setting = Union[Dict[str, str], List[str], str, int]
|
||||||
|
|
||||||
|
|
||||||
class Override(NamedTuple):
|
@dataclass(frozen=True)
|
||||||
|
class Override:
|
||||||
select_pattern: str
|
select_pattern: str
|
||||||
options: Dict[str, Setting]
|
options: Dict[str, Setting]
|
||||||
|
|
||||||
@@ -550,12 +545,12 @@ class Options:
|
|||||||
def summary(self, identifiers: List[str]) -> str:
|
def summary(self, identifiers: List[str]) -> str:
|
||||||
lines = [
|
lines = [
|
||||||
f"{option_name}: {option_value!r}"
|
f"{option_name}: {option_value!r}"
|
||||||
for option_name, option_value in sorted(self.globals._asdict().items())
|
for option_name, option_value in sorted(asdict(self.globals).items())
|
||||||
]
|
]
|
||||||
|
|
||||||
build_option_defaults = self.build_options(identifier=None)
|
build_option_defaults = self.build_options(identifier=None)
|
||||||
|
|
||||||
for option_name, default_value in sorted(build_option_defaults._asdict().items()):
|
for option_name, default_value in sorted(asdict(build_option_defaults).items()):
|
||||||
if option_name == "globals":
|
if option_name == "globals":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -563,7 +558,7 @@ class Options:
|
|||||||
|
|
||||||
# if any identifiers have an overridden value, print that too
|
# if any identifiers have an overridden value, print that too
|
||||||
for identifier in identifiers:
|
for identifier in identifiers:
|
||||||
option_value = self.build_options(identifier=identifier)._asdict()[option_name]
|
option_value = getattr(self.build_options(identifier=identifier), option_name)
|
||||||
if option_value != default_value:
|
if option_value != default_value:
|
||||||
lines.append(f" {identifier}: {option_value!r}")
|
lines.append(f" {identifier}: {option_value!r}")
|
||||||
|
|
||||||
|
|||||||
+10
-9
@@ -1,5 +1,4 @@
|
|||||||
import contextlib
|
import contextlib
|
||||||
import dataclasses
|
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import itertools
|
import itertools
|
||||||
import os
|
import os
|
||||||
@@ -11,6 +10,7 @@ import sys
|
|||||||
import textwrap
|
import textwrap
|
||||||
import time
|
import time
|
||||||
import urllib.request
|
import urllib.request
|
||||||
|
from dataclasses import dataclass
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -22,7 +22,6 @@ from typing import (
|
|||||||
Iterable,
|
Iterable,
|
||||||
Iterator,
|
Iterator,
|
||||||
List,
|
List,
|
||||||
NamedTuple,
|
|
||||||
Optional,
|
Optional,
|
||||||
Sequence,
|
Sequence,
|
||||||
TextIO,
|
TextIO,
|
||||||
@@ -228,7 +227,7 @@ def selector_matches(patterns: str, string: str) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
# Once we require Python 3.10+, we can add kw_only=True
|
# Once we require Python 3.10+, we can add kw_only=True
|
||||||
@dataclasses.dataclass
|
@dataclass(frozen=True)
|
||||||
class IdentifierSelector:
|
class IdentifierSelector:
|
||||||
"""
|
"""
|
||||||
This class holds a set of build/skip patterns. You call an instance with a
|
This class holds a set of build/skip patterns. You call an instance with a
|
||||||
@@ -266,14 +265,14 @@ class IdentifierSelector:
|
|||||||
return should_build and not should_skip
|
return should_build and not should_skip
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass
|
@dataclass(frozen=True)
|
||||||
class BuildSelector(IdentifierSelector):
|
class BuildSelector(IdentifierSelector):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
# Note that requires-python is not needed for TestSelector, as you can't test
|
# Note that requires-python is not needed for TestSelector, as you can't test
|
||||||
# what you can't build.
|
# what you can't build.
|
||||||
@dataclasses.dataclass
|
@dataclass(frozen=True)
|
||||||
class TestSelector(IdentifierSelector):
|
class TestSelector(IdentifierSelector):
|
||||||
build_config: str = "*"
|
build_config: str = "*"
|
||||||
|
|
||||||
@@ -413,6 +412,12 @@ def unwrap(text: str) -> str:
|
|||||||
return re.sub(r"\s+", " ", text)
|
return re.sub(r"\s+", " ", text)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class FileReport:
|
||||||
|
name: str
|
||||||
|
size: str
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def print_new_wheels(msg: str, output_dir: Path) -> Iterator[None]:
|
def print_new_wheels(msg: str, output_dir: Path) -> Iterator[None]:
|
||||||
"""
|
"""
|
||||||
@@ -427,10 +432,6 @@ def print_new_wheels(msg: str, output_dir: Path) -> Iterator[None]:
|
|||||||
yield
|
yield
|
||||||
final_contents = set(output_dir.iterdir())
|
final_contents = set(output_dir.iterdir())
|
||||||
|
|
||||||
class FileReport(NamedTuple):
|
|
||||||
name: str
|
|
||||||
size: str
|
|
||||||
|
|
||||||
new_contents = [
|
new_contents = [
|
||||||
FileReport(wheel.name, f"{(wheel.stat().st_size + 1023) // 1024:,d}")
|
FileReport(wheel.name, f"{(wheel.stat().st_size + 1023) // 1024:,d}")
|
||||||
for wheel in final_contents - existing_contents
|
for wheel in final_contents - existing_contents
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
from dataclasses import dataclass
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, List, NamedTuple, Optional, Sequence, Set
|
from typing import Dict, List, Optional, Sequence, Set
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
|
|
||||||
from filelock import FileLock
|
from filelock import FileLock
|
||||||
@@ -45,7 +46,8 @@ def get_nuget_args(version: str, arch: str, output_directory: Path) -> List[str]
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class PythonConfiguration(NamedTuple):
|
@dataclass(frozen=True)
|
||||||
|
class PythonConfiguration:
|
||||||
version: str
|
version: str
|
||||||
arch: str
|
arch: str
|
||||||
identifier: str
|
identifier: str
|
||||||
|
|||||||
+10
-10
@@ -2,15 +2,15 @@ from cibuildwheel.options import CommandLineArguments
|
|||||||
|
|
||||||
|
|
||||||
def get_default_command_line_arguments() -> CommandLineArguments:
|
def get_default_command_line_arguments() -> CommandLineArguments:
|
||||||
defaults = CommandLineArguments()
|
defaults = CommandLineArguments(
|
||||||
|
platform="auto",
|
||||||
defaults.platform = "auto"
|
allow_empty=False,
|
||||||
defaults.allow_empty = False
|
archs=None,
|
||||||
defaults.archs = None
|
config_file="",
|
||||||
defaults.config_file = ""
|
output_dir=None,
|
||||||
defaults.output_dir = None
|
package_dir=".",
|
||||||
defaults.package_dir = "."
|
prerelease_pythons=False,
|
||||||
defaults.prerelease_pythons = False
|
print_build_identifiers=False,
|
||||||
defaults.print_build_identifiers = False
|
)
|
||||||
|
|
||||||
return defaults
|
return defaults
|
||||||
|
|||||||
Reference in New Issue
Block a user