-
-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can immutable dataclasses be hashed as dictionary keys? #160
Comments
Ok, I kind of gotten it to work with SerializableType if I drop the dataclass decorator on the NodeIdentifier, but printing it out isn't pretty. It would be really great dataclass serialization as keys was supported. |
Hi @user293811
Let me explain why you see this exception. All the supported serialization formats (json, msgpack, yaml, toml) are kind of dictionary based and allow only simple immutable types to be keys. By default dataclasses are serialized into dicts which can't be dictionary keys because they are mutable. NamedTuples are serialized into lists or dicts depending on the engine you choose (default is lists), so they can't be dictionary keys too. Taking all above into account, if you want to use dataclasses or named tuples as keys in your structure, you should provide a custom serialization (and deserialization for the reverse) method that will convert them into simple immutable object like string. As you have noticed, SerializableType is one of the available approaches to providing a custom serialization method. However, in the current implementation of mappings serialization there is still a code checking that the key is not a dataclass: mashumaro/mashumaro/core/meta/types/common.py Lines 138 to 147 in 92d539c
This is why you were forced to remove the dataclass decorator. To workaround this problem we can extend this condition by checking SerializableType subclassing. Serialization will fail with The proposed fix looks trivial. I can do it but if you're willing to contribute yourself, PR is welcome. Edit: Oh, I just noticed that using forward references breaks this fix on python 3.8. It would be better if I looked at it myself. |
This looks like another problem related to ForwardRef support. I managed to support forward references to TypedDicts here but this is something new. Could you provide a reproducible example with details in a separate issue? I'd like to cover as many cases as possible. |
I modified the process of checking to check if the key type is Hashable. This alteration will also trigger an If you remove mashumaro.exceptions.UnserializableField: Field "network" of type dict[NodeIdentifier, NodeConfig] in NetworkConfig is not serializable: NodeIdentifier is unhashable and can not be used as a key |
Is your feature request related to a problem? Please describe.
I'd like to be able to hash (immutable) dataclass objects as keys. Currently I have a field which contains a dict for which the keys are a dataclass object. I get the following error:
I tried subclassing NamedTuple and got:
Describe the solution you'd like
Would be great if I could have immutable dataclasses as keys.
Describe alternatives you've considered
Tried named tuples, which did not work.
Additional context
This is my intended usecase:
The text was updated successfully, but these errors were encountered: