Skip to content

Commit

Permalink
Support JSON decoding dicts with custom key types
Browse files Browse the repository at this point in the history
  • Loading branch information
jcrist committed Dec 5, 2023
1 parent 443649e commit 330c00d
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
3 changes: 3 additions & 0 deletions msgspec/_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -16529,6 +16529,9 @@ json_decode_dict_key_fallback(
else {
out = PyUnicode_DecodeUTF8(view, size, NULL);
}
if (MS_UNLIKELY(type->types & (MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC))) {
return ms_decode_custom(out, self->dec_hook, type, path);
}
return ms_check_str_constraints(out, type, path);
}
if (type->types & (
Expand Down
21 changes: 21 additions & 0 deletions tests/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -2115,6 +2115,27 @@ def enc_hook(x):
with pytest.raises(RecursionError):
msgspec.json.encode({Custom("x"): 1}, enc_hook=lambda x: x)

def test_decode_dict_custom_key(self):
class Custom:
def __init__(self, value):
self.value = value

def __hash__(self):
return hash(self.value)

def __eq__(self, other):
return self.value == other.value

def dec_hook(typ, obj):
if typ == Custom:
return Custom(obj)
raise NotImplementedError

msg = b'{"a":1,"b":2}'

obj = msgspec.json.decode(msg, type=Dict[Custom, int], dec_hook=dec_hook)
assert obj == {Custom("a"): 1, Custom("b"): 2}

@pytest.mark.parametrize(
"s, error",
[
Expand Down

0 comments on commit 330c00d

Please sign in to comment.