jcrist / msgspec

A fast serialization and validation library, with builtin support for JSON, MessagePack, YAML, and TOML
https://jcristharif.com/msgspec/
BSD 3-Clause "New" or "Revised" License
2.44k stars 75 forks source link

`msgspec.convert` seems to not call `dec_hook` for custom dict key #775

Open the-forest-tree opened 4 days ago

the-forest-tree commented 4 days ago

Description

Hi,

I am not sure if this is really a bug it might be expected behavior depending of how different json.decode is from convert

The issue I am facing is that dec_hook is not called for a custom dict key when using convert

I refer to the tests suite that was added for this issue

from msgspec import convert, json

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 __repr__(self):
        return f"Custom({self.value})"

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

# This works as expected
json.decode('{"a": true, "b": false}', type=dict[Custom, bool], dec_hook=dec_hook)
# Output: {Custom(a): True, Custom(b): False}

# This does not return Custom as dict keys
convert(dict(a=True, b=False), dict[Custom, bool], dec_hook=dec_hook)
# Output: {'a': True, 'b': False}

# But works for dict values
convert(dict(a=True, b=False), dict[Custom, Custom], dec_hook=dec_hook)
# Output: {'a': Custom(True), 'b': Custom(False)}