mirror of
https://github.com/python/cpython.git
synced 2025-07-09 20:35:26 +00:00
bpo-42536: GC track recycled tuples (GH-23623)
Several built-in and standard library types now ensure that their internal result tuples are always tracked by the garbage collector: - collections.OrderedDict.items - dict.items - enumerate - functools.reduce - itertools.combinations - itertools.combinations_with_replacement - itertools.permutations - itertools.product - itertools.zip_longest - zip Previously, they could have become untracked by a prior garbage collection.
This commit is contained in:
parent
2de5097ba4
commit
226a012d1c
12 changed files with 192 additions and 0 deletions
|
@ -2,6 +2,7 @@ import unittest
|
|||
import operator
|
||||
import sys
|
||||
import pickle
|
||||
import gc
|
||||
|
||||
from test import support
|
||||
|
||||
|
@ -134,6 +135,18 @@ class EnumerateTestCase(unittest.TestCase, PickleTest):
|
|||
self.assertEqual(len(set(map(id, list(enumerate(self.seq))))), len(self.seq))
|
||||
self.assertEqual(len(set(map(id, enumerate(self.seq)))), min(1,len(self.seq)))
|
||||
|
||||
@support.cpython_only
|
||||
def test_enumerate_result_gc(self):
|
||||
# bpo-42536: enumerate's tuple-reuse speed trick breaks the GC's
|
||||
# assumptions about what can be untracked. Make sure we re-track result
|
||||
# tuples whenever we reuse them.
|
||||
it = self.enum([[]])
|
||||
gc.collect()
|
||||
# That GC collection probably untracked the recycled internal result
|
||||
# tuple, which is initialized to (None, None). Make sure it's re-tracked
|
||||
# when it's mutated and returned from __next__:
|
||||
self.assertTrue(gc.is_tracked(next(it)))
|
||||
|
||||
class MyEnum(enumerate):
|
||||
pass
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue