python 3.9 compat: introduce typehelpers.py for NoneType, UnionType, TypeAlias
This commit is contained in:
parent
c357b0a968
commit
b84d2202db
9 changed files with 34 additions and 27 deletions
|
@ -3,11 +3,10 @@ from __future__ import annotations
|
|||
from munch import Munch
|
||||
from typing import Any, Optional, Mapping, Union
|
||||
|
||||
from dataclass import DataClass, munchclass
|
||||
from dataclass import DataClass
|
||||
from constants import Arch
|
||||
|
||||
|
||||
@munchclass()
|
||||
class SparseProfile(DataClass):
|
||||
parent: Optional[str]
|
||||
device: Optional[str]
|
||||
|
@ -23,7 +22,6 @@ class SparseProfile(DataClass):
|
|||
return f'{type(self)}{dict.__repr__(self.toDict())}'
|
||||
|
||||
|
||||
@munchclass()
|
||||
class Profile(SparseProfile):
|
||||
parent: Optional[str]
|
||||
device: str
|
||||
|
@ -36,12 +34,10 @@ class Profile(SparseProfile):
|
|||
size_extra_mb: Union[str, int]
|
||||
|
||||
|
||||
@munchclass()
|
||||
class WrapperSection(DataClass):
|
||||
type: str # NOTE: rename to 'wrapper_type' if this causes problems
|
||||
|
||||
|
||||
@munchclass()
|
||||
class BuildSection(DataClass):
|
||||
ccache: bool
|
||||
clean_mode: bool
|
||||
|
@ -50,20 +46,17 @@ class BuildSection(DataClass):
|
|||
threads: int
|
||||
|
||||
|
||||
@munchclass()
|
||||
class PkgbuildsSection(DataClass):
|
||||
git_repo: str
|
||||
git_branch: str
|
||||
|
||||
|
||||
@munchclass()
|
||||
class PacmanSection(DataClass):
|
||||
parallel_downloads: int
|
||||
check_space: bool
|
||||
repo_branch: str
|
||||
|
||||
|
||||
@munchclass()
|
||||
class PathsSection(DataClass):
|
||||
cache_dir: str
|
||||
chroots: str
|
||||
|
@ -101,7 +94,6 @@ class ProfilesSection(DataClass):
|
|||
return f'{type(self)}{dict.__repr__(self.toDict())}'
|
||||
|
||||
|
||||
@munchclass()
|
||||
class Config(DataClass):
|
||||
wrapper: WrapperSection
|
||||
build: BuildSection
|
||||
|
@ -138,7 +130,6 @@ class Config(DataClass):
|
|||
return Config(_vals, validate=validate)
|
||||
|
||||
|
||||
@munchclass()
|
||||
class RuntimeConfiguration(DataClass):
|
||||
verbose: bool
|
||||
no_wrap: bool
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from typing_extensions import TypeAlias
|
||||
from typehelpers import TypeAlias
|
||||
|
||||
FASTBOOT = 'fastboot'
|
||||
FLASH_PARTS = {
|
||||
|
|
10
dataclass.py
10
dataclass.py
|
@ -3,15 +3,11 @@ from __future__ import annotations
|
|||
import logging
|
||||
import toml
|
||||
|
||||
from dataclasses import dataclass
|
||||
from munch import Munch
|
||||
from toml.encoder import TomlEncoder, TomlPreserveInlineDictEncoder
|
||||
from typing import ClassVar, Generator, Optional, Union, Mapping, Any, get_type_hints, get_origin, get_args, Iterable
|
||||
from types import UnionType, NoneType
|
||||
|
||||
|
||||
def munchclass(*args, init=False, **kwargs):
|
||||
return dataclass(*args, init=init, slots=True, **kwargs)
|
||||
from typehelpers import UnionType, NoneType
|
||||
|
||||
|
||||
def resolve_type_hint(hint: type, ignore_origins: list[type] = []) -> Iterable[type]:
|
||||
|
@ -73,12 +69,12 @@ class DataClass(Munch):
|
|||
type_hints = cls._type_hints if type_hints is None else type_hints
|
||||
if key in type_hints:
|
||||
_classes = tuple[type](resolve_type_hint(type_hints[key]))
|
||||
optional = NoneType in _classes
|
||||
optional = bool(set([NoneType, None]).intersection(_classes))
|
||||
if optional and value is None:
|
||||
results[key] = None
|
||||
continue
|
||||
if issubclass(_classes[0], dict):
|
||||
assert isinstance(value, dict) or optional
|
||||
assert isinstance(value, dict) or (optional and value is None), f'{key=} is not dict: {value!r}, {_classes=}'
|
||||
target_class = _classes[0]
|
||||
if target_class in [None, NoneType, Optional]:
|
||||
for target in _classes[1:]:
|
||||
|
|
|
@ -5,7 +5,7 @@ from typing import Optional
|
|||
|
||||
from config.state import config
|
||||
from constants import Arch, ARCHES
|
||||
from config.scheme import DataClass, munchclass
|
||||
from dataclass import DataClass
|
||||
from distro.distro import get_kupfer_local
|
||||
from distro.package import LocalPackage
|
||||
from packages.pkgbuild import Pkgbuild, _pkgbuilds_cache, discover_pkgbuilds, get_pkgbuild_by_path, init_pkgbuilds
|
||||
|
@ -43,7 +43,6 @@ class DeviceSummary(DataClass):
|
|||
return separator.join([f"{color_str(name, bold=True, use_colors=colors)}: {value}" for name, value in fields.items()])
|
||||
|
||||
|
||||
@munchclass()
|
||||
class Device(DataClass):
|
||||
name: str
|
||||
arch: Arch
|
||||
|
|
|
@ -2,7 +2,7 @@ import logging
|
|||
import os
|
||||
|
||||
from shutil import copyfileobj
|
||||
from typing import Optional
|
||||
from typing import Optional, Union
|
||||
from urllib.request import urlopen
|
||||
|
||||
from exec.file import get_temp_dir, makedir
|
||||
|
@ -17,7 +17,7 @@ class BinaryPackage(PackageInfo):
|
|||
arch: str
|
||||
filename: str
|
||||
resolved_url: Optional[str]
|
||||
_desc: Optional[dict[str, str | list[str]]]
|
||||
_desc: Optional[dict[str, Union[str, list[str]]]]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
@ -39,7 +39,7 @@ class BinaryPackage(PackageInfo):
|
|||
@classmethod
|
||||
def parse_desc(clss, desc_str: str, resolved_repo_url=None):
|
||||
"""Parses a desc file, returning a PackageInfo"""
|
||||
desc: dict[str, str | list[str]] = {}
|
||||
desc: dict[str, Union[str, list[str]]] = {}
|
||||
for segment in f'\n{desc_str}'.split('\n%'):
|
||||
if not segment.strip():
|
||||
continue
|
||||
|
|
|
@ -6,7 +6,7 @@ import toml
|
|||
import yaml
|
||||
|
||||
from copy import deepcopy
|
||||
from typing import ClassVar, Optional, Mapping
|
||||
from typing import ClassVar, Optional, Mapping, Union
|
||||
|
||||
from config.state import config
|
||||
from constants import Arch, BASE_DISTROS, KUPFER_HTTPS, REPOS_CONFIG_FILE, REPOSITORIES
|
||||
|
@ -33,7 +33,7 @@ class BaseDistroRepo(AbstrRepoConfig):
|
|||
|
||||
|
||||
class RepoConfig(AbstrRepoConfig):
|
||||
remote_url: Optional[str | dict[Arch, str]]
|
||||
remote_url: Optional[Union[str, dict[Arch, str]]]
|
||||
local_only: Optional[bool]
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,9 @@ import subprocess
|
|||
|
||||
from subprocess import CompletedProcess # make it easy for users of this module
|
||||
from shlex import quote as shell_quote
|
||||
from typing import IO, Optional, Union, TypeAlias
|
||||
from typing import IO, Optional, Union
|
||||
|
||||
from typehelpers import TypeAlias
|
||||
|
||||
ElevationMethod: TypeAlias = str
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import multiprocessing
|
|||
import os
|
||||
|
||||
from joblib import Parallel, delayed
|
||||
from typing import Iterable, Optional, TypeAlias
|
||||
from typing import Iterable, Optional
|
||||
|
||||
from config.state import config, ConfigStateHolder
|
||||
from constants import Arch
|
||||
|
@ -16,6 +16,7 @@ from exec.file import remove_file
|
|||
from logger import setup_logging
|
||||
from utils import git, git_get_branch
|
||||
from wrapper import check_programs_wrap
|
||||
from typehelpers import TypeAlias
|
||||
|
||||
from .srcinfo_cache import SrcinfoMetaFile
|
||||
|
||||
|
|
18
typehelpers.py
Normal file
18
typehelpers.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
from typing import Union
|
||||
|
||||
try:
|
||||
from typing import TypeAlias # type: ignore[attr-defined]
|
||||
except ImportError:
|
||||
from typing_extensions import TypeAlias
|
||||
|
||||
TypeAlias = TypeAlias
|
||||
|
||||
try:
|
||||
from types import UnionType
|
||||
except ImportError:
|
||||
UnionType: TypeAlias = Union # type: ignore[no-redef]
|
||||
|
||||
try:
|
||||
from types import NoneType
|
||||
except ImportError:
|
||||
NoneType: TypeAlias = type(None) # type: ignore[no-redef]
|
Loading…
Add table
Add a link
Reference in a new issue