summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_weakref.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_weakref.py')
-rw-r--r--Lib/test/test_weakref.py36
1 files changed, 36 insertions, 0 deletions
diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py
index 0a59120..3e7347c 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -1298,6 +1298,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()
@@ -1319,6 +1349,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
@@ -1342,6 +1376,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)