Пример #1
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)
Пример #2
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()
Пример #3
0
 def create(name, size):
     block = Marshal.AllocHGlobal(size)
     if name == 'PyFile_Type':
         CPyMarshal.Zero(block, size);
         CPyMarshal.WritePtrField(block, PyTypeObject, 'tp_dealloc', mapper.GetFuncPtr('IC_file_dealloc'))
     mapper.RegisterData(name, block)
     blocks.append(block)
Пример #4
0
 def testPySequence_GetItem_DoesNotActualiseTuples(self, mapper, _):
     obj1 = object()
     obj1Ptr = mapper.Store(obj1)
     obj2 = object()
     obj2Ptr = mapper.Store(obj2)
     
     tuplePtr = mapper.PyTuple_New(1)
     CPyMarshal.WritePtrField(tuplePtr, PyTupleObject, "ob_item", obj1Ptr)
     
     # check that GetItem returns correct object, increffed
     self.assertEquals(mapper.PySequence_GetItem(tuplePtr, 0), obj1Ptr)
     self.assertEquals(CPyMarshal.ReadIntField(obj1Ptr, PyObject, "ob_refcnt"), 2)
     
     # replace item, check that correct object is retrieved
     CPyMarshal.WritePtrField(tuplePtr, PyTupleObject, "ob_item", obj2Ptr)
     self.assertEquals(mapper.Retrieve(tuplePtr), (obj2,))
Пример #5
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")
    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()
Пример #7
0
 def testActualiseFloat(self, mapper, call_later):
     fptr = Marshal.AllocHGlobal(Marshal.SizeOf(PyFloatObject))
     call_later(lambda: Marshal.FreeHGlobal(fptr))
     CPyMarshal.WritePtrField(fptr, PyFloatObject, "ob_type",
                              mapper.PyFloat_Type)
     CPyMarshal.WriteIntField(fptr, PyFloatObject, "ob_refcnt", 1)
     CPyMarshal.WriteDoubleField(fptr, PyFloatObject, "ob_fval", 1.234)
     self.assertEquals(mapper.Retrieve(fptr), 1.234)
Пример #8
0
 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
Пример #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)
Пример #10
0
    def testWritePtrField(self):
        data = Marshal.AllocHGlobal(Marshal.SizeOf(PyObject()))
        CPyMarshal.Zero(data, Marshal.SizeOf(PyObject()))

        CPyMarshal.WritePtrField(data, PyObject, "ob_type", IntPtr(12345))
        dataStruct = PtrToStructure(data, PyObject)
        self.assertEquals(dataStruct.ob_type, IntPtr(12345), "failed to write")

        Marshal.FreeHGlobal(data)
Пример #11
0
    def testReadCStringFieldEmpty(self):
        data = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject()))
        CPyMarshal.Zero(data, Marshal.SizeOf(PyTypeObject()))
        CPyMarshal.WritePtrField(data, PyTypeObject, "tp_doc", IntPtr.Zero)

        self.assertEquals(
            CPyMarshal.ReadCStringField(data, PyTypeObject, "tp_doc"), "",
            "failed to read correctly")

        Marshal.FreeHGlobal(data)
Пример #12
0
 def testNotAutoActualisableTypes(self, mapper, _):
     safeTypes = "PyString_Type PyList_Type PyTuple_Type PyType_Type PyFile_Type PyFloat_Type".split()
     discoveryModes = ("IncRef", "Retrieve", "DecRef", "RefCount")
     for _type in filter(lambda s: s not in safeTypes, BUILTIN_TYPES):
         for mode in discoveryModes:
             objPtr = Marshal.AllocHGlobal(Marshal.SizeOf(PyObject))
             CPyMarshal.WriteIntField(objPtr, PyObject, "ob_refcnt", 2)
             CPyMarshal.WritePtrField(objPtr, PyObject, "ob_type", getattr(mapper, _type))
             self.assertRaises(CannotInterpretException, getattr(mapper, mode), objPtr)
             Marshal.FreeHGlobal(objPtr)
Пример #13
0
    def testReadPtrField(self):
        data = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject()))
        CPyMarshal.Zero(data, Marshal.SizeOf(PyTypeObject()))

        CPyMarshal.WritePtrField(data, PyTypeObject, "tp_doc", IntPtr(12345))
        self.assertEquals(
            CPyMarshal.ReadPtrField(data, PyTypeObject, "tp_doc"),
            IntPtr(12345), "failed to read")

        Marshal.FreeHGlobal(data)
Пример #14
0
    def testFinalDecRefComplainsAboutMissing_tp_dealloc(self):
        frees = []
        mapper = PythonMapper(GetAllocatingTestAllocator([], frees))
        deallocTypes = CreateTypes(mapper)

        typePtr = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject()))
        CPyMarshal.WritePtrField(typePtr, PyTypeObject, "tp_dealloc", IntPtr.Zero)

        obj = object()
        objPtr = mapper.Store(obj)
        CPyMarshal.WritePtrField(objPtr, PyObject, "ob_type", typePtr)

        mapper.IncRef(objPtr)

        del frees [:]
        mapper.DecRef(objPtr)
        self.assertEquals(frees, [], "freed prematurely")
        self.assertRaisesClr(CannotInterpretException, mapper.DecRef, objPtr)

        mapper.Dispose()
        deallocTypes()
Пример #15
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
Пример #16
0
def WriteTypeField(typePtr, name, value):
    if name in PTR_ARGS:
        CPyMarshal.WritePtrField(typePtr, PyTypeObject, name, value)
        return lambda: None
    if name in INT_ARGS:
        CPyMarshal.WriteIntField(typePtr, PyTypeObject, name, int(value))
        return lambda: None
    if name in STRING_ARGS:
        ptr = Marshal.StringToHGlobalAnsi(value)
        CPyMarshal.WritePtrField(typePtr, PyTypeObject, name, ptr)
        return lambda: Marshal.FreeHGlobal(ptr)
    if name in TABLE_ARGS:
        ptr, dealloc = MakeItemsTablePtr(value)
        CPyMarshal.WritePtrField(typePtr, PyTypeObject, name, ptr)
        return dealloc
    if name in FUNC_ARGS:
        if value is not None:
            dgt = FUNC_ARGS[name](value)
            CPyMarshal.WriteFunctionPtrField(typePtr, PyTypeObject, name, dgt)
            return GC_NotYet(dgt)
        return lambda: None
    raise KeyError("WriteTypeField can't handle %s, %s" % (name, value))
Пример #17
0
    def testReadCStringField(self):
        data = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject()))
        CPyMarshal.Zero(data, Marshal.SizeOf(PyTypeObject()))
        string = "Hey, I am a string. I have tricksy \\escapes\\."
        strPtr = Marshal.StringToHGlobalAnsi(string)
        CPyMarshal.WritePtrField(data, PyTypeObject, "tp_doc", strPtr)

        self.assertEquals(
            CPyMarshal.ReadCStringField(data, PyTypeObject, "tp_doc"), string,
            "failed to read correctly")

        Marshal.FreeHGlobal(data)
        Marshal.FreeHGlobal(strPtr)
Пример #18
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()
Пример #19
0
            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
Пример #20
0
    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")
Пример #21
0
 def testFinalDecRefOfObjectWithTypeCalls_tp_dealloc(self, mapper, _):
     calls = []
     def TypeDealloc(ptr):
         calls.append(ptr)
     deallocDgt = dgt_void_ptr(TypeDealloc)
     deallocFP = Marshal.GetFunctionPointerForDelegate(deallocDgt)
     
     typePtr = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject()))
     deallocPtr = CPyMarshal.Offset(typePtr, Marshal.OffsetOf(PyTypeObject, "tp_dealloc"))
     CPyMarshal.WritePtr(deallocPtr, deallocFP)
     
     obj = object()
     objPtr = mapper.Store(obj)
     CPyMarshal.WritePtrField(objPtr, PyObject, "ob_type", typePtr)
     
     mapper.IncRef(objPtr)
     mapper.DecRef(objPtr)
     self.assertEquals(calls, [], "called prematurely")
     mapper.DecRef(objPtr)
     self.assertEquals(calls, [objPtr], "not called when refcount hit 0")
Пример #22
0
    def testStoreUnknownType(self, mapper, _):
        class C(object):
            __name__ = "cantankerous.cochineal"
        cPtr = mapper.Store(C)
        self.assertEquals(CPyMarshal.ReadIntField(cPtr, PyTypeObject, "ob_refcnt"), 2, "seems easiest to 'leak' types, and ensure they live forever")
        self.assertEquals(CPyMarshal.ReadPtrField(cPtr, PyTypeObject, "ob_type"), mapper.PyType_Type)
        self.assertEquals(CPyMarshal.ReadPtrField(cPtr, PyTypeObject, "tp_base"), mapper.PyBaseObject_Type)
        self.assertEquals(CPyMarshal.ReadPtrField(cPtr, PyTypeObject, "tp_bases"), IntPtr.Zero)
        self.assertEquals(CPyMarshal.ReadPtrField(cPtr, PyTypeObject, "tp_as_number"), IntPtr.Zero)

        namePtr = CPyMarshal.ReadPtrField(cPtr, PyTypeObject, "tp_name")
        self.assertEquals(mapper.Retrieve(namePtr), "cantankerous.cochineal")

        baseFlags = CPyMarshal.ReadIntField(cPtr, PyTypeObject, "tp_flags")
        self.assertEquals(baseFlags & UInt32(Py_TPFLAGS.READY), UInt32(Py_TPFLAGS.READY), "did not ready newly-stored type")
        
        instancePtr = Marshal.AllocHGlobal(Marshal.SizeOf(PyObject))
        CPyMarshal.WritePtrField(instancePtr, PyObject, "ob_type", cPtr)
        CPyMarshal.WriteIntField(instancePtr, PyObject, "ob_refcnt", 2)
        
        instance = mapper.Retrieve(instancePtr)
        self.assertEquals(isinstance(instance, C), True)
        self.assertEquals(mapper.Store(instance), instancePtr)