示例#1
0
    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()
示例#2
0
    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()
示例#4
0
    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()
示例#5
0
    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()
示例#6
0
    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()
示例#7
0
    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()
示例#8
0
    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()
示例#9
0
    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()
示例#10
0
 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()
示例#13
0
 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()
示例#14
0
    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()
示例#16
0
 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()
示例#17
0
    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()
示例#18
0
 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()
示例#19
0
 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()
示例#20
0
 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()
示例#21
0
    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()
示例#22
0
 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")
示例#23
0
    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()
示例#25
0
    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()
示例#26
0
 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()
示例#27
0
 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()
示例#28
0
    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()
示例#29
0
    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()
示例#30
0
 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()