def test_Py_InitModule4_VarargsKwargsFunction(self): mapper = PythonMapper() deallocTypes = CreateTypes(mapper) args = (object(), object()) kwargs = {'a': object(), 'b': object()} result = object() resultPtr = mapper.Store(result) mapper.IncRef(resultPtr) def func(_, argsPtr, kwargsPtr): self.assertEquals(_, MODULE_PTR) self.assertEquals(mapper.Retrieve(argsPtr), args) self.assertEquals(mapper.Retrieve(kwargsPtr), kwargs) return resultPtr method, deallocMethod = MakeMethodDef("func", func, METH.VARARGS | METH.KEYWORDS) def testModule(module, mapper): self.assertEquals(module.func(*args, **kwargs), result, "not hooked up") self.assert_Py_InitModule4_withSingleMethod(mapper, method, testModule) deallocMethod() deallocTypes()
def testPySlice_DeallocDecRefsItemsAndCallsCorrectFreeFunction(self): frees = [] mapper = PythonMapper(GetAllocatingTestAllocator([], frees)) deallocTypes = CreateTypes(mapper) calls = [] def CustomFree(ptr): calls.append(ptr) freeDgt = dgt_void_ptr(CustomFree) CPyMarshal.WriteFunctionPtrField(mapper.PySlice_Type, PyTypeObject, "tp_free", freeDgt) slicePtr = mapper.Store(slice(1, 2, 3)) del frees[:] mapper.IC_PySlice_Dealloc(slicePtr) self.assertEquals(len(frees), 3, "did not dealloc each item") self.assertEquals(calls, [slicePtr], "did not call type's free function") mapper.PyObject_Free(slicePtr) mapper.Dispose() deallocTypes()
def testRefCountIncRefDecRef(self): frees = [] allocator = GetAllocatingTestAllocator([], frees) mapper = PythonMapper(allocator) deallocTypes = CreateTypes(mapper) obj1 = object() ptr = mapper.Store(obj1) self.assertEquals(mapper.HasPtr(ptr), True) mapper.IncRef(ptr) self.assertEquals(mapper.RefCount(ptr), 2, "unexpected refcount") self.assertEquals(mapper.HasPtr(ptr), True) del frees[:] mapper.DecRef(ptr) self.assertEquals(mapper.RefCount(ptr), 1, "unexpected refcount") self.assertEquals(mapper.HasPtr(ptr), True) self.assertEquals(frees, [], "unexpected deallocations") mapper.DecRef(ptr) self.assertEquals(mapper.HasPtr(ptr), False) self.assertEquals(frees, [ptr], "unexpected deallocations") self.assertRaises(KeyError, lambda: mapper.PyObject_Free(ptr)) mapper.Dispose() deallocTypes()
def testCreateEmptyString(self): allocs = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, [])) deallocTypes = CreateTypes(mapper) del allocs[:] try: testString = "we run the grease racket in this town" + self.getStringWithValues( 0, 256) testLength = len(testString) strPtr = mapper.PyString_FromStringAndSize(IntPtr.Zero, testLength) baseSize = Marshal.SizeOf(PyStringObject) self.assertEquals(allocs, [(strPtr, testLength + baseSize)], "allocated wrong") self.assertStringObjectHasLength(strPtr, testLength) self.assertHasStringType(strPtr, mapper) testBytes = self.byteArrayFromString(testString) self.fillStringDataWithBytes(strPtr, testBytes) resultStr = mapper.Retrieve(strPtr) self.assertEquals(resultStr, testString, "failed to read string data") strPtr2 = mapper.Store(resultStr) self.assertEquals(strPtr2, strPtr, "did not remember already had this string") self.assertEquals(mapper.RefCount(strPtr), 2, "did not incref on store") finally: mapper.Dispose() deallocTypes()
def testStoreStringCreatesStringType(self): allocs = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, [])) deallocTypes = CreateTypes(mapper) del allocs[:] testString = "fnord" + self.getStringWithValues(1, 256) testBytes = self.byteArrayFromString(testString) testData = self.ptrFromByteArray(testBytes) testLength = len(testString) try: strPtr = mapper.Store(testString) baseSize = Marshal.SizeOf(PyStringObject) self.assertEquals(allocs, [(strPtr, testLength + baseSize)], "allocated wrong") self.assertHasStringType(strPtr, mapper) self.assertStringObjectHasLength(strPtr, testLength) self.assertStringObjectHasDataBytes(strPtr, testBytes) self.assertEquals(mapper.Retrieve(strPtr), testString, "failed to read string data") strPtr2 = mapper.Store(testString) self.assertEquals(strPtr2, strPtr, "did not remember already had this string") self.assertEquals(mapper.RefCount(strPtr), 2, "did not incref on store") finally: mapper.Dispose() deallocTypes()
def testShrink(self): allocs = [] frees = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, frees)) deallocTypes = CreateTypes(mapper) del allocs[:] oldLength = 365 newLength = 20 ptrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(IntPtr)) try: strPtr = mapper.PyString_FromStringAndSize(IntPtr.Zero, oldLength) Marshal.WriteIntPtr(ptrPtr, strPtr) baseSize = Marshal.SizeOf(PyStringObject) self.assertEquals(allocs, [(strPtr, oldLength + baseSize)], "allocated wrong") self.assertEquals(mapper._PyString_Resize(ptrPtr, newLength), 0, "bad return on success") self.assertHasStringType(strPtr, mapper) self.assertStringObjectHasLength(strPtr, newLength) self.assertEquals(allocs, [(strPtr, oldLength + baseSize)], "unexpected extra alloc") self.assertEquals(frees, [], "unexpected frees") finally: mapper.Dispose() Marshal.FreeHGlobal(ptrPtr) deallocTypes()
def assertTypeDeallocWorks(self, typename, CreateMapper, CreateInstance, TestConsequences): mapper = CreateMapper() deallocTypes = CreateTypes(mapper) calls = [] def tp_free(ptr): calls.append(("tp_free", ptr)) self.tp_freeDgt = dgt_void_ptr(tp_free) CPyMarshal.WriteFunctionPtrField(getattr(mapper, typename), PyTypeObject, "tp_free", self.tp_freeDgt) objPtr = CreateInstance(mapper, calls) deallocDgt = CPyMarshal.ReadFunctionPtrField(getattr(mapper, typename), PyTypeObject, "tp_dealloc", dgt_void_ptr) deallocDgt(objPtr) TestConsequences(mapper, objPtr, calls) mapper.Dispose() deallocTypes()
def testPyTuple_DeallocDecRefsItemsAndCallsCorrectFreeFunction(self): frees = [] mapper = PythonMapper(GetAllocatingTestAllocator([], frees)) deallocTypes = CreateTypes(mapper) calls = [] def CustomFree(ptr): calls.append(ptr) freeDgt = dgt_void_ptr(CustomFree) CPyMarshal.WriteFunctionPtrField(mapper.PyTuple_Type, PyTypeObject, "tp_free", freeDgt) tuplePtr, itemPtrs = MakeTuple(mapper, (1, 2, 3)) mapper.IC_PyTuple_Dealloc(tuplePtr) for itemPtr in itemPtrs: self.assertEquals(itemPtr in frees, True, "did not decref item") self.assertEquals(calls, [tuplePtr], "did not call type's free function") mapper.PyObject_Free(tuplePtr) mapper.Dispose() deallocTypes()
def testSomeItems(self): allocs = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, [])) deallocTypes = CreateTypes(mapper) typeSpec = { "tp_basicsize": 32, "tp_itemsize": 64, } typePtr, deallocType = MakeTypePtr(mapper, typeSpec) del allocs[:] result = mapper.PyType_GenericAlloc(typePtr, 3) self.assertEquals(allocs, [(result, 224)], "allocated wrong") refcount = CPyMarshal.ReadIntField(result, PyObject, "ob_refcnt") self.assertEquals(refcount, 1, "bad initialisation") instanceType = CPyMarshal.ReadPtrField(result, PyObject, "ob_type") self.assertEquals(instanceType, typePtr, "bad type ptr") size = CPyMarshal.ReadIntField(result, PyVarObject, "ob_size") self.assertEquals(size, 3, "bad ob_size") headerSize = Marshal.SizeOf(PyVarObject) zerosPtr = OffsetPtr(result, headerSize) for i in range(224 - headerSize): self.assertEquals(CPyMarshal.ReadByte(zerosPtr), 0, "not zeroed") zerosPtr = OffsetPtr(zerosPtr, 1) mapper.Dispose() deallocTypes() deallocType()
def testExtensionTypesAutoActualisable(self): discoveryModes = { "IncRef": lambda f, o: self.assertMaps(mapper, f, o, 5), "Retrieve": lambda f, o: self.assertMaps(mapper, f, o, 4), "DecRef": lambda f, o: self.assertMaps(mapper, f, o, 3), "RefCount": lambda f, o: self.assertMaps(mapper, f, o, 4), } allocator = HGlobalAllocator() mapper = PythonMapper(allocator) deallocTypes = CreateTypes(mapper) # delay deallocs to avoid types with the same addresses causing confusion userTypeDeallocs = [] try: for (mode, TestFunc) in discoveryModes.items(): typePtr, deallocType = MakeTypePtr(mapper, {"tp_name": mode + "Class"}) userTypeDeallocs.append(deallocType) objPtr = allocator.Alloc(Marshal.SizeOf(PyObject)) CPyMarshal.WriteIntField(objPtr, PyObject, "ob_refcnt", 2) CPyMarshal.WritePtrField(objPtr, PyObject, "ob_type", typePtr) discoveryFunc = getattr(mapper, mode) TestFunc(discoveryFunc, objPtr) finally: mapper.Dispose() for deallocFunc in userTypeDeallocs: deallocFunc() deallocTypes()
def testBasicStoreRetrieveFree(self): frees = [] allocs = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, frees)) deallocTypes = CreateTypes(mapper) del allocs[:] obj1 = object() ptr = mapper.Store(obj1) self.assertEquals(len(allocs), 1, "unexpected number of allocations") self.assertEquals(allocs[0], (ptr, Marshal.SizeOf(PyObject)), "unexpected result") self.assertNotEquals(ptr, IntPtr.Zero, "did not store reference") self.assertEquals(mapper.RefCount(ptr), 1, "unexpected refcount") self.assertEquals(CPyMarshal.ReadPtrField(ptr, PyObject, "ob_type"), mapper.PyBaseObject_Type, "nearly-opaque pointer had wrong type") obj2 = mapper.Retrieve(ptr) self.assertTrue(obj1 is obj2, "retrieved wrong object") self.assertEquals(frees, [], "unexpected deallocations") mapper.PyObject_Free(ptr) self.assertEquals(frees, [ptr], "unexpected deallocations") self.assertRaises(KeyError, lambda: mapper.PyObject_Free(ptr)) mapper.Dispose() deallocTypes()
def testDestroysObjectsOfUnmanagedTypesFirst(self): frees = [] mapper = PythonMapper(GetAllocatingTestAllocator([], frees)) deallocTypes = CreateTypes(mapper) modulePtr = MakeAndAddEmptyModule(mapper) module = mapper.Retrieve(modulePtr) calls = [] def Del(instancePtr): calls.append(("del", instancePtr)) mapper.PyObject_Free(instancePtr) typeSpec = {'tp_name': 'klass', 'tp_dealloc': Del} typePtr, deallocType = MakeTypePtr(mapper, typeSpec) mapper.PyModule_AddObject(modulePtr, 'klass', typePtr) easyptr = mapper.Store(123) instance1 = module.klass() hardptr = mapper.Store(instance1) instance2 = module.klass() brokenptr = mapper.Store(instance2) CPyMarshal.WritePtrField(brokenptr, PyObject, 'ob_type', IntPtr.Zero) mapper.Dispose() self.assertEquals( frees.index(hardptr) < frees.index(easyptr), True, "failed to dealloc in correct order") self.assertEquals(calls, [('del', hardptr)], "failed to clean up klass instance") deallocType() deallocTypes()
def testPyList_DeallocDecRefsItemsAndCallsCorrectFreeFunction(self): frees = [] mapper = PythonMapper(GetAllocatingTestAllocator([], frees)) deallocTypes = CreateTypes(mapper) calls = [] def CustomFree(ptr): calls.append(ptr) mapper.PyObject_Free(listPtr) self.freeDgt = dgt_void_ptr(CustomFree) CPyMarshal.WriteFunctionPtrField(mapper.PyList_Type, PyTypeObject, "tp_free", self.freeDgt) listPtr = mapper.Store([1, 2, 3]) itemPtrs = [] dataStore = CPyMarshal.ReadPtrField(listPtr, PyListObject, "ob_item") for _ in range(3): itemPtrs.append(CPyMarshal.ReadPtr(dataStore)) dataStore = OffsetPtr(dataStore, CPyMarshal.PtrSize) mapper.IC_PyList_Dealloc(listPtr) for itemPtr in itemPtrs: self.assertEquals(itemPtr in frees, True, "did not decref item") self.assertEquals(calls, [listPtr], "did not call type's free function") mapper.Dispose() deallocTypes()
def testDeleteList(self): deallocs = [] mapper = PythonMapper(GetAllocatingTestAllocator([], deallocs)) deallocTypes = CreateTypes(mapper) item1 = object() item2 = object() itemPtr1 = mapper.Store(item1) itemPtr2 = mapper.Store(item2) listPtr = mapper.PyList_New(0) mapper.PyList_Append(listPtr, itemPtr1) mapper.PyList_Append(listPtr, itemPtr2) mapper.DecRef(itemPtr1) mapper.DecRef(itemPtr2) self.assertEquals(len(deallocs), 1, "should have deallocated original data block only at this point") dataStore = CPyMarshal.ReadPtrField(listPtr, PyListObject, "ob_item") mapper.DecRef(listPtr) listDeallocs = deallocs[1:] self.assertEquals(len(listDeallocs), 4, "should dealloc list object; data store; both items") expectedDeallocs = [listPtr, dataStore, itemPtr1, itemPtr2] self.assertEquals(set(listDeallocs), set(expectedDeallocs), "deallocated wrong stuff") mapper.Dispose() deallocTypes()
def testStoreSameObjectIncRefsOriginal(self): frees = [] allocs = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, frees)) deallocTypes = CreateTypes(mapper) del allocs[:] obj1 = object() result1 = mapper.Store(obj1) result2 = mapper.Store(obj1) self.assertEquals(allocs, [(result1, Marshal.SizeOf(PyObject))], "unexpected result") self.assertEquals(result1, result2, "did not return same ptr") self.assertEquals(mapper.RefCount(result1), 2, "did not incref") mapper.DecRef(result1) del frees[:] mapper.DecRef(result1) self.assertEquals(frees, [result1], "did not free memory") result3 = mapper.Store(obj1) self.assertEquals( allocs, [(result1, Marshal.SizeOf(PyObject)), (result3, Marshal.SizeOf(PyObject))], "unexpected result -- failed to clear reverse mapping?") mapper.Dispose() deallocTypes()
def testPyList_New_NonZeroLength(self): allocs = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, [])) deallocTypes = CreateTypes(mapper) del allocs[:] SIZE = 27 listPtr = mapper.PyList_New(SIZE) listStruct = Marshal.PtrToStructure(listPtr, PyListObject) self.assertEquals(listStruct.ob_refcnt, 1, "bad refcount") self.assertEquals(listStruct.ob_type, mapper.PyList_Type, "bad type") self.assertEquals(listStruct.ob_size, SIZE, "bad ob_size") self.assertEquals(listStruct.allocated, SIZE, "bad allocated") dataPtr = listStruct.ob_item self.assertNotEquals(dataPtr, IntPtr.Zero, "failed to allocate space for data") expectedAllocs = [(dataPtr, (SIZE * CPyMarshal.PtrSize)), (listPtr, Marshal.SizeOf(PyListObject))] self.assertEquals(set(allocs), set(expectedAllocs), "allocated wrong") for _ in range(SIZE): self.assertEquals(CPyMarshal.ReadPtr(dataPtr), IntPtr.Zero, "failed to zero memory") dataPtr = OffsetPtr(dataPtr, CPyMarshal.PtrSize) mapper.Dispose() deallocTypes()
def testCreateStringWithData(self): allocs = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, [])) deallocTypes = CreateTypes(mapper) del allocs[:] try: testString = "we also run the shovel racket" + self.getStringWithValues( 0, 256) testBytes = self.byteArrayFromString(testString) testData = self.ptrFromByteArray(testBytes) testLength = len(testString) strPtr = mapper.PyString_FromStringAndSize(testData, testLength) baseSize = Marshal.SizeOf(PyStringObject) self.assertEquals(allocs, [(strPtr, testLength + baseSize)], "allocated wrong") self.assertHasStringType(strPtr, mapper) self.assertStringObjectHasLength(strPtr, testLength) self.assertStringObjectHasDataBytes(strPtr, testBytes) self.assertEquals(mapper.Retrieve(strPtr), testString, "failed to read string data") finally: mapper.Dispose() deallocTypes()
def testIC_PyBaseObject_Init(self, mapper, _): "this function shouldn't do anything..." mapper = PythonMapper() deallocTypes = CreateTypes(mapper) self.assertEquals(mapper.IC_PyBaseObject_Init(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero), 0) mapper.Dispose() deallocTypes()
def assertUsual_tp_dealloc(self, typename): mapper = PythonMapper() deallocTypes = CreateTypes(mapper) tp_deallocPtr = CPyMarshal.ReadPtrField( getattr(mapper, typename), PyTypeObject, "tp_dealloc") self.assertEquals(tp_deallocPtr, mapper.GetFuncPtr("IC_PyBaseObject_Dealloc"), "wrong tp_dealloc for " + typename) mapper.Dispose() deallocTypes()
def patched(*args): mapper = mapperCls() deallocTypes = CreateTypes(mapper) deallocs = [mapper.Dispose, deallocTypes] newArgs = args + (mapper, deallocs.append) mapper.EnsureGIL() try: return func(*newArgs) finally: mapper.ReleaseGIL() for dealloc in deallocs: dealloc()
def testDecRefObjectWithZeroRefCountFails(self): allocator = HGlobalAllocator() mapper = PythonMapper(allocator) deallocTypes = CreateTypes(mapper) # need to use same allocator as mapper, otherwise it gets upset on shutdown objPtr = allocator.Alloc(Marshal.SizeOf(PyObject())) CPyMarshal.WriteIntField(objPtr, PyObject, "ob_refcnt", 0) CPyMarshal.WritePtrField(objPtr, PyObject, "ob_type", mapper.PyBaseObject_Type) mapper.StoreBridge(objPtr, object()) self.assertRaisesClr(BadRefCountException, lambda: mapper.DecRef(objPtr)) mapper.Dispose() deallocTypes()
def testUnmanagedOpenCreatesCPyFile(self, mapper, addToCleanUp): argsPtr = mapper.Store(READ_ARGS) kwargsPtr = IntPtr.Zero deallocTypes = CreateTypes(mapper) addToCleanUp(deallocTypes) for kallable in (mapper.PyFile_Type, mapper.Store(open)): # ok, it seems these are the same object in ipy. # I doubt they always will be, though :-). filePtr = mapper.PyObject_Call(kallable, argsPtr, kwargsPtr) self.assertEquals(CPyMarshal.ReadPtrField(filePtr, PyObject, 'ob_type'), mapper.PyFile_Type) ipy_type = type(mapper.Retrieve(filePtr)) self.assertFalse(ipy_type is file, "we don't want ipy files used in c code") self.assertEquals(ipy_type.__name__, "cpy_file")
def testPyDict_GetItemSuccess(self): frees = [] mapper = PythonMapper(GetAllocatingTestAllocator([], frees)) deallocTypes = CreateTypes(mapper) dictPtr = mapper.Store({12345: 67890}) mapper.EnsureGIL() itemPtr = mapper.PyDict_GetItem(dictPtr, mapper.Store(12345)) self.assertEquals(mapper.Retrieve(itemPtr), 67890, "failed to get item") self.assertEquals(mapper.RefCount(itemPtr), 1, "something is wrong") mapper.ReleaseGIL() self.assertEquals(itemPtr in frees, True) mapper.Dispose() deallocTypes()
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 testGrow(self): allocs = [] frees = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, frees)) deallocTypes = CreateTypes(mapper) del allocs[:] oldLength = 20 testString = "slings and arrows" + self.getStringWithValues(0, 256) newLength = len(testString) oldStrPtr = mapper.PyString_FromStringAndSize(IntPtr.Zero, oldLength) ptrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(IntPtr)) try: Marshal.WriteIntPtr(ptrPtr, oldStrPtr) newStrPtr = IntPtr.Zero baseSize = Marshal.SizeOf(PyStringObject) self.assertEquals(allocs, [(oldStrPtr, oldLength + baseSize)], "allocated wrong") self.assertEquals(mapper._PyString_Resize(ptrPtr, newLength), 0, "bad return on success") newStrPtr = Marshal.ReadIntPtr(ptrPtr) expectedAllocs = [(oldStrPtr, oldLength + baseSize), (newStrPtr, newLength + baseSize)] self.assertEquals(allocs, expectedAllocs, "allocated wrong") self.assertEquals(frees, [oldStrPtr], "did not free unused memory") self.assertHasStringType(newStrPtr, mapper) self.assertStringObjectHasLength(newStrPtr, newLength) testBytes = self.byteArrayFromString(testString) self.fillStringDataWithBytes(newStrPtr, testBytes) self.assertEquals(mapper.Retrieve(newStrPtr), testString, "failed to read string data") if oldStrPtr != newStrPtr: # this would otherwise fail (very, very rarely) self.assertEquals(oldStrPtr in frees, True) finally: mapper.Dispose() Marshal.FreeHGlobal(ptrPtr) deallocTypes()
def test_Py_InitModule4_NoArgsFunction(self): mapper = PythonMapper() deallocTypes = CreateTypes(mapper) result = object() resultPtr = mapper.Store(result) mapper.IncRef(resultPtr) def func(_, __): self.assertEquals((_, __), (MODULE_PTR, IntPtr.Zero)) return resultPtr method, deallocMethod = MakeMethodDef("func", func, METH.NOARGS) def testModule(module, mapper): self.assertEquals(module.func(), result, "not hooked up") self.assert_Py_InitModule4_withSingleMethod(mapper, method, testModule) deallocMethod() deallocTypes()
def testTooBig(self): allocs = [] frees = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, frees)) deallocTypes = CreateTypes(mapper) mapper.EnsureGIL() mapper.ReleaseGIL() mem1 = getattr(mapper, MALLOC_NAME)(4) del allocs[:] self.assertEquals(getattr(mapper, REALLOC_NAME)(mem1, sys.maxint), IntPtr.Zero) self.assertMapperHasError(mapper, None) self.assertEquals(frees, []) self.assertEquals(allocs, []) mapper.Dispose() deallocTypes()
def testPyList_Append(self): allocs = [] deallocs = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, deallocs)) deallocTypes = CreateTypes(mapper) del allocs[:] listPtr = mapper.PyList_New(0) self.assertEquals(allocs, [(listPtr, Marshal.SizeOf(PyListObject))], "bad alloc") item1 = object() item2 = object() itemPtr1 = mapper.Store(item1) itemPtr2 = mapper.Store(item2) self.assertEquals(mapper.PyList_Append(listPtr, itemPtr1), 0, "failed to report success") self.assertEquals(len(allocs), 4, "didn't allocate memory for data store (list; item1; item2; data store comes 4th)") dataPtrAfterFirstAppend = CPyMarshal.ReadPtrField(listPtr, PyListObject, "ob_item") self.assertEquals(allocs[3], (dataPtrAfterFirstAppend, CPyMarshal.PtrSize), "allocated wrong amount of memory") self.assertEquals(CPyMarshal.ReadPtr(dataPtrAfterFirstAppend), itemPtr1, "failed to fill memory") self.assertEquals(mapper.RefCount(itemPtr1), 2, "failed to incref new contents") self.assertEquals(mapper.Retrieve(listPtr), [item1], "retrieved wrong list") # make refcount 1, to prove that references are not lost when reallocing data mapper.DecRef(itemPtr1) self.assertEquals(mapper.PyList_Append(listPtr, itemPtr2), 0, "failed to report success") self.assertEquals(len(allocs), 5, "didn't allocate memory for new, larger data store") self.assertEquals(deallocs, [dataPtrAfterFirstAppend]) dataPtrAfterSecondAppend = CPyMarshal.ReadPtrField(listPtr, PyListObject, "ob_item") self.assertEquals(allocs[4], (dataPtrAfterSecondAppend, (CPyMarshal.PtrSize * 2)), "allocated wrong amount of memory") self.assertEquals(CPyMarshal.ReadPtr(dataPtrAfterSecondAppend), itemPtr1, "failed to keep reference to first item") self.assertEquals(CPyMarshal.ReadPtr(OffsetPtr(dataPtrAfterSecondAppend, CPyMarshal.PtrSize)), itemPtr2, "failed to keep reference to first item") self.assertEquals(mapper.RefCount(itemPtr1), 1, "wrong refcount for item existing only in list") self.assertEquals(mapper.RefCount(itemPtr2), 2, "wrong refcount newly-added item") self.assertEquals(mapper.Retrieve(listPtr), [item1, item2], "retrieved wrong list") mapper.Dispose() deallocTypes()
def testPyList_New_ZeroLength(self): allocs = [] mapper = PythonMapper(GetAllocatingTestAllocator(allocs, [])) deallocTypes = CreateTypes(mapper) del allocs[:] listPtr = mapper.PyList_New(0) self.assertEquals(allocs, [(listPtr, Marshal.SizeOf(PyListObject))], "bad alloc") listStruct = Marshal.PtrToStructure(listPtr, PyListObject) self.assertEquals(listStruct.ob_refcnt, 1, "bad refcount") self.assertEquals(listStruct.ob_type, mapper.PyList_Type, "bad type") self.assertEquals(listStruct.ob_size, 0, "bad ob_size") self.assertEquals(listStruct.ob_item, IntPtr.Zero, "bad data pointer") self.assertEquals(listStruct.allocated, 0, "bad allocated") self.assertEquals(mapper.Retrieve(listPtr), [], "mapped to wrong object") mapper.Dispose() deallocTypes()
def test_Py_InitModule4_OldargsFunction_OneArg(self): mapper = PythonMapper() deallocTypes = CreateTypes(mapper) arg = object() result = object() resultPtr = mapper.Store(result) mapper.IncRef(resultPtr) def func(_, argPtr): self.assertEquals(_, MODULE_PTR) self.assertEquals(mapper.Retrieve(argPtr), arg) return resultPtr method, deallocMethod = MakeMethodDef("func", func, METH.OLDARGS) def testModule(module, mapper): self.assertEquals(module.func(arg), result, "not hooked up") self.assert_Py_InitModule4_withSingleMethod(mapper, method, testModule) deallocMethod() deallocTypes()