Repository navigation
String enums in dicts/lists are json serialized differently in Python 3.15 #148241
Copy link
Copy link
Closed
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Activity
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Apr 8, 2026 - changed the title
[-]String enums in dicts/lists are serialized differently in Python 3.15[/-][+]String enums in dicts/lists are json serialized differently in Python 3.15[/+]on Apr 8, 2026 - addedstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
on Apr 8, 2026 This is because the
__str__changed, on main:>>> str(parsed['key']) 'AStringEnum.A'
whereas previously:
>>> str(parsed['key']) 'a'
Code to write the dictionary key:
- Python 3.14:
encoder_listencode_obj()=>encoder_encode_string()=>py_encode_basestring_ascii()=>ascii_escape_unicode(). This function copies the string character by character usingPyUnicode_READ(). - Python 3.15:
encoder_listencode_obj()=>encoder_writer_string()=>write_escaped_ascii(). This function callsPyUnicodeWriter_WriteStr()which callsPyObject_Str()since the dictionary key is astrsubclass and not exactly thestrtype.PyObject_Str()returnsAStringEnum.Astring.
So the difference is in
write_escaped_ascii()which now callsPyObject_Str()forstrsubclasses.- Python 3.14:
Example:
import enum import _testlimitedcapi unicode_fromobject = _testlimitedcapi.unicode_fromobject class AStringEnum(str, enum.Enum): A = "a" obj = AStringEnum.A print(f"str: {str(obj)!r}") print(f"PyUnicode_FromObject: {unicode_fromobject(obj)!r}")
Output on Python 3.15:
str: 'AStringEnum.A' PyUnicode_FromObject: 'a'- added a commit that references this issue
on Apr 8, 2026 I close the issue, it has been fixed by the change b7e1d51. Thanks for the bug report!
Reacted by Hugo van Kemenade- added a commit that references this issue
on May 19, 2026
Metadata
Metadata
Assignees
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Bug report
Bug description:
Cross posting from cattrs: python-attrs/cattrs#744
There's a difference in how Python 3.14 and Pytthon 3.15 handle json serialization of string enum values stored in other types which is exposed by cattrs tests.
I have failed to find any track record for this behavior in the available docs.
See:
Python 3.15.0a7
>>> import json >>> from enum import Enum >>> class AStringEnum(str, Enum): ... A = "a" ... >>> val = AStringEnum.A >>> json.dumps(val) '"a"' >>> in_dict = json.dumps({"key": val}) >>> in_dict '{"key": "AStringEnum.A"}' >>> parsed = json.loads(in_dict) >>> type(parsed['key']) <class 'str'> >>> repr(parsed['key']) "'AStringEnum.A'" >>> AStringEnum(parsed['key']) Traceback (most recent call last): File "<python-input-15>", line 1, in <module> AStringEnum(parsed['key']) ~~~~~~~~~~~^^^^^^^^^^^^^^^ File "/usr/lib64/python3.15/enum.py", line 732, in __call__ return cls.__new__(cls, value) ~~~~~~~~~~~^^^^^^^^^^^^ File "/usr/lib64/python3.15/enum.py", line 1221, in __new__ raise ve_exc ValueError: 'AStringEnum.A' is not a valid AStringEnumPython 3.14.3
CPython versions tested on:
3.15
Operating systems tested on:
Linux
Linked PRs