diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -91,12 +91,15 @@ # Deleting an existing item uses self.__map to find the link which gets # removed by updating the links in the predecessor and successor nodes. dict_delitem(self, key) + root = self.__root link = self.__map.pop(key) link_prev = link.prev link_next = link.next link_prev.next = link_next link_next.prev = link_prev - + link.prev = root + link.next = root + def __iter__(self): 'od.__iter__() <==> iter(od)' # Traverse the linked list in order. diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -1368,6 +1368,20 @@ items = [('a', 1), ('c', 3), ('b', 2)] self.assertEqual(list(MyOD(items).items()), items) + def test_iterate_mutate(self): + # Test fix for issue 19414 + pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4)] + od = OrderedDict(pairs) + it = iter(od.values()) + next(it) + del od['a'] + del od['b'] + while True: + try: + next(it) + except StopIteration: + break + class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol): type2test = OrderedDict