def testCreateEllipsis(self, mapper, addToCleanUp): ellipsisTypePtr = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject)) addToCleanUp(lambda: Marshal.FreeHGlobal(ellipsisTypePtr)) ellipsisPtr = Marshal.AllocHGlobal(Marshal.SizeOf(PyObject)) addToCleanUp(lambda: Marshal.FreeHGlobal(ellipsisPtr)) mapper.RegisterData("PyEllipsis_Type", ellipsisTypePtr) mapper.RegisterData("_Py_EllipsisObject", ellipsisPtr) self.assertEquals( CPyMarshal.ReadPtrField(ellipsisPtr, PyObject, "ob_type"), mapper.PyEllipsis_Type) self.assertEquals( CPyMarshal.ReadIntField(ellipsisPtr, PyObject, "ob_refcnt"), 1) self.assertEquals(mapper.Store(Ellipsis), ellipsisPtr) self.assertEquals(mapper.RefCount(ellipsisPtr), 2)
def testWriteDoubleField(self): data = Marshal.AllocHGlobal(Marshal.SizeOf(PyFloatObject())) CPyMarshal.Zero(data, Marshal.SizeOf(PyFloatObject())) CPyMarshal.WriteDoubleField(data, PyFloatObject, "ob_fval", 7.6e-5) dataStruct = PtrToStructure(data, PyFloatObject) self.assertEquals(dataStruct.ob_fval, 7.6e-5) Marshal.FreeHGlobal(data)
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)
def testWorksWithNonString(self, mapper, addDealloc): dataPtrPtr = Marshal.AllocHGlobal(CPyMarshal.PtrSize * 2) sizePtr = CPyMarshal.Offset(dataPtrPtr, CPyMarshal.PtrSize) addDealloc(lambda: Marshal.FreeHGlobal(dataPtrPtr)) self.assertEquals( mapper.PyString_AsStringAndSize(mapper.Store(object()), dataPtrPtr, sizePtr), -1) self.assertMapperHasError(mapper, TypeError)
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")
def testFills(self, mapper, addToCleanUp): # TODO: if we set a lower value, numpy will crash inside arr_add_docstring # I consider docstrings to be low-priority-enough that it's OK to fudge this # for now. also, fixing it would be hard ;). flagPtr = Marshal.AllocHGlobal(Marshal.SizeOf(Int32)) addToCleanUp(lambda: Marshal.FreeHGlobal(flagPtr)) mapper.RegisterData("Py_OptimizeFlag", flagPtr) self.assertEquals(CPyMarshal.ReadInt(flagPtr), 2)
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)
def testReadPtr(self): data = Marshal.AllocHGlobal(CPyMarshal.PtrSize) Marshal.WriteIntPtr(data, IntPtr(0)) self.assertEquals(CPyMarshal.ReadPtr(data), IntPtr(0), "wrong") Marshal.WriteIntPtr(data, IntPtr(100001)) self.assertEquals(CPyMarshal.ReadPtr(data), IntPtr(100001), "wrong") Marshal.FreeHGlobal(data)
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)
def testReadByte(self): data = Marshal.AllocHGlobal(1) Marshal.WriteByte(data, 0) self.assertEquals(CPyMarshal.ReadByte(data), 0, "wrong") Marshal.WriteByte(data, 255) self.assertEquals(CPyMarshal.ReadByte(data), 255, "wrong") Marshal.FreeHGlobal(data)
def testWriteUInt(self): data = Marshal.AllocHGlobal(CPyMarshal.IntSize) CPyMarshal.WriteUInt(data, 0) self.assertEquals(Marshal.ReadInt32(data), 0, "wrong") CPyMarshal.WriteUInt(data, 0xFFFFFFFF) self.assertEquals(Marshal.ReadInt32(data), -1, "wrong") Marshal.FreeHGlobal(data)
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)
def testReadDoubleField(self): data = Marshal.AllocHGlobal(Marshal.SizeOf(PyFloatObject())) CPyMarshal.Zero(data, Marshal.SizeOf(PyFloatObject())) CPyMarshal.WriteDoubleField(data, PyFloatObject, "ob_fval", -1.2e34) self.assertEquals( CPyMarshal.ReadDoubleField(data, PyFloatObject, "ob_fval"), -1.2e34) Marshal.FreeHGlobal(data)
def testWriteIntField(self): data = Marshal.AllocHGlobal(Marshal.SizeOf(PyIntObject())) CPyMarshal.Zero(data, Marshal.SizeOf(PyIntObject())) for value in (Int32.MaxValue, Int32.MinValue): CPyMarshal.WriteIntField(data, PyIntObject, "ob_ival", value) dataStruct = PtrToStructure(data, PyIntObject) self.assertEquals(dataStruct.ob_ival, value, "failed to write") Marshal.FreeHGlobal(data)
def testReadUInt(self): data = Marshal.AllocHGlobal(CPyMarshal.IntSize) Marshal.WriteInt32(data, 0) self.assertEquals(CPyMarshal.ReadUInt(data), 0, "wrong") Marshal.WriteInt32(data, -1) self.assertEquals(CPyMarshal.ReadUInt(data), 0xFFFFFFFF, "wrong") Marshal.FreeHGlobal(data)
def testPyObject_Init(self, mapper, addToCleanUp): typePtr, deallocType = MakeTypePtr(mapper, {'tp_name': 'FooType'}) addToCleanUp(deallocType) objPtr = Marshal.AllocHGlobal(Marshal.SizeOf(PyObject())) addToCleanUp(lambda: Marshal.FreeHGlobal(objPtr)) self.assertEquals(mapper.PyObject_Init(objPtr, typePtr), objPtr, 'did not return the "new instance"') self.assertEquals(CPyMarshal.ReadPtrField(objPtr, PyObject, "ob_type"), typePtr, "wrong type") self.assertEquals(CPyMarshal.ReadIntField(objPtr, PyObject, "ob_refcnt"), 1, "wrong refcount") self.assertEquals(mapper.HasPtr(objPtr), False)
def testReadIntField(self): data = Marshal.AllocHGlobal(Marshal.SizeOf(PyIntObject())) CPyMarshal.Zero(data, Marshal.SizeOf(PyIntObject())) for value in (Int32.MaxValue, Int32.MinValue): CPyMarshal.WriteIntField(data, PyIntObject, "ob_ival", value) self.assertEquals( CPyMarshal.ReadIntField(data, PyIntObject, "ob_ival"), value, "failed to read") Marshal.FreeHGlobal(data)
def assertDataSetterSetsAndRemembers(self, mapperSubclass, dataSymbol, allocSize, memoryTest): dataPtr = Marshal.AllocHGlobal(allocSize) mapper = mapperSubclass() mapper.RegisterData(dataSymbol, dataPtr) memoryTest(dataPtr) self.assertEquals(getattr(mapper, dataSymbol), dataPtr, "failed to remember pointer") Marshal.FreeHGlobal(dataPtr)
def testWriteUIntField(self): data = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject())) CPyMarshal.Zero(data, Marshal.SizeOf(PyTypeObject())) for value in (UInt32.MaxValue, UInt32.MinValue): CPyMarshal.WriteUIntField(data, PyTypeObject, "tp_version_tag", value) dataStruct = PtrToStructure(data, PyTypeObject) self.assertEquals(dataStruct.tp_version_tag, value, "failed to write") Marshal.FreeHGlobal(data)
def testWriteCStringField(self): data = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject())) CPyMarshal.Zero(data, Marshal.SizeOf(PyTypeObject())) string = "Hey, I am a string. I have tricksy \\escapes\\." CPyMarshal.WriteCStringField(data, PyTypeObject, "tp_doc", string) self.assertEquals( CPyMarshal.ReadCStringField(data, PyTypeObject, "tp_doc"), string, "failed to read correctly") Marshal.FreeHGlobal( CPyMarshal.ReadPtrField(data, PyTypeObject, "tp_doc")) Marshal.FreeHGlobal(data)
def testReadUIntField(self): data = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject())) CPyMarshal.Zero(data, Marshal.SizeOf(PyTypeObject())) for value in (UInt32.MaxValue, UInt32.MinValue): CPyMarshal.WriteUIntField(data, PyTypeObject, "tp_version_tag", value) self.assertEquals( CPyMarshal.ReadUIntField(data, PyTypeObject, "tp_version_tag"), value, "failed to read") Marshal.FreeHGlobal(data)
def testIC_PyFile_AsFile_Exhaustion(self, mapper, _, __): argsPtr = mapper.Store(READ_ARGS) kwargsPtr = IntPtr.Zero buflen = len(TEST_TEXT) + 10 buf = Marshal.AllocHGlobal(buflen) for _ in range(1000): filePtr = mapper.Store(open(*READ_ARGS)) FILE = mapper.IC_PyFile_AsFile(filePtr) self.assertNotEquals(FILE, IntPtr.Zero, "exhausted") mapper.Retrieve(filePtr).close() # note: we don't call fclose until the file is destroyed, rather than closed # we don't *think* this will be a problem in normal use mapper.DecRef(filePtr)
def testIC_PyFile_AsFile(self, mapper, addToCleanUp, stderr_writes): buflen = len(TEST_TEXT) + 10 buf = Marshal.AllocHGlobal(buflen) filePtr = mapper.Store(open(*READ_ARGS)) f = mapper.IC_PyFile_AsFile(filePtr) self.assertEquals(stderr_writes, [('Warning: creating unmanaged FILE* from managed stream. Please use ironclad.open with this extension.',), ('\n',)]) self.assertEquals(Unmanaged.fread(buf, 1, buflen, f), len(TEST_TEXT), "didn't get a real FILE") ptr = buf for c in TEST_TEXT: self.assertEquals(Marshal.ReadByte(ptr), ord(c), "got bad data from FILE") ptr = OffsetPtr(ptr, 1) Marshal.FreeHGlobal(buf)
def MakeNumSeqMapMethods(_type, slots): size = Marshal.SizeOf(_type()) ptr = Marshal.AllocHGlobal(size) CPyMarshal.Zero(ptr, size) deallocs = [] for (slot, func) in slots.items(): dgt = NUMSEQMAP_METHODS[slot](func) CPyMarshal.WriteFunctionPtrField(ptr, _type, slot, dgt) deallocs.append(GC_NotYet(dgt)) def dealloc(): for f in deallocs: f() Marshal.FreeHGlobal(ptr) return ptr, dealloc
def testCanChangeValuesDuringIteration(self, mapper, addDealloc): posPtr = Marshal.AllocHGlobal(CPyMarshal.PtrSize * 3) keyPtrPtr = CPyMarshal.Offset(posPtr, CPyMarshal.PtrSize) valuePtrPtr = CPyMarshal.Offset(keyPtrPtr, CPyMarshal.PtrSize) addDealloc(lambda: Marshal.FreeHGlobal(posPtr)) CPyMarshal.WriteInt(posPtr, 0) d = dict(a=1, b=2, c=3) dPtr = mapper.Store(d) while mapper.PyDict_Next(dPtr, posPtr, keyPtrPtr, valuePtrPtr) != 0: key = mapper.Retrieve(CPyMarshal.ReadPtr(keyPtrPtr)) value = mapper.Retrieve(CPyMarshal.ReadPtr(valuePtrPtr)) d[key] = value * 10 self.assertEquals(d, dict(a=10, b=20, c=30))
def testErrorCaseSecondArg(self, mapper, addToCleanup): part1Ptr = mapper.Store(17) mapper.IncRef(part1Ptr) # avoid garbage collection startingRefCnt = mapper.RefCount(part1Ptr) part2Ptr = mapper.Store("three") stringPtrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(IntPtr)) addToCleanup(lambda: Marshal.FreeHGlobal(stringPtrPtr)) Marshal.WriteIntPtr(stringPtrPtr, part1Ptr) mapper.PyString_Concat(stringPtrPtr, part2Ptr) self.assertMapperHasError(mapper, TypeError) self.assertEquals(Marshal.ReadIntPtr(stringPtrPtr), IntPtr(0)) self.assertEquals(startingRefCnt - mapper.RefCount(part1Ptr), 1)
def MakeItemsTablePtr(items): if not items: return IntPtr.Zero, lambda: None itemtype = items[0].__class__ typesize = Marshal.SizeOf(itemtype()) size = typesize * (len(items) + 1) tablePtr = Marshal.AllocHGlobal(size) CPyMarshal.Zero(tablePtr, size) for i, item in enumerate(items): Marshal.StructureToPtr(item, OffsetPtr(tablePtr, typesize * i), False) def dealloc(): Marshal.DestroyStructure(tablePtr, itemtype) Marshal.FreeHGlobal(tablePtr) return tablePtr, dealloc
def testIteratesSuccessfully(self, mapper, addDealloc): posPtr = Marshal.AllocHGlobal(CPyMarshal.PtrSize * 3) keyPtrPtr = CPyMarshal.Offset(posPtr, CPyMarshal.PtrSize) valuePtrPtr = CPyMarshal.Offset(keyPtrPtr, CPyMarshal.PtrSize) addDealloc(lambda: Marshal.FreeHGlobal(posPtr)) CPyMarshal.WriteInt(posPtr, 0) d = dict(a=1, b=2, c=3) dPtr = mapper.Store(d) result = {} while mapper.PyDict_Next(dPtr, posPtr, keyPtrPtr, valuePtrPtr) != 0: key = mapper.Retrieve(CPyMarshal.ReadPtr(keyPtrPtr)) value = mapper.Retrieve(CPyMarshal.ReadPtr(valuePtrPtr)) result[key] = value self.assertEquals(result, d)
def testBasic(self, mapper, addToCleanup): part1Ptr = mapper.Store("one two") mapper.IncRef(part1Ptr) # avoid garbage collection part2Ptr = mapper.Store(" three") startingRefCnt = mapper.RefCount(part1Ptr) stringPtrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(IntPtr)) addToCleanup(lambda: Marshal.FreeHGlobal(stringPtrPtr)) Marshal.WriteIntPtr(stringPtrPtr, part1Ptr) mapper.PyString_Concat(stringPtrPtr, part2Ptr) self.assertMapperHasError(mapper, None) newStringPtr = Marshal.ReadIntPtr(stringPtrPtr) self.assertEquals(mapper.Retrieve(newStringPtr), "one two three") self.assertEquals(startingRefCnt - mapper.RefCount(part1Ptr), 1)
def testNotADict(self, mapper, addDealloc): posPtr = Marshal.AllocHGlobal(CPyMarshal.PtrSize) addDealloc(lambda: Marshal.FreeHGlobal(posPtr)) CPyMarshal.WriteInt(posPtr, 0) self.assertEquals( mapper.PyDict_Next(mapper.Store(object()), posPtr, IntPtr.Zero, IntPtr.Zero), 0) self.assertMapperHasError(mapper, TypeError)