77 lines
1.9 KiB
Python
77 lines
1.9 KiB
Python
![]() |
from typing import *
|
||
|
|
||
|
from .exception import UnmarshalException
|
||
|
|
||
|
|
||
|
def init(obj: Any, d: Dict, types: Dict) -> None:
|
||
|
if d is None:
|
||
|
return
|
||
|
for k, v in d.items():
|
||
|
if not hasattr(obj, k):
|
||
|
continue
|
||
|
t: Type = types.get(k)
|
||
|
setattr(obj, k, parse(t, v, k))
|
||
|
|
||
|
|
||
|
def parse(t: Type, v: Any, field: Any) -> Any:
|
||
|
if t is None or v is None:
|
||
|
return v
|
||
|
|
||
|
type_ = type_of(t)
|
||
|
if type_ is list or type_ is tuple or type_ is List:
|
||
|
if not isinstance(v, (list, tuple)):
|
||
|
raise UnmarshalException(t, type(v), field)
|
||
|
if hasattr(t, "__args__"):
|
||
|
sub_t = t.__args__[0]
|
||
|
return [parse(sub_t, i, field) for i in v]
|
||
|
return v
|
||
|
|
||
|
if type_ is dict or type_ is Dict:
|
||
|
if not isinstance(v, dict):
|
||
|
raise UnmarshalException(t, type(v), field)
|
||
|
if hasattr(t, "__args__"):
|
||
|
val_t = t.__args__[1]
|
||
|
return {k: parse(val_t, v[k], k) for k in v}
|
||
|
return v
|
||
|
|
||
|
if type_ is set or type_ is Set:
|
||
|
if not isinstance(v, set):
|
||
|
raise UnmarshalException(t, type(v), field)
|
||
|
if hasattr(t, "__args__"):
|
||
|
sub_t = t.__args__[0]
|
||
|
return {parse(sub_t, i, field) for i in v}
|
||
|
return v
|
||
|
|
||
|
if type_ is object:
|
||
|
if not isinstance(v, dict):
|
||
|
raise UnmarshalException(t, type(v), field)
|
||
|
return t(v)
|
||
|
|
||
|
return v
|
||
|
|
||
|
|
||
|
def type_of(t: Type) -> Type:
|
||
|
if t is int or \
|
||
|
t is float or \
|
||
|
t is complex or \
|
||
|
t is str or \
|
||
|
t is bool or \
|
||
|
t is list or \
|
||
|
t is tuple or \
|
||
|
t is dict or \
|
||
|
t is set or \
|
||
|
t is Any:
|
||
|
return t
|
||
|
|
||
|
if hasattr(t, "_name"):
|
||
|
name = getattr(t, "_name")
|
||
|
if name == "Dict":
|
||
|
return Dict
|
||
|
if name == "List":
|
||
|
return List
|
||
|
if name == "Set":
|
||
|
return Set
|
||
|
return Any
|
||
|
|
||
|
return object
|