diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2014-10-05 20:04:06 +0200 |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2014-10-05 20:04:06 +0200 |
commit | 414e15a88d461be37e8f29c7a2158b5d32b9ef9c (patch) | |
tree | 5d20a313e7a685e31901949cb0f5b3533175507e /Lib/test/test_weakref.py | |
parent | 861470c83607a4312d3c65bce3e18414b965e586 (diff) | |
parent | 1bf974dc6e15799856b1e5d6316238ecedcd798f (diff) | |
download | cpython-414e15a88d461be37e8f29c7a2158b5d32b9ef9c.tar.gz cpython-414e15a88d461be37e8f29c7a2158b5d32b9ef9c.zip |
Closes #21173: Fix len() on a WeakKeyDictionary when .clear() was called with an iterator alive.
Diffstat (limited to 'Lib/test/test_weakref.py')
-rw-r--r-- | Lib/test/test_weakref.py | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index 94c98adacdf..e735376a67f 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -1310,6 +1310,36 @@ class MappingTestCase(TestBase): dict.clear() self.assertEqual(len(dict), 0) + def check_weak_del_and_len_while_iterating(self, dict, testcontext): + # Check that len() works when both iterating and removing keys + # explicitly through various means (.pop(), .clear()...), while + # implicit mutation is deferred because an iterator is alive. + # (each call to testcontext() should schedule one item for removal + # for this test to work properly) + o = Object(123456) + with testcontext(): + n = len(dict) + dict.popitem() + self.assertEqual(len(dict), n - 1) + dict[o] = o + self.assertEqual(len(dict), n) + with testcontext(): + self.assertEqual(len(dict), n - 1) + dict.pop(next(dict.keys())) + self.assertEqual(len(dict), n - 2) + with testcontext(): + self.assertEqual(len(dict), n - 3) + del dict[next(dict.keys())] + self.assertEqual(len(dict), n - 4) + with testcontext(): + self.assertEqual(len(dict), n - 5) + dict.popitem() + self.assertEqual(len(dict), n - 6) + with testcontext(): + dict.clear() + self.assertEqual(len(dict), 0) + self.assertEqual(len(dict), 0) + def test_weak_keys_destroy_while_iterating(self): # Issue #7105: iterators shouldn't crash when a key is implicitly removed dict, objects = self.make_weak_keyed_dict() @@ -1331,6 +1361,10 @@ class MappingTestCase(TestBase): it = None # should commit all removals gc.collect() self.check_weak_destroy_and_mutate_while_iterating(dict, testcontext) + # Issue #21173: len() fragile when keys are both implicitly and + # explicitly removed. + dict, objects = self.make_weak_keyed_dict() + self.check_weak_del_and_len_while_iterating(dict, testcontext) def test_weak_values_destroy_while_iterating(self): # Issue #7105: iterators shouldn't crash when a key is implicitly removed @@ -1354,6 +1388,8 @@ class MappingTestCase(TestBase): it = None # should commit all removals gc.collect() self.check_weak_destroy_and_mutate_while_iterating(dict, testcontext) + dict, objects = self.make_weak_valued_dict() + self.check_weak_del_and_len_while_iterating(dict, testcontext) def test_make_weak_keyed_dict_from_dict(self): o = Object(3) |