msgspec
msgspec copied to clipboard
Structs with dictionaries with enum keys do not encode
Description
On msgspec 0.19.0, I get this behaviour:
from typing import Dict
from enum import Enum
import msgspec
class SomeEnum(Enum):
EXAMPLE_VALUE = "hello"
class SomeModel(msgspec.Struct):
values: Dict[SomeEnum, int] = {}
def test_msgspec_logic():
a = SomeModel()
a.values[SomeEnum.EXAMPLE_VALUE] = 2
msgspec.json.encode(a)
if __name__ == "__main__":
test_msgspec_logic()
I get this error:
(venv) abone@fedora:~/mflu/mflu/tests$ python3 test_models.py
Traceback (most recent call last):
File "/home/abone/mflu/mflu/tests/test_models.py", line 20, in <module>
test_msgspec_logic()
~~~~~~~~~~~~~~~~~~^^
File "/home/abone/mflu/mflu/tests/test_models.py", line 17, in test_msgspec_logic
msgspec.json.encode(a)
~~~~~~~~~~~~~~~~~~~^^^
TypeError: Only dicts with str-like or number-like keys are supported
This used to work in 0.18.6 on Python 3.12, but with 0.19.0 on Python 3.13, it does not.
I am currently making a game that relies a lot on this behaviour, so I will gladly help with narrowing the problem down or whatever else I can do.
I just confirmed that this behaviour is tied to msgspec 0.19.0 itself, running 0.19.0 in Python 3.12 has the same bug.
I can also produce in Python 3.11, msgspec==0.19.0 fails while msgspec==0.18.6 passes without issue. Decoding also seems to work fine. Seems like a reasonably significant regression
@ahrnbom
Got curious and tried something:
from typing import Dict
from enum import Enum
import msgspec
# inherit from both str and Enum
class SomeEnum(str, Enum):
EXAMPLE_VALUE = "hello"
class SomeModel(msgspec.Struct):
values: Dict[SomeEnum, int] = {}
def test_msgspec_logic():
a = SomeModel()
a.values[SomeEnum.EXAMPLE_VALUE] = 2
msgspec.json.encode(a)
if __name__ == "__main__":
test_msgspec_logic()
It does not count as a fix since msgspec should still work with native Enum (I guess at least), but inheriting from str (since your enumerator is a string type) could be used as a workaround
Here's a PR that fixes this particular problem: https://github.com/jcrist/msgspec/pull/838