https://github.com/python/cpython/commit/727890410b71de200f2ab918827bb97e7a3c5a2b
commit: 727890410b71de200f2ab918827bb97e7a3c5a2b
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-03-30T22:06:44+03:00
summary:

gh-145056: Fix merging of collections.OrderedDict and frozendict (GH-146466)

files:
A Misc/NEWS.d/next/Library/2026-03-26-14-51-55.gh-issue-145056.QS-6l1.rst
M Lib/collections/__init__.py
M Lib/test/test_ordered_dict.py
M Objects/odictobject.c

diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py
index 2eee4c70955513..ba60df037f28cb 100644
--- a/Lib/collections/__init__.py
+++ b/Lib/collections/__init__.py
@@ -328,14 +328,14 @@ def __ior__(self, other):
         return self
 
     def __or__(self, other):
-        if not isinstance(other, dict):
+        if not isinstance(other, (dict, frozendict)):
             return NotImplemented
         new = self.__class__(self)
         new.update(other)
         return new
 
     def __ror__(self, other):
-        if not isinstance(other, dict):
+        if not isinstance(other, (dict, frozendict)):
             return NotImplemented
         new = self.__class__(other)
         new.update(self)
diff --git a/Lib/test/test_ordered_dict.py b/Lib/test/test_ordered_dict.py
index 4204a6a47d2a81..642c2722711c7c 100644
--- a/Lib/test/test_ordered_dict.py
+++ b/Lib/test/test_ordered_dict.py
@@ -698,6 +698,7 @@ def test_merge_operator(self):
         d |= list(b.items())
         expected = OrderedDict({0: 0, 1: 1, 2: 2, 3: 3})
         self.assertEqual(a | dict(b), expected)
+        self.assertEqual(a | frozendict(b), expected)
         self.assertEqual(a | b, expected)
         self.assertEqual(c, expected)
         self.assertEqual(d, expected)
@@ -706,12 +707,17 @@ def test_merge_operator(self):
         c |= a
         expected = OrderedDict({1: 1, 2: 1, 3: 3, 0: 0})
         self.assertEqual(dict(b) | a, expected)
+        self.assertEqual(frozendict(b) | a, expected)
+        self.assertEqual(a.__ror__(frozendict(b)), expected)
         self.assertEqual(b | a, expected)
         self.assertEqual(c, expected)
 
         self.assertIs(type(a | b), OrderedDict)
         self.assertIs(type(dict(a) | b), OrderedDict)
+        self.assertIs(type(frozendict(a) | b), frozendict)
+        self.assertIs(type(b.__ror__(frozendict(a))), OrderedDict)
         self.assertIs(type(a | dict(b)), OrderedDict)
+        self.assertIs(type(a | frozendict(b)), OrderedDict)
 
         expected = a.copy()
         a |= ()
diff --git 
a/Misc/NEWS.d/next/Library/2026-03-26-14-51-55.gh-issue-145056.QS-6l1.rst 
b/Misc/NEWS.d/next/Library/2026-03-26-14-51-55.gh-issue-145056.QS-6l1.rst
new file mode 100644
index 00000000000000..4eaabfbb9a87a0
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-03-26-14-51-55.gh-issue-145056.QS-6l1.rst
@@ -0,0 +1 @@
+Fix merging of :class:`collections.OrderedDict` and :class:`frozendict`.
diff --git a/Objects/odictobject.c b/Objects/odictobject.c
index e3ec0ae470c5d8..b391283e83795d 100644
--- a/Objects/odictobject.c
+++ b/Objects/odictobject.c
@@ -906,7 +906,7 @@ odict_or(PyObject *left, PyObject *right)
         type = Py_TYPE(right);
         other = left;
     }
-    if (!PyDict_Check(other)) {
+    if (!PyAnyDict_Check(other)) {
         Py_RETURN_NOTIMPLEMENTED;
     }
     PyObject *new = PyObject_CallOneArg((PyObject*)type, left);
@@ -2268,7 +2268,7 @@ static int
 mutablemapping_update_arg(PyObject *self, PyObject *arg)
 {
     int res = 0;
-    if (PyDict_CheckExact(arg)) {
+    if (PyAnyDict_CheckExact(arg)) {
         PyObject *items = PyDict_Items(arg);
         if (items == NULL) {
             return -1;

_______________________________________________
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]

Reply via email to