100 lines
2.8 KiB
Python
100 lines
2.8 KiB
Python
from collections.abc import ItemsView, Iterator, KeysView, MutableMapping, Set
|
|
from types import GenericAlias, UnionType
|
|
from typing import (
|
|
ClassVar,
|
|
Never,
|
|
Protocol,
|
|
TypeAliasType,
|
|
cast,
|
|
get_args,
|
|
get_origin,
|
|
overload,
|
|
)
|
|
|
|
|
|
class TypedYamlDict[K: object, V: object](Protocol):
|
|
def __getitem__(self, key: str | K, /) -> V: ...
|
|
# def __setitem__(self, key: str, value: V, /) -> V: ...
|
|
def __delitem__(self, key: Never | K, /) -> None: ...
|
|
def __contains__(self, key: K, /) -> bool: ...
|
|
def __iter__(self) -> Iterator[K]: ...
|
|
def __len__(self) -> int: ...
|
|
def keys(self) -> KeysView[K]: ...
|
|
def items(self) -> ItemsView[K, V]: ...
|
|
def pop(self, key: Never | K, /) -> V: ...
|
|
|
|
# def popitem(self) -> tuple[K, V]: ...
|
|
|
|
# def clear(self) -> None: ...
|
|
|
|
__required_keys__: ClassVar[frozenset[str]]
|
|
__optional_keys__: ClassVar[frozenset[str]]
|
|
|
|
|
|
# class Test(TypedDict):
|
|
# var: str
|
|
#
|
|
#
|
|
# x = Test(var="test")
|
|
#
|
|
#
|
|
# def is_typed_dict_test(obj: TypedYamlDict[object, object]) -> None:
|
|
# print(obj)
|
|
# pass
|
|
#
|
|
#
|
|
# is_typed_dict_test(x)
|
|
|
|
type T_Primitive = None | bool | int | str
|
|
|
|
type T_PrimIters = tuple[T_Prim, ...] | list[T_Prim] | Set[T_Prim] | Iterator[T_Prim]
|
|
type T_PrimDict = MutableMapping[T_Primitive, T_Prim]
|
|
type T_Prim = T_Primitive | T_PrimIters | T_PrimDict
|
|
|
|
type T_YamlIters = tuple[T_Yaml, ...] | list[T_Yaml] | Set[T_Yaml] | Iterator[T_Yaml]
|
|
type T_YamlDict = MutableMapping[str, T_Yaml]
|
|
type T_YamlRW = T_YamlIters | T_YamlDict
|
|
type T_Yaml = T_Primitive | T_YamlRW
|
|
|
|
|
|
type T_YamlPostDict = TypedYamlDict[str, T_YamlPost]
|
|
type T_YamlPostRes = tuple[T_YamlPost, ...] | T_YamlPostDict
|
|
type T_YamlPost = T_Primitive | T_YamlPostRes
|
|
|
|
|
|
def get_union_types(annotations: UnionType) -> Iterator[type]:
|
|
for annotation in get_args(annotations): # pyright: ignore[reportAny]
|
|
if isinstance(annotation, TypeAliasType):
|
|
annotation = annotation.__value__ # pyright: ignore[reportAny]
|
|
if isinstance(annotation, UnionType):
|
|
yield from get_union_types(annotation)
|
|
continue
|
|
yield get_types(annotation) # pyright: ignore[reportAny]
|
|
|
|
|
|
@overload
|
|
def get_types(annotation: UnionType) -> tuple[type]:
|
|
pass
|
|
|
|
|
|
@overload
|
|
def get_types(annotation: GenericAlias) -> type:
|
|
pass
|
|
|
|
|
|
@overload
|
|
def get_types(annotation: TypeAliasType) -> type | tuple[type, ...]:
|
|
pass
|
|
|
|
|
|
def get_types(
|
|
annotation: TypeAliasType | GenericAlias | UnionType,
|
|
) -> type | tuple[type, ...]:
|
|
if isinstance(annotation, TypeAliasType):
|
|
annotation = annotation.__value__ # pyright: ignore[reportAny]
|
|
if isinstance(annotation, GenericAlias):
|
|
return get_origin(annotation)
|
|
if isinstance(annotation, UnionType):
|
|
return tuple(get_union_types(annotation))
|
|
return cast(type, annotation) # pyright: ignore[reportInvalidCast]
|