Function to extract both keys and Python object types from specially formatted dictionary keys and make
their respective values into Python objects of those types.
Parameters: |
-
json_dict
(Dict[str, Any] )
–
JSON dictionary that may contain keys in the format type.key_name (e.g.
path.root_directory) with corresponding string values representing Python objects of that type.
|
Returns: |
-
Dict[str, Any]
–
dict[str, Any]: Dictionary with both keys and Python object values derived from specially formatted JSON
dictionary keys.
|
Source code in src/pyobjson/data.py
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97 | def extract_typed_key_value_pairs(json_dict: Dict[str, Any]) -> Dict[str, Any]:
"""Function to extract both keys and Python object types from specially formatted dictionary keys and make
their respective values into Python objects of those types.
Args:
json_dict (Dict[str, Any]): JSON dictionary that may contain keys in the format type.key_name (e.g.
path.root_directory) with corresponding string values representing Python objects of that type.
Returns:
dict[str, Any]: Dictionary with both keys and Python object values derived from specially formatted JSON
dictionary keys.
"""
derived_key_value_pairs = {}
for key, value in json_dict.items():
# check if key is formatted with a single "." to indicate a value type
if key.count(".") == 1:
type_name, key = key.split(".")
type_category = None
if type_name.count(":") == 1:
type_category, type_name = type_name.split(":")
if type_category == "collection":
if type_name == "dict":
# do nothing because JSON supports dictionaries
pass
elif type_name == "list":
# do nothing because JSON supports lists
pass
elif type_name == "set":
value = set(value)
elif type_name == "tuple":
value = tuple(value)
elif type_name == "path": # handle posix paths
value = Path(value)
elif type_name == "callable": # handle callables (functions, methods, etc.)
# extract the callable components from a value with format module.callable::arg1:type1,arg2:type2
callable_path, callable_args = value.split("::", 1)
# extract the callable module and name
module, callable_name = callable_path.rsplit(".", 1)
# use the callable module and name to import the callable itself and set it to the value
value = getattr(import_module(module), callable_name)
elif type_name == "datetime": # handle datetime objects
value = datetime.fromisoformat(value)
else:
raise ValueError(f"JSON data ({key}: {value}) is not compatible with pyobjson.")
derived_key_value_pairs[key] = value
else:
# add key-value pair without modification if key is not formatted with a single "." to indicate a value type
derived_key_value_pairs[key] = value
return derived_key_value_pairs
|