Skip to content

Commit 06aed90

Browse files
Issue #27576: Fix call order in OrderedDict.__init__().
1 parent 7d895ac commit 06aed90

3 files changed

Lines changed: 30 additions & 2 deletions

File tree

Lib/test/test_ordered_dict.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,19 @@ def test_update(self):
9898
self.assertRaises(TypeError, OrderedDict().update, (), ())
9999
self.assertRaises(TypeError, OrderedDict.update)
100100

101+
def test_init_calls(self):
102+
calls = []
103+
class Spam:
104+
def keys(self):
105+
calls.append('keys')
106+
return ()
107+
def items(self):
108+
calls.append('items')
109+
return ()
110+
111+
self.OrderedDict(Spam())
112+
self.assertEqual(calls, ['keys'])
113+
101114
def test_fromkeys(self):
102115
OrderedDict = self.OrderedDict
103116
od = OrderedDict.fromkeys('abc')

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ Core and Builtins
113113
Library
114114
-------
115115

116+
- Issue #27576: Fix call order in OrderedDict.__init__().
117+
116118
- email.generator.DecodedGenerator now supports the policy keyword.
117119

118120
- Issue #28027: Remove undocumented modules from ``Lib/plat-*``: IN, CDROM,

Objects/odictobject.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2356,8 +2356,7 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
23562356
PyObject *other = PyTuple_GET_ITEM(args, 0); /* borrowed reference */
23572357
assert(other != NULL);
23582358
Py_INCREF(other);
2359-
if (PyDict_CheckExact(other) ||
2360-
_PyObject_HasAttrId(other, &PyId_items)) { /* never fails */
2359+
if PyDict_CheckExact(other) {
23612360
PyObject *items;
23622361
if (PyDict_CheckExact(other))
23632362
items = PyDict_Items(other);
@@ -2400,6 +2399,20 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
24002399
if (res != 0 || PyErr_Occurred())
24012400
return NULL;
24022401
}
2402+
else if (_PyObject_HasAttrId(other, &PyId_items)) { /* never fails */
2403+
PyObject *items;
2404+
if (PyDict_CheckExact(other))
2405+
items = PyDict_Items(other);
2406+
else
2407+
items = _PyObject_CallMethodId(other, &PyId_items, NULL);
2408+
Py_DECREF(other);
2409+
if (items == NULL)
2410+
return NULL;
2411+
res = mutablemapping_add_pairs(self, items);
2412+
Py_DECREF(items);
2413+
if (res == -1)
2414+
return NULL;
2415+
}
24032416
else {
24042417
res = mutablemapping_add_pairs(self, other);
24052418
Py_DECREF(other);

0 commit comments

Comments
 (0)