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]