Browse Source

Issue #27576: Fix call order in OrderedDict.__init__().

pull/9921/head
Eric Snow 9 years ago
parent
commit
06aed90a1f
  1. 13
      Lib/test/test_ordered_dict.py
  2. 2
      Misc/NEWS
  3. 17
      Objects/odictobject.c

13
Lib/test/test_ordered_dict.py

@ -98,6 +98,19 @@ class OrderedDictTests:
self.assertRaises(TypeError, OrderedDict().update, (), ())
self.assertRaises(TypeError, OrderedDict.update)
def test_init_calls(self):
calls = []
class Spam:
def keys(self):
calls.append('keys')
return ()
def items(self):
calls.append('items')
return ()
self.OrderedDict(Spam())
self.assertEqual(calls, ['keys'])
def test_fromkeys(self):
OrderedDict = self.OrderedDict
od = OrderedDict.fromkeys('abc')

2
Misc/NEWS

@ -113,6 +113,8 @@ Core and Builtins
Library
-------
- Issue #27576: Fix call order in OrderedDict.__init__().
- email.generator.DecodedGenerator now supports the policy keyword.
- Issue #28027: Remove undocumented modules from ``Lib/plat-*``: IN, CDROM,

17
Objects/odictobject.c

@ -2356,8 +2356,7 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
PyObject *other = PyTuple_GET_ITEM(args, 0); /* borrowed reference */
assert(other != NULL);
Py_INCREF(other);
if (PyDict_CheckExact(other) ||
_PyObject_HasAttrId(other, &PyId_items)) { /* never fails */
if PyDict_CheckExact(other) {
PyObject *items;
if (PyDict_CheckExact(other))
items = PyDict_Items(other);
@ -2400,6 +2399,20 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
if (res != 0 || PyErr_Occurred())
return NULL;
}
else if (_PyObject_HasAttrId(other, &PyId_items)) { /* never fails */
PyObject *items;
if (PyDict_CheckExact(other))
items = PyDict_Items(other);
else
items = _PyObject_CallMethodId(other, &PyId_items, NULL);
Py_DECREF(other);
if (items == NULL)
return NULL;
res = mutablemapping_add_pairs(self, items);
Py_DECREF(items);
if (res == -1)
return NULL;
}
else {
res = mutablemapping_add_pairs(self, other);
Py_DECREF(other);

Loading…
Cancel
Save