Spaces:
Running
Running
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) | |