def test_finalization_preprocess_and_postprocess(self): # Note that this test is done here again (already was in another class # in this module), to see that everything works as it should also with # a different flag-context. comments = [] self0 = self class A: def __del__(self): self0.assertIn("run PreProcess", comments) comments.append("A del") # let's simulate a time-consuming finalizer # to ensure that post finalization processing # is sensitive to this time.sleep(0.5) comments.append("A del done") class PreProcess(Runnable): def run(self): self0.assertEqual(comments, []) comments.append("run PreProcess") class PostProcess(Runnable): def run(self): self0.assertIn("run PreProcess", comments) self0.assertIn("A del", comments) self0.assertIn("A del done", comments) comments.append("run PostProcess") a = A() a = None prePr = PreProcess() postPr = PostProcess() time.sleep(1) # <- to avoid that the newly registered processes # become subject to previous run (remember: We # are not in monitor-mode, i.e. gc runs async. gc.registerPreFinalizationProcess(prePr) gc.registerPostFinalizationProcess(postPr) # Note that order matters here: # If the flag gc.DONT_FINALIZE_RESURRECTED_OBJECTS is used, # gc.registerPostFinalizationProcess(postPr, 0) would lead to failure, # because postPr asserts that a's finalizer already ran. Since # DONT_FINALIZE_RESURRECTED_OBJECTS also inserted a postprocess, # to perform delayed finalization, the 0-index would prepend postPr # before the process that actually runs the finalizers. System.gc() # we wait a bit longer here, since PostProcess runs asynchronous # and must wait for the finalizer of A time.sleep(2) self.assertIn("run PostProcess", comments) comments = [] gc.unregisterPreFinalizationProcess(prePr) gc.unregisterPostFinalizationProcess(postPr)
def test_finalization_preprocess_and_postprocess(self): #Note that this test is done here again (already was in another class #in this module), to see that everything works as it should also with #a different flag-context. comments = [] self0 = self class A: def __del__(self): self0.assertIn("run PreProcess", comments) comments.append("A del") #let's simulate a time-consuming finalizer #to ensure that post finalization processing #is sensitive to this time.sleep(0.5) comments.append("A del done") class PreProcess(Runnable): def run(self): self0.assertEqual(comments, []) comments.append("run PreProcess") class PostProcess(Runnable): def run(self): self0.assertIn("run PreProcess", comments) self0.assertIn("A del", comments) self0.assertIn("A del done", comments) comments.append("run PostProcess") a = A() a = None prePr = PreProcess() postPr = PostProcess() time.sleep(1) # <- to avoid that the newly registered processes # become subject to previous run (remember: We # are not in monitor-mode, i.e. gc runs async. gc.registerPreFinalizationProcess(prePr) gc.registerPostFinalizationProcess(postPr) #Note that order matters here: #If the flag gc.DONT_FINALIZE_RESURRECTED_OBJECTS is used, #gc.registerPostFinalizationProcess(postPr, 0) would lead to failure, #because postPr asserts that a's finalizer already ran. Since #DONT_FINALIZE_RESURRECTED_OBJECTS also inserted a postprocess, #to perform delayed finalization, the 0-index would prepend postPr #before the process that actually runs the finalizers. System.gc() #we wait a bit longer here, since PostProcess runs asynchronous #and must wait for the finalizer of A time.sleep(2) self.assertIn("run PostProcess", comments) comments = [] gc.unregisterPreFinalizationProcess(prePr) gc.unregisterPostFinalizationProcess(postPr)
def test_forced_with_extern_NonPyObjectFinalizer_that_notifies_gc(self): comments = [] class A: def __init__(self, index): self.index = index def __del__(self): comments.append("A_del_" + str(self.index)) class PreProcess(Runnable): preCount = 0 def run(self): PreProcess.preCount += 1 class PostProcess(Runnable): postCount = 0 def run(self): PostProcess.postCount += 1 prePr = PreProcess() postPr = PostProcess() time.sleep(1) # <- to avoid that the newly registered processes # become subject to previous run (remember: We # are not in monitor-mode, i.e. gc runs async. gc.registerPreFinalizationProcess(prePr) gc.registerPostFinalizationProcess(postPr) for i in range(4): f = A(i) del f #NastyFinalizer would cause this test occasionally to fail externFinalizer = GCTestHelper.NotSoNastyFinalizer() del externFinalizer for i in range(4, 8): f = A(i) del f System.gc() # we wait a bit longer here, since PostProcess runs asynchronous # and must wait for the finalizer of A time.sleep(4) self.assertEqual(len(comments), 8) self.assertEqual(PreProcess.preCount, 1) self.assertEqual(PostProcess.postCount, 1) comments = [] gc.unregisterPreFinalizationProcess(prePr) gc.unregisterPostFinalizationProcess(postPr)
def test_with_extern_NonPyObjectFinalizer_that_notifies_gc(self): comments = [] class A: def __init__(self, index): self.index = index def __del__(self): comments.append("A_del_"+str(self.index)) class PreProcess(Runnable): preCount = 0 def run(self): PreProcess.preCount += 1 class PostProcess(Runnable): postCount = 0 def run(self): PostProcess.postCount += 1 prePr = PreProcess() postPr = PostProcess() time.sleep(1) # <- to avoid that the newly registered processes # become subject to previous run (remember: We # are not in monitor-mode, i.e. gc runs async. gc.registerPreFinalizationProcess(prePr) gc.registerPostFinalizationProcess(postPr) for i in range(4): f = A(i) del f #NastyFinalizer would cause this test occasionally to fail externFinalizer = GCTestHelper.NotSoNastyFinalizer() del externFinalizer for i in range(4, 8): f = A(i) del f System.gc() #we wait a bit longer here, since PostProcess runs asynchronous #and must wait for the finalizer of A time.sleep(4) self.assertEqual(len(comments), 8) self.assertEqual(PreProcess.preCount, 1) self.assertEqual(PostProcess.postCount, 1) comments = [] gc.unregisterPreFinalizationProcess(prePr) gc.unregisterPostFinalizationProcess(postPr)