xref: /petsc/src/binding/petsc4py/test/test_gc.py (revision 053abcdfeaa3c4bf7b7c01a7334c7edc5567db03)
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