https://github.com/python/cpython/commit/7b0bd9eb91ce0d4546c6d6f537eea558d1bf5fc8
commit: 7b0bd9eb91ce0d4546c6d6f537eea558d1bf5fc8
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2026-02-21T12:22:47+01:00
summary:
gh-141510, PEP 814: Add frozendict support to json (#144903)
files:
A Misc/NEWS.d/next/Library/2026-02-17-11-15-17.gh-issue-141510.ZmqEUb.rst
M Lib/json/encoder.py
M Lib/test/test_json/test_dump.py
M Modules/_json.c
diff --git a/Lib/json/encoder.py b/Lib/json/encoder.py
index 4c70e8b75ed132..718b3254241c56 100644
--- a/Lib/json/encoder.py
+++ b/Lib/json/encoder.py
@@ -79,7 +79,7 @@ class JSONEncoder(object):
+-------------------+---------------+
| Python | JSON |
+===================+===============+
- | dict | object |
+ | dict, frozendict | object |
+-------------------+---------------+
| list, tuple | array |
+-------------------+---------------+
@@ -308,7 +308,7 @@ def _iterencode_list(lst, _current_indent_level):
yield buf
if isinstance(value, (list, tuple)):
chunks = _iterencode_list(value, _current_indent_level)
- elif isinstance(value, dict):
+ elif isinstance(value, (dict, frozendict)):
chunks = _iterencode_dict(value, _current_indent_level)
else:
chunks = _iterencode(value, _current_indent_level)
@@ -395,7 +395,7 @@ def _iterencode_dict(dct, _current_indent_level):
else:
if isinstance(value, (list, tuple)):
chunks = _iterencode_list(value, _current_indent_level)
- elif isinstance(value, dict):
+ elif isinstance(value, (dict, frozendict)):
chunks = _iterencode_dict(value, _current_indent_level)
else:
chunks = _iterencode(value, _current_indent_level)
@@ -429,7 +429,7 @@ def _iterencode(o, _current_indent_level):
yield _floatstr(o)
elif isinstance(o, (list, tuple)):
yield from _iterencode_list(o, _current_indent_level)
- elif isinstance(o, dict):
+ elif isinstance(o, (dict, frozendict)):
yield from _iterencode_dict(o, _current_indent_level)
else:
if markers is not None:
diff --git a/Lib/test/test_json/test_dump.py b/Lib/test/test_json/test_dump.py
index 39470754003bb6..9880698455ca5e 100644
--- a/Lib/test/test_json/test_dump.py
+++ b/Lib/test/test_json/test_dump.py
@@ -12,6 +12,18 @@ def test_dump(self):
def test_dumps(self):
self.assertEqual(self.dumps({}), '{}')
+ def test_dumps_dict(self):
+ self.assertEqual(self.dumps({'x': 1, 'y': 2}),
+ '{"x": 1, "y": 2}')
+ self.assertEqual(self.dumps(frozendict({'x': 1, 'y': 2})),
+ '{"x": 1, "y": 2}')
+ lst = [{'x': 1}, frozendict(y=2)]
+ self.assertEqual(self.dumps(lst),
+ '[{"x": 1}, {"y": 2}]')
+ data = {'x': dict(a=1), 'y': frozendict(b=2)}
+ self.assertEqual(self.dumps(data),
+ '{"x": {"a": 1}, "y": {"b": 2}}')
+
def test_dump_skipkeys(self):
v = {b'invalid_key': False, 'valid_key': True}
with self.assertRaises(TypeError):
diff --git
a/Misc/NEWS.d/next/Library/2026-02-17-11-15-17.gh-issue-141510.ZmqEUb.rst
b/Misc/NEWS.d/next/Library/2026-02-17-11-15-17.gh-issue-141510.ZmqEUb.rst
new file mode 100644
index 00000000000000..59a8b4165cdd15
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-02-17-11-15-17.gh-issue-141510.ZmqEUb.rst
@@ -0,0 +1,2 @@
+The :mod:`json` module now supports the :class:`frozendict` type. Patch by
+Victor Stinner.
diff --git a/Modules/_json.c b/Modules/_json.c
index c7e62c4fe55c64..cbede8f44dc065 100644
--- a/Modules/_json.c
+++ b/Modules/_json.c
@@ -1599,7 +1599,7 @@ encoder_listencode_obj(PyEncoderObject *s,
PyUnicodeWriter *writer,
_Py_LeaveRecursiveCall();
return rv;
}
- else if (PyDict_Check(obj)) {
+ else if (PyAnyDict_Check(obj)) {
if (_Py_EnterRecursiveCall(" while encoding a JSON object"))
return -1;
rv = encoder_listencode_dict(s, writer, obj, indent_level,
indent_cache);
@@ -1838,7 +1838,7 @@ encoder_listencode_dict(PyEncoderObject *s,
PyUnicodeWriter *writer,
goto bail;
}
- if (s->sort_keys || !PyDict_CheckExact(dct)) {
+ if (s->sort_keys || !PyAnyDict_CheckExact(dct)) {
PyObject *items = PyMapping_Items(dct);
if (items == NULL || (s->sort_keys && PyList_Sort(items) < 0)) {
Py_XDECREF(items);
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]