1from petsc4py import PETSc 2import os 3import unittest 4import gc 5import weakref 6 7# -------------------------------------------------------------------- 8 9## gc.set_debug((gc.DEBUG_STATS | 10## gc.DEBUG_LEAK) & 11## ~gc.DEBUG_SAVEALL) 12 13# -------------------------------------------------------------------- 14 15PYSABI = os.path.basename(PETSc.__file__).split(".")[1] == "abi3" 16 17 18class BaseTestGC: 19 def setUp(self): 20 self.obj = self.CLASS().create(comm=PETSc.COMM_SELF) 21 22 def tearDown(self): 23 wref = self.make_weakref() 24 self.assertTrue(wref() is self.obj) 25 self.obj = None 26 gc.collect() 27 if PYSABI: 28 # garbage collection is not supported 29 # the weak reference is still alive 30 self.assertTrue(wref() is not None) 31 self.assertEqual(wref().getRefCount(), 1) 32 wref().destroy() 33 else: 34 # the weak reference is gone 35 self.assertTrue(wref() is None) 36 del wref 37 PETSc.garbage_cleanup() 38 39 def make_weakref(self): 40 return weakref.ref(self.obj) 41 42 def testCycleInSelf(self): 43 self.obj.setAttr('myself', self.obj) 44 45 def testCycleInMethod(self): 46 self.obj.setAttr('mymeth', self.obj.view) 47 48 def testCycleInInstance(self): 49 class A: 50 pass 51 52 a = A() 53 a.obj = self.obj 54 self.obj.setAttr('myinst', a) 55 56 def testCycleInAllWays(self): 57 self.testCycleInSelf() 58 self.testCycleInMethod() 59 self.testCycleInInstance() 60 61 62# -------------------------------------------------------------------- 63 64 65class TestGCVec(BaseTestGC, unittest.TestCase): 66 CLASS = PETSc.Vec 67 68 69class TestGCVecSubType(TestGCVec): 70 CLASS = type('_Vec', (PETSc.Vec,), {}) 71 72 73class TestGCMat(BaseTestGC, unittest.TestCase): 74 CLASS = PETSc.Mat 75 76 77class TestGCMatSubType(TestGCMat): 78 CLASS = type('_Mat', (PETSc.Mat,), {}) 79 80 81class TestGCPC(BaseTestGC, unittest.TestCase): 82 CLASS = PETSc.PC 83 84 85class TestGCPCSubType(TestGCPC): 86 CLASS = type('_PC', (PETSc.PC,), {}) 87 88 89class TestGCKSP(BaseTestGC, unittest.TestCase): 90 CLASS = PETSc.KSP 91 92 93class TestGCKSPSubType(TestGCKSP): 94 CLASS = type('_KSP', (PETSc.KSP,), {}) 95 96 97class TestGCSNES(BaseTestGC, unittest.TestCase): 98 CLASS = PETSc.SNES 99 100 def testCycleInAppCtx(self): 101 self.obj.setAppCtx(self.obj) 102 103 104class TestGCSNESSubType(TestGCSNES): 105 CLASS = type('_SNES', (PETSc.SNES,), {}) 106 107 108class TestGCTS(BaseTestGC, unittest.TestCase): 109 CLASS = PETSc.TS 110 111 def testCycleInAppCtx(self): 112 self.obj.setAppCtx(self.obj) 113 114 115class TestGCTSSubType(TestGCTS): 116 CLASS = type('_TS', (PETSc.TS,), {}) 117 118 def testCycleInAppCtx(self): 119 self.obj.setAppCtx(self.obj) 120 121 122# -------------------------------------------------------------------- 123 124if __name__ == '__main__': 125 unittest.main() 126