Kano001's picture
Upload 919 files
375a1cf verified
raw
history blame
7.54 kB
import sys
from attr import (
Factory,
NOTHING,
fields as attrs_fields,
Attribute,
)
from dataclasses import (
MISSING,
is_dataclass,
fields as dataclass_fields,
)
from typing import (
Any,
Dict,
FrozenSet,
List,
Mapping as TypingMapping,
MutableMapping as TypingMutableMapping,
MutableSequence as TypingMutableSequence,
MutableSet as TypingMutableSet,
Sequence as TypingSequence,
Set as TypingSet,
Tuple,
)
version_info = sys.version_info[0:3]
is_py37 = version_info[:2] == (3, 7)
is_py38 = version_info[:2] == (3, 8)
is_py39_plus = version_info[:2] >= (3, 9)
if is_py37:
def get_args(cl):
return cl.__args__
def get_origin(cl):
return getattr(cl, "__origin__", None)
else:
from typing import get_args, get_origin # NOQA
def has(cls):
return hasattr(cls, "__attrs_attrs__") or hasattr(
cls, "__dataclass_fields__"
)
def has_with_generic(cls):
"""Test whether the class if a normal or generic attrs or dataclass."""
return has(cls) or has(get_origin(cls))
def fields(type):
try:
return type.__attrs_attrs__
except AttributeError:
try:
return dataclass_fields(type)
except AttributeError:
raise Exception("Not an attrs or dataclass class.")
def adapted_fields(type) -> List[Attribute]:
"""Return the attrs format of `fields()` for attrs and dataclasses."""
if is_dataclass(type):
return [
Attribute(
attr.name,
attr.default
if attr.default is not MISSING
else (
Factory(attr.default_factory)
if attr.default_factory is not MISSING
else NOTHING
),
None,
True,
None,
True,
attr.init,
True,
type=attr.type,
)
for attr in dataclass_fields(type)
]
else:
return attrs_fields(type)
if is_py37 or is_py38:
Set = TypingSet
MutableSet = TypingMutableSet
Sequence = TypingSequence
MutableSequence = TypingMutableSequence
MutableMapping = TypingMutableMapping
Mapping = TypingMapping
from typing import Union, _GenericAlias
def is_annotated(_):
return False
def is_tuple(type):
return type in (Tuple, tuple) or (
type.__class__ is _GenericAlias
and issubclass(type.__origin__, Tuple)
)
def is_union_type(obj):
return (
obj is Union
or isinstance(obj, _GenericAlias)
and obj.__origin__ is Union
)
def is_sequence(type: Any) -> bool:
return type in (List, list, Tuple, tuple) or (
type.__class__ is _GenericAlias
and type.__origin__ is not Union
and issubclass(type.__origin__, TypingSequence)
)
def is_mutable_set(type):
return type is set or (
type.__class__ is _GenericAlias
and issubclass(type.__origin__, MutableSet)
)
def is_frozenset(type):
return type is frozenset or (
type.__class__ is _GenericAlias
and issubclass(type.__origin__, FrozenSet)
)
def is_mapping(type):
return type in (TypingMapping, dict) or (
type.__class__ is _GenericAlias
and issubclass(type.__origin__, TypingMapping)
)
bare_list_args = List.__args__
bare_seq_args = TypingSequence.__args__
bare_mapping_args = TypingMapping.__args__
bare_dict_args = Dict.__args__
bare_mutable_seq_args = TypingMutableSequence.__args__
def is_bare(type):
args = type.__args__
return (
args == bare_list_args
or args == bare_seq_args
or args == bare_mapping_args
or args == bare_dict_args
or args == bare_mutable_seq_args
)
else:
# 3.9+
from typing import (
Union,
_GenericAlias,
_SpecialGenericAlias,
_UnionGenericAlias,
_AnnotatedAlias,
)
from collections.abc import (
MutableSequence as AbcMutableSequence,
Sequence as AbcSequence,
MutableSet as AbcMutableSet,
Set as AbcSet,
MutableMapping as AbcMutableMapping,
Mapping as AbcMapping,
)
Set = AbcSet
MutableSet = AbcMutableSet
Sequence = AbcSequence
MutableSequence = AbcMutableSequence
MutableMapping = AbcMutableMapping
Mapping = AbcMapping
def is_annotated(type) -> bool:
return getattr(type, "__class__", None) is _AnnotatedAlias
def is_tuple(type):
return (
type in (Tuple, tuple)
or (
type.__class__ is _GenericAlias
and issubclass(type.__origin__, Tuple)
)
or (getattr(type, "__origin__", None) is tuple)
)
def is_union_type(obj):
return (
obj is Union
or isinstance(obj, _UnionGenericAlias)
and obj.__origin__ is Union
)
def is_sequence(type: Any) -> bool:
origin = getattr(type, "__origin__", None)
return (
type
in (
List,
list,
TypingSequence,
TypingMutableSequence,
AbcMutableSequence,
tuple,
)
or (
type.__class__ is _GenericAlias
and (
(origin is not tuple)
and issubclass(
origin,
TypingSequence,
)
or origin is tuple
and type.__args__[1] is ...
)
)
or (origin in (list, AbcMutableSequence, AbcSequence))
or (origin is tuple and type.__args__[1] is ...)
)
def is_mutable_set(type):
return (
type in (TypingSet, TypingMutableSet, set)
or (
type.__class__ is _GenericAlias
and issubclass(type.__origin__, TypingMutableSet)
)
or (
getattr(type, "__origin__", None)
in (set, AbcMutableSet, AbcSet)
)
)
def is_frozenset(type):
return (
type in (FrozenSet, frozenset)
or (
type.__class__ is _GenericAlias
and issubclass(type.__origin__, FrozenSet)
)
or (getattr(type, "__origin__", None) is frozenset)
)
def is_bare(type):
return isinstance(type, _SpecialGenericAlias) or (
not hasattr(type, "__origin__") and not hasattr(type, "__args__")
)
def is_mapping(type):
return (
type
in (
TypingMapping,
Dict,
TypingMutableMapping,
dict,
AbcMutableMapping,
)
or (
type.__class__ is _GenericAlias
and issubclass(type.__origin__, TypingMapping)
)
or (
getattr(type, "__origin__", None)
in (dict, AbcMutableMapping, AbcMapping)
)
or issubclass(type, dict)
)
def is_generic(obj):
return isinstance(obj, _GenericAlias)