Skip to content

Commit

Permalink
handle JSON serialisation with compound keys
Browse files Browse the repository at this point in the history
  • Loading branch information
rhayes777 committed Sep 27, 2024
1 parent 760d489 commit 17d8061
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 3 deletions.
35 changes: 32 additions & 3 deletions autoconf/dictable.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

logger = logging.getLogger(__name__)


np_type_map = {
"bool": "bool_",
}
Expand Down Expand Up @@ -47,6 +46,22 @@ def is_array(obj) -> bool:
return False


def compound_key_dict(obj):
"""
Converts a dictionary with compound keys to a dictionary with a single key.
"""
return {
"type": "compound_dict",
"arguments": [
{
"key": to_dict(key),
"value": to_dict(value),
}
for key, value in obj.items()
],
}


def to_dict(obj, filter_args: Tuple[str, ...] = ()) -> dict:
if isinstance(obj, (int, float, str, bool, type(None))):
return obj
Expand Down Expand Up @@ -101,14 +116,20 @@ def to_dict(obj, filter_args: Tuple[str, ...] = ()) -> dict:
if isinstance(obj, tuple):
return {"type": "tuple", "values": list(map(to_dict, obj))}
if isinstance(obj, dict):
return {
result = {
"type": "dict",
"arguments": {
key: to_dict(value)
for key, value in obj.items()
if key not in filter_args
},
}
try:
json.dumps(result)
return result
except TypeError:
return compound_key_dict(obj)

if obj.__class__.__name__ == "method":
return to_dict(obj())
if obj.__class__.__module__ == "builtins":
Expand Down Expand Up @@ -297,7 +318,15 @@ def from_dict(dictionary, **kwargs):
if type_ == "tuple":
return tuple(map(from_dict, dictionary["values"]))
if type_ == "dict":
return {key: from_dict(value, **kwargs) for key, value in dictionary.items()}
return {
key: from_dict(value, **kwargs)
for key, value in dictionary["arguments"].items()
}
if type_ == "compound_dict":
return {
from_dict(item["key"], **kwargs): from_dict(item["value"], **kwargs)
for item in dictionary["arguments"]
}

if type_ == "type":
return get_class(dictionary["class_path"])
Expand Down
7 changes: 7 additions & 0 deletions test_autoconf/test_dictable.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,10 @@ def test_int64_slice():
)
)
)


def test_compound_key():
d = {(1, 2): 1}

string = json.dumps(to_dict(d))
assert d == from_dict(json.loads(string))

0 comments on commit 17d8061

Please sign in to comment.