From 53d2c41f77ab7658a1380bc304946b4920e5b49b Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sat, 3 May 2014 21:58:45 -0700 Subject: Issue #19414: Have the OrderedDict mark deleted links as unusable. This gives an earlier and more visible failure if a link is deleted during iteration. --- Lib/collections/__init__.py | 2 ++ Lib/test/test_collections.py | 10 ++++++++++ Misc/NEWS | 3 +++ 3 files changed, 15 insertions(+) diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 3605cc3..a55fee1 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -96,6 +96,8 @@ class OrderedDict(dict): link_next = link.next link_prev.next = link_next link_next.prev = link_prev + link.prev = None + link.next = None def __iter__(self): 'od.__iter__() <==> iter(od)' diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index d352d2a..7e14980 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -1193,6 +1193,16 @@ class TestOrderedDict(unittest.TestCase): [t[1] for t in reversed(pairs)]) self.assertEqual(list(reversed(od.items())), list(reversed(pairs))) + def test_detect_deletion_during_iteration(self): + od = OrderedDict.fromkeys('abc') + it = iter(od) + key = next(it) + del od[key] + with self.assertRaises(Exception): + # Note, the exact exception raised is not guaranteed + # The only guarantee that the next() will not succeed + next(it) + def test_popitem(self): pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) diff --git a/Misc/NEWS b/Misc/NEWS index c618212..9eaab87 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -73,6 +73,9 @@ Library Decimal.quantize() method in the Python version. It had never been present in the C version. +- Issue #19414: Have the OrderedDict mark deleted links as unusable. + This gives an early failure if the link is deleted during iteration. + - Issue #21421: Add __slots__ to the MappingViews ABC. Patch by Josh Rosenberg. -- cgit v0.12