Beispiel #1
0
    def testUnmanagedThreadState(self, mapper, _):
        mapper.ReleaseGIL()
        # current thread state should be null if nobody has the GIL
        self.assertEquals(CPyMarshal.ReadPtr(mapper._PyThreadState_Current),
                          IntPtr.Zero)

        mapper.EnsureGIL()
        mapper.LastException = NameError("Harold")
        ts = CPyMarshal.ReadPtr(mapper._PyThreadState_Current)
        curexc_type = CPyMarshal.ReadPtrField(ts, PyThreadState, "curexc_type")
        curexc_value = CPyMarshal.ReadPtrField(ts, PyThreadState,
                                               "curexc_value")
        self.assertEquals(mapper.Retrieve(curexc_type), NameError)
        self.assertEquals(mapper.Retrieve(curexc_value), "Harold")
        mapper.ReleaseGIL()

        def CheckOtherThread():
            mapper.EnsureGIL()
            ts2 = CPyMarshal.ReadPtr(mapper._PyThreadState_Current)
            self.assertNotEquals(ts2, ts)
            curexc_type = CPyMarshal.ReadPtrField(ts2, PyThreadState,
                                                  "curexc_type")
            curexc_value = CPyMarshal.ReadPtrField(ts2, PyThreadState,
                                                   "curexc_value")
            self.assertEquals(curexc_type, IntPtr.Zero)
            self.assertEquals(curexc_value, IntPtr.Zero)
            mapper.ReleaseGIL()

        thread = Thread(ThreadStart(CheckOtherThread))
        thread.Start()
        thread.Join()
        mapper.EnsureGIL()
Beispiel #2
0
    def testReadyBuiltinTypes(self, mapper, _):
        mapper.ReadyBuiltinTypes()

        for _type in BUILTIN_TYPES:
            typePtr = getattr(mapper, _type)
            basePtr = CPyMarshal.ReadPtrField(typePtr, PyTypeObject, "tp_base")

            if typePtr != mapper.PySeqIter_Type:
                # PySeqIter_Type is suprrisingly tedious to turn into a proper PythonType in C#
                tp_dict = mapper.Retrieve(
                    CPyMarshal.ReadPtrField(typePtr, PyTypeObject, "tp_dict"))
                self.assertEquals(mapper.Retrieve(typePtr).__dict__, tp_dict)

            if typePtr not in (mapper.PyBaseObject_Type, mapper.PyBool_Type):
                self.assertEquals(
                    CPyMarshal.ReadPtrField(typePtr, PyTypeObject, "tp_base"),
                    mapper.PyBaseObject_Type)
            if typePtr == mapper.PyBool_Type:
                self.assertEquals(
                    CPyMarshal.ReadPtrField(typePtr, PyTypeObject, "tp_base"),
                    mapper.PyInt_Type)
            typeTypePtr = CPyMarshal.ReadPtrField(typePtr, PyTypeObject,
                                                  "ob_type")
            if typePtr != mapper.PyType_Type:
                self.assertEquals(typeTypePtr, mapper.PyType_Type)
Beispiel #3
0
    def testStoreSlice(self, mapper, _):
        obj = slice(1, 2, 3)
        objPtr = mapper.Store(obj)
        self.assertEquals(mapper.RefCount(objPtr), 1)
        self.assertEquals(mapper.Retrieve(objPtr), obj)

        self.assertEquals(
            CPyMarshal.ReadPtrField(objPtr, PySliceObject, "ob_type"),
            mapper.PySlice_Type)
        self.assertEquals(
            CPyMarshal.ReadIntField(objPtr, PySliceObject, "ob_refcnt"), 1)

        startPtr = CPyMarshal.ReadPtrField(objPtr, PySliceObject, "start")
        self.assertEquals(mapper.Retrieve(startPtr), 1)
        mapper.IncRef(startPtr)
        stopPtr = CPyMarshal.ReadPtrField(objPtr, PySliceObject, "stop")
        self.assertEquals(mapper.Retrieve(stopPtr), 2)
        mapper.IncRef(stopPtr)
        stepPtr = CPyMarshal.ReadPtrField(objPtr, PySliceObject, "step")
        self.assertEquals(mapper.Retrieve(stepPtr), 3)
        mapper.IncRef(stepPtr)

        mapper.DecRef(objPtr)
        self.assertEquals(mapper.RefCount(startPtr), 1)
        self.assertEquals(mapper.RefCount(stopPtr), 1)
        self.assertEquals(mapper.RefCount(stepPtr), 1)
Beispiel #4
0
 def testNumberMethods(self, mapper, _):
     numberTypes = ("PyInt_Type", "PyLong_Type", "PyFloat_Type", "PyComplex_Type")
     implementedFields = {
         "nb_int": mapper.GetFuncPtr("PyNumber_Int"),
         "nb_long": mapper.GetFuncPtr("PyNumber_Long"),
         "nb_float": mapper.GetFuncPtr("PyNumber_Float"),
         "nb_multiply": mapper.GetFuncPtr("PyNumber_Multiply")
     }
     
     for _type in numberTypes:
         typePtr = getattr(mapper, _type)
         nmPtr = CPyMarshal.ReadPtrField(typePtr, PyTypeObject, "tp_as_number")
         self.assertNotEquals(nmPtr, IntPtr.Zero)
         for field in implementedFields:
             fieldPtr = CPyMarshal.ReadPtrField(nmPtr, PyNumberMethods, field)
             self.assertNotEquals(fieldPtr, IntPtr.Zero)
             self.assertEquals(fieldPtr, implementedFields[field])
         
         flags = CPyMarshal.ReadIntField(typePtr, PyTypeObject, "tp_flags")
         hasIndex = bool(flags & int(Py_TPFLAGS.HAVE_INDEX))
         if (not _type in ("PyFloat_Type", "PyComplex_Type")):
             self.assertEquals(hasIndex, True, _type)
             fieldPtr = CPyMarshal.ReadPtrField(nmPtr, PyNumberMethods, "nb_index")
             self.assertNotEquals(fieldPtr, IntPtr.Zero)
             self.assertEquals(fieldPtr, mapper.GetFuncPtr("PyNumber_Index"))
         else:
             self.assertEquals(hasIndex, False)
Beispiel #5
0
 def testFields(self, mapper, CallLater):
     basePtr, deallocBase = MakeTypePtr(mapper, {})
     typePtr, deallocType = MakeTypePtr(mapper, {})
     CallLater(deallocBase)
     CallLater(deallocType)
     
     # The purpose of this rigmarole is to enable me to use SOME_VALUE
     # for every field, rather than creating 'proper' values for every 
     # field -- once I've Retrieved the types, I won't actualise them 
     # again, so I can put any old non-zero nonsense in any field to 
     # check that it gets inherited (or not)
     mapper.Retrieve(basePtr)
     mapper.Retrieve(typePtr)
     CPyMarshal.WriteIntField(typePtr, PyTypeObject, "tp_flags", int(Py_TPFLAGS.HAVE_CLASS))
     # end rigmarole
     
     CPyMarshal.WritePtrField(typePtr, PyTypeObject, "tp_base", basePtr)
     for field in INHERIT_FIELDS + DONT_INHERIT_FIELDS:
         CPyMarshal.WritePtrField(typePtr, PyTypeObject, field, NO_VALUE)
         CPyMarshal.WritePtrField(basePtr, PyTypeObject, field, SOME_VALUE)
     
     mapper.PyType_Ready(typePtr)
     for field in INHERIT_FIELDS:
         self.assertEquals(CPyMarshal.ReadPtrField(typePtr, PyTypeObject, field), SOME_VALUE)
     for field in DONT_INHERIT_FIELDS:
         self.assertEquals(CPyMarshal.ReadPtrField(typePtr, PyTypeObject, field), NO_VALUE)
Beispiel #6
0
    def testPyType_Ready(self, mapper, addToCleanUp):
        typePtr = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject()))
        CPyMarshal.Zero(typePtr, Marshal.SizeOf(PyTypeObject()))
        addToCleanUp(lambda: Marshal.FreeHGlobal(typePtr))

        self.assertEquals(mapper.PyType_Ready(typePtr), 0, "wrong")
        self.assertEquals(
            CPyMarshal.ReadPtrField(typePtr, PyTypeObject, "ob_type"),
            mapper.PyType_Type, "failed to fill in missing ob_type")
        self.assertEquals(
            CPyMarshal.ReadPtrField(typePtr, PyTypeObject, "tp_base"),
            mapper.PyBaseObject_Type, "failed to fill in missing tp_base")
        tp_dict = mapper.Retrieve(
            CPyMarshal.ReadPtrField(typePtr, PyTypeObject, "tp_dict"))
        self.assertEquals(mapper.Retrieve(typePtr).__dict__, tp_dict)

        typeFlags = CPyMarshal.ReadIntField(typePtr, PyTypeObject, "tp_flags")
        self.assertEquals(typeFlags & UInt32(Py_TPFLAGS.READY),
                          UInt32(Py_TPFLAGS.READY), "did not ready type")
        self.assertEquals(
            typeFlags & UInt32(Py_TPFLAGS.HAVE_CLASS),
            UInt32(Py_TPFLAGS.HAVE_CLASS),
            "we always set this flag, for no better reason than 'it makes ctypes kinda work'"
        )

        CPyMarshal.WritePtrField(typePtr, PyTypeObject, "ob_type", IntPtr.Zero)
        self.assertEquals(mapper.PyType_Ready(typePtr), 0, "wrong")
        self.assertEquals(
            CPyMarshal.ReadPtrField(typePtr, PyTypeObject, "ob_type"),
            IntPtr.Zero, "unexpectedly and unnecessarily rereadied type")
Beispiel #7
0
    def testTrueFalse(self, mapper, _):
        truePtr = Marshal.AllocHGlobal(Marshal.SizeOf(PyIntObject))
        mapper.RegisterData("_Py_TrueStruct", truePtr)
        self.assertTrue(mapper.Retrieve(truePtr) is True)
        self.assertEquals(
            CPyMarshal.ReadPtrField(truePtr, PyIntObject, 'ob_type'),
            mapper.PyBool_Type)
        self.assertEquals(
            CPyMarshal.ReadIntField(truePtr, PyIntObject, 'ob_refcnt'), 1)
        self.assertEquals(
            CPyMarshal.ReadIntField(truePtr, PyIntObject, 'ob_ival'), 1)
        truePtr2 = mapper.Store(True)
        self.assertEquals(truePtr2, truePtr)
        self.assertEquals(mapper.RefCount(truePtr), 2)

        falsePtr = Marshal.AllocHGlobal(Marshal.SizeOf(PyIntObject))
        mapper.RegisterData("_Py_ZeroStruct", falsePtr)
        self.assertTrue(mapper.Retrieve(falsePtr) is False)
        self.assertEquals(
            CPyMarshal.ReadPtrField(falsePtr, PyIntObject, 'ob_type'),
            mapper.PyBool_Type)
        self.assertEquals(
            CPyMarshal.ReadIntField(falsePtr, PyIntObject, 'ob_refcnt'), 1)
        self.assertEquals(
            CPyMarshal.ReadIntField(falsePtr, PyIntObject, 'ob_ival'), 0)
        falsePtr2 = mapper.Store(False)
        self.assertEquals(falsePtr2, falsePtr)
        self.assertEquals(mapper.RefCount(falsePtr), 2)
Beispiel #8
0
 def testStoreIPyFile(self, mapper, _):
     f = open(*READ_ARGS)
     fPtr = mapper.Store(f)
     self.assertEquals(CPyMarshal.ReadPtrField(fPtr, PyObject, 'ob_type'), mapper.PyFile_Type)
     self.assertEquals(CPyMarshal.ReadIntField(fPtr, PyObject, 'ob_refcnt'), 1)
     self.assertEquals(CPyMarshal.ReadIntField(fPtr, PyFileObject, 'f_fp'), -2)
     self.assertEquals(mapper.Retrieve(CPyMarshal.ReadPtrField(fPtr, PyFileObject, 'f_name')), READ_ARGS[0])
     self.assertEquals(mapper.Retrieve(CPyMarshal.ReadPtrField(fPtr, PyFileObject, 'f_mode')), READ_ARGS[1])
Beispiel #9
0
 def testBaseTypeMissing(self, mapper, CallLater):
     mapper.PyType_Ready(mapper.PyBaseObject_Type)
     self.assertEquals(CPyMarshal.ReadPtrField(mapper.PyBaseObject_Type, PyTypeObject, "tp_base"), IntPtr.Zero)
     
     typePtr, deallocType = MakeTypePtr(mapper, {})
     CallLater(deallocType)
     CPyMarshal.WritePtrField(typePtr, PyTypeObject, "tp_base", NO_VALUE)
     mapper.PyType_Ready(typePtr)
     self.assertEquals(CPyMarshal.ReadPtrField(typePtr, PyTypeObject, "tp_base"), mapper.PyBaseObject_Type)
Beispiel #10
0
    def testStringifiers(self, mapper, _):
        IC_PyString_Str = mapper.GetFuncPtr("IC_PyString_Str")
        tp_str = CPyMarshal.ReadPtrField(mapper.PyString_Type, PyTypeObject,
                                         "tp_str")
        self.assertEquals(tp_str, IC_PyString_Str)

        PyObject_Repr = mapper.GetFuncPtr("PyObject_Repr")
        tp_repr = CPyMarshal.ReadPtrField(mapper.PyString_Type, PyTypeObject,
                                          "tp_repr")
        self.assertEquals(tp_repr, PyObject_Repr)
Beispiel #11
0
 def CheckOtherThread():
     mapper.EnsureGIL()
     ts2 = CPyMarshal.ReadPtr(mapper._PyThreadState_Current)
     self.assertNotEquals(ts2, ts)
     curexc_type = CPyMarshal.ReadPtrField(ts2, PyThreadState,
                                           "curexc_type")
     curexc_value = CPyMarshal.ReadPtrField(ts2, PyThreadState,
                                            "curexc_value")
     self.assertEquals(curexc_type, IntPtr.Zero)
     self.assertEquals(curexc_value, IntPtr.Zero)
     mapper.ReleaseGIL()
Beispiel #12
0
    def testSequenceProtocol(self, mapper, _):
        strPtr = mapper.PyString_Type

        seqPtr = CPyMarshal.ReadPtrField(strPtr, PyTypeObject,
                                         'tp_as_sequence')
        self.assertNotEquals(seqPtr, IntPtr.Zero)
        concatPtr = CPyMarshal.ReadPtrField(seqPtr, PySequenceMethods,
                                            'sq_concat')
        # concat_core tested further down
        self.assertEquals(concatPtr,
                          mapper.GetFuncPtr('IC_PyString_Concat_Core'))
Beispiel #13
0
    def testStoreList(self, mapper, _):
        list_ = [1, 2, 3]
        listPtr = mapper.Store(list_)
        self.assertEquals(id(mapper.Retrieve(listPtr)), id(list_))
        
        typePtr = CPyMarshal.ReadPtrField(listPtr, PyObject, "ob_type")
        self.assertEquals(typePtr, mapper.PyList_Type, "wrong type")

        dataStore = CPyMarshal.ReadPtrField(listPtr, PyListObject, "ob_item")
        for i in range(1, 4):
            self.assertEquals(mapper.Retrieve(CPyMarshal.ReadPtr(dataStore)), i, "contents not stored")
            self.assertEquals(mapper.RefCount(CPyMarshal.ReadPtr(dataStore)), 1, "bad refcount for items")
            dataStore = OffsetPtr(dataStore, CPyMarshal.PtrSize)
Beispiel #14
0
    def testStoreTupleCreatesTupleType(self):
        allocs = []
        mapper = PythonMapper(GetAllocatingTestAllocator(allocs, []))

        typeBlock = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject()))
        mapper.RegisterData("PyTuple_Type", typeBlock)

        theTuple = (0, 1, 2)
        tuplePtr = mapper.Store(theTuple)
        self.assertEquals(
            CPyMarshal.ReadPtrField(tuplePtr, PyTupleObject, "ob_type"),
            typeBlock, "wrong type")

        dataPtr = OffsetPtr(tuplePtr, Marshal.OffsetOf(PyTupleObject,
                                                       "ob_item"))
        for i in range(3):
            item = mapper.Retrieve(CPyMarshal.ReadPtr(dataPtr))
            self.assertEquals(item, i, "did not store data")
            dataPtr = OffsetPtr(dataPtr, CPyMarshal.PtrSize)

        tuplePtr2 = mapper.Store(theTuple)
        self.assertEquals(tuplePtr2, tuplePtr,
                          "didn't realise already had this tuple")
        self.assertEquals(mapper.RefCount(tuplePtr), 2, "didn't incref")

        mapper.Dispose()
        Marshal.FreeHGlobal(typeBlock)
Beispiel #15
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()
Beispiel #16
0
    def testStoreTypeDictCreatesDictTypeWhichWorks(self, mapper, addToCleanUp):
        typeBlock = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject))
        addToCleanUp(lambda: Marshal.FreeHGlobal(typeBlock))
        mapper.RegisterData("PyDict_Type", typeBlock)

        class klass(object):
            pass

        dictPtr = mapper.Store(klass.__dict__)
        self.assertEquals(
            CPyMarshal.ReadPtrField(dictPtr, PyObject, "ob_type"), typeBlock,
            "wrong type")

        self.assertEquals(
            mapper.PyDict_SetItemString(dictPtr, 'foo', mapper.Store('bar')),
            0)
        self.assertEquals(
            mapper.PyDict_SetItem(dictPtr, mapper.Store('baz'),
                                  mapper.Store('qux')), 0)
        self.assertEquals(
            mapper.Retrieve(mapper.PyDict_GetItemString(dictPtr, 'foo')),
            'bar')
        self.assertEquals(
            mapper.Retrieve(mapper.PyDict_GetItem(dictPtr,
                                                  mapper.Store('baz'))), 'qux')
        self.assertEquals(klass.foo, 'bar')
        self.assertEquals(klass.baz, 'qux')
        self.assertEquals(mapper.PyDict_Size(dictPtr), len(klass.__dict__))
Beispiel #17
0
 def CreateInstance(mapper, calls):
     listPtr = mapper.Store([1, 2, 3])
     dataStore = CPyMarshal.ReadPtrField(listPtr, PyListObject, "ob_item")
     for _ in range(3):
         itemPtrs.append(CPyMarshal.ReadPtr(dataStore))
         dataStore = OffsetPtr(dataStore, CPyMarshal.PtrSize)
     return listPtr
    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()
Beispiel #19
0
def log_info(obj, size=None):
    """
    Print useful debugging information about the first argument.
    Optional second argument allows you to specify how many bytes of the object's
    unmanaged representation to print; it is not generally useful or wise to make
    use of it.
    """
    print
    print 'before storing:'
    _mapper.LogMappingInfo(id(obj))

    print
    print 'after storing:'
    objPtr = _mapper.Store(obj)
    if size is None:
        typePtr = CPyMarshal.ReadPtrField(objPtr, PyObject, "ob_type")
        size = CPyMarshal.ReadIntField(typePtr, PyTypeObject, "tp_basicsize")
        itemsize = CPyMarshal.ReadIntField(typePtr, PyTypeObject,
                                           "tp_itemsize")
        if itemsize > 0:
            itemcount = CPyMarshal.ReadIntField(objPtr, PyVarObject, "ob_size")
            size += itemcount * itemsize
    print 'printing %d bytes of object at %x' % (size, objPtr)
    CPyMarshal.Log(objPtr, size)
    print
    _mapper.DecRef(objPtr)
Beispiel #20
0
 def testTypeMappings(self, mapper, _):
     for (k, v) in BUILTIN_TYPES.items():
         typePtr = getattr(mapper, k)
         self.assertEquals(CPyMarshal.ReadCStringField(typePtr, PyTypeObject, 'tp_name'), v.__name__)
         
         if typePtr == mapper.PyFile_Type:
             self.assertNotEquals(mapper.Retrieve(typePtr), v, "failed to map PyFile_Type to something-that-isn't file")
         else:
             self.assertEquals(mapper.Retrieve(typePtr), v, "failed to map " + k)
         
         if typePtr in (mapper.PyType_Type, mapper.PyBaseObject_Type):
             # surprising refcount because of the unmanaged PyFile malarkey
             self.assertEquals(mapper.RefCount(typePtr), 2, "failed to add reference to " + k)
         else:
             self.assertEquals(mapper.RefCount(typePtr), 1, "failed to add reference to " + k)
         
         mapper.PyType_Ready(typePtr)
         self.assertNotEquals(CPyMarshal.ReadIntField(typePtr, PyTypeObject, "tp_basicsize"), 0)
         basePtr = CPyMarshal.ReadPtrField(typePtr, PyTypeObject, "tp_base")
         if k == "PyBaseObject_Type":
             self.assertEquals(basePtr, IntPtr.Zero)
         elif k == "PyBool_Type":
             self.assertEquals(basePtr, mapper.PyInt_Type)
         else:
             self.assertEquals(basePtr, mapper.PyBaseObject_Type)
Beispiel #21
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()
Beispiel #22
0
    def testBufferProtocol(self, mapper, later):
        # should all be implemented in C really, but weaving cpy string type into
        # our code feels too much like hard work for now
        strPtr = mapper.PyString_Type

        bufPtr = CPyMarshal.ReadPtrField(strPtr, PyTypeObject, 'tp_as_buffer')
        self.assertNotEquals(bufPtr, IntPtr.Zero)
        getreadbuffer = CPyMarshal.ReadFunctionPtrField(
            bufPtr, PyBufferProcs, 'bf_getreadbuffer', dgt_int_ptrintptr)
        getwritebuffer = CPyMarshal.ReadFunctionPtrField(
            bufPtr, PyBufferProcs, 'bf_getwritebuffer', dgt_int_ptrintptr)
        getcharbuffer = CPyMarshal.ReadFunctionPtrField(
            bufPtr, PyBufferProcs, 'bf_getcharbuffer', dgt_int_ptrintptr)
        getsegcount = CPyMarshal.ReadFunctionPtrField(bufPtr, PyBufferProcs,
                                                      'bf_getsegcount',
                                                      dgt_int_ptrptr)

        ptrptr = Marshal.AllocHGlobal(Marshal.SizeOf(IntPtr))
        later(lambda: Marshal.FreeHGlobal(ptrptr))

        strptr = mapper.Store("hullo")
        for getter in (getreadbuffer, getcharbuffer):
            self.assertEquals(getter(strptr, 0, ptrptr), 5)
            self.assertEquals(
                CPyMarshal.ReadPtr(ptrptr),
                CPyMarshal.GetField(strptr, PyStringObject, 'ob_sval'))
            self.assertEquals(getter(strptr, 1, ptrptr), -1)
            self.assertMapperHasError(mapper, SystemError)

        self.assertEquals(getwritebuffer(strptr, 0, ptrptr), -1)
        self.assertMapperHasError(mapper, SystemError)

        self.assertEquals(getsegcount(strptr, ptrptr), 1)
        self.assertEquals(CPyMarshal.ReadInt(ptrptr), 5)
        self.assertEquals(getsegcount(strptr, IntPtr.Zero), 1)
Beispiel #23
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()
Beispiel #24
0
 def testPyLong_FromUnsignedLongLong(self, mapper, _):
     for value in map(UInt64, (18000000000000000000, 0)):
         ptr = mapper.PyLong_FromUnsignedLongLong(value)
         self.assertEquals(mapper.Retrieve(ptr), value,
                           "stored/retrieved wrong")
         self.assertEquals(
             CPyMarshal.ReadPtrField(ptr, PyObject, "ob_type"),
             mapper.PyLong_Type, "bad type")
Beispiel #25
0
 def testStoreUnknownTypeWithBases(self, mapper, _):
     class C(object): pass
     class D(object): pass
     class E(C, D): pass
     
     ePtr = mapper.Store(E)
     basesPtr = CPyMarshal.ReadPtrField(ePtr, PyTypeObject, "tp_bases")
     self.assertEquals(mapper.Retrieve(basesPtr), (C, D))
Beispiel #26
0
 def testPyLong_FromDouble(self, mapper, _):
     for value in (0.0, 1.0, 12345678.9, -123456.789):
         ptr = mapper.PyLong_FromDouble(value)
         self.assertEquals(mapper.Retrieve(ptr), long(value),
                           "stored/retrieved wrong")
         self.assertEquals(
             CPyMarshal.ReadPtrField(ptr, PyObject, "ob_type"),
             mapper.PyLong_Type, "bad type")
Beispiel #27
0
 def testPyLong_FromLong(self, mapper, _):
     for value in (1555555555, -1555555555, 0):
         ptr = mapper.PyLong_FromLong(value)
         self.assertEquals(mapper.Retrieve(ptr), value,
                           "stored/retrieved wrong")
         self.assertEquals(
             CPyMarshal.ReadPtrField(ptr, PyObject, "ob_type"),
             mapper.PyLong_Type, "bad type")
Beispiel #28
0
    def testStoreDictCreatesDictType(self, mapper, addToCleanUp):
        typeBlock = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject))
        addToCleanUp(lambda: Marshal.FreeHGlobal(typeBlock))
        mapper.RegisterData("PyDict_Type", typeBlock)

        dictPtr = mapper.Store({0: 1, 2: 3})
        self.assertEquals(
            CPyMarshal.ReadPtrField(dictPtr, PyObject, "ob_type"), typeBlock,
            "wrong type")
Beispiel #29
0
 def testStoreLong(self, mapper, _):
     for value in (5555555555, -5555555555, long(0), UInt32.MaxValue):
         ptr = mapper.Store(value)
         self.assertEquals(mapper.Retrieve(ptr), value,
                           "stored/retrieved wrong")
         self.assertEquals(
             CPyMarshal.ReadPtrField(ptr, PyObject, "ob_type"),
             mapper.PyLong_Type, "bad type")
         mapper.DecRef(ptr)
Beispiel #30
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()