Created
May 8, 2023 00:33
-
-
Save carlosplanchon/7c3c3ac5189dc0ca746af00f5d030f6a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import attrs | |
import cattrs | |
import copy | |
import json | |
from typing import Any, Callable | |
################### | |
# UNSTRUCTURE # | |
################### | |
def is_attrs_obj(obj: Callable) -> bool: | |
return hasattr(obj, "__attrs_attrs__") | |
def aux_unstructure_dict(d: dict[Any]) -> None: | |
to_add = {} | |
to_remove = [] | |
for k, v in d.items(): | |
if isinstance(v, dict): | |
aux_unstructure_dict(d=v) | |
if is_attrs_obj(obj=k): | |
converted_k = json.dumps(cattrs.unstructure(k)) | |
to_add[converted_k] = v | |
to_remove.append(k) | |
d.update(to_add) | |
for k in to_remove: | |
d.pop(k) | |
return None | |
def unstructure_dict(d: dict[Any]) -> dict[Any]: | |
d_copy = copy.deepcopy(d) | |
aux_unstructure_dict(d=d_copy) | |
return d_copy | |
################# | |
# STRUCTURE # | |
################# | |
def get_attrs_obj_attrs(obj: Callable) -> list[str]: | |
if hasattr(obj, "__attrs_attrs__") is False: | |
raise AssertionError("obj is not an attrs obj.") | |
attr_names: list[str] = [ | |
attr.name for attr in obj.__attrs_attrs__\ | |
if attr.init is True | |
] | |
return attr_names | |
def is_structurable(key: Any, target_obj: Any) -> bool: | |
attr_names: list[str] = get_attrs_obj_attrs(obj=target_obj) | |
all_tagnames_in_key: bool = all( | |
[f'"{attr}":' in key for attr in attr_names]) | |
return all_tagnames_in_key | |
def structure_key(key: Any, target_obj: Any) -> Any: | |
key_dict: dict[str, Any] = json.loads(key) | |
structured_key = cattrs.structure(key_dict, target_obj) | |
return structured_key | |
def eval_dict_key(key: Any, target_obj: Any) -> Any: | |
if is_structurable(key=key, target_obj=target_obj): | |
return key | |
structured_key = structure_key(key=key, target_obj=target_obj) | |
return structured_key | |
def aux_structure_dict( | |
unstructured_d: dict[Any], | |
target_obj: Callable | |
) -> None: | |
to_add = {} | |
to_remove = [] | |
for k, v in unstructured_d.items(): | |
if isinstance(v, dict): | |
aux_structure_dict(unstructured_d=v, target_obj=target_obj) | |
if is_structurable(key=k, target_obj=target_obj): | |
structured_key = structure_key(key=k, target_obj=target_obj) | |
to_add[structured_key] = v | |
to_remove.append(k) | |
unstructured_d.update(to_add) | |
for k in to_remove: | |
unstructured_d.pop(k) | |
return None | |
def structure_dict( | |
unstructured_d: dict[Any], | |
target_obj: Callable | |
) -> dict[Any]: | |
unstructured_d_copy = copy.deepcopy(unstructured_d) | |
aux_structure_dict( | |
unstructured_d=unstructured_d_copy, | |
target_obj=target_obj | |
) | |
return unstructured_d_copy |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment