def testUnloadsAutomagically(self): pi = PydImporter() pi.Load("tests\\data\\setvalue.pyd") del pi gcwait() self.assertEquals(Unmanaged.GetModuleHandle("setvalue.pyd"), IntPtr.Zero, "failed to unload on dispose")
def testUnmapsAutomagically(self): sr = StubReference(os.path.join("build", "ironclad", "python26.dll")) self.assertNotEquals(Unmanaged.GetModuleHandle("python26.dll"), IntPtr.Zero, "library not mapped by construction") del sr gcwait() self.assertEquals(Unmanaged.GetModuleHandle("python26.dll"), IntPtr.Zero, "library not unmapped on finalize")
def testUnmapsAutomagically(self): sr = StubReference(DLL_PATH) self.assertNotEquals(Unmanaged.GetModuleHandle(PYTHON_DLL), IntPtr.Zero, "library not mapped by construction") del sr gcwait() self.assertEquals(Unmanaged.GetModuleHandle(PYTHON_DLL), IntPtr.Zero, "library not unmapped on finalize")
def testBridgeAssociateCanWeaken(self): def do(): # see NOTE map, ptr, obj, ref = self.getVars() map.BridgeAssociate(ptr, obj) map.UpdateStrength(ptr) del obj return map, ptr, ref map, ptr, ref = do() gcwait() self.assertEquals(ref.IsAlive, False, "failed to GC") self.assertRaisesClr(NullReferenceException, map.GetObj, ptr) map.Release(ptr)
def testAssociateIsStrong(self): def do(): # see NOTE map, ptr, obj, ref = self.getVars() map.Associate(ptr, obj) del obj return map, ptr, ref map, ptr, ref = do() gcwait() self.assertEquals(ref.IsAlive, True, "unexpected GC") self.assertEquals(map.HasObj(ref.Target), True, "wrong") self.assertEquals(map.GetObj(ptr), ref.Target, "not mapped") self.assertEquals(map.HasPtr(ptr), True, "wrong") self.assertEquals(map.GetPtr(ref.Target), ptr, "not mapped")
def testPyBaseObject_TypeDeallocCallsObjTypesFreeFunction(self, mapper, addToCleanUp): calls = [] def Some_FreeFunc(objPtr): calls.append(objPtr) self.freeDgt = dgt_void_ptr(Some_FreeFunc) baseObjTypeBlock = mapper.PyBaseObject_Type objTypeBlock = mapper.PyDict_Type # type not actually important objPtr = Marshal.AllocHGlobal(Marshal.SizeOf(PyObject())) addToCleanUp(lambda: Marshal.FreeHGlobal(objPtr)) CPyMarshal.WriteFunctionPtrField(objTypeBlock, PyTypeObject, "tp_free", self.freeDgt) CPyMarshal.WritePtrField(objPtr, PyObject, "ob_type", objTypeBlock) gcwait() # this should make the function pointers invalid if we forgot to store references to the delegates mapper.IC_PyBaseObject_Dealloc(objPtr) self.assertEquals(calls, [objPtr], "wrong calls")
def testPyBaseObject_TypeDeallocCallsObjTypesFreeFunction(self, mapper, addToCleanUp): calls = [] def Some_FreeFunc(objPtr): calls.append(objPtr) self.freeDgt = dgt_void_ptr(Some_FreeFunc) baseObjTypeBlock = mapper.PyBaseObject_Type objTypeBlock = mapper.PyDict_Type # type not actually important objPtr = Marshal.AllocHGlobal(Marshal.SizeOf(PyObject)) addToCleanUp(lambda: Marshal.FreeHGlobal(objPtr)) CPyMarshal.WriteFunctionPtrField(objTypeBlock, PyTypeObject, "tp_free", self.freeDgt) CPyMarshal.WritePtrField(objPtr, PyObject, "ob_type", objTypeBlock) gcwait() # this should make the function pointers invalid if we forgot to store references to the delegates mapper.IC_PyBaseObject_Dealloc(objPtr) self.assertEquals(calls, [objPtr], "wrong calls")
def testStoreBridge(self): allocator = HGlobalAllocator() mapper = PythonMapper(allocator) deallocTypes = CreateTypes(mapper) # need to use same allocator as mapper, otherwise it gets upset on shutdown ptr = allocator.Alloc(Marshal.SizeOf(PyObject)) try: def do(): # see NOTE in interestingptrmaptest obj = object() ref = WeakReference(obj) CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 1) CPyMarshal.WritePtrField(ptr, PyObject, "ob_type", mapper.PyBaseObject_Type) mapper.StoreBridge(ptr, obj) self.assertEquals(mapper.Retrieve(ptr), obj, "object not stored") self.assertEquals(mapper.Store(obj), ptr, "object not reverse-mapped") mapper.Weaken(obj) CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 1) mapper.IncRef(ptr) del obj return ref ref = do() gcwait() self.assertEquals(ref.IsAlive, True, "was not strengthened by IncRef") mapper.DecRef(ptr) gcwait() self.assertEquals(ref.IsAlive, False, "was not weakened by DecRef") finally: # need to dealloc ptr ourselves, it doesn't happen automatically # except for objects with Dispatchers mapper.IC_PyBaseObject_Dealloc(ptr) mapper.Dispose() deallocTypes()
def assertMaps(self, mapper, func, ptr, refcnt): func(ptr) obj = mapper.Retrieve(ptr) ref = WeakReference(obj) self.assertEquals(mapper.Store(obj), ptr) self.assertEquals(mapper.RefCount(ptr), refcnt) while mapper.RefCount(ptr) > 2: mapper.DecRef(ptr) del obj gcwait() self.assertEquals(ref.IsAlive, True) obj = ref.Target mapper.DecRef(ptr) del obj gcwait() self.assertEquals(ref.IsAlive, False)
def testPyListTypeField_tp_dealloc(self): calls = [] class MyPM(PythonMapper): def IC_PyList_Dealloc(self, listPtr): calls.append(listPtr) mapper = MyPM() typeBlock = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject())) mapper.RegisterData("PyList_Type", typeBlock) gcwait() # this will make the function pointers invalid if we forgot to store references to the delegates deallocDgt = CPyMarshal.ReadFunctionPtrField(typeBlock, PyTypeObject, "tp_dealloc", dgt_void_ptr) deallocDgt(IntPtr(12345)) self.assertEquals(calls, [IntPtr(12345)], "wrong calls") mapper.Dispose() Marshal.FreeHGlobal(typeBlock)
def testAssociateCanWeaken(self): def do(): # see NOTE map, ptr, obj, ref = self.getVars() map.Associate(ptr, obj) self.assertEquals(map.HasPtr(ptr), True) self.assertEquals(ref.IsAlive, True, "unexpected GC") del obj map.Release(ptr) return map, ptr, ref map, ptr, ref = do() gcwait() self.assertEquals(map.HasPtr(ptr), False) self.assertEquals(ref.IsAlive, False, "failed to GC") self.assertRaisesClr(BadMappingException, map.GetObj, ptr)
def testPyListTypeField_tp_dealloc(self): calls = [] class MyPM(PythonMapper): def IC_PyList_Dealloc(self, listPtr): calls.append(listPtr) mapper = MyPM() typeBlock = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject)) mapper.RegisterData("PyList_Type", typeBlock) gcwait() # this will make the function pointers invalid if we forgot to store references to the delegates deallocDgt = CPyMarshal.ReadFunctionPtrField(typeBlock, PyTypeObject, "tp_dealloc", dgt_void_ptr) deallocDgt(IntPtr(12345)) self.assertEquals(calls, [IntPtr(12345)], "wrong calls") mapper.Dispose() Marshal.FreeHGlobal(typeBlock)
def testUpdateStrengthStrengthensWeakRefWithRefcnt2(self): def do(): # see NOTE map, ptr, obj, ref = self.getVars() self.keepalive = map map.BridgeAssociate(ptr, obj) map.UpdateStrength(ptr) # ref should now be weak, but obj is still referenced in this scope CPyMarshal.WriteIntField(ptr, PyObject, 'ob_refcnt', 2) map.UpdateStrength(ptr) # should now be strong; safe to del obj del obj return ref ref = do() gcwait() self.assertEquals(ref.IsAlive, True, "unexpected GC")
def testReleaseGILChecksBridgePtrs(self): frees = [] allocator = GetAllocatingTestAllocator([], frees) mapper = PythonMapper(allocator) deallocTypes = CreateTypes(mapper) # force no throttling of cleanup mapper.GCThreshold = 0 def do1(): obj = object() ref = WeakReference(obj) # need to use same allocator as mapper, otherwise it gets upset on shutdown ptr = allocator.Alloc(Marshal.SizeOf(PyObject)) CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 2) CPyMarshal.WritePtrField(ptr, PyObject, "ob_type", mapper.PyBaseObject_Type) mapper.StoreBridge(ptr, obj) # refcount > 1 means ref should have been strengthened del obj return ref, ptr ref, ptr = do1() gcwait() self.assertEquals(ref.IsAlive, True, "was reaped unexpectedly (refcount was 2)") CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 1) mapper.EnsureGIL() mapper.ReleaseGIL() # refcount < 2 should have been weakened gcwait() self.assertRaises(NullReferenceException, mapper.Retrieve, ptr) # need to dealloc ptr ourselves, it doesn't hapen automatically # except for objects with Dispatchers mapper.IC_PyBaseObject_Dealloc(ptr) mapper.Dispose() deallocTypes()
def testStrengthenWeakenUnmanagedInstance(self): frees = [] allocator = GetAllocatingTestAllocator([], frees) mapper = PythonMapper(allocator) deallocTypes = CreateTypes(mapper) # need to use same allocator as mapper, otherwise it gets upset on shutdown ptr = allocator.Alloc(Marshal.SizeOf(PyObject)) try: def do1(): # see NOTE in interestingptrmaptest obj = object() ref = WeakReference(obj) CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 1) CPyMarshal.WritePtrField(ptr, PyObject, "ob_type", mapper.PyBaseObject_Type) mapper.StoreBridge(ptr, obj) del obj return ref ref = do1() gcwait() self.assertEquals(ref.IsAlive, True, "was not strongly referenced") def do2(): obj = ref.Target mapper.Weaken(obj) del obj do2() gcwait() self.assertRaises(NullReferenceException, mapper.Retrieve, ptr) finally: # need to dealloc ptr ourselves, it doesn't hapen automatically # except for objects with Dispatchers mapper.IC_PyBaseObject_Dealloc(ptr) mapper.Dispose() deallocTypes()
def testCheckBridgePtrsShouldUpdateAll(self): def do(): # see NOTE map, ptr1, obj1, ref1 = self.getVars() _, ptr2, obj2, ref2 = self.getVars() map.BridgeAssociate(ptr1, obj1) map.BridgeAssociate(ptr2, obj2) # make both ptrs 'ready to weaken' CPyMarshal.WriteIntField(ptr1, PyObject, 'ob_refcnt', 1) CPyMarshal.WriteIntField(ptr2, PyObject, 'ob_refcnt', 1) map.CheckBridgePtrs(True) del obj1 del obj2 return map, ref1, ref2 map, ref1, ref2 = do() gcwait() self.assertEquals(ref1.IsAlive, False, "failed to GC") self.assertEquals(ref2.IsAlive, False, "failed to GC")
def testStoreBridge(self): allocator = HGlobalAllocator() mapper = PythonMapper(allocator) deallocTypes = CreateTypes(mapper) # need to use same allocator as mapper, otherwise it gets upset on shutdown ptr = allocator.Alloc(Marshal.SizeOf(PyObject())) try: def do(): # see NOTE in interestingptrmaptest obj = object() ref = WeakReference(obj) CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 1) CPyMarshal.WritePtrField(ptr, PyObject, "ob_type", mapper.PyBaseObject_Type) mapper.StoreBridge(ptr, obj) self.assertEquals(mapper.Retrieve(ptr), obj, "object not stored") self.assertEquals(mapper.Store(obj), ptr, "object not reverse-mapped") mapper.Weaken(obj) CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 1) mapper.IncRef(ptr) del obj return ref ref = do() gcwait() self.assertEquals(ref.IsAlive, True, "was not strengthened by IncRef") mapper.DecRef(ptr) gcwait() self.assertEquals(ref.IsAlive, False, "was not weakened by DecRef") finally: # need to dealloc ptr ourselves, it doesn't happen automatically # except for objects with Dispatchers mapper.IC_PyBaseObject_Dealloc(ptr) mapper.Dispose() deallocTypes()
def testReleaseGILChecksBridgePtrs(self): frees = [] allocator = GetAllocatingTestAllocator([], frees) mapper = PythonMapper(allocator) deallocTypes = CreateTypes(mapper) # force no throttling of cleanup mapper.GCThreshold = 0 def do1(): obj = object() ref = WeakReference(obj) # need to use same allocator as mapper, otherwise it gets upset on shutdown ptr = allocator.Alloc(Marshal.SizeOf(PyObject())) CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 2) CPyMarshal.WritePtrField(ptr, PyObject, "ob_type", mapper.PyBaseObject_Type) mapper.StoreBridge(ptr, obj) # refcount > 1 means ref should have been strengthened del obj return ref, ptr ref, ptr = do1() gcwait() self.assertEquals(ref.IsAlive, True, "was reaped unexpectedly (refcount was 2)") CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 1) mapper.EnsureGIL() mapper.ReleaseGIL() # refcount < 2 should have been weakened gcwait() self.assertRaisesClr(NullReferenceException, mapper.Retrieve, ptr) # need to dealloc ptr ourselves, it doesn't hapen automatically # except for objects with Dispatchers mapper.IC_PyBaseObject_Dealloc(ptr) mapper.Dispose() deallocTypes()
def testStrengthenWeakenUnmanagedInstance(self): frees = [] allocator = GetAllocatingTestAllocator([], frees) mapper = PythonMapper(allocator) deallocTypes = CreateTypes(mapper) # need to use same allocator as mapper, otherwise it gets upset on shutdown ptr = allocator.Alloc(Marshal.SizeOf(PyObject())) try: def do1(): # see NOTE in interestingptrmaptest obj = object() ref = WeakReference(obj) CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 1) CPyMarshal.WritePtrField(ptr, PyObject, "ob_type", mapper.PyBaseObject_Type) mapper.StoreBridge(ptr, obj) del obj return ref ref = do1() gcwait() self.assertEquals(ref.IsAlive, True, "was not strongly referenced") def do2(): obj = ref.Target mapper.Weaken(obj) del obj do2() gcwait() self.assertRaisesClr(NullReferenceException, mapper.Retrieve, ptr) finally: # need to dealloc ptr ourselves, it doesn't hapen automatically # except for objects with Dispatchers mapper.IC_PyBaseObject_Dealloc(ptr) mapper.Dispose() deallocTypes()
def tearDown(self): gcwait() unittest.TestCase.tearDown(self)