def test_clear_refcycles(self): # .clear() doesn't leave any refcycle behind with support.disable_gc(): class C: pass c = C() wr = weakref.ref(c) exc = self.outer(c=c) del c self.assertIsNot(None, wr()) self.clear_traceback_frames(exc.__traceback__) self.assertIs(None, wr())
def test(cls): """ A context manager to use around all finalization tests. """ with support.disable_gc(): cls.del_calls.clear() cls.tp_del_calls.clear() NonGCSimpleBase._cleaning = False try: yield if cls.errors: raise cls.errors[0] finally: NonGCSimpleBase._cleaning = True cls._cleanup()
def collect_in_thread(period=0.0001): """ Ensure GC collections happen in a different thread, at a high frequency. """ threading = support.import_module('threading') please_stop = False def collect(): while not please_stop: time.sleep(period) gc.collect() with support.disable_gc(): t = threading.Thread(target=collect) t.start() try: yield finally: please_stop = True t.join()
def test_close_with_cleared_frame(self): def innermost(): yield def inner(): outer_gen = yield yield from innermost() def outer(): inner_gen = yield yield from inner_gen with disable_gc(): inner_gen = inner() outer_gen = outer() outer_gen.send(None) outer_gen.send(inner_gen) outer_gen.send(outer_gen) del outer_gen del inner_gen gc_collect()
def test_close_with_cleared_frame(self): # See issue #17669. # # Create a stack of generators: outer() delegating to inner() # delegating to innermost(). The key point is that the instance of # inner is created first: this ensures that its frame appears before # the instance of outer in the GC linked list. # # At the gc.collect call: # - frame_clear is called on the inner_gen frame. # - gen_dealloc is called on the outer_gen generator (the only # reference is in the frame's locals). # - gen_close is called on the outer_gen generator. # - gen_close_iter is called to close the inner_gen generator, which # in turn calls gen_close, and gen_yf. # # Previously, gen_yf would crash since inner_gen's frame had been # cleared (and in particular f_stacktop was NULL). def innermost(): yield def inner(): outer_gen = yield yield from innermost() def outer(): inner_gen = yield yield from inner_gen with disable_gc(): inner_gen = inner() outer_gen = outer() outer_gen.send(None) outer_gen.send(inner_gen) outer_gen.send(outer_gen) del outer_gen del inner_gen gc_collect()
def testNoCycles(self): case = unittest.TestCase() wr = weakref.ref(case) with support.disable_gc(): del case self.assertFalse(wr())