Skip to content

Instantly share code, notes, and snippets.

@MichaelNesterenko
Created November 13, 2024 11:06
Show Gist options
  • Save MichaelNesterenko/1b2590fbe9b20a389aa8430f30cc1b32 to your computer and use it in GitHub Desktop.
Save MichaelNesterenko/1b2590fbe9b20a389aa8430f30cc1b32 to your computer and use it in GitHub Desktop.
python dict to obj
from dataclasses import dataclass
from inspect import get_annotations
@dataclass
class MySubData:
value: str
@dataclass
class MyData:
list_value: list[MySubData]
dict_value: dict[str, MySubData]
drct_value: MySubData
def is_builtin(cls: type) -> bool:
return cls.__module__ == object.__module__
def raise_(e: BaseException) -> None:
raise e
def to_raw_type(cls: type) -> type:
return getattr(cls, "__origin__", cls)
def isinstance_(obj : object, cls: type) -> bool:
return isinstance(obj, to_raw_type(cls))
def get_class_args[T](cls: type, default: T) -> T:
return getattr(cls, "__args__", default)
def dict_to_obj[T](src: object, cls: type[T]) -> T:
if is_builtin(cls) and not isinstance_(src, cls):
raise Exception(f"incompatible src and target classes: {src.__class__} != {cls}")
map_dict = lambda src, cls: [
class_annotations:= { k: get_class_args(cls, (str, object))[1] for k in src.keys() } if to_raw_type(cls) == dict else get_annotations(cls),
raise_(Exception(f"expecting dict to map into {cls}")) if not isinstance(src, dict) else None,
raise_(Exception(f"unexpected inputs for {cls}: {diff}")) if len(diff := (src.keys() - class_annotations.keys())) > 0 else None,
{ k: dict_to_obj(v, class_annotations[k]) for k, v in src.items() }
][-1]
return (
[ dict_to_obj(v, get_class_args(cls, (object,))[0]) for v in src ] if to_raw_type(cls) == list else
map_dict(src, cls) if to_raw_type(cls) == dict else
src if is_builtin(cls) else
cls(**map_dict(src, cls))
)
print(dict_to_obj(
{
"list_value": [ { "value": "some-value1" } ],
"dict_value": { "key": { "value": "some-value2" } },
"drct_value": { "value": "some-value3" }
},
MyData
))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment