diff -r dcf9e9ae5393 Lib/test/test_ordered_dict.py --- a/Lib/test/test_ordered_dict.py Wed Dec 23 00:37:50 2015 +0200 +++ b/Lib/test/test_ordered_dict.py Wed Dec 23 16:10:04 2015 +0200 @@ -546,7 +546,7 @@ class OrderedDictTests: dict.__setitem__(od, 'spam', 1) self.assertNotIn('NULL', repr(od)) - def test_dict_delitem(self): + def test_dict_delitem_repr(self): OrderedDict = self.OrderedDict od = OrderedDict() od['spam'] = 1 @@ -555,6 +555,45 @@ class OrderedDictTests: with self.assertRaises(KeyError): repr(od) + def test_dict_delitem_iter(self): + OrderedDict = self.OrderedDict + keys = ['key%s' % i for i in range(10)] + od = OrderedDict() + for k in keys: + od[k] = k + for k in keys[:-1]: + dict.__delitem__(od, k) + + it = iter(od.items()) + with self.assertRaises(KeyError): + next(it) + it = iter(od.values()) + with self.assertRaises(KeyError): + next(it) + it = iter(od) + try: + # Shouldn't hung + list(it) + except KeyError: + # C implementation raises an error, Python implementation doesn't + pass + + def test_dict_delitem_move_to_end(self): + OrderedDict = self.OrderedDict + keys = ['key%s' % i for i in range(10)] + od = OrderedDict() + for k in keys: + od[k] = k + for k in keys[1:]: + dict.__delitem__(od, k) + + od.move_to_end(keys[0]) + try: + od.move_to_end(keys[1]) + except KeyError: + # C implementation raises an error, Python implementation doesn't + pass + def test_dict_clear(self): OrderedDict = self.OrderedDict od = OrderedDict() diff -r dcf9e9ae5393 Objects/odictobject.c --- a/Objects/odictobject.c Wed Dec 23 00:37:50 2015 +0200 +++ b/Objects/odictobject.c Wed Dec 23 16:10:04 2015 +0200 @@ -620,6 +620,7 @@ static _ODictNode * { Py_ssize_t index; Py_hash_t hash; + _ODictNode *node; if (_odict_EMPTY(od)) return NULL; @@ -629,7 +630,12 @@ static _ODictNode * index = _odict_get_index(od, key, hash); if (index < 0) return NULL; - return od->od_fast_nodes[index]; + node = od->od_fast_nodes[index]; + if (node == NULL) + return NULL; + if (node->key != od->od_dict.ma_keys->dk_entries[index].me_key) + return NULL; + return node; } static void @@ -1023,7 +1029,6 @@ odict_setdefault(register PyODictObject if (result == NULL) { if (PyErr_Occurred()) return NULL; - assert(_odict_find_node(od, key) == NULL); if (PyODict_SetItem((PyObject *)od, key, failobj) >= 0) { result = failobj; Py_INCREF(failobj);