python 3.9 compat: introduce typehelpers.py for NoneType, UnionType, TypeAlias

This commit is contained in:
InsanePrawn 2023-04-16 20:48:48 +00:00
parent c357b0a968
commit b84d2202db
9 changed files with 34 additions and 27 deletions

View file

@ -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

View file

@ -1,4 +1,4 @@
from typing_extensions import TypeAlias
from typehelpers import TypeAlias
FASTBOOT = 'fastboot'
FLASH_PARTS = {

View file

@ -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:]:

View file

@ -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

View file

@ -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

View file

@ -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]

View file

@ -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

View file

@ -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
View 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]