ctypes-commit Mailing List for ctypes (Page 82)
Brought to you by:
theller
You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
(8) |
May
(90) |
Jun
(143) |
Jul
(106) |
Aug
(94) |
Sep
(84) |
Oct
(163) |
Nov
(60) |
Dec
(58) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(128) |
Feb
(79) |
Mar
(227) |
Apr
(192) |
May
(179) |
Jun
(41) |
Jul
(53) |
Aug
(103) |
Sep
(28) |
Oct
(38) |
Nov
(81) |
Dec
(17) |
2006 |
Jan
(184) |
Feb
(111) |
Mar
(188) |
Apr
(67) |
May
(58) |
Jun
(123) |
Jul
(73) |
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
From: Thomas H. <th...@us...> - 2004-12-02 08:02:49
|
Update of /cvsroot/ctypes/ctypes/win32/com In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8036 Modified Files: __init__.py Log Message: Inheritance of the _fields_ attribute now works correctly: It is possible to extend, but not replace the _fields_ attribute in Structure sub-subclasses. Added a strange hack to be able to still have the old behaviour. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/win32/com/__init__.py,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** __init__.py 29 Oct 2004 18:54:55 -0000 1.41 --- __init__.py 2 Dec 2004 08:02:39 -0000 1.42 *************** *** 195,198 **** --- 195,199 ---- class IUnknown(Structure): + _use_broken_old_ctypes_structure_semantics_ = None # hack, hack __metaclass__ = _interface_meta _iid_ = GUID("{00000000-0000-0000-C000-000000000046}") |
From: Thomas H. <th...@us...> - 2004-12-02 08:00:10
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7385 Modified Files: stgdict.c Log Message: Inheritance of the _fields_ attribute now works correctly: It is possible to extend, but not replace the _fields_ attribute in Structure sub-subclasses. Added a strange hack to be able to still have the old behaviour. Index: stgdict.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/stgdict.c,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** stgdict.c 19 Nov 2004 11:07:22 -0000 1.26 --- stgdict.c 2 Dec 2004 08:00:00 -0000 1.27 *************** *** 168,172 **** StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) { ! StgDictObject *stgdict; int len, offset, size, align, i; int union_size, total_align; --- 168,172 ---- StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) { ! StgDictObject *stgdict, *basedict; int len, offset, size, align, i; int union_size, total_align; *************** *** 175,182 **** --- 175,199 ---- PyObject *isPacked; int pack = 0; + int ffi_ofs; + /* HACK Alert: I cannot be bothered to fix ctypes.com, so there has to + be a way to use the old, broken sematics: _fields_ are not extended + but replaced in subclasses. + + XXX Remove this in ctypes 1.0! + */ + int use_broken_old_ctypes_semantics; + PyObject *py_use_broken_old_ctypes_semantics; if (fields == NULL) return 0; + py_use_broken_old_ctypes_semantics = \ + PyObject_GetAttrString(type, "_use_broken_old_ctypes_structure_semantics_"); + if (py_use_broken_old_ctypes_semantics) { + use_broken_old_ctypes_semantics = 1; + Py_DECREF(py_use_broken_old_ctypes_semantics); + } else + PyErr_Clear(); + isPacked = PyObject_GetAttrString(type, "_pack_"); if (isPacked) { *************** *** 205,218 **** if (stgdict->ffi_type.elements) PyMem_Free(stgdict->ffi_type.elements); - - offset = 0; - size = 0; - align = 0; - union_size = 0; - total_align = 1; ! stgdict->ffi_type.type = FFI_TYPE_STRUCT; ! stgdict->ffi_type.elements = PyMem_Malloc(sizeof(ffi_type *) * (len + 1)); ! memset(stgdict->ffi_type.elements, 0, sizeof(ffi_type *) * (len + 1)); #define realdict ((PyObject *)&stgdict->dict) --- 222,249 ---- if (stgdict->ffi_type.elements) PyMem_Free(stgdict->ffi_type.elements); ! basedict = PyType_stgdict(((PyTypeObject *)type)->tp_base); ! if (basedict && !use_broken_old_ctypes_semantics) { ! size = offset = basedict->size; ! align = basedict->align; ! union_size = 0; ! total_align = align ? align : 1; ! stgdict->ffi_type.type = FFI_TYPE_STRUCT; ! stgdict->ffi_type.elements = PyMem_Malloc(sizeof(ffi_type *) * (basedict->length + len + 1)); ! memset(stgdict->ffi_type.elements, 0, sizeof(ffi_type *) * (basedict->length + len + 1)); ! memcpy(stgdict->ffi_type.elements, basedict->ffi_type.elements, ! sizeof(ffi_type *) * (basedict->length)); ! ffi_ofs = basedict->length; ! } else { ! offset = 0; ! size = 0; ! align = 0; ! union_size = 0; ! total_align = 1; ! stgdict->ffi_type.type = FFI_TYPE_STRUCT; ! stgdict->ffi_type.elements = PyMem_Malloc(sizeof(ffi_type *) * (len + 1)); ! memset(stgdict->ffi_type.elements, 0, sizeof(ffi_type *) * (len + 1)); ! ffi_ofs = 0; ! } #define realdict ((PyObject *)&stgdict->dict) *************** *** 232,236 **** dict = PyType_stgdict(desc); if (dict) ! stgdict->ffi_type.elements[i] = &dict->ffi_type; if (PyTuple_Size(pair) == 3) { /* bits specified */ switch(dict->ffi_type.type) { --- 263,267 ---- dict = PyType_stgdict(desc); if (dict) ! stgdict->ffi_type.elements[ffi_ofs + i] = &dict->ffi_type; if (PyTuple_Size(pair) == 3) { /* bits specified */ switch(dict->ffi_type.type) { *************** *** 308,312 **** stgdict->size = size; stgdict->align = total_align; ! stgdict->length = len; return 0; } --- 339,343 ---- stgdict->size = size; stgdict->align = total_align; ! stgdict->length = len; /* ADD ffi_ofs? */ return 0; } |
From: Thomas H. <th...@us...> - 2004-12-01 14:52:14
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3788 Modified Files: test_keeprefs.py test_internals.py Log Message: Adapted the tests to the optimization done. Index: test_keeprefs.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_keeprefs.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_keeprefs.py 30 Nov 2004 19:38:19 -0000 1.2 --- test_keeprefs.py 1 Dec 2004 14:52:04 -0000 1.3 *************** *** 5,14 **** def test_cint(self): x = c_int() - # a simple object has an empty _objects dict, if uninitialized self.assertEquals(x._objects, None) - # setting the value populates the dict x.value = 42 self.assertEquals(x._objects, None) - x = c_int(99) self.assertEquals(x._objects, None) --- 5,11 ---- *************** *** 16,25 **** def test_ccharp(self): x = c_char_p() - # a simple object has an empty _objects dict, if uninitialized self.assertEquals(x._objects, None) - # setting the value populates the dict x.value = "abc" self.assertEquals(x._objects, "abc") - x = c_char_p("spam") self.assertEquals(x._objects, "spam") --- 13,19 ---- *************** *** 33,40 **** x = X() self.assertEquals(x._objects, None) - x.a = 42 x.b = 99 ! self.assertEquals(x._objects, {"0": None, "1": None}) def test_ccharp_struct(self): --- 27,33 ---- x = X() self.assertEquals(x._objects, None) x.a = 42 x.b = 99 ! self.assertEquals(x._objects, None) def test_ccharp_struct(self): *************** *** 60,79 **** r.lr.x = 2 r.lr.y = 3 ! self.assertEquals(r._objects, ! {'00': None, '01': None, '10': None, '11': None}) r = RECT() ! r.ul = POINT(1, 2) ! self.assertEquals(r._objects, {'0': {'0': None, '1': None}}) r.ul.x = 22 r.ul.y = 44 ! # The current solution retains unneeded objects as well: ! self.assertEquals(r._objects, ! {'0': {'0': None, '1': None}, # r.ul = POINT(1, 2) ! '00': None, # r.ul.x = 22 ! '10': None}) # r.ul.x = 44 ! # The entry marked '<-' above is no longer needed, it refers to the ! # POINT we have assigned, but the coords are already overwritten. ! # But, oh well... class ArrayTestCase(unittest.TestCase): --- 53,65 ---- r.lr.x = 2 r.lr.y = 3 ! self.assertEquals(r._objects, None) r = RECT() ! pt = POINT(1, 2) ! r.ul = pt ! self.assertEquals(r._objects, {'0': {}}) r.ul.x = 22 r.ul.y = 44 ! self.assertEquals(r._objects, {'0': {}}) class ArrayTestCase(unittest.TestCase): *************** *** 86,90 **** ia[1] = 2 ia[2] = 3 ! self.assertEquals(ia._objects, {"0": None, "1": None, "2": None}) class X(Structure): --- 72,76 ---- ia[1] = 2 ia[2] = 3 ! self.assertEquals(ia._objects, None) class X(Structure): *************** *** 96,108 **** x.a[0] = 42 x.a[1] = 96 ! self.assertEquals(x._objects, {"0": None, "01": None, "11": None}) ! x.a = ia ! self.assertEquals(x._objects, ! {'0': None, ! '1': {'0': None, '1': None, '2': None}, ! '01': None, ! '11': None}) ! # See above, some entries unneeded. class PointerTestCase(unittest.TestCase): --- 82,88 ---- x.a[0] = 42 x.a[1] = 96 ! self.assertEquals(x._objects, None) x.a = ia ! self.assertEquals(x._objects, {'1': {}}) class PointerTestCase(unittest.TestCase): *************** *** 142,161 **** print x._objects ! ##class PointerToStructure(unittest.TestCase): ! ## def test(self): ! ## class POINT(Structure): ! ## _fields_ = [("x", c_int), ("y", c_int)] ! ## class RECT(Structure): ! ## _fields_ = [("a", POINTER(POINT)), ! ## ("b", POINTER(POINT))] ! ## r = RECT() ! ## p1 = POINT(1, 2) ! ## p2 = POINT(3, 4) ! ## r.a = pointer(p1) ! ## r.a[0].x = 42 ! ## r.a[0].y = 99 ! ## r.b = pointer(p2) if __name__ == "__main__": --- 122,143 ---- print x._objects ! class PointerToStructure(unittest.TestCase): ! def test(self): ! class POINT(Structure): ! _fields_ = [("x", c_int), ("y", c_int)] ! class RECT(Structure): ! _fields_ = [("a", POINTER(POINT)), ! ("b", POINTER(POINT))] ! r = RECT() ! p1 = POINT(1, 2) ! r.a = pointer(p1) ! r.b = pointer(p1) ! from pprint import pprint as pp ! pp(p1._objects) ! pp(r._objects) ! r.a[0].x = 42 ! r.a[0].y = 99 if __name__ == "__main__": Index: test_internals.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_internals.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_internals.py 30 Nov 2004 19:38:19 -0000 1.5 --- test_internals.py 1 Dec 2004 14:52:04 -0000 1.6 *************** *** 46,50 **** x.a = a x.b = b ! self.failUnlessEqual(x._objects, {"0": None, "1": None}) def test_embedded_structs(self): --- 46,50 ---- x.a = a x.b = b ! self.failUnlessEqual(x._objects, None) def test_embedded_structs(self): *************** *** 62,66 **** self.failUnlessEqual(y._objects, {"0": {}, "1": {}}) x1.a, x2.b = 42, 93 ! self.failUnlessEqual(y._objects, {"0": {"0": None}, "1": {"1": None}}) def test_xxx(self): --- 62,66 ---- self.failUnlessEqual(y._objects, {"0": {}, "1": {}}) x1.a, x2.b = 42, 93 ! self.failUnlessEqual(y._objects, {"0": {}, "1": {}}) def test_xxx(self): *************** *** 92,97 **** A = c_int*4 a = A(11, 22, 33, 44) ! self.failUnlessEqual(a._objects, ! {"0": None, "1": None, "2": None, "3": None}) x = X() --- 92,96 ---- A = c_int*4 a = A(11, 22, 33, 44) ! self.failUnlessEqual(a._objects, None) x = X() |
From: Thomas H. <th...@us...> - 2004-12-01 12:35:15
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5777 Modified Files: _ctypes.c Log Message: Avoid ambiguous else. Enable an optimization. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.189 retrieving revision 1.190 diff -C2 -d -r1.189 -r1.190 *** _ctypes.c 30 Nov 2004 19:38:10 -0000 1.189 --- _ctypes.c 1 Dec 2004 12:35:06 -0000 1.190 *************** *** 1583,1589 **** self = self->b_base; if (self->b_objects == NULL) ! if (self->b_length) self->b_objects = PyDict_New(); ! else { Py_INCREF(Py_None); self->b_objects = Py_None; --- 1583,1589 ---- self = self->b_base; if (self->b_objects == NULL) ! if (self->b_length) { self->b_objects = PyDict_New(); ! } else { Py_INCREF(Py_None); self->b_objects = Py_None; *************** *** 1627,1636 **** /* Optimization: no need to store None */ - #if 0 if (keep == Py_None) { Py_DECREF(Py_None); return 0; } - #endif ob = CData_GetContainer(target); if (ob->b_objects == NULL || !PyDict_Check(ob->b_objects)) { --- 1627,1634 ---- |
From: Thomas H. <th...@us...> - 2004-11-30 19:38:29
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12119 Modified Files: test_structures.py test_internals.py Added Files: test_keeprefs.py Log Message: Merging is still black art for me ;-( Indexes start at 0. --- NEW FILE: test_keeprefs.py --- from ctypes import * import unittest class SimpleTestCase(unittest.TestCase): def test_cint(self): x = c_int() # a simple object has an empty _objects dict, if uninitialized self.assertEquals(x._objects, None) # setting the value populates the dict x.value = 42 self.assertEquals(x._objects, None) x = c_int(99) self.assertEquals(x._objects, None) def test_ccharp(self): x = c_char_p() # a simple object has an empty _objects dict, if uninitialized self.assertEquals(x._objects, None) # setting the value populates the dict x.value = "abc" self.assertEquals(x._objects, "abc") x = c_char_p("spam") self.assertEquals(x._objects, "spam") class StructureTestCase(unittest.TestCase): def test_cint_struct(self): class X(Structure): _fields_ = [("a", c_int), ("b", c_int)] x = X() self.assertEquals(x._objects, None) x.a = 42 x.b = 99 self.assertEquals(x._objects, {"0": None, "1": None}) def test_ccharp_struct(self): class X(Structure): _fields_ = [("a", c_char_p), ("b", c_char_p)] x = X() self.assertEquals(x._objects, None) x.a = "spam" x.b = "foo" self.assertEquals(x._objects, {"0": "spam", "1": "foo"}) def test_struct_struct(self): class POINT(Structure): _fields_ = [("x", c_int), ("y", c_int)] class RECT(Structure): _fields_ = [("ul", POINT), ("lr", POINT)] r = RECT() r.ul.x = 0 r.ul.y = 1 r.lr.x = 2 r.lr.y = 3 self.assertEquals(r._objects, {'00': None, '01': None, '10': None, '11': None}) r = RECT() r.ul = POINT(1, 2) self.assertEquals(r._objects, {'0': {'0': None, '1': None}}) r.ul.x = 22 r.ul.y = 44 # The current solution retains unneeded objects as well: self.assertEquals(r._objects, {'0': {'0': None, '1': None}, # r.ul = POINT(1, 2) '00': None, # r.ul.x = 22 '10': None}) # r.ul.x = 44 # The entry marked '<-' above is no longer needed, it refers to the # POINT we have assigned, but the coords are already overwritten. # But, oh well... class ArrayTestCase(unittest.TestCase): def test_cint_array(self): INTARR = c_int * 3 ia = INTARR() self.assertEquals(ia._objects, None) ia[0] = 1 ia[1] = 2 ia[2] = 3 self.assertEquals(ia._objects, {"0": None, "1": None, "2": None}) class X(Structure): _fields_ = [("x", c_int), ("a", INTARR)] x = X() x.x = 1000 x.a[0] = 42 x.a[1] = 96 self.assertEquals(x._objects, {"0": None, "01": None, "11": None}) x.a = ia self.assertEquals(x._objects, {'0': None, '1': {'0': None, '1': None, '2': None}, '01': None, '11': None}) # See above, some entries unneeded. class PointerTestCase(unittest.TestCase): def X_test_p_cint(self): x = pointer(c_int(42)) print x._objects class DeletePointerTestCase(unittest.TestCase): def X_test(self): class X(Structure): _fields_ = [("p", POINTER(c_char_p))] x = X() i = c_char_p("abc def") from sys import getrefcount as grc print "2?", grc(i) x.p = pointer(i) print "3?", grc(i) for i in range(320): c_int(99) x.p[0] print x.p[0] ## del x ## print "2?", grc(i) ## del i import gc gc.collect() for i in range(320): c_int(99) x.p[0] print x.p[0] print x.p.contents ## print x._objects x.p[0] = "spam spam" ## print x.p[0] print "+" * 42 print x._objects ##class PointerToStructure(unittest.TestCase): ## def test(self): ## class POINT(Structure): ## _fields_ = [("x", c_int), ("y", c_int)] ## class RECT(Structure): ## _fields_ = [("a", POINTER(POINT)), ## ("b", POINTER(POINT))] ## r = RECT() ## p1 = POINT(1, 2) ## p2 = POINT(3, 4) ## r.a = pointer(p1) ## r.a[0].x = 42 ## r.a[0].y = 99 ## r.b = pointer(p2) if __name__ == "__main__": unittest.main() Index: test_internals.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_internals.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_internals.py 9 Jun 2004 19:47:25 -0000 1.4 --- test_internals.py 30 Nov 2004 19:38:19 -0000 1.5 *************** *** 27,31 **** ci = c_int(i) self.failUnlessEqual(3, grc(i)) ! self.failUnlessEqual([None], ci._objects) def test_c_char_p(self): --- 27,31 ---- ci = c_int(i) self.failUnlessEqual(3, grc(i)) ! self.failUnlessEqual(ci._objects, None) def test_c_char_p(self): *************** *** 34,39 **** cs = c_char_p(s) self.failUnlessEqual(4, grc(s)) ! self.failUnlessSame(s, cs._objects[0]) ! self.failUnlessEqual([s], cs._objects) def test_simple_struct(self): --- 34,38 ---- cs = c_char_p(s) self.failUnlessEqual(4, grc(s)) ! self.failUnlessSame(cs._objects, s) def test_simple_struct(self): *************** *** 44,51 **** b = 421235 x = X() ! self.failUnlessEqual(x._objects, [None, None]) x.a = a x.b = b ! self.failUnlessEqual(x._objects, [None, None]) def test_embedded_structs(self): --- 43,50 ---- b = 421235 x = X() ! self.failUnlessEqual(x._objects, None) x.a = a x.b = b ! self.failUnlessEqual(x._objects, {"0": None, "1": None}) def test_embedded_structs(self): *************** *** 57,68 **** y = Y() ! self.failUnlessEqual(y._objects, [None, None]) x1, x2 = X(), X() y.x, y.y = x1, x2 ! self.failUnlessEqual(y._objects, [[None, None], [None, None]]) x1.a, x2.b = 42, 93 ! self.failUnlessEqual(y._objects, [[None, None], [None, None]]) ! ## self.failUnlessEqual(y.x._objects, [None, None]) def test_xxx(self): --- 56,66 ---- y = Y() ! self.failUnlessEqual(y._objects, None) x1, x2 = X(), X() y.x, y.y = x1, x2 ! self.failUnlessEqual(y._objects, {"0": {}, "1": {}}) x1.a, x2.b = 42, 93 ! self.failUnlessEqual(y._objects, {"0": {"0": None}, "1": {"1": None}}) def test_xxx(self): *************** *** 79,87 **** x.a = s1 x.b = s2 ! self.failUnlessEqual(x._objects, [s1, s2]) y = Y() y.x = x ! self.failUnlessEqual(y._objects, [[s1, s2], None]) ## x = y.x ## del y --- 77,85 ---- x.a = s1 x.b = s2 ! self.failUnlessEqual(x._objects, {"0": s1, "1": s2}) y = Y() y.x = x ! self.failUnlessEqual(y._objects, {"0": {"0": s1, "1": s2}}) ## x = y.x ## del y *************** *** 94,98 **** A = c_int*4 a = A(11, 22, 33, 44) ! self.failUnlessEqual(a._objects, [None, None, None, None]) x = X() --- 92,97 ---- A = c_int*4 a = A(11, 22, 33, 44) ! self.failUnlessEqual(a._objects, ! {"0": None, "1": None, "2": None, "3": None}) x = X() Index: test_structures.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_structures.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** test_structures.py 4 Nov 2004 18:04:41 -0000 1.26 --- test_structures.py 30 Nov 2004 19:38:19 -0000 1.27 *************** *** 295,310 **** # This fails with SystemError: bad arg to internal function # or with IndexError (with a patch I have) ! try: ! s.array[0] = 42 ! except (SystemError, IndexError): ! pass items = [s.array[i] for i in range(3)] ! self.failUnlessEqual(items, [1, 2, 3]) ! # and this one with IndexError: invalid index ! try: ! s.array[1] = 42 ! except IndexError: ! pass items = [s.array[i] for i in range(3)] --- 295,307 ---- # This fails with SystemError: bad arg to internal function # or with IndexError (with a patch I have) ! ! s.array[0] = 42 ! items = [s.array[i] for i in range(3)] ! self.failUnlessEqual(items, [42, 2, 3]) ! s.array[0] = 1 ! ! ## s.array[1] = 42 items = [s.array[i] for i in range(3)] |
From: Thomas H. <th...@us...> - 2004-11-30 19:38:19
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12049 Modified Files: _ctypes.c Log Message: Merging is still black art for me ;-( Indexes start at 0. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.188 retrieving revision 1.189 diff -C2 -d -r1.188 -r1.189 *** _ctypes.c 30 Nov 2004 16:40:25 -0000 1.188 --- _ctypes.c 30 Nov 2004 19:38:10 -0000 1.189 *************** *** 92,100 **** #endif - #ifndef METH_CLASS - #define METH_CLASS 0x0010 /* from Python 2.3 */ - #define NO_METH_CLASS - #endif - PyObject *PyExc_ArgError; --- 92,95 ---- *************** *** 1609,1615 **** char *cp = string; int len; ! *cp++ = index + '1'; while (target->b_base) { ! *cp++ = target->b_index + '1'; target = target->b_base; } --- 1604,1610 ---- char *cp = string; int len; ! *cp++ = index + '0'; while (target->b_base) { ! *cp++ = target->b_index + '0'; target = target->b_base; } *************** *** 3560,3593 **** } - /* - * XXX What about errors ??? - */ - #ifdef NO_METH_CLASS - void DoClassMethods(PyTypeObject *type) - { - PyObject *func; - PyObject *meth; - PyMethodDef *ml = type->tp_methods; - - for (; ml->ml_name; ++ml) { - if ((ml->ml_flags & METH_CLASS) == 0) - continue; - ml->ml_flags &= ~METH_CLASS; - func = PyCFunction_New(ml, NULL); - if (!func) - return; - meth = PyObject_CallFunctionObjArgs( - (PyObject *)&PyClassMethod_Type, - func, NULL); - if (!meth) - return; - if (-1 == PyDict_SetItemString(type->tp_dict, - ml->ml_name, - meth)) - return; - } - } - #endif - static char *module_docs = "Create and manipulate C compatible data types in Python."; --- 3555,3558 ---- |
From: Thomas H. <th...@us...> - 2004-11-30 18:43:09
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28353 Modified Files: Tag: KEEP_IN_DICT_BRANCH _ctypes.c Log Message: Remove the Python 2.2 METH_CLASS stuff, unneeded now. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.185.2.5 retrieving revision 1.185.2.6 diff -C2 -d -r1.185.2.5 -r1.185.2.6 *** _ctypes.c 30 Nov 2004 10:52:29 -0000 1.185.2.5 --- _ctypes.c 30 Nov 2004 18:42:57 -0000 1.185.2.6 *************** *** 92,100 **** #endif - #ifndef METH_CLASS - #define METH_CLASS 0x0010 /* from Python 2.3 */ - #define NO_METH_CLASS - #endif - PyObject *PyExc_ArgError; --- 92,95 ---- *************** *** 3560,3593 **** } - /* - * XXX What about errors ??? - */ - #ifdef NO_METH_CLASS - void DoClassMethods(PyTypeObject *type) - { - PyObject *func; - PyObject *meth; - PyMethodDef *ml = type->tp_methods; - - for (; ml->ml_name; ++ml) { - if ((ml->ml_flags & METH_CLASS) == 0) - continue; - ml->ml_flags &= ~METH_CLASS; - func = PyCFunction_New(ml, NULL); - if (!func) - return; - meth = PyObject_CallFunctionObjArgs( - (PyObject *)&PyClassMethod_Type, - func, NULL); - if (!meth) - return; - if (-1 == PyDict_SetItemString(type->tp_dict, - ml->ml_name, - meth)) - return; - } - } - #endif - static char *module_docs = "Create and manipulate C compatible data types in Python."; --- 3555,3558 ---- |
From: Thomas H. <th...@us...> - 2004-11-30 16:40:44
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26012 Modified Files: Tag: DELAYED_STRUCTS_BRANCH test_structures.py test_internals.py Added Files: Tag: DELAYED_STRUCTS_BRANCH test_keeprefs.py Log Message: Merge in the changes from the KEEP_IN_DICT_BRANCH. --- NEW FILE: test_keeprefs.py --- from ctypes import * import unittest class SimpleTestCase(unittest.TestCase): def test_cint(self): x = c_int() # a simple object has an empty _objects dict, if uninitialized self.assertEquals(x._objects, None) # setting the value populates the dict x.value = 42 self.assertEquals(x._objects, None) x = c_int(99) self.assertEquals(x._objects, None) def test_ccharp(self): x = c_char_p() # a simple object has an empty _objects dict, if uninitialized self.assertEquals(x._objects, None) # setting the value populates the dict x.value = "abc" self.assertEquals(x._objects, "abc") x = c_char_p("spam") self.assertEquals(x._objects, "spam") class StructureTestCase(unittest.TestCase): def test_cint_struct(self): class X(Structure): _fields_ = [("a", c_int), ("b", c_int)] x = X() self.assertEquals(x._objects, None) x.a = 42 x.b = 99 self.assertEquals(x._objects, {"1": None, "2": None}) def test_ccharp_struct(self): class X(Structure): _fields_ = [("a", c_char_p), ("b", c_char_p)] x = X() self.assertEquals(x._objects, None) x.a = "spam" x.b = "foo" self.assertEquals(x._objects, {"1": "spam", "2": "foo"}) def test_struct_struct(self): class POINT(Structure): _fields_ = [("x", c_int), ("y", c_int)] class RECT(Structure): _fields_ = [("ul", POINT), ("lr", POINT)] r = RECT() r.ul.x = 0 r.ul.y = 1 r.lr.x = 2 r.lr.y = 3 self.assertEquals(r._objects, {'11': None, '12': None, '21': None, '22': None}) r = RECT() r.ul = POINT(1, 2) self.assertEquals(r._objects, {'1': {'1': None, '2': None}}) r.ul.x = 22 r.ul.y = 44 # The current solution retains unneeded objects as well: self.assertEquals(r._objects, {'1': {'1': None, '2': None}, # r.ul = POINT(1, 2) '11': None, # r.ul.x = 22 '21': None}) # r.ul.x = 44 # The entry marked '<-' above is no longer needed, it refers to the # POINT we have assigned, but the coords are already overwritten. # But, oh well... class ArrayTestCase(unittest.TestCase): def test_cint_array(self): INTARR = c_int * 3 ia = INTARR() self.assertEquals(ia._objects, None) ia[0] = 1 ia[1] = 2 ia[2] = 3 self.assertEquals(ia._objects, {"1": None, "2": None, "3": None}) class X(Structure): _fields_ = [("x", c_int), ("a", INTARR)] x = X() x.x = 1000 x.a[0] = 42 x.a[1] = 96 self.assertEquals(x._objects, {"1": None, "12": None, "22": None}) x.a = ia self.assertEquals(x._objects, {'1': None, '2': {'1': None, '2': None, '3': None}, '12': None, '22': None}) # See above, some entries unneeded. class PointerTestCase(unittest.TestCase): def X_test_p_cint(self): x = pointer(c_int(42)) print x._objects class DeletePointerTestCase(unittest.TestCase): def X_test(self): class X(Structure): _fields_ = [("p", POINTER(c_char_p))] x = X() i = c_char_p("abc def") from sys import getrefcount as grc print "2?", grc(i) x.p = pointer(i) print "3?", grc(i) for i in range(320): c_int(99) x.p[0] print x.p[0] ## del x ## print "2?", grc(i) ## del i import gc gc.collect() for i in range(320): c_int(99) x.p[0] print x.p[0] print x.p.contents ## print x._objects x.p[0] = "spam spam" ## print x.p[0] print "+" * 42 print x._objects ##class PointerToStructure(unittest.TestCase): ## def test(self): ## class POINT(Structure): ## _fields_ = [("x", c_int), ("y", c_int)] ## class RECT(Structure): ## _fields_ = [("a", POINTER(POINT)), ## ("b", POINTER(POINT))] ## r = RECT() ## p1 = POINT(1, 2) ## p2 = POINT(3, 4) ## r.a = pointer(p1) ## r.a[0].x = 42 ## r.a[0].y = 99 ## r.b = pointer(p2) if __name__ == "__main__": unittest.main() Index: test_internals.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_internals.py,v retrieving revision 1.4 retrieving revision 1.4.2.1 diff -C2 -d -r1.4 -r1.4.2.1 *** test_internals.py 9 Jun 2004 19:47:25 -0000 1.4 --- test_internals.py 30 Nov 2004 16:40:35 -0000 1.4.2.1 *************** *** 6,9 **** --- 6,12 ---- # XXX This test must be reviewed for correctness!!! + # autodetect an optimization in _ctypes.c::KeepRef() + DEBUG = c_int(2)._objects != {} + """ ctypes' types are container types. *************** *** 27,31 **** ci = c_int(i) self.failUnlessEqual(3, grc(i)) ! self.failUnlessEqual([None], ci._objects) def test_c_char_p(self): --- 30,37 ---- ci = c_int(i) self.failUnlessEqual(3, grc(i)) ! if DEBUG: ! self.failUnlessEqual(ci._objects, None) ! else: ! self.failUnlessEqual(ci._objects, {}) def test_c_char_p(self): *************** *** 34,39 **** cs = c_char_p(s) self.failUnlessEqual(4, grc(s)) ! self.failUnlessSame(s, cs._objects[0]) ! self.failUnlessEqual([s], cs._objects) def test_simple_struct(self): --- 40,44 ---- cs = c_char_p(s) self.failUnlessEqual(4, grc(s)) ! self.failUnlessSame(cs._objects, s) def test_simple_struct(self): *************** *** 44,51 **** b = 421235 x = X() ! self.failUnlessEqual(x._objects, [None, None]) x.a = a x.b = b ! self.failUnlessEqual(x._objects, [None, None]) def test_embedded_structs(self): --- 49,59 ---- b = 421235 x = X() ! self.failUnlessEqual(x._objects, None) x.a = a x.b = b ! if DEBUG: ! self.failUnlessEqual(x._objects, {"1": None, "2": None}) ! else: ! self.failUnlessEqual(x._objects, {}) def test_embedded_structs(self): *************** *** 57,68 **** y = Y() ! self.failUnlessEqual(y._objects, [None, None]) x1, x2 = X(), X() y.x, y.y = x1, x2 ! self.failUnlessEqual(y._objects, [[None, None], [None, None]]) x1.a, x2.b = 42, 93 ! self.failUnlessEqual(y._objects, [[None, None], [None, None]]) ! ## self.failUnlessEqual(y.x._objects, [None, None]) def test_xxx(self): --- 65,78 ---- y = Y() ! self.failUnlessEqual(y._objects, None) x1, x2 = X(), X() y.x, y.y = x1, x2 ! self.failUnlessEqual(y._objects, {"1": {}, "2": {}}) x1.a, x2.b = 42, 93 ! if DEBUG: ! self.failUnlessEqual(y._objects, {"1": {"1": None}, "2": {"2": None}}) ! else: ! self.failUnlessEqual(y._objects, {"A": {}, "B": {}}) def test_xxx(self): *************** *** 79,87 **** x.a = s1 x.b = s2 ! self.failUnlessEqual(x._objects, [s1, s2]) y = Y() y.x = x ! self.failUnlessEqual(y._objects, [[s1, s2], None]) ## x = y.x ## del y --- 89,97 ---- x.a = s1 x.b = s2 ! self.failUnlessEqual(x._objects, {"1": s1, "2": s2}) y = Y() y.x = x ! self.failUnlessEqual(y._objects, {"1": {"1": s1, "2": s2}}) ## x = y.x ## del y *************** *** 94,98 **** A = c_int*4 a = A(11, 22, 33, 44) ! self.failUnlessEqual(a._objects, [None, None, None, None]) x = X() --- 104,112 ---- A = c_int*4 a = A(11, 22, 33, 44) ! if DEBUG: ! self.failUnlessEqual(a._objects, ! {"1": None, "2": None, "3": None, "4": None}) ! else: ! self.failUnlessEqual(a._objects, {}) x = X() Index: test_structures.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_structures.py,v retrieving revision 1.26 retrieving revision 1.26.2.1 diff -C2 -d -r1.26 -r1.26.2.1 *** test_structures.py 4 Nov 2004 18:04:41 -0000 1.26 --- test_structures.py 30 Nov 2004 16:40:35 -0000 1.26.2.1 *************** *** 295,310 **** # This fails with SystemError: bad arg to internal function # or with IndexError (with a patch I have) ! try: ! s.array[0] = 42 ! except (SystemError, IndexError): ! pass items = [s.array[i] for i in range(3)] ! self.failUnlessEqual(items, [1, 2, 3]) ! # and this one with IndexError: invalid index ! try: ! s.array[1] = 42 ! except IndexError: ! pass items = [s.array[i] for i in range(3)] --- 295,307 ---- # This fails with SystemError: bad arg to internal function # or with IndexError (with a patch I have) ! ! s.array[0] = 42 ! items = [s.array[i] for i in range(3)] ! self.failUnlessEqual(items, [42, 2, 3]) ! s.array[0] = 1 ! ! ## s.array[1] = 42 items = [s.array[i] for i in range(3)] |
From: Thomas H. <th...@us...> - 2004-11-30 16:40:35
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25968 Modified Files: ctypes.h cfield.c _ctypes.c Log Message: Merge in the changes from the KEEP_IN_DICT_BRANCH. Index: ctypes.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v retrieving revision 1.63 retrieving revision 1.64 diff -C2 -d -r1.63 -r1.64 *** ctypes.h 25 Nov 2004 15:01:40 -0000 1.63 --- ctypes.h 30 Nov 2004 16:40:25 -0000 1.64 *************** *** 63,68 **** } CFuncPtrObject; - extern PyObject *CData_GetList(CDataObject *mem); - extern PyTypeObject StgDict_Type; #define StgDict_CheckExact(v) ((v)->ob_type == &StgDict_Type) --- 63,66 ---- Index: cfield.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/cfield.c,v retrieving revision 1.69 retrieving revision 1.70 diff -C2 -d -r1.69 -r1.70 *** cfield.c 25 Nov 2004 14:04:06 -0000 1.69 --- cfield.c 30 Nov 2004 16:40:25 -0000 1.70 *************** *** 919,922 **** --- 919,923 ---- z_get(void *ptr, unsigned size) { + /* XXX What about invalid pointers ??? */ if (*(void **)ptr) return PyString_FromString(*(char **)ptr); Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.187 retrieving revision 1.188 diff -C2 -d -r1.187 -r1.188 *** _ctypes.c 25 Nov 2004 15:01:40 -0000 1.187 --- _ctypes.c 30 Nov 2004 16:40:25 -0000 1.188 *************** *** 1219,1223 **** stgdict->ffi_type = *fmt->pffi_type; stgdict->align = fmt->pffi_type->alignment; ! stgdict->length = 1; stgdict->size = fmt->pffi_type->size; stgdict->setfunc = fmt->setfunc; --- 1219,1223 ---- stgdict->ffi_type = *fmt->pffi_type; stgdict->align = fmt->pffi_type->alignment; ! stgdict->length = 0; stgdict->size = fmt->pffi_type->size; stgdict->setfunc = fmt->setfunc; *************** *** 1582,1658 **** */ ! /* Return a list of size <size> filled with None's. */ ! static PyObject * ! NoneList(int size) ! { ! int i; ! PyObject *list; ! ! list = PyList_New(size); ! if (!list) ! return NULL; ! for (i = 0; i < size; ++i) { ! Py_INCREF(Py_None); ! PyList_SET_ITEM(list, i, Py_None); ! } ! return list; ! } ! ! #define ASSERT_CDATA(x) assert(((x)->b_base == NULL) ^ ((x)->b_objects == NULL)) ! ! /* ! * Return the list(tree) entry corresponding to a memory object. ! * Borrowed reference! ! */ ! static PyObject * ! CData_GetList(CDataObject *mem) { ! PyObject *list; ! PyObject *obj; ! ASSERT_CDATA(mem); ! if (!mem->b_base) { ! return mem->b_objects; ! } else { ! // assert(mem->b_objects == NULL); ! list = CData_GetList(mem->b_base); ! if (list == NULL) ! return NULL; ! obj = PyList_GetItem(list, mem->b_index); ! if (obj == NULL) ! return NULL; ! if (obj == Py_None) { ! obj = NoneList(mem->b_length); ! if (-1 == PyList_SetItem(list, mem->b_index, obj)) ! return NULL; } ! return obj; ! } ! } ! ! /* ! * Make sure object <mem> has a list of length <length> ! * at index <index>. Initially all list members are None. ! */ ! static int ! CData_EnsureList(CDataObject *mem, int index, int length) ! { ! PyObject *list; ! PyObject *obj; ! ! list = CData_GetList(mem); ! if (!list) ! return -1; ! obj = PyList_GetItem(list, index); ! if (!obj) ! return -1; ! ! if (obj == Py_None) { ! obj = NoneList(length); ! if (!obj) ! return -1; ! if (-1 == PyList_SetItem(list, index, obj)) ! return -1; ! } ! return 0; } --- 1582,1598 ---- */ ! static CDataObject * ! CData_GetContainer(CDataObject *self) { ! while (self->b_base) ! self = self->b_base; ! if (self->b_objects == NULL) ! if (self->b_length) ! self->b_objects = PyDict_New(); ! else { ! Py_INCREF(Py_None); ! self->b_objects = Py_None; } ! return self; } *************** *** 1660,1691 **** GetKeepedObjects(CDataObject *target) { ! return CData_GetList(target); } ! /* set an exception and return -1 if a call to KeepRef will fail, 0 otherwise */ ! static int ! CanKeepRef(CDataObject *target, int index) { ! PyObject *objects = CData_GetList(target); ! if (!objects) ! return -1; ! if (index < 0 || PyList_Size(objects) <= index) { ! PyErr_SetString(PyExc_IndexError, ! "invalid index"); ! return -1; } ! return 0; } - /* Keep a reference to 'keep' in the 'target', at index 'index' */ static int KeepRef(CDataObject *target, int index, PyObject *keep) { int result; ! PyObject *list = CData_GetList(target); ! result = PyList_SetItem(list, index, keep); ! if (result == -1) ! return -1; ! return 0; } --- 1600,1652 ---- GetKeepedObjects(CDataObject *target) { ! return CData_GetContainer(target)->b_objects; } ! static PyObject * ! unique_key(CDataObject *target, int index) { ! char string[256]; /* XXX is that enough? */ ! char *cp = string; ! int len; ! *cp++ = index + '1'; ! while (target->b_base) { ! *cp++ = target->b_index + '1'; ! target = target->b_base; } ! len = cp - string; ! return PyString_FromStringAndSize(string, cp-string); } /* Keep a reference to 'keep' in the 'target', at index 'index' */ + /* + * KeepRef travels the target's b_base pointer down to the root, + * building a sequence of indexes during the path. The indexes, which are a + * couple of small integers, are used to build a byte string usable as + * key int the root object's _objects dict. + */ static int KeepRef(CDataObject *target, int index, PyObject *keep) { int result; ! CDataObject *ob; ! PyObject *key; ! ! /* Optimization: no need to store None */ ! #if 0 ! if (keep == Py_None) { ! Py_DECREF(Py_None); ! return 0; ! } ! #endif ! ob = CData_GetContainer(target); ! if (ob->b_objects == NULL || !PyDict_Check(ob->b_objects)) { ! Py_XDECREF(ob->b_objects); ! ob->b_objects = keep; /* refcount consumed */ ! return 0; ! } ! key = unique_key(target, index); ! result = PyDict_SetItem(ob->b_objects, key, keep); ! Py_DECREF(key); ! Py_DECREF(keep); ! return result; } *************** *** 1890,1895 **** cd = (CDataObject *)mem; - ASSERT_CDATA(cd); - return mem; } --- 1851,1854 ---- *************** *** 1993,1998 **** into a pointer. So, again, we have to keep the whole object pointed to (which is the array in this case) alive, and not ! only it's object list. So we create a new list, containing ! the b_objects list PLUS the array itself, and return that! */ return Py_BuildValue("(OO)", keep, value); --- 1952,1957 ---- into a pointer. So, again, we have to keep the whole object pointed to (which is the array in this case) alive, and not ! only it's object list. So we create a tuple, containing ! b_objects list PLUS the array itself, and return that! */ return Py_BuildValue("(OO)", keep, value); *************** *** 2022,2028 **** } - /* Make sure KeepRef will not fail! */ - if (-1 == CanKeepRef(mem, index)) - return -1; result = _CData_set(mem, type, setfunc, value, size, ptr); --- 1981,1984 ---- *************** *** 2031,2036 **** /* KeepRef steals a refcount from it's last argument */ ! return KeepRef(mem, index, result); ! } --- 1987,1993 ---- /* KeepRef steals a refcount from it's last argument */ ! /* If KeepRef fails, we are stumped. The dst memory block has already ! been changed */ ! return KeepRef(mem, index, result); } *************** *** 2096,2108 **** obj->b_size = size; obj->b_needsfree = 0; - if (-1 == CData_EnsureList(obj->b_base, - spec->index, length)) { - Py_DECREF(obj); - return NULL; - } } else { obj->b_base = NULL; obj->b_index = 0; ! obj->b_objects = NoneList(length); obj->b_length = length; --- 2053,2060 ---- obj->b_size = size; obj->b_needsfree = 0; } else { obj->b_base = NULL; obj->b_index = 0; ! obj->b_objects = NULL; obj->b_length = length; *************** *** 2120,2129 **** obj->b_base = NULL; obj->b_index = 0; ! ! /* 1.11 us in Python 2.3 -OO, 30% of total creation time for c_int() */ ! /* 2.2 us in Pyton 2.2 -OO, ~20% of total creation time */ ! /* Should we use an array of objects in the CDataObject structure ! instead of the b_objects pointer pointing to a list? */ ! obj->b_objects = NoneList(length); obj->b_length = length; --- 2072,2076 ---- obj->b_base = NULL; obj->b_index = 0; ! obj->b_objects = NULL; obj->b_length = length; *************** *** 2137,2141 **** memset(obj->b_ptr, 0, size); } - ASSERT_CDATA(obj); return (PyObject *)obj; } --- 2084,2087 ---- |
From: Thomas H. <th...@us...> - 2004-11-30 10:53:11
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10409 Modified Files: Tag: KEEP_IN_DICT_BRANCH test_keeprefs.py test_internals.py Log Message: More optimizations: create the b_objects dictionary only when requested. Index: test_keeprefs.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/Attic/test_keeprefs.py,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -C2 -d -r1.1.2.2 -r1.1.2.3 *** test_keeprefs.py 30 Nov 2004 10:36:06 -0000 1.1.2.2 --- test_keeprefs.py 30 Nov 2004 10:52:57 -0000 1.1.2.3 *************** *** 32,36 **** x = X() ! self.assertEquals(x._objects, {}) x.a = 42 --- 32,36 ---- x = X() ! self.assertEquals(x._objects, None) x.a = 42 *************** *** 43,47 **** ("b", c_char_p)] x = X() ! self.assertEquals(x._objects, {}) x.a = "spam" --- 43,47 ---- ("b", c_char_p)] x = X() ! self.assertEquals(x._objects, None) x.a = "spam" *************** *** 82,86 **** ia = INTARR() ! self.assertEquals(ia._objects, {}) ia[0] = 1 ia[1] = 2 --- 82,86 ---- ia = INTARR() ! self.assertEquals(ia._objects, None) ia[0] = 1 ia[1] = 2 Index: test_internals.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_internals.py,v retrieving revision 1.4.4.3 retrieving revision 1.4.4.4 diff -C2 -d -r1.4.4.3 -r1.4.4.4 *** test_internals.py 30 Nov 2004 10:36:06 -0000 1.4.4.3 --- test_internals.py 30 Nov 2004 10:52:57 -0000 1.4.4.4 *************** *** 49,53 **** b = 421235 x = X() ! self.failUnlessEqual(x._objects, {}) x.a = a x.b = b --- 49,53 ---- b = 421235 x = X() ! self.failUnlessEqual(x._objects, None) x.a = a x.b = b *************** *** 65,69 **** y = Y() ! self.failUnlessEqual(y._objects, {}) x1, x2 = X(), X() --- 65,69 ---- y = Y() ! self.failUnlessEqual(y._objects, None) x1, x2 = X(), X() |
From: Thomas H. <th...@us...> - 2004-11-30 10:52:42
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10297 Modified Files: Tag: KEEP_IN_DICT_BRANCH _ctypes.c Log Message: More optimizations: create the b_objects dictionary only when requested. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.185.2.4 retrieving revision 1.185.2.5 diff -C2 -d -r1.185.2.4 -r1.185.2.5 *** _ctypes.c 30 Nov 2004 10:33:51 -0000 1.185.2.4 --- _ctypes.c 30 Nov 2004 10:52:29 -0000 1.185.2.5 *************** *** 1587,1590 **** --- 1587,1597 ---- while (self->b_base) self = self->b_base; + if (self->b_objects == NULL) + if (self->b_length) + self->b_objects = PyDict_New(); + else { + Py_INCREF(Py_None); + self->b_objects = Py_None; + } return self; } *************** *** 1945,1950 **** into a pointer. So, again, we have to keep the whole object pointed to (which is the array in this case) alive, and not ! only it's object list. So we create a new list, containing ! the b_objects list PLUS the array itself, and return that! */ return Py_BuildValue("(OO)", keep, value); --- 1952,1957 ---- into a pointer. So, again, we have to keep the whole object pointed to (which is the array in this case) alive, and not ! only it's object list. So we create a tuple, containing ! b_objects list PLUS the array itself, and return that! */ return Py_BuildValue("(OO)", keep, value); *************** *** 2049,2059 **** obj->b_base = NULL; obj->b_index = 0; ! if (length) ! obj->b_objects = PyDict_New(); ! else { ! Py_INCREF(Py_None); ! obj->b_objects = Py_None; ! } ! obj->b_length = length; --- 2056,2060 ---- obj->b_base = NULL; obj->b_index = 0; ! obj->b_objects = NULL; obj->b_length = length; *************** *** 2071,2080 **** obj->b_base = NULL; obj->b_index = 0; ! if (length) ! obj->b_objects = PyDict_New(); ! else { ! Py_INCREF(Py_None); ! obj->b_objects = Py_None; ! } obj->b_length = length; --- 2072,2076 ---- obj->b_base = NULL; obj->b_index = 0; ! obj->b_objects = NULL; obj->b_length = length; |
From: Thomas H. <th...@us...> - 2004-11-30 10:36:17
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6778 Modified Files: Tag: KEEP_IN_DICT_BRANCH test_keeprefs.py test_internals.py Log Message: Adapted the tests. Index: test_keeprefs.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/Attic/test_keeprefs.py,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** test_keeprefs.py 25 Nov 2004 16:59:44 -0000 1.1.2.1 --- test_keeprefs.py 30 Nov 2004 10:36:06 -0000 1.1.2.2 *************** *** 6,27 **** x = c_int() # a simple object has an empty _objects dict, if uninitialized ! self.assertEquals(x._objects, {}) # setting the value populates the dict x.value = 42 ! self.assertEquals(x._objects, {"A": None}) x = c_int(99) ! self.assertEquals(x._objects, {"A": None}) def test_ccharp(self): x = c_char_p() # a simple object has an empty _objects dict, if uninitialized ! self.assertEquals(x._objects, {}) # setting the value populates the dict x.value = "abc" ! self.assertEquals(x._objects, {"A": "abc"}) x = c_char_p("spam") ! self.assertEquals(x._objects, {"A": "spam"}) class StructureTestCase(unittest.TestCase): --- 6,27 ---- x = c_int() # a simple object has an empty _objects dict, if uninitialized ! self.assertEquals(x._objects, None) # setting the value populates the dict x.value = 42 ! self.assertEquals(x._objects, None) x = c_int(99) ! self.assertEquals(x._objects, None) def test_ccharp(self): x = c_char_p() # a simple object has an empty _objects dict, if uninitialized ! self.assertEquals(x._objects, None) # setting the value populates the dict x.value = "abc" ! self.assertEquals(x._objects, "abc") x = c_char_p("spam") ! self.assertEquals(x._objects, "spam") class StructureTestCase(unittest.TestCase): *************** *** 36,40 **** x.a = 42 x.b = 99 ! self.assertEquals(x._objects, {"A": None, "B": None}) def test_ccharp_struct(self): --- 36,40 ---- x.a = 42 x.b = 99 ! self.assertEquals(x._objects, {"1": None, "2": None}) def test_ccharp_struct(self): *************** *** 47,51 **** x.a = "spam" x.b = "foo" ! self.assertEquals(x._objects, {"A": "spam", "B": "foo"}) def test_struct_struct(self): --- 47,51 ---- x.a = "spam" x.b = "foo" ! self.assertEquals(x._objects, {"1": "spam", "2": "foo"}) def test_struct_struct(self): *************** *** 61,76 **** r.lr.y = 3 self.assertEquals(r._objects, ! {'AA': None, 'AB': None, 'BA': None, 'BB': None}) r = RECT() r.ul = POINT(1, 2) ! self.assertEquals(r._objects, {'A': {'A': None, 'B': None}}) r.ul.x = 22 r.ul.y = 44 # The current solution retains unneeded objects as well: self.assertEquals(r._objects, ! {'A': {'A': None, 'B': None}, # r.ul = POINT(1, 2) ! 'AA': None, # r.ul.x = 22 ! 'BA': None}) # r.ul.x = 44 # The entry marked '<-' above is no longer needed, it refers to the # POINT we have assigned, but the coords are already overwritten. --- 61,76 ---- r.lr.y = 3 self.assertEquals(r._objects, ! {'11': None, '12': None, '21': None, '22': None}) r = RECT() r.ul = POINT(1, 2) ! self.assertEquals(r._objects, {'1': {'1': None, '2': None}}) r.ul.x = 22 r.ul.y = 44 # The current solution retains unneeded objects as well: self.assertEquals(r._objects, ! {'1': {'1': None, '2': None}, # r.ul = POINT(1, 2) ! '11': None, # r.ul.x = 22 ! '21': None}) # r.ul.x = 44 # The entry marked '<-' above is no longer needed, it refers to the # POINT we have assigned, but the coords are already overwritten. *************** *** 86,90 **** ia[1] = 2 ia[2] = 3 ! self.assertEquals(ia._objects, {"A": None, "B": None, "C": None}) class X(Structure): --- 86,90 ---- ia[1] = 2 ia[2] = 3 ! self.assertEquals(ia._objects, {"1": None, "2": None, "3": None}) class X(Structure): *************** *** 96,114 **** x.a[0] = 42 x.a[1] = 96 ! self.assertEquals(x._objects, {"A": None, "AB": None, "BB": None}) x.a = ia self.assertEquals(x._objects, ! {'A': None, ! 'B': {'A': None, 'C': None, 'B': None}, ! 'AB': None, ! 'BB': None}) # See above, some entries unneeded. class PointerTestCase(unittest.TestCase): ! def test_p_cint(self): x = pointer(c_int(42)) print x._objects if __name__ == "__main__": --- 96,161 ---- x.a[0] = 42 x.a[1] = 96 ! self.assertEquals(x._objects, {"1": None, "12": None, "22": None}) x.a = ia self.assertEquals(x._objects, ! {'1': None, ! '2': {'1': None, '2': None, '3': None}, ! '12': None, ! '22': None}) # See above, some entries unneeded. class PointerTestCase(unittest.TestCase): ! def X_test_p_cint(self): x = pointer(c_int(42)) print x._objects + class DeletePointerTestCase(unittest.TestCase): + def X_test(self): + class X(Structure): + _fields_ = [("p", POINTER(c_char_p))] + x = X() + i = c_char_p("abc def") + from sys import getrefcount as grc + print "2?", grc(i) + x.p = pointer(i) + print "3?", grc(i) + for i in range(320): + c_int(99) + x.p[0] + print x.p[0] + ## del x + ## print "2?", grc(i) + ## del i + import gc + gc.collect() + for i in range(320): + c_int(99) + x.p[0] + print x.p[0] + print x.p.contents + ## print x._objects + + x.p[0] = "spam spam" + ## print x.p[0] + print "+" * 42 + print x._objects + + ##class PointerToStructure(unittest.TestCase): + ## def test(self): + ## class POINT(Structure): + ## _fields_ = [("x", c_int), ("y", c_int)] + ## class RECT(Structure): + ## _fields_ = [("a", POINTER(POINT)), + ## ("b", POINTER(POINT))] + ## r = RECT() + ## p1 = POINT(1, 2) + ## p2 = POINT(3, 4) + + ## r.a = pointer(p1) + ## r.a[0].x = 42 + ## r.a[0].y = 99 + + ## r.b = pointer(p2) if __name__ == "__main__": Index: test_internals.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_internals.py,v retrieving revision 1.4.4.2 retrieving revision 1.4.4.3 diff -C2 -d -r1.4.4.2 -r1.4.4.3 *** test_internals.py 25 Nov 2004 16:18:07 -0000 1.4.4.2 --- test_internals.py 30 Nov 2004 10:36:06 -0000 1.4.4.3 *************** *** 31,35 **** self.failUnlessEqual(3, grc(i)) if DEBUG: ! self.failUnlessEqual(ci._objects, {"A": None}) else: self.failUnlessEqual(ci._objects, {}) --- 31,35 ---- self.failUnlessEqual(3, grc(i)) if DEBUG: ! self.failUnlessEqual(ci._objects, None) else: self.failUnlessEqual(ci._objects, {}) *************** *** 40,45 **** cs = c_char_p(s) self.failUnlessEqual(4, grc(s)) ! self.failUnlessSame(cs._objects["A"], s) ! self.failUnlessEqual(cs._objects, {"A": s}) def test_simple_struct(self): --- 40,44 ---- cs = c_char_p(s) self.failUnlessEqual(4, grc(s)) ! self.failUnlessSame(cs._objects, s) def test_simple_struct(self): *************** *** 54,58 **** x.b = b if DEBUG: ! self.failUnlessEqual(x._objects, {"A": None, "B": None}) else: self.failUnlessEqual(x._objects, {}) --- 53,57 ---- x.b = b if DEBUG: ! self.failUnlessEqual(x._objects, {"1": None, "2": None}) else: self.failUnlessEqual(x._objects, {}) *************** *** 70,77 **** x1, x2 = X(), X() y.x, y.y = x1, x2 ! self.failUnlessEqual(y._objects, {"A": {}, "B": {}}) x1.a, x2.b = 42, 93 if DEBUG: ! self.failUnlessEqual(y._objects, {"A": {"A": None}, "B": {"B": None}}) else: self.failUnlessEqual(y._objects, {"A": {}, "B": {}}) --- 69,76 ---- x1, x2 = X(), X() y.x, y.y = x1, x2 ! self.failUnlessEqual(y._objects, {"1": {}, "2": {}}) x1.a, x2.b = 42, 93 if DEBUG: ! self.failUnlessEqual(y._objects, {"1": {"1": None}, "2": {"2": None}}) else: self.failUnlessEqual(y._objects, {"A": {}, "B": {}}) *************** *** 90,98 **** x.a = s1 x.b = s2 ! self.failUnlessEqual(x._objects, {"A": s1, "B": s2}) y = Y() y.x = x ! self.failUnlessEqual(y._objects, {"A": {"A": s1, "B": s2}}) ## x = y.x ## del y --- 89,97 ---- x.a = s1 x.b = s2 ! self.failUnlessEqual(x._objects, {"1": s1, "2": s2}) y = Y() y.x = x ! self.failUnlessEqual(y._objects, {"1": {"1": s1, "2": s2}}) ## x = y.x ## del y *************** *** 107,111 **** if DEBUG: self.failUnlessEqual(a._objects, ! {"A": None, "B": None, "C": None, "D": None}) else: self.failUnlessEqual(a._objects, {}) --- 106,110 ---- if DEBUG: self.failUnlessEqual(a._objects, ! {"1": None, "2": None, "3": None, "4": None}) else: self.failUnlessEqual(a._objects, {}) |
From: Thomas H. <th...@us...> - 2004-11-30 10:34:12
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6297 Modified Files: Tag: KEEP_IN_DICT_BRANCH _ctypes.c Log Message: Optimization: simple types don't get a dict as b_objects. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.185.2.3 retrieving revision 1.185.2.4 diff -C2 -d -r1.185.2.3 -r1.185.2.4 *** _ctypes.c 26 Nov 2004 18:46:51 -0000 1.185.2.3 --- _ctypes.c 30 Nov 2004 10:33:51 -0000 1.185.2.4 *************** *** 1219,1223 **** stgdict->ffi_type = *fmt->pffi_type; stgdict->align = fmt->pffi_type->alignment; ! stgdict->length = 1; stgdict->size = fmt->pffi_type->size; stgdict->setfunc = fmt->setfunc; --- 1219,1223 ---- stgdict->ffi_type = *fmt->pffi_type; stgdict->align = fmt->pffi_type->alignment; ! stgdict->length = 0; stgdict->size = fmt->pffi_type->size; stgdict->setfunc = fmt->setfunc; *************** *** 1582,1593 **** */ ! #define ASSERT_CDATA(x) assert(((x)->b_base == NULL) ^ ((x)->b_objects == NULL)) ! ! static PyObject * CData_GetContainer(CDataObject *self) { while (self->b_base) self = self->b_base; ! return self->b_objects; } --- 1582,1591 ---- */ ! static CDataObject * CData_GetContainer(CDataObject *self) { while (self->b_base) self = self->b_base; ! return self; } *************** *** 1595,1599 **** GetKeepedObjects(CDataObject *target) { ! return CData_GetContainer(target); } --- 1593,1597 ---- GetKeepedObjects(CDataObject *target) { ! return CData_GetContainer(target)->b_objects; } *************** *** 1604,1610 **** char *cp = string; int len; ! *cp++ = index + 'A'; while (target->b_base) { ! *cp++ = target->b_index + 'A'; target = target->b_base; } --- 1602,1608 ---- char *cp = string; int len; ! *cp++ = index + '1'; while (target->b_base) { ! *cp++ = target->b_index + '1'; target = target->b_base; } *************** *** 1623,1630 **** { int result; ! PyObject *dict; PyObject *key; ! /* This is an optimization, but enabling it may hide bugs */ #if 0 if (keep == Py_None) { --- 1621,1628 ---- { int result; ! CDataObject *ob; PyObject *key; ! /* Optimization: no need to store None */ #if 0 if (keep == Py_None) { *************** *** 1633,1639 **** } #endif ! dict = CData_GetContainer(target); key = unique_key(target, index); ! result = PyDict_SetItem(dict, key, keep); Py_DECREF(key); Py_DECREF(keep); --- 1631,1642 ---- } #endif ! ob = CData_GetContainer(target); ! if (ob->b_objects == NULL || !PyDict_Check(ob->b_objects)) { ! Py_XDECREF(ob->b_objects); ! ob->b_objects = keep; /* refcount consumed */ ! return 0; ! } key = unique_key(target, index); ! result = PyDict_SetItem(ob->b_objects, key, keep); Py_DECREF(key); Py_DECREF(keep); *************** *** 1841,1846 **** cd = (CDataObject *)mem; - ASSERT_CDATA(cd); - return mem; } --- 1844,1847 ---- *************** *** 2048,2052 **** obj->b_base = NULL; obj->b_index = 0; ! obj->b_objects = PyDict_New(); obj->b_length = length; --- 2049,2059 ---- obj->b_base = NULL; obj->b_index = 0; ! if (length) ! obj->b_objects = PyDict_New(); ! else { ! Py_INCREF(Py_None); ! obj->b_objects = Py_None; ! } ! obj->b_length = length; *************** *** 2064,2069 **** obj->b_base = NULL; obj->b_index = 0; ! ! obj->b_objects = PyDict_New(); obj->b_length = length; --- 2071,2080 ---- obj->b_base = NULL; obj->b_index = 0; ! if (length) ! obj->b_objects = PyDict_New(); ! else { ! Py_INCREF(Py_None); ! obj->b_objects = Py_None; ! } obj->b_length = length; *************** *** 2077,2081 **** memset(obj->b_ptr, 0, size); } - ASSERT_CDATA(obj); return (PyObject *)obj; } --- 2088,2091 ---- |
From: Thomas H. <th...@us...> - 2004-11-26 18:47:04
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17554 Modified Files: Tag: KEEP_IN_DICT_BRANCH _ctypes.c Log Message: Remove unused function. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.185.2.2 retrieving revision 1.185.2.3 diff -C2 -d -r1.185.2.2 -r1.185.2.3 *** _ctypes.c 25 Nov 2004 16:17:58 -0000 1.185.2.2 --- _ctypes.c 26 Nov 2004 18:46:51 -0000 1.185.2.3 *************** *** 1598,1608 **** } - /* set an exception and return -1 if a call to KeepRef will fail, 0 otherwise */ - static int - CanKeepRef(CDataObject *target, int index) - { - return 0; - } - static PyObject * unique_key(CDataObject *target, int index) --- 1598,1601 ---- |
From: Thomas H. <th...@us...> - 2004-11-26 18:40:25
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16309 Modified Files: Tag: KEEP_IN_DICT_BRANCH cfield.c Log Message: Add TODO style comment. Index: cfield.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/cfield.c,v retrieving revision 1.68.2.1 retrieving revision 1.68.2.2 diff -C2 -d -r1.68.2.1 -r1.68.2.2 *** cfield.c 25 Nov 2004 14:53:35 -0000 1.68.2.1 --- cfield.c 26 Nov 2004 18:40:15 -0000 1.68.2.2 *************** *** 919,922 **** --- 919,923 ---- z_get(void *ptr, unsigned size) { + /* XXX What about invalid pointers ??? */ if (*(void **)ptr) return PyString_FromString(*(char **)ptr); |
From: Thomas H. <th...@us...> - 2004-11-25 16:59:53
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8548 Added Files: Tag: KEEP_IN_DICT_BRANCH test_keeprefs.py Log Message: New test, showing the _objects internals. --- NEW FILE: test_keeprefs.py --- from ctypes import * import unittest class SimpleTestCase(unittest.TestCase): def test_cint(self): x = c_int() # a simple object has an empty _objects dict, if uninitialized self.assertEquals(x._objects, {}) # setting the value populates the dict x.value = 42 self.assertEquals(x._objects, {"A": None}) x = c_int(99) self.assertEquals(x._objects, {"A": None}) def test_ccharp(self): x = c_char_p() # a simple object has an empty _objects dict, if uninitialized self.assertEquals(x._objects, {}) # setting the value populates the dict x.value = "abc" self.assertEquals(x._objects, {"A": "abc"}) x = c_char_p("spam") self.assertEquals(x._objects, {"A": "spam"}) class StructureTestCase(unittest.TestCase): def test_cint_struct(self): class X(Structure): _fields_ = [("a", c_int), ("b", c_int)] x = X() self.assertEquals(x._objects, {}) x.a = 42 x.b = 99 self.assertEquals(x._objects, {"A": None, "B": None}) def test_ccharp_struct(self): class X(Structure): _fields_ = [("a", c_char_p), ("b", c_char_p)] x = X() self.assertEquals(x._objects, {}) x.a = "spam" x.b = "foo" self.assertEquals(x._objects, {"A": "spam", "B": "foo"}) def test_struct_struct(self): class POINT(Structure): _fields_ = [("x", c_int), ("y", c_int)] class RECT(Structure): _fields_ = [("ul", POINT), ("lr", POINT)] r = RECT() r.ul.x = 0 r.ul.y = 1 r.lr.x = 2 r.lr.y = 3 self.assertEquals(r._objects, {'AA': None, 'AB': None, 'BA': None, 'BB': None}) r = RECT() r.ul = POINT(1, 2) self.assertEquals(r._objects, {'A': {'A': None, 'B': None}}) r.ul.x = 22 r.ul.y = 44 # The current solution retains unneeded objects as well: self.assertEquals(r._objects, {'A': {'A': None, 'B': None}, # r.ul = POINT(1, 2) 'AA': None, # r.ul.x = 22 'BA': None}) # r.ul.x = 44 # The entry marked '<-' above is no longer needed, it refers to the # POINT we have assigned, but the coords are already overwritten. # But, oh well... class ArrayTestCase(unittest.TestCase): def test_cint_array(self): INTARR = c_int * 3 ia = INTARR() self.assertEquals(ia._objects, {}) ia[0] = 1 ia[1] = 2 ia[2] = 3 self.assertEquals(ia._objects, {"A": None, "B": None, "C": None}) class X(Structure): _fields_ = [("x", c_int), ("a", INTARR)] x = X() x.x = 1000 x.a[0] = 42 x.a[1] = 96 self.assertEquals(x._objects, {"A": None, "AB": None, "BB": None}) x.a = ia self.assertEquals(x._objects, {'A': None, 'B': {'A': None, 'C': None, 'B': None}, 'AB': None, 'BB': None}) # See above, some entries unneeded. class PointerTestCase(unittest.TestCase): def test_p_cint(self): x = pointer(c_int(42)) print x._objects if __name__ == "__main__": unittest.main() |
From: Thomas H. <th...@us...> - 2004-11-25 16:18:16
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32503 Modified Files: Tag: KEEP_IN_DICT_BRANCH test_internals.py Log Message: Keys into the _objects dict are now byte strings, each byte representing an index. For ease of debugging, indexes start at 'A' instead of '\0'. Index: test_internals.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_internals.py,v retrieving revision 1.4.4.1 retrieving revision 1.4.4.2 diff -C2 -d -r1.4.4.1 -r1.4.4.2 *** test_internals.py 25 Nov 2004 14:55:40 -0000 1.4.4.1 --- test_internals.py 25 Nov 2004 16:18:07 -0000 1.4.4.2 *************** *** 31,35 **** self.failUnlessEqual(3, grc(i)) if DEBUG: ! self.failUnlessEqual(ci._objects, {0: None}) else: self.failUnlessEqual(ci._objects, {}) --- 31,35 ---- self.failUnlessEqual(3, grc(i)) if DEBUG: ! self.failUnlessEqual(ci._objects, {"A": None}) else: self.failUnlessEqual(ci._objects, {}) *************** *** 40,45 **** cs = c_char_p(s) self.failUnlessEqual(4, grc(s)) ! self.failUnlessSame(cs._objects[0], s) ! self.failUnlessEqual(cs._objects, {0: s}) def test_simple_struct(self): --- 40,45 ---- cs = c_char_p(s) self.failUnlessEqual(4, grc(s)) ! self.failUnlessSame(cs._objects["A"], s) ! self.failUnlessEqual(cs._objects, {"A": s}) def test_simple_struct(self): *************** *** 54,58 **** x.b = b if DEBUG: ! self.failUnlessEqual(x._objects, {0: None, 1: None}) else: self.failUnlessEqual(x._objects, {}) --- 54,58 ---- x.b = b if DEBUG: ! self.failUnlessEqual(x._objects, {"A": None, "B": None}) else: self.failUnlessEqual(x._objects, {}) *************** *** 70,79 **** x1, x2 = X(), X() y.x, y.y = x1, x2 ! self.failUnlessEqual(y._objects, {0: {}, 1: {}}) x1.a, x2.b = 42, 93 if DEBUG: ! self.failUnlessEqual(y._objects, {0: {0: None}, 1: {1: None}}) else: ! self.failUnlessEqual(y._objects, {0: {}, 1: {}}) def test_xxx(self): --- 70,79 ---- x1, x2 = X(), X() y.x, y.y = x1, x2 ! self.failUnlessEqual(y._objects, {"A": {}, "B": {}}) x1.a, x2.b = 42, 93 if DEBUG: ! self.failUnlessEqual(y._objects, {"A": {"A": None}, "B": {"B": None}}) else: ! self.failUnlessEqual(y._objects, {"A": {}, "B": {}}) def test_xxx(self): *************** *** 90,98 **** x.a = s1 x.b = s2 ! self.failUnlessEqual(x._objects, {0: s1, 1: s2}) y = Y() y.x = x ! self.failUnlessEqual(y._objects, {0: {0: s1, 1: s2}}) ## x = y.x ## del y --- 90,98 ---- x.a = s1 x.b = s2 ! self.failUnlessEqual(x._objects, {"A": s1, "B": s2}) y = Y() y.x = x ! self.failUnlessEqual(y._objects, {"A": {"A": s1, "B": s2}}) ## x = y.x ## del y *************** *** 106,110 **** a = A(11, 22, 33, 44) if DEBUG: ! self.failUnlessEqual(a._objects, {0: None, 1: None, 2: None, 3: None}) else: self.failUnlessEqual(a._objects, {}) --- 106,111 ---- a = A(11, 22, 33, 44) if DEBUG: ! self.failUnlessEqual(a._objects, ! {"A": None, "B": None, "C": None, "D": None}) else: self.failUnlessEqual(a._objects, {}) |
From: Thomas H. <th...@us...> - 2004-11-25 16:18:07
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32437 Modified Files: Tag: KEEP_IN_DICT_BRANCH _ctypes.c Log Message: Keys into the _objects dict are now byte strings, each byte representing an index. For ease of debugging, indexes start at 'A' instead of '\0'. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.185.2.1 retrieving revision 1.185.2.2 diff -C2 -d -r1.185.2.1 -r1.185.2.2 *** _ctypes.c 25 Nov 2004 14:53:35 -0000 1.185.2.1 --- _ctypes.c 25 Nov 2004 16:17:58 -0000 1.185.2.2 *************** *** 1605,1618 **** } /* Keep a reference to 'keep' in the 'target', at index 'index' */ /* ! * XXX KeepRef should travel the target's b_base pointer down to the root, * building a sequence of indexes during the path. The indexes, which are a ! * couple of small integers, should be used to build a unique value usable as ! * key int the root object's _objects dict. For simplicity, tuples of ! * integers can be used, for better performance, a single integer built by a ! * perfect hash function from the indexes would be better. ! * ! * Nothing of this implemented so far. */ static int --- 1605,1628 ---- } + static PyObject * + unique_key(CDataObject *target, int index) + { + char string[256]; /* XXX is that enough? */ + char *cp = string; + int len; + *cp++ = index + 'A'; + while (target->b_base) { + *cp++ = target->b_index + 'A'; + target = target->b_base; + } + len = cp - string; + return PyString_FromStringAndSize(string, cp-string); + } /* Keep a reference to 'keep' in the 'target', at index 'index' */ /* ! * KeepRef travels the target's b_base pointer down to the root, * building a sequence of indexes during the path. The indexes, which are a ! * couple of small integers, are used to build a byte string usable as ! * key int the root object's _objects dict. */ static int *************** *** 1631,1635 **** #endif dict = CData_GetContainer(target); ! key = PyInt_FromLong(index); /* XXX */ result = PyDict_SetItem(dict, key, keep); Py_DECREF(key); --- 1641,1645 ---- #endif dict = CData_GetContainer(target); ! key = unique_key(target, index); result = PyDict_SetItem(dict, key, keep); Py_DECREF(key); *************** *** 1970,1976 **** } - /* Make sure KeepRef will not fail! */ - if (-1 == CanKeepRef(mem, index)) - return -1; result = _CData_set(mem, type, setfunc, value, size, ptr); --- 1980,1983 ---- *************** *** 1979,1984 **** /* KeepRef steals a refcount from it's last argument */ ! return KeepRef(mem, index, result); ! } --- 1986,1992 ---- /* KeepRef steals a refcount from it's last argument */ ! /* If KeepRef fails, we are stumped. The dst memory block has already ! been changed */ ! return KeepRef(mem, index, result); } |
From: Thomas H. <th...@us...> - 2004-11-25 15:08:27
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16043 Modified Files: Tag: KEEP_IN_DICT_BRANCH ctypes.h Log Message: Removed unneeded function declaration. Index: ctypes.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v retrieving revision 1.61 retrieving revision 1.61.2.1 diff -C2 -d -r1.61 -r1.61.2.1 *** ctypes.h 19 Nov 2004 11:07:23 -0000 1.61 --- ctypes.h 25 Nov 2004 15:08:15 -0000 1.61.2.1 *************** *** 63,68 **** } CFuncPtrObject; - extern PyObject *CData_GetList(CDataObject *mem); - extern PyTypeObject StgDict_Type; #define StgDict_CheckExact(v) ((v)->ob_type == &StgDict_Type) --- 63,66 ---- |
From: Thomas H. <th...@us...> - 2004-11-25 15:01:52
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14356 Modified Files: ctypes.h _ctypes.c Log Message: Revert the commits - they should have been on a branch. Index: ctypes.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -d -r1.62 -r1.63 *** ctypes.h 25 Nov 2004 14:42:42 -0000 1.62 --- ctypes.h 25 Nov 2004 15:01:40 -0000 1.63 *************** *** 63,66 **** --- 63,68 ---- } CFuncPtrObject; + extern PyObject *CData_GetList(CDataObject *mem); + extern PyTypeObject StgDict_Type; #define StgDict_CheckExact(v) ((v)->ob_type == &StgDict_Type) Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.186 retrieving revision 1.187 diff -C2 -d -r1.186 -r1.187 *** _ctypes.c 25 Nov 2004 14:46:38 -0000 1.186 --- _ctypes.c 25 Nov 2004 15:01:40 -0000 1.187 *************** *** 1582,1593 **** */ #define ASSERT_CDATA(x) assert(((x)->b_base == NULL) ^ ((x)->b_objects == NULL)) static PyObject * ! CData_GetContainer(CDataObject *self) { ! while (self->b_base) ! self = self->b_base; ! return self->b_objects; } --- 1582,1658 ---- */ + /* Return a list of size <size> filled with None's. */ + static PyObject * + NoneList(int size) + { + int i; + PyObject *list; + + list = PyList_New(size); + if (!list) + return NULL; + for (i = 0; i < size; ++i) { + Py_INCREF(Py_None); + PyList_SET_ITEM(list, i, Py_None); + } + return list; + } + #define ASSERT_CDATA(x) assert(((x)->b_base == NULL) ^ ((x)->b_objects == NULL)) + /* + * Return the list(tree) entry corresponding to a memory object. + * Borrowed reference! + */ static PyObject * ! CData_GetList(CDataObject *mem) { ! PyObject *list; ! PyObject *obj; ! ASSERT_CDATA(mem); ! if (!mem->b_base) { ! return mem->b_objects; ! } else { ! // assert(mem->b_objects == NULL); ! list = CData_GetList(mem->b_base); ! if (list == NULL) ! return NULL; ! obj = PyList_GetItem(list, mem->b_index); ! if (obj == NULL) ! return NULL; ! if (obj == Py_None) { ! obj = NoneList(mem->b_length); ! if (-1 == PyList_SetItem(list, mem->b_index, obj)) ! return NULL; ! } ! return obj; ! } ! } ! ! /* ! * Make sure object <mem> has a list of length <length> ! * at index <index>. Initially all list members are None. ! */ ! static int ! CData_EnsureList(CDataObject *mem, int index, int length) ! { ! PyObject *list; ! PyObject *obj; ! ! list = CData_GetList(mem); ! if (!list) ! return -1; ! obj = PyList_GetItem(list, index); ! if (!obj) ! return -1; ! ! if (obj == Py_None) { ! obj = NoneList(length); ! if (!obj) ! return -1; ! if (-1 == PyList_SetItem(list, index, obj)) ! return -1; ! } ! return 0; } *************** *** 1595,1599 **** GetKeepedObjects(CDataObject *target) { ! return CData_GetContainer(target); } --- 1660,1664 ---- GetKeepedObjects(CDataObject *target) { ! return CData_GetList(target); } *************** *** 1602,1639 **** CanKeepRef(CDataObject *target, int index) { return 0; } /* Keep a reference to 'keep' in the 'target', at index 'index' */ - /* - * XXX KeepRef should travel the target's b_base pointer down to the root, - * building a sequence of indexes during the path. The indexes, which are a - * couple of small integers, should be used to build a unique value usable as - * key int the root object's _objects dict. For simplicity, tuples of - * integers can be used, for better performance, a single integer built by a - * perfect hash function from the indexes would be better. - * - * Nothing of this implemented so far. - */ static int KeepRef(CDataObject *target, int index, PyObject *keep) { int result; ! PyObject *dict; ! PyObject *key; ! ! /* This is an optimization, but enabling it may hide bugs */ ! #if 0 ! if (keep == Py_None) { ! Py_DECREF(Py_None); ! return 0; ! } ! #endif ! dict = CData_GetContainer(target); ! key = PyInt_FromLong(index); /* XXX */ ! result = PyDict_SetItem(dict, key, keep); ! Py_DECREF(key); ! Py_DECREF(keep); ! return result; } --- 1667,1691 ---- CanKeepRef(CDataObject *target, int index) { + PyObject *objects = CData_GetList(target); + if (!objects) + return -1; + if (index < 0 || PyList_Size(objects) <= index) { + PyErr_SetString(PyExc_IndexError, + "invalid index"); + return -1; + } return 0; } /* Keep a reference to 'keep' in the 'target', at index 'index' */ static int KeepRef(CDataObject *target, int index, PyObject *keep) { int result; ! PyObject *list = CData_GetList(target); ! result = PyList_SetItem(list, index, keep); ! if (result == -1) ! return -1; ! return 0; } *************** *** 2044,2051 **** obj->b_size = size; obj->b_needsfree = 0; } else { obj->b_base = NULL; obj->b_index = 0; ! obj->b_objects = PyDict_New(); obj->b_length = length; --- 2096,2108 ---- obj->b_size = size; obj->b_needsfree = 0; + if (-1 == CData_EnsureList(obj->b_base, + spec->index, length)) { + Py_DECREF(obj); + return NULL; + } } else { obj->b_base = NULL; obj->b_index = 0; ! obj->b_objects = NoneList(length); obj->b_length = length; *************** *** 2064,2068 **** obj->b_index = 0; ! obj->b_objects = PyDict_New(); obj->b_length = length; --- 2121,2129 ---- obj->b_index = 0; ! /* 1.11 us in Python 2.3 -OO, 30% of total creation time for c_int() */ ! /* 2.2 us in Pyton 2.2 -OO, ~20% of total creation time */ ! /* Should we use an array of objects in the CDataObject structure ! instead of the b_objects pointer pointing to a list? */ ! obj->b_objects = NoneList(length); obj->b_length = length; |
From: Thomas H. <th...@us...> - 2004-11-25 14:55:50
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13085 Modified Files: Tag: KEEP_IN_DICT_BRANCH test_structures.py test_internals.py Log Message: Adapted the tests according to the new _objects implementation. Index: test_internals.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_internals.py,v retrieving revision 1.4 retrieving revision 1.4.4.1 diff -C2 -d -r1.4 -r1.4.4.1 *** test_internals.py 9 Jun 2004 19:47:25 -0000 1.4 --- test_internals.py 25 Nov 2004 14:55:40 -0000 1.4.4.1 *************** *** 6,9 **** --- 6,12 ---- # XXX This test must be reviewed for correctness!!! + # autodetect an optimization in _ctypes.c::KeepRef() + DEBUG = c_int(2)._objects != {} + """ ctypes' types are container types. *************** *** 27,31 **** ci = c_int(i) self.failUnlessEqual(3, grc(i)) ! self.failUnlessEqual([None], ci._objects) def test_c_char_p(self): --- 30,37 ---- ci = c_int(i) self.failUnlessEqual(3, grc(i)) ! if DEBUG: ! self.failUnlessEqual(ci._objects, {0: None}) ! else: ! self.failUnlessEqual(ci._objects, {}) def test_c_char_p(self): *************** *** 34,39 **** cs = c_char_p(s) self.failUnlessEqual(4, grc(s)) ! self.failUnlessSame(s, cs._objects[0]) ! self.failUnlessEqual([s], cs._objects) def test_simple_struct(self): --- 40,45 ---- cs = c_char_p(s) self.failUnlessEqual(4, grc(s)) ! self.failUnlessSame(cs._objects[0], s) ! self.failUnlessEqual(cs._objects, {0: s}) def test_simple_struct(self): *************** *** 44,51 **** b = 421235 x = X() ! self.failUnlessEqual(x._objects, [None, None]) x.a = a x.b = b ! self.failUnlessEqual(x._objects, [None, None]) def test_embedded_structs(self): --- 50,60 ---- b = 421235 x = X() ! self.failUnlessEqual(x._objects, {}) x.a = a x.b = b ! if DEBUG: ! self.failUnlessEqual(x._objects, {0: None, 1: None}) ! else: ! self.failUnlessEqual(x._objects, {}) def test_embedded_structs(self): *************** *** 57,68 **** y = Y() ! self.failUnlessEqual(y._objects, [None, None]) x1, x2 = X(), X() y.x, y.y = x1, x2 ! self.failUnlessEqual(y._objects, [[None, None], [None, None]]) x1.a, x2.b = 42, 93 ! self.failUnlessEqual(y._objects, [[None, None], [None, None]]) ! ## self.failUnlessEqual(y.x._objects, [None, None]) def test_xxx(self): --- 66,79 ---- y = Y() ! self.failUnlessEqual(y._objects, {}) x1, x2 = X(), X() y.x, y.y = x1, x2 ! self.failUnlessEqual(y._objects, {0: {}, 1: {}}) x1.a, x2.b = 42, 93 ! if DEBUG: ! self.failUnlessEqual(y._objects, {0: {0: None}, 1: {1: None}}) ! else: ! self.failUnlessEqual(y._objects, {0: {}, 1: {}}) def test_xxx(self): *************** *** 79,87 **** x.a = s1 x.b = s2 ! self.failUnlessEqual(x._objects, [s1, s2]) y = Y() y.x = x ! self.failUnlessEqual(y._objects, [[s1, s2], None]) ## x = y.x ## del y --- 90,98 ---- x.a = s1 x.b = s2 ! self.failUnlessEqual(x._objects, {0: s1, 1: s2}) y = Y() y.x = x ! self.failUnlessEqual(y._objects, {0: {0: s1, 1: s2}}) ## x = y.x ## del y *************** *** 94,98 **** A = c_int*4 a = A(11, 22, 33, 44) ! self.failUnlessEqual(a._objects, [None, None, None, None]) x = X() --- 105,112 ---- A = c_int*4 a = A(11, 22, 33, 44) ! if DEBUG: ! self.failUnlessEqual(a._objects, {0: None, 1: None, 2: None, 3: None}) ! else: ! self.failUnlessEqual(a._objects, {}) x = X() Index: test_structures.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_structures.py,v retrieving revision 1.26 retrieving revision 1.26.4.1 diff -C2 -d -r1.26 -r1.26.4.1 *** test_structures.py 4 Nov 2004 18:04:41 -0000 1.26 --- test_structures.py 25 Nov 2004 14:55:40 -0000 1.26.4.1 *************** *** 295,310 **** # This fails with SystemError: bad arg to internal function # or with IndexError (with a patch I have) ! try: ! s.array[0] = 42 ! except (SystemError, IndexError): ! pass items = [s.array[i] for i in range(3)] ! self.failUnlessEqual(items, [1, 2, 3]) ! # and this one with IndexError: invalid index ! try: ! s.array[1] = 42 ! except IndexError: ! pass items = [s.array[i] for i in range(3)] --- 295,307 ---- # This fails with SystemError: bad arg to internal function # or with IndexError (with a patch I have) ! ! s.array[0] = 42 ! items = [s.array[i] for i in range(3)] ! self.failUnlessEqual(items, [42, 2, 3]) ! s.array[0] = 1 ! ! ## s.array[1] = 42 items = [s.array[i] for i in range(3)] |
From: Thomas H. <th...@us...> - 2004-11-25 14:53:46
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12672 Modified Files: Tag: KEEP_IN_DICT_BRANCH cfield.c _ctypes.c Log Message: Accidently I checked in the changes into HEAD instead of KEEP_IN_DICT_BRANCH. Index: cfield.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/cfield.c,v retrieving revision 1.68 retrieving revision 1.68.2.1 diff -C2 -d -r1.68 -r1.68.2.1 *** cfield.c 19 Nov 2004 12:59:27 -0000 1.68 --- cfield.c 25 Nov 2004 14:53:35 -0000 1.68.2.1 *************** *** 273,277 **** 0, /* tp_setattr */ 0, /* tp_compare */ ! CField_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ --- 273,277 ---- 0, /* tp_setattr */ 0, /* tp_compare */ ! (reprfunc)CField_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.185 retrieving revision 1.185.2.1 diff -C2 -d -r1.185 -r1.185.2.1 *** _ctypes.c 25 Nov 2004 09:37:44 -0000 1.185 --- _ctypes.c 25 Nov 2004 14:53:35 -0000 1.185.2.1 *************** *** 1582,1658 **** */ - /* Return a list of size <size> filled with None's. */ - static PyObject * - NoneList(int size) - { - int i; - PyObject *list; - - list = PyList_New(size); - if (!list) - return NULL; - for (i = 0; i < size; ++i) { - Py_INCREF(Py_None); - PyList_SET_ITEM(list, i, Py_None); - } - return list; - } - #define ASSERT_CDATA(x) assert(((x)->b_base == NULL) ^ ((x)->b_objects == NULL)) - /* - * Return the list(tree) entry corresponding to a memory object. - * Borrowed reference! - */ static PyObject * ! CData_GetList(CDataObject *mem) ! { ! PyObject *list; ! PyObject *obj; ! ASSERT_CDATA(mem); ! if (!mem->b_base) { ! return mem->b_objects; ! } else { ! // assert(mem->b_objects == NULL); ! list = CData_GetList(mem->b_base); ! if (list == NULL) ! return NULL; ! obj = PyList_GetItem(list, mem->b_index); ! if (obj == NULL) ! return NULL; ! if (obj == Py_None) { ! obj = NoneList(mem->b_length); ! if (-1 == PyList_SetItem(list, mem->b_index, obj)) ! return NULL; ! } ! return obj; ! } ! } ! ! /* ! * Make sure object <mem> has a list of length <length> ! * at index <index>. Initially all list members are None. ! */ ! static int ! CData_EnsureList(CDataObject *mem, int index, int length) { ! PyObject *list; ! PyObject *obj; ! ! list = CData_GetList(mem); ! if (!list) ! return -1; ! obj = PyList_GetItem(list, index); ! if (!obj) ! return -1; ! ! if (obj == Py_None) { ! obj = NoneList(length); ! if (!obj) ! return -1; ! if (-1 == PyList_SetItem(list, index, obj)) ! return -1; ! } ! return 0; } --- 1582,1593 ---- */ #define ASSERT_CDATA(x) assert(((x)->b_base == NULL) ^ ((x)->b_objects == NULL)) static PyObject * ! CData_GetContainer(CDataObject *self) { ! while (self->b_base) ! self = self->b_base; ! return self->b_objects; } *************** *** 1660,1664 **** GetKeepedObjects(CDataObject *target) { ! return CData_GetList(target); } --- 1595,1599 ---- GetKeepedObjects(CDataObject *target) { ! return CData_GetContainer(target); } *************** *** 1667,1691 **** CanKeepRef(CDataObject *target, int index) { - PyObject *objects = CData_GetList(target); - if (!objects) - return -1; - if (index < 0 || PyList_Size(objects) <= index) { - PyErr_SetString(PyExc_IndexError, - "invalid index"); - return -1; - } return 0; } /* Keep a reference to 'keep' in the 'target', at index 'index' */ static int KeepRef(CDataObject *target, int index, PyObject *keep) { int result; ! PyObject *list = CData_GetList(target); ! result = PyList_SetItem(list, index, keep); ! if (result == -1) ! return -1; ! return 0; } --- 1602,1639 ---- CanKeepRef(CDataObject *target, int index) { return 0; } /* Keep a reference to 'keep' in the 'target', at index 'index' */ + /* + * XXX KeepRef should travel the target's b_base pointer down to the root, + * building a sequence of indexes during the path. The indexes, which are a + * couple of small integers, should be used to build a unique value usable as + * key int the root object's _objects dict. For simplicity, tuples of + * integers can be used, for better performance, a single integer built by a + * perfect hash function from the indexes would be better. + * + * Nothing of this implemented so far. + */ static int KeepRef(CDataObject *target, int index, PyObject *keep) { int result; ! PyObject *dict; ! PyObject *key; ! ! /* This is an optimization, but enabling it may hide bugs */ ! #if 0 ! if (keep == Py_None) { ! Py_DECREF(Py_None); ! return 0; ! } ! #endif ! dict = CData_GetContainer(target); ! key = PyInt_FromLong(index); /* XXX */ ! result = PyDict_SetItem(dict, key, keep); ! Py_DECREF(key); ! Py_DECREF(keep); ! return result; } *************** *** 2096,2108 **** obj->b_size = size; obj->b_needsfree = 0; - if (-1 == CData_EnsureList(obj->b_base, - spec->index, length)) { - Py_DECREF(obj); - return NULL; - } } else { obj->b_base = NULL; obj->b_index = 0; ! obj->b_objects = NoneList(length); obj->b_length = length; --- 2044,2051 ---- obj->b_size = size; obj->b_needsfree = 0; } else { obj->b_base = NULL; obj->b_index = 0; ! obj->b_objects = PyDict_New(); obj->b_length = length; *************** *** 2121,2129 **** obj->b_index = 0; ! /* 1.11 us in Python 2.3 -OO, 30% of total creation time for c_int() */ ! /* 2.2 us in Pyton 2.2 -OO, ~20% of total creation time */ ! /* Should we use an array of objects in the CDataObject structure ! instead of the b_objects pointer pointing to a list? */ ! obj->b_objects = NoneList(length); obj->b_length = length; --- 2064,2068 ---- obj->b_index = 0; ! obj->b_objects = PyDict_New(); obj->b_length = length; |
From: Thomas H. <th...@us...> - 2004-11-25 14:46:52
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11420 Modified Files: _ctypes.c Log Message: First step towards fixing the nasty pointer bug - store objects which need to be kept alive in a dictionary instead of a list. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.185 retrieving revision 1.186 diff -C2 -d -r1.185 -r1.186 *** _ctypes.c 25 Nov 2004 09:37:44 -0000 1.185 --- _ctypes.c 25 Nov 2004 14:46:38 -0000 1.186 *************** *** 1582,1658 **** */ - /* Return a list of size <size> filled with None's. */ - static PyObject * - NoneList(int size) - { - int i; - PyObject *list; - - list = PyList_New(size); - if (!list) - return NULL; - for (i = 0; i < size; ++i) { - Py_INCREF(Py_None); - PyList_SET_ITEM(list, i, Py_None); - } - return list; - } - #define ASSERT_CDATA(x) assert(((x)->b_base == NULL) ^ ((x)->b_objects == NULL)) - /* - * Return the list(tree) entry corresponding to a memory object. - * Borrowed reference! - */ static PyObject * ! CData_GetList(CDataObject *mem) ! { ! PyObject *list; ! PyObject *obj; ! ASSERT_CDATA(mem); ! if (!mem->b_base) { ! return mem->b_objects; ! } else { ! // assert(mem->b_objects == NULL); ! list = CData_GetList(mem->b_base); ! if (list == NULL) ! return NULL; ! obj = PyList_GetItem(list, mem->b_index); ! if (obj == NULL) ! return NULL; ! if (obj == Py_None) { ! obj = NoneList(mem->b_length); ! if (-1 == PyList_SetItem(list, mem->b_index, obj)) ! return NULL; ! } ! return obj; ! } ! } ! ! /* ! * Make sure object <mem> has a list of length <length> ! * at index <index>. Initially all list members are None. ! */ ! static int ! CData_EnsureList(CDataObject *mem, int index, int length) { ! PyObject *list; ! PyObject *obj; ! ! list = CData_GetList(mem); ! if (!list) ! return -1; ! obj = PyList_GetItem(list, index); ! if (!obj) ! return -1; ! ! if (obj == Py_None) { ! obj = NoneList(length); ! if (!obj) ! return -1; ! if (-1 == PyList_SetItem(list, index, obj)) ! return -1; ! } ! return 0; } --- 1582,1593 ---- */ #define ASSERT_CDATA(x) assert(((x)->b_base == NULL) ^ ((x)->b_objects == NULL)) static PyObject * ! CData_GetContainer(CDataObject *self) { ! while (self->b_base) ! self = self->b_base; ! return self->b_objects; } *************** *** 1660,1664 **** GetKeepedObjects(CDataObject *target) { ! return CData_GetList(target); } --- 1595,1599 ---- GetKeepedObjects(CDataObject *target) { ! return CData_GetContainer(target); } *************** *** 1667,1691 **** CanKeepRef(CDataObject *target, int index) { - PyObject *objects = CData_GetList(target); - if (!objects) - return -1; - if (index < 0 || PyList_Size(objects) <= index) { - PyErr_SetString(PyExc_IndexError, - "invalid index"); - return -1; - } return 0; } /* Keep a reference to 'keep' in the 'target', at index 'index' */ static int KeepRef(CDataObject *target, int index, PyObject *keep) { int result; ! PyObject *list = CData_GetList(target); ! result = PyList_SetItem(list, index, keep); ! if (result == -1) ! return -1; ! return 0; } --- 1602,1639 ---- CanKeepRef(CDataObject *target, int index) { return 0; } /* Keep a reference to 'keep' in the 'target', at index 'index' */ + /* + * XXX KeepRef should travel the target's b_base pointer down to the root, + * building a sequence of indexes during the path. The indexes, which are a + * couple of small integers, should be used to build a unique value usable as + * key int the root object's _objects dict. For simplicity, tuples of + * integers can be used, for better performance, a single integer built by a + * perfect hash function from the indexes would be better. + * + * Nothing of this implemented so far. + */ static int KeepRef(CDataObject *target, int index, PyObject *keep) { int result; ! PyObject *dict; ! PyObject *key; ! ! /* This is an optimization, but enabling it may hide bugs */ ! #if 0 ! if (keep == Py_None) { ! Py_DECREF(Py_None); ! return 0; ! } ! #endif ! dict = CData_GetContainer(target); ! key = PyInt_FromLong(index); /* XXX */ ! result = PyDict_SetItem(dict, key, keep); ! Py_DECREF(key); ! Py_DECREF(keep); ! return result; } *************** *** 2096,2108 **** obj->b_size = size; obj->b_needsfree = 0; - if (-1 == CData_EnsureList(obj->b_base, - spec->index, length)) { - Py_DECREF(obj); - return NULL; - } } else { obj->b_base = NULL; obj->b_index = 0; ! obj->b_objects = NoneList(length); obj->b_length = length; --- 2044,2051 ---- obj->b_size = size; obj->b_needsfree = 0; } else { obj->b_base = NULL; obj->b_index = 0; ! obj->b_objects = PyDict_New(); obj->b_length = length; *************** *** 2121,2129 **** obj->b_index = 0; ! /* 1.11 us in Python 2.3 -OO, 30% of total creation time for c_int() */ ! /* 2.2 us in Pyton 2.2 -OO, ~20% of total creation time */ ! /* Should we use an array of objects in the CDataObject structure ! instead of the b_objects pointer pointing to a list? */ ! obj->b_objects = NoneList(length); obj->b_length = length; --- 2064,2068 ---- obj->b_index = 0; ! obj->b_objects = PyDict_New(); obj->b_length = length; |
From: Thomas H. <th...@us...> - 2004-11-25 14:42:52
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10615 Modified Files: ctypes.h Log Message: Remove a function declaration. Index: ctypes.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v retrieving revision 1.61 retrieving revision 1.62 diff -C2 -d -r1.61 -r1.62 *** ctypes.h 19 Nov 2004 11:07:23 -0000 1.61 --- ctypes.h 25 Nov 2004 14:42:42 -0000 1.62 *************** *** 63,68 **** } CFuncPtrObject; - extern PyObject *CData_GetList(CDataObject *mem); - extern PyTypeObject StgDict_Type; #define StgDict_CheckExact(v) ((v)->ob_type == &StgDict_Type) --- 63,66 ---- |
From: Thomas H. <th...@us...> - 2004-11-25 14:05:07
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2329 Modified Files: setup.py Log Message: Forgot to increment the version number. Index: setup.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/setup.py,v retrieving revision 1.110 retrieving revision 1.111 diff -C2 -d -r1.110 -r1.111 *** setup.py 22 Oct 2004 07:09:48 -0000 1.110 --- setup.py 25 Nov 2004 14:04:54 -0000 1.111 *************** *** 12,16 **** LIBFFI_SOURCES='source/gcc/libffi' ! __version__ = "0.9.2" ################################################################ --- 12,16 ---- LIBFFI_SOURCES='source/gcc/libffi' ! __version__ = "0.9.3" ################################################################ |