Skip to content

Instantly share code, notes, and snippets.

@carlosplanchon
Created May 8, 2023 00:33
Show Gist options
  • Save carlosplanchon/7c3c3ac5189dc0ca746af00f5d030f6a to your computer and use it in GitHub Desktop.
Save carlosplanchon/7c3c3ac5189dc0ca746af00f5d030f6a to your computer and use it in GitHub Desktop.
#!/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