From 161ed33a4386fd00c0b9496deb716a683d29c839 Mon Sep 17 00:00:00 2001 From: da-woods Date: Sun, 31 May 2026 21:58:23 +0100 Subject: [PATCH 1/3] Update mapping methods in abstract.c to accept frozendict as well as dict Specifically `PyMapping_GetOptionalItem`, `PyMapping_Keys`, `PyMapping_Values` and `PyMapping_Items`. --- Objects/abstract.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Objects/abstract.c b/Objects/abstract.c index 48b3137152e7bf3..28f751965f36b94 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -208,7 +208,7 @@ PyObject_GetItem(PyObject *o, PyObject *key) int PyMapping_GetOptionalItem(PyObject *obj, PyObject *key, PyObject **result) { - if (PyDict_CheckExact(obj)) { + if (PyAnyDict_CheckExact(obj)) { return PyDict_GetItemRef(obj, key, result); } @@ -2462,7 +2462,7 @@ PyMapping_Keys(PyObject *o) if (o == NULL) { return null_error(); } - if (PyDict_CheckExact(o)) { + if (PyAnyDict_CheckExact(o)) { return PyDict_Keys(o); } return method_output_as_list(o, &_Py_ID(keys)); @@ -2474,7 +2474,7 @@ PyMapping_Items(PyObject *o) if (o == NULL) { return null_error(); } - if (PyDict_CheckExact(o)) { + if (PyAnyDict_CheckExact(o)) { return PyDict_Items(o); } return method_output_as_list(o, &_Py_ID(items)); @@ -2486,7 +2486,7 @@ PyMapping_Values(PyObject *o) if (o == NULL) { return null_error(); } - if (PyDict_CheckExact(o)) { + if (PyAnyDict_CheckExact(o)) { return PyDict_Values(o); } return method_output_as_list(o, &_Py_ID(values)); From 5dbcd9a0df20b560bb6b08c1468e984da310c93f Mon Sep 17 00:00:00 2001 From: da-woods Date: Thu, 18 Jun 2026 19:15:00 +0100 Subject: [PATCH 2/3] Add C API tests --- Lib/test/test_capi/test_abstract.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_capi/test_abstract.py b/Lib/test/test_capi/test_abstract.py index 3a2ed9f5db82f0f..e455a8636209247 100644 --- a/Lib/test/test_capi/test_abstract.py +++ b/Lib/test/test_capi/test_abstract.py @@ -411,6 +411,11 @@ def test_mapping_getoptionalitem(self): self.assertEqual(getitem(dct2, 'a'), 1) self.assertEqual(getitem(dct2, 'b'), KeyError) + frozendct = frozendict(dct) + self.assertEqual(getitem(frozendct, 'a'), 1) + self.assertEqual(getitem(frozendct, 'b'), KeyError) + self.assertEqual(getitem(frozendct, '\U0001f40d'), 2) + self.assertEqual(getitem(['a', 'b', 'c'], 1), 'b') self.assertRaises(TypeError, getitem, 42, 'a') @@ -431,6 +436,11 @@ def test_mapping_getoptionalitemstring(self): self.assertEqual(getitemstring(dct2, b'a'), 1) self.assertEqual(getitemstring(dct2, b'b'), KeyError) + frozendct = frozendict(dct) + self.assertEqual(getitemstring(frozendct, 'a'), 1) + self.assertEqual(getitemstring(frozendct, 'b'), KeyError) + self.assertEqual(getitemstring(frozendct, '\U0001f40d'.encode()), 2) + self.assertRaises(TypeError, getitemstring, 42, b'a') self.assertRaises(UnicodeDecodeError, getitemstring, {}, b'\xff') self.assertRaises(SystemError, getitemstring, {}, NULL) @@ -677,8 +687,10 @@ def items(self): dict_obj = {'foo': 1, 'bar': 2, 'spam': 3} for mapping in [{}, OrderedDict(), Mapping1(), Mapping2(), + frozendict(), dict_obj, OrderedDict(dict_obj), - Mapping1(dict_obj), Mapping2(dict_obj)]: + Mapping1(dict_obj), Mapping2(dict_obj), + frozendict(dict_obj)]: self.assertListEqual(_testlimitedcapi.mapping_keys(mapping), list(mapping.keys())) self.assertListEqual(_testlimitedcapi.mapping_values(mapping), From 9efaa9c551f4d4855589037a467f237cca488ed9 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Thu, 18 Jun 2026 18:24:21 +0000 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/C_API/2026-06-18-18-24-11.gh-issue-141510.-EOHJ1.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/C_API/2026-06-18-18-24-11.gh-issue-141510.-EOHJ1.rst diff --git a/Misc/NEWS.d/next/C_API/2026-06-18-18-24-11.gh-issue-141510.-EOHJ1.rst b/Misc/NEWS.d/next/C_API/2026-06-18-18-24-11.gh-issue-141510.-EOHJ1.rst new file mode 100644 index 000000000000000..c77b462e97bdd1d --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2026-06-18-18-24-11.gh-issue-141510.-EOHJ1.rst @@ -0,0 +1 @@ +Add :class:`frozendict` to the fast paths of :c:func:`PyMapping_GetOptionalItem`, :c:func:`PyMapping_Keys`, :c:func:`PyMapping_Values`, and :c:func:`PyMapping_Items`.