112 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			112 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Python
		
	
	
	
import dataclasses
 | 
						|
import typing
 | 
						|
from contextlib import suppress
 | 
						|
 | 
						|
from .macros import PY_36, PY_37, PY_38, PY_39
 | 
						|
 | 
						|
DataClassDictMixinPath = "mashumaro.serializer.base.dict.DataClassDictMixin"
 | 
						|
 | 
						|
 | 
						|
def get_type_origin(t):
 | 
						|
    try:
 | 
						|
        if PY_36:
 | 
						|
            return t.__extra__
 | 
						|
        elif PY_37 or PY_38 or PY_39:
 | 
						|
            return t.__origin__
 | 
						|
    except AttributeError:
 | 
						|
        return t
 | 
						|
 | 
						|
 | 
						|
def type_name(t):
 | 
						|
    if is_generic(t):
 | 
						|
        return str(t)
 | 
						|
    else:
 | 
						|
        try:
 | 
						|
            return f"{t.__module__}.{t.__qualname__}"
 | 
						|
        except AttributeError:
 | 
						|
            return str(t)
 | 
						|
 | 
						|
 | 
						|
def is_special_typing_primitive(t):
 | 
						|
    try:
 | 
						|
        issubclass(t, object)
 | 
						|
        return False
 | 
						|
    except TypeError:
 | 
						|
        return True
 | 
						|
 | 
						|
 | 
						|
def is_generic(t):
 | 
						|
    if PY_37 or PY_38 or PY_39:
 | 
						|
        # noinspection PyProtectedMember
 | 
						|
        # noinspection PyUnresolvedReferences
 | 
						|
        return t.__class__ is typing._GenericAlias
 | 
						|
    elif PY_36:
 | 
						|
        # noinspection PyUnresolvedReferences
 | 
						|
        return issubclass(t.__class__, typing.GenericMeta)
 | 
						|
    else:
 | 
						|
        raise NotImplementedError
 | 
						|
 | 
						|
 | 
						|
def is_union(t):
 | 
						|
    try:
 | 
						|
        return t.__origin__ is typing.Union
 | 
						|
    except AttributeError:
 | 
						|
        return False
 | 
						|
 | 
						|
 | 
						|
def is_type_var(t):
 | 
						|
    return hasattr(t, "__constraints__")
 | 
						|
 | 
						|
 | 
						|
def is_class_var(t):
 | 
						|
    if PY_36:
 | 
						|
        return (
 | 
						|
            is_special_typing_primitive(t) and type(t).__name__ == "_ClassVar"
 | 
						|
        )
 | 
						|
    if PY_37 or PY_38 or PY_39:
 | 
						|
        return get_type_origin(t) is typing.ClassVar
 | 
						|
    else:
 | 
						|
        raise NotImplementedError
 | 
						|
 | 
						|
 | 
						|
def is_init_var(t):
 | 
						|
    if PY_36 or PY_37:
 | 
						|
        return get_type_origin(t) is dataclasses.InitVar
 | 
						|
    elif PY_38 or PY_39:
 | 
						|
        return isinstance(t, dataclasses.InitVar)
 | 
						|
    else:
 | 
						|
        raise NotImplementedError
 | 
						|
 | 
						|
 | 
						|
def get_class_that_define_method(method_name, cls):
 | 
						|
    for cls in cls.__mro__:
 | 
						|
        if method_name in cls.__dict__:
 | 
						|
            return cls
 | 
						|
 | 
						|
 | 
						|
def is_dataclass_dict_mixin(t):
 | 
						|
    return type_name(t) == DataClassDictMixinPath
 | 
						|
 | 
						|
 | 
						|
def is_dataclass_dict_mixin_subclass(t):
 | 
						|
    with suppress(AttributeError):
 | 
						|
        for cls in t.__mro__:
 | 
						|
            if is_dataclass_dict_mixin(cls):
 | 
						|
                return True
 | 
						|
    return False
 | 
						|
 | 
						|
 | 
						|
__all__ = [
 | 
						|
    "get_type_origin",
 | 
						|
    "type_name",
 | 
						|
    "is_special_typing_primitive",
 | 
						|
    "is_generic",
 | 
						|
    "is_union",
 | 
						|
    "is_type_var",
 | 
						|
    "is_class_var",
 | 
						|
    "is_init_var",
 | 
						|
    "get_class_that_define_method",
 | 
						|
    "is_dataclass_dict_mixin",
 | 
						|
    "is_dataclass_dict_mixin_subclass",
 | 
						|
]
 |