ctypes-commit Mailing List for ctypes (Page 61)
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...> - 2005-04-05 19:30:36
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10316 Added Files: test_setfunc.py Log Message: Test the internal setfunc function of ctypes types. --- NEW FILE: test_setfunc.py --- # Test the (internal) setfunc function. import unittest from ctypes import * s_types = (c_byte, c_short, c_int, c_long, c_longlong) u_types = (c_ubyte, c_ushort, c_uint, c_ulong, c_ulonglong) # ctypes int classes __init__ and from_param should accept exactly the same objects. class TestIntegers(unittest.TestCase): def test_init(self): # we can now initialize any ctypes int type... for cls in s_types + u_types: # ...from any ctypes int type, or python int. for obj in [typ(42) for typ in s_types + u_types] + [42, 42L]: self.failUnlessEqual(cls(obj).value, 42) # but not from other types for obj in (c_char("x"), c_char_p("x"), "x", c_float(42), c_double(42), 42.0): self.assertRaises(TypeError, lambda: cls(obj)) def test_fromparam(self): for cls in s_types + u_types: for obj in [typ(42) for typ in s_types + u_types] + [42, 42L]: # from_param currently either returns the object itself, # or a PyCArgObject. param = cls.from_param(obj) if obj == param: continue self.failUnlessEqual(repr(param), "<cparam '%s' (42)>" % cls._type_) for obj in (c_char("x"), c_char_p("x"), "x", c_float(42), c_double(42), 42.0): self.assertRaises(TypeError, lambda: cls.from_para,(obj)) def test_setfield(self): for cls in s_types + u_types: class X(Structure): _fields_ = [("v", cls)] x = X() for obj in [typ(42) for typ in s_types + u_types] + [42, 42L]: x.v = obj self.failUnlessEqual(x.v, 42) for obj in (c_char("x"), c_char_p("x"), "x", c_float(42), c_double(42), 42.0): self.assertRaises(TypeError, setattr, x, "v", obj) if __name__ == "__main__": unittest.main() |
From: Thomas H. <th...@us...> - 2005-04-05 19:20:18
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6524 Modified Files: test_numbers.py Log Message: Remove a test that no longer works (and shouldn't have worked, anyway). Index: test_numbers.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_numbers.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** test_numbers.py 31 Mar 2005 17:06:21 -0000 1.22 --- test_numbers.py 5 Apr 2005 19:20:09 -0000 1.23 *************** *** 177,186 **** self.failUnlessEqual(v.value, a[0]) - def test_init(self): - # c_int() can be initialized from Python's int, and c_int. - # Not from c_long or so, which seems strange, abd should - # probably be changed: - self.assertRaises(TypeError, c_int, c_long(42)) - ## def test_perf(self): ## check_perf() --- 177,180 ---- |
From: Thomas H. <th...@us...> - 2005-04-05 19:13:58
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4240 Modified Files: test_leaks.py Log Message: This change makes the leak detection test both faster and more robust (hopefully). Index: test_leaks.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_leaks.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_leaks.py 27 Oct 2004 17:32:16 -0000 1.7 --- test_leaks.py 5 Apr 2005 19:13:50 -0000 1.8 *************** *** 58,66 **** def test_cycles_refcount(self): last_refcount = 0 ! for x in xrange(5): ! self.make_cyclic_structures(1000) while gc.collect(): pass total_refcount = sys.gettotalrefcount() if last_refcount >= total_refcount: return --- 58,67 ---- def test_cycles_refcount(self): last_refcount = 0 ! for x in xrange(20): ! self.make_cyclic_structures(200) while gc.collect(): pass total_refcount = sys.gettotalrefcount() + ## print total_refcount if last_refcount >= total_refcount: return |
From: Thomas H. <th...@us...> - 2005-04-05 19:01:59
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv466 Modified Files: cfield.c Log Message: get_long, get_ulong, get_longlong and get_ulonglong now accept ctypes int instances in addition to Python int and long. Index: cfield.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/cfield.c,v retrieving revision 1.106 retrieving revision 1.107 diff -C2 -d -r1.106 -r1.107 *** cfield.c 4 Apr 2005 15:41:10 -0000 1.106 --- cfield.c 5 Apr 2005 19:01:48 -0000 1.107 *************** *** 280,304 **** /******************************************************************/ /* ! Accessor functions ! */ ! ! /* Derived from Modules/structmodule.c: Helper routines to get a Python ! integer and raise the appropriate error if it isn't one. ! */ ! ! /* ! We should change get_long and friends to accept c_int() and other integer ! like instances as well. When we have done that, and also changed the other ! ..._get functions to accept instances of their type, the _from_param methods ! in ctypes.c can replaced by calls to ..._get(). ! ! One possibility would be to call their getfunc, which returns an PyIntObject ! or PyLongObject. ! ! Hm, the problem is what to pass for 'size'. Maybe zero, but c_get() asserts ! that size is 1. The assertion is probably wrong. The result from c_get will ! not be accepted here anyway because we accept only ints or longs. ! ! I should clarify what the site parameter for getfunc means. For integer like types, it specifies bitfield size for structure fields in the third and fourth byte. See the GET_BITFIELD() macro. --- 280,284 ---- /******************************************************************/ /* ! I should clarify what the size parameter for getfunc means. For integer like types, it specifies bitfield size for structure fields in the third and fourth byte. See the GET_BITFIELD() macro. *************** *** 307,321 **** _ctypes.c::CharArray_getfunc. */ ! static int ! get_long(PyObject *v, long *p) { ! long x; if (!PyInt_Check(v) && !PyLong_Check(v)) { PyErr_Format(PyExc_TypeError, "int expected instead of %s instance", v->ob_type->tp_name); ! return -1; } x = PyInt_AsUnsignedLongMask(v); if (x == -1 && PyErr_Occurred()) return -1; --- 287,335 ---- _ctypes.c::CharArray_getfunc. */ ! /* ! Accessor functions ! */ ! ! /* ! Helper routines to get a Python integer and raise the appropriate error if ! it isn't one. ! */ ! ! static PyObject * ! _make_int(PyObject *v) { ! StgDictObject *dict = PyObject_stgdict(v); ! if (dict) { ! CDataObject *src = (CDataObject *)v; ! PyObject *obj = dict->getfunc(src->b_ptr, 0, NULL, src, 0); ! if (obj == NULL) { ! if (PyErr_ExceptionMatches(PyExc_TypeError)) ! PyErr_Format(PyExc_TypeError, ! "int expected instead of %s instance", ! v->ob_type->tp_name); ! return NULL; ! } ! v = obj; ! } else ! Py_INCREF(v); if (!PyInt_Check(v) && !PyLong_Check(v)) { PyErr_Format(PyExc_TypeError, "int expected instead of %s instance", v->ob_type->tp_name); ! Py_DECREF(v); ! return NULL; } + return v; + } + + static int + get_long(PyObject *v, long *p) + { + long x; + v = _make_int(v); + if (v == NULL) + return -1; x = PyInt_AsUnsignedLongMask(v); + Py_DECREF(v); if (x == -1 && PyErr_Occurred()) return -1; *************** *** 324,340 **** } - /* Same, but handling unsigned long */ - static int get_ulong(PyObject *v, unsigned long *p) { unsigned long x; ! if (!PyInt_Check(v) && !PyLong_Check(v)) { ! PyErr_Format(PyExc_TypeError, ! "int expected instead of %s instance", ! v->ob_type->tp_name); return -1; - } x = PyInt_AsUnsignedLongMask(v); if (x == -1 && PyErr_Occurred()) return -1; --- 338,350 ---- } static int get_ulong(PyObject *v, unsigned long *p) { unsigned long x; ! v = _make_int(v); ! if (v == NULL) return -1; x = PyInt_AsUnsignedLongMask(v); + Py_DECREF(v); if (x == -1 && PyErr_Occurred()) return -1; *************** *** 344,361 **** #ifdef HAVE_LONG_LONG - - /* Same, but handling native long long. */ - static int get_longlong(PyObject *v, PY_LONG_LONG *p) { PY_LONG_LONG x; ! if (!PyInt_Check(v) && !PyLong_Check(v)) { ! PyErr_Format(PyExc_TypeError, ! "int expected instead of %s instance", ! v->ob_type->tp_name); return -1; - } x = PyInt_AsUnsignedLongLongMask(v); if (x == -1 && PyErr_Occurred()) return -1; --- 354,366 ---- #ifdef HAVE_LONG_LONG static int get_longlong(PyObject *v, PY_LONG_LONG *p) { PY_LONG_LONG x; ! v = _make_int(v); ! if (v == NULL) return -1; x = PyInt_AsUnsignedLongLongMask(v); + Py_DECREF(v); if (x == -1 && PyErr_Occurred()) return -1; *************** *** 364,380 **** } - /* Same, but handling native unsigned long long. */ - static int get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p) { unsigned PY_LONG_LONG x; ! if (!PyInt_Check(v) && !PyLong_Check(v)) { ! PyErr_Format(PyExc_TypeError, ! "int expected instead of %s instance", ! v->ob_type->tp_name); return -1; - } x = PyInt_AsUnsignedLongLongMask(v); if (x == -1 && PyErr_Occurred()) return -1; --- 369,381 ---- } static int get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p) { unsigned PY_LONG_LONG x; ! v = _make_int(v); ! if (v == NULL) return -1; x = PyInt_AsUnsignedLongLongMask(v); + Py_DECREF(v); if (x == -1 && PyErr_Occurred()) return -1; *************** *** 382,386 **** return 0; } - #endif --- 383,386 ---- |
From: Thomas H. <th...@us...> - 2005-04-05 16:58:50
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27071 Modified Files: _ctypes.c Log Message: Changed version number to 2.0.0.0cvs. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.274 retrieving revision 1.275 diff -C2 -d -r1.274 -r1.275 *** _ctypes.c 1 Apr 2005 19:38:52 -0000 1.274 --- _ctypes.c 5 Apr 2005 16:58:40 -0000 1.275 *************** *** 3944,3948 **** PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL)); PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI)); ! PyModule_AddStringConstant(m, "__version__", "0.9.7beta"); PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL); --- 3944,3948 ---- PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL)); PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI)); ! PyModule_AddStringConstant(m, "__version__", "2.0.0.0cvs"); PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL); |
From: Thomas H. <th...@us...> - 2005-04-05 16:58:22
|
Update of /cvsroot/ctypes/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27004 Modified Files: __init__.py Log Message: Changed version number to 2.0.0.0cvs. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/__init__.py,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -d -r1.62 -r1.63 *** __init__.py 1 Apr 2005 19:38:24 -0000 1.62 --- __init__.py 5 Apr 2005 16:58:13 -0000 1.63 *************** *** 9,13 **** del _magicfile ! __version__ = "0.9.7beta" from _ctypes import Union, Structure, Array --- 9,13 ---- del _magicfile ! __version__ = "2.0.0.0cvs" from _ctypes import Union, Structure, Array |
From: Thomas H. <th...@us...> - 2005-04-05 16:58:13
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26880 Modified Files: setup.py Log Message: Changed version number to 2.0.0.0cvs. Index: setup.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/setup.py,v retrieving revision 1.123 retrieving revision 1.124 diff -C2 -d -r1.123 -r1.124 *** setup.py 1 Apr 2005 19:38:13 -0000 1.123 --- setup.py 5 Apr 2005 16:58:03 -0000 1.124 *************** *** 12,16 **** LIBFFI_SOURCES='source/gcc/libffi' ! __version__ = "0.9.7beta" ################################################################ --- 12,16 ---- LIBFFI_SOURCES='source/gcc/libffi' ! __version__ = "2.0.0.0cvs" ################################################################ |
From: Thomas H. <th...@us...> - 2005-04-04 15:56:08
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13724 Modified Files: Tag: branch_1_0 ChangeLog Log Message: Record changes. Index: ChangeLog =================================================================== RCS file: /cvsroot/ctypes/ctypes/ChangeLog,v retrieving revision 1.86 retrieving revision 1.86.2.1 diff -C2 -d -r1.86 -r1.86.2.1 *** ChangeLog 18 Mar 2005 18:09:41 -0000 1.86 --- ChangeLog 4 Apr 2005 15:55:55 -0000 1.86.2.1 *************** *** 1,2 **** --- 1,13 ---- + 2005-04-04 Thomas Heller <th...@py...> + + * Fix a refcount leak. + + * Fix a possible segfault in the 'cast' function (the code + possibly tried to Py_DECREF an uninitialized pointer). + + 2005-04-04 Thomas Heller <th...@py...> + + * CVS: Created a branch_1_0 branch. + 2005-03-18 Thomas Heller <th...@py...> |
From: Thomas H. <th...@us...> - 2005-04-04 15:51:14
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12298 Modified Files: Tag: branch_1_0 _ctypes.c Log Message: Fix a refcount leak. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.226 retrieving revision 1.226.2.1 diff -C2 -d -r1.226 -r1.226.2.1 *** _ctypes.c 16 Mar 2005 19:58:45 -0000 1.226 --- _ctypes.c 4 Apr 2005 15:51:04 -0000 1.226.2.1 *************** *** 1935,1938 **** --- 1935,1939 ---- if (PyTuple_Check(value)) { PyObject *ob; + PyObject *result; ob = PyObject_CallObject(type, value); if (ob == NULL) { *************** *** 1941,1946 **** return NULL; } ! return _CData_set(dst, type, setfunc, ob, ! size, ptr); } else if (value == Py_None && PointerTypeObject_Check(type)) { *(void **)dst->b_ptr = NULL; --- 1942,1949 ---- return NULL; } ! result = _CData_set(dst, type, setfunc, ob, ! size, ptr); ! Py_DECREF(ob); ! return result; } else if (value == Py_None && PointerTypeObject_Check(type)) { *(void **)dst->b_ptr = NULL; |
From: Thomas H. <th...@us...> - 2005-04-04 15:46:15
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10885 Modified Files: Tag: branch_1_0 callproc.c Log Message: NULL out the struct argument keep field. Index: callproc.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callproc.c,v retrieving revision 1.127 retrieving revision 1.127.2.1 diff -C2 -d -r1.127 -r1.127.2.1 *** callproc.c 10 Mar 2005 08:53:33 -0000 1.127 --- callproc.c 4 Apr 2005 15:46:06 -0000 1.127.2.1 *************** *** 448,451 **** --- 448,452 ---- static int ConvParam(PyObject *obj, int index, struct argument *pa) { + pa->keep = NULL; /* so we cannot forget it later */ if (PyCArg_CheckExact(obj)) { PyCArgObject *carg = (PyCArgObject *)obj; |
From: Thomas H. <th...@us...> - 2005-04-04 15:41:20
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9708 Modified Files: cfield.c Log Message: Apparently the U_get and U_set functions are no longer used. Index: cfield.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/cfield.c,v retrieving revision 1.105 retrieving revision 1.106 diff -C2 -d -r1.105 -r1.106 *** cfield.c 1 Apr 2005 12:37:04 -0000 1.105 --- cfield.c 4 Apr 2005 15:41:10 -0000 1.106 *************** *** 807,877 **** } - /* U - a unicode string */ - static PyObject * - U_get(void *ptr, unsigned size, PyObject *type, CDataObject *src, int index) - { - PyObject *result; - unsigned int len; - Py_UNICODE *p; - - size /= sizeof(wchar_t); /* we count character units here, not bytes */ - - result = PyUnicode_FromWideChar((wchar_t *)ptr, size); - if (!result) - return NULL; /*COV*/ - /* We need 'result' to be able to count the characters with wcslen, - since ptr may not be NUL terminated. If the length is smaller (if - it was actually NUL terminated, we construct a new one and throw - away the result. - */ - /* chop off at the first NUL character, if any. */ - p = PyUnicode_AS_UNICODE(result); - for (len = 0; len < size; ++len) - if (!p[len]) - break; - - if (len < size) { - PyObject *ob = PyUnicode_FromWideChar((wchar_t *)ptr, len); - Py_DECREF(result); - return ob; - } - return result; - } - - static PyObject * - U_set(void *ptr, PyObject *value, unsigned length, PyObject *type) - { - unsigned int size; - assert(type); - /* It's easier to calculate in characters than in bytes */ - length /= sizeof(wchar_t); - - if (PyString_Check(value)) { - value = PyUnicode_FromEncodedObject(value, - conversion_mode_encoding, - conversion_mode_errors); - if (!value) - return NULL; - } else if (!PyUnicode_Check(value)) { - PyErr_Format(PyExc_TypeError, - "unicode string expected instead of %s instance", - value->ob_type->tp_name); - return NULL; - } else - Py_INCREF(value); - size = PyUnicode_GET_SIZE(value); - if (size > length) { - PyErr_Format(PyExc_ValueError, - "string too long (%d, maximum length %d)", - size, length); - Py_DECREF(value); - return NULL; - } else if (size < length-1) - /* copy terminating NUL character if there is space */ - size += 1; - PyUnicode_AsWideChar((PyUnicodeObject *)value, (wchar_t *)ptr, size); - return value; - } - #endif --- 807,810 ---- *************** *** 1094,1133 **** static struct fielddesc formattable[] = { ! { 'b', b_set, b_get, &ffi_type_schar}, ! { 'B', B_set, B_get, &ffi_type_uchar}, ! { 'c', c_set, c_get, &ffi_type_schar}, ! { 'd', d_set, d_get, &ffi_type_double}, ! { 'f', f_set, f_get, &ffi_type_float}, ! { 'h', h_set, h_get, &ffi_type_sshort}, ! { 'H', H_set, H_get, &ffi_type_ushort}, ! { 'i', i_set, i_get, &ffi_type_sint}, ! { 'I', I_set, I_get, &ffi_type_uint}, /* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */ /* As soon as we can get rid of the type codes, this is no longer a problem */ #if SIZEOF_LONG == 4 ! { 'l', l_set, l_get, &ffi_type_sint}, ! { 'L', L_set, L_get, &ffi_type_uint}, #elif SIZEOF_LONG == 8 ! { 'l', l_set, l_get, &ffi_type_slong}, ! { 'L', L_set, L_get, &ffi_type_ulong}, #else # error #endif #ifdef HAVE_LONG_LONG ! { 'q', q_set, q_get, &ffi_type_slong}, ! { 'Q', Q_set, Q_get, &ffi_type_ulong}, #endif ! { 'P', P_set, P_get, &ffi_type_pointer}, ! { 'z', z_set, z_get, &ffi_type_pointer}, #ifdef CTYPES_UNICODE ! { 'u', u_set, u_get, NULL}, /* ffi_type set later */ ! { 'U', U_set, U_get, &ffi_type_pointer}, ! { 'Z', Z_set, Z_get, &ffi_type_pointer}, #endif #ifdef MS_WIN32 ! { 'X', BSTR_set, BSTR_get, &ffi_type_pointer}, ! { 'v', vBOOL_set, vBOOL_get, &ffi_type_sshort}, #endif ! { 'O', O_set, O_get, &ffi_type_pointer}, { 0, NULL, NULL, NULL}, }; --- 1027,1065 ---- static struct fielddesc formattable[] = { ! { 'b', b_set, b_get, &ffi_type_schar}, /* c_byte */ ! { 'B', B_set, B_get, &ffi_type_uchar}, /* c_ubyte */ ! { 'c', c_set, c_get, &ffi_type_schar}, /* c_char */ ! { 'd', d_set, d_get, &ffi_type_double}, /* c_double */ ! { 'f', f_set, f_get, &ffi_type_float}, /* c_float */ ! { 'h', h_set, h_get, &ffi_type_sshort}, /* c_short */ ! { 'H', H_set, H_get, &ffi_type_ushort}, /* c_ushort */ ! { 'i', i_set, i_get, &ffi_type_sint}, /* c_int */ ! { 'I', I_set, I_get, &ffi_type_uint}, /* c_uint */ /* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */ /* As soon as we can get rid of the type codes, this is no longer a problem */ #if SIZEOF_LONG == 4 ! { 'l', l_set, l_get, &ffi_type_sint}, /* c_long */ ! { 'L', L_set, L_get, &ffi_type_uint}, /* c_ulong */ #elif SIZEOF_LONG == 8 ! { 'l', l_set, l_get, &ffi_type_slong}, /* c_long */ ! { 'L', L_set, L_get, &ffi_type_ulong}, /* c_ulong */ #else # error #endif #ifdef HAVE_LONG_LONG ! { 'q', q_set, q_get, &ffi_type_slong}, /* c_longlong */ ! { 'Q', Q_set, Q_get, &ffi_type_ulong}, /* c_ulonglong */ #endif ! { 'P', P_set, P_get, &ffi_type_pointer}, /* c_void_p */ ! { 'z', z_set, z_get, &ffi_type_pointer}, /* c_char_p */ #ifdef CTYPES_UNICODE ! { 'u', u_set, u_get, NULL}, /* ffi_type set later */ /* c_wchar */ ! { 'Z', Z_set, Z_get, &ffi_type_pointer}, /* c_wchar_p */ #endif #ifdef MS_WIN32 ! { 'X', BSTR_set, BSTR_get, &ffi_type_pointer}, /* BSTR */ ! { 'v', vBOOL_set, vBOOL_get, &ffi_type_sshort}, /* VARIANT_BOOL */ #endif ! { 'O', O_set, O_get, &ffi_type_pointer}, /* py_object */ { 0, NULL, NULL, NULL}, }; *************** *** 1141,1150 **** getentry(char *fmt) { - static int initialized = 0; struct fielddesc *table = formattable; ! if (!initialized) { initialized = 1; - #ifdef CTYPES_UNICODE if (sizeof(wchar_t) == sizeof(short)) getentry("u")->pffi_type = &ffi_type_sshort; --- 1073,1081 ---- getentry(char *fmt) { struct fielddesc *table = formattable; ! #ifdef CTYPES_UNICODE ! static int initialized = 0; if (!initialized) { initialized = 1; if (sizeof(wchar_t) == sizeof(short)) getentry("u")->pffi_type = &ffi_type_sshort; *************** *** 1153,1159 **** else if (sizeof(wchar_t) == sizeof(long)) getentry("u")->pffi_type = &ffi_type_slong; - #endif } ! for (; table->code; ++table) { if (table->code == fmt[0]) --- 1084,1089 ---- else if (sizeof(wchar_t) == sizeof(long)) getentry("u")->pffi_type = &ffi_type_slong; } ! #endif for (; table->code; ++table) { if (table->code == fmt[0]) |
From: Thomas H. <th...@us...> - 2005-04-04 15:39:15
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9239 Modified Files: callproc.c Log Message: Initialize the 'keep' field of struct argument. Index: callproc.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callproc.c,v retrieving revision 1.139 retrieving revision 1.140 diff -C2 -d -r1.139 -r1.140 *** callproc.c 31 Mar 2005 18:45:38 -0000 1.139 --- callproc.c 4 Apr 2005 15:39:04 -0000 1.140 *************** *** 430,433 **** --- 430,434 ---- StgDictObject *stgdict; + pa->keep = NULL; /* so we cannot forget it later */ if (PyCArg_CheckExact(obj)) { PyCArgObject *carg = (PyCArgObject *)obj; *************** *** 1296,1299 **** --- 1297,1301 ---- if (!PyArg_ParseTuple(args, "OO", &obj, &ctype)) return NULL; + memset(&a, 0, sizeof(struct argument)); if (-1 == ConvParam(obj, 1, &a)) return NULL; |
From: Thomas H. <th...@us...> - 2005-04-01 19:39:20
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2070 Modified Files: _ctypes.c Log Message: Some todo comments. Changed version number to 0.9.7beta. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.273 retrieving revision 1.274 diff -C2 -d -r1.273 -r1.274 *** _ctypes.c 1 Apr 2005 18:35:47 -0000 1.273 --- _ctypes.c 1 Apr 2005 19:38:52 -0000 1.274 *************** *** 1,3 **** --- 1,22 ---- /* + xyz_asparam(CDataObject *self, struct argument *pa) + + Instance method. + + Copies the contents of self's buffer into pa's buffer, + keeps self alive in pa->keep, sets ps'a ffi_type. + */ + + /* + xyz_from_param(PyObject *type, PyObject *value) + + Class method (instance method on the metatype to be exact). + + Adapts 'value' to the ctypes 'type', and returns something that can be used + as a function call argument. Should probably create a new CArgObject, the + use the type's setfunc to store value in it. + */ + + /* ToDo: *************** *** 333,336 **** --- 352,356 ---- "Convert a Python object into a function call parameter."; + /* Used for Array, Structure, Union, CFuncPtr */ static PyObject * CDataType_from_param(PyObject *type, PyObject *value) *************** *** 1163,1166 **** --- 1183,1193 ---- c_wchar_p_from_param(PyObject *type, PyObject *value) { + /* Again, this should use setfunc (Z_set). + Z_set handles None, Unicode, String, but not Array, Pointer, + CArgObject. + + But it handles, although it shouldn't, int and long. + Would be an api change to fix this. + */ if (value == Py_None) { Py_INCREF(Py_None); *************** *** 1355,1358 **** --- 1382,1386 ---- pa->ffi_type = &dict->ffi_type; /* Hm, Aren't here any little/big endian issues? */ + assert(sizeof(pa->value) >= self->b_size); memcpy(&pa->value, self->b_ptr, self->b_size); Py_INCREF(self); *************** *** 3916,3920 **** PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL)); PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI)); ! PyModule_AddStringConstant(m, "__version__", "0.9.6"); PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL); --- 3944,3948 ---- PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL)); PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI)); ! PyModule_AddStringConstant(m, "__version__", "0.9.7beta"); PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL); |
From: Thomas H. <th...@us...> - 2005-04-01 19:38:52
|
Update of /cvsroot/ctypes/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1934 Modified Files: __init__.py Log Message: Some todo comments. Changed version number to 0.9.7beta. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/__init__.py,v retrieving revision 1.61 retrieving revision 1.62 diff -C2 -d -r1.61 -r1.62 *** __init__.py 18 Mar 2005 17:39:31 -0000 1.61 --- __init__.py 1 Apr 2005 19:38:24 -0000 1.62 *************** *** 9,13 **** del _magicfile ! __version__ = "0.9.6" from _ctypes import Union, Structure, Array --- 9,13 ---- del _magicfile ! __version__ = "0.9.7beta" from _ctypes import Union, Structure, Array |
From: Thomas H. <th...@us...> - 2005-04-01 19:38:25
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1711 Modified Files: setup.py Log Message: Some todo comments. Changed version number to 0.9.7beta. Index: setup.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/setup.py,v retrieving revision 1.122 retrieving revision 1.123 diff -C2 -d -r1.122 -r1.123 *** setup.py 17 Mar 2005 19:30:07 -0000 1.122 --- setup.py 1 Apr 2005 19:38:13 -0000 1.123 *************** *** 12,16 **** LIBFFI_SOURCES='source/gcc/libffi' ! __version__ = "0.9.6" ################################################################ --- 12,16 ---- LIBFFI_SOURCES='source/gcc/libffi' ! __version__ = "0.9.7beta" ################################################################ |
From: Thomas H. <th...@us...> - 2005-04-01 19:36:30
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv762 Added Files: test_overloading.py Log Message: More tests. --- NEW FILE: test_overloading.py --- from ctypes import * import unittest class Test(unittest.TestCase): def test_from_field(self): class TwoTuple(Structure): _fields_ = [("i", c_int), ("j", c_int)] def __from_field__(cls, ptr): assert isinstance(ptr, (int, long)) # Could we somehow use the CFieldObject descriptors # cls.i and cls.j to access the in-memory data block # without creating an instance of cls? v = cls.from_address(ptr) return v.i, v.j __from_field__ = classmethod(__from_field__) def __to_field__(cls, ptr, value): raise "Halt" assert isinstance(ptr, (int, long)) v = cls.from_address(ptr) v.i = value[0] v.j = value[1] __to_field__ = classmethod(__to_field__) class X(Structure): _fields_ = [("a", TwoTuple)] x = X() # This works anyway - bad example. __to_field__ is not called. x.a = (42, 24) ## EXPERIMENTAL ## self.failUnlessEqual(x.a, (42, 24)) def test_sideeffects(self): class POINT(Structure): _fields_ = [("x", c_int), ("y", c_int)] class RECT(Structure): _fields_ = [("ul", POINT), ("lr", POINT)] # Structures can be initialized by calling them with tuples. r = RECT((1, 2), (3, 4)) self.failUnlessEqual((r.ul.x, r.ul.y), (1, 2)) self.failUnlessEqual((r.lr.x, r.lr.y), (3, 4)) # What I didn't even know was that assigning tuples to fields does also work: r.ul = (11, 22) r.lr = (33, 44) self.failUnlessEqual((r.ul.x, r.ul.y), (11, 22)) self.failUnlessEqual((r.lr.x, r.lr.y), (33, 44)) # We can also initialize structures with keyword args. # Should assigning dicts to fields also work? It doesn't. POINT(x=1, y=2) ## r.ul = {"x":1, "y":2} if __name__ == "__main__": unittest.main() |
From: Thomas H. <th...@us...> - 2005-04-01 19:34:36
|
Update of /cvsroot/ctypes/ctypes/ctypes/wrap In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31662 Modified Files: codegenerator.py Log Message: Small fixes. Index: codegenerator.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/wrap/codegenerator.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** codegenerator.py 22 Mar 2005 12:08:09 -0000 1.7 --- codegenerator.py 1 Apr 2005 19:34:10 -0000 1.8 *************** *** 3,6 **** --- 3,9 ---- # $Log$ + # Revision 1.8 2005/04/01 19:34:10 theller + # Small fixes. + # # Revision 1.7 2005/03/22 12:08:09 theller # Some general cleanup, and make generate_code (which does all the *************** *** 292,300 **** self.generate(struct.get_head()) self.more.add(struct) - if head.struct.location: - print >> self.stream, "# %s %s" % head.struct.location basenames = [self.type_name(b) for b in head.struct.bases] if basenames: self.need_GUID() method_names = [m.name for m in head.struct.members if type(m) is typedesc.Method] print >> self.stream, "class %s(%s):" % (head.struct.name, ", ".join(basenames)) --- 295,303 ---- self.generate(struct.get_head()) self.more.add(struct) basenames = [self.type_name(b) for b in head.struct.bases] if basenames: self.need_GUID() + if head.struct.location: + print >> self.stream, "# %s %s" % head.struct.location method_names = [m.name for m in head.struct.members if type(m) is typedesc.Method] print >> self.stream, "class %s(%s):" % (head.struct.name, ", ".join(basenames)) |
From: Thomas H. <th...@us...> - 2005-04-01 19:31:49
|
Update of /cvsroot/ctypes/ctypes/comtypes/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29940 Modified Files: typedesc.py tlbparser.py Log Message: ComMethod gets dispid aka memid. Index: tlbparser.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/tools/tlbparser.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** tlbparser.py 22 Mar 2005 15:21:21 -0000 1.6 --- tlbparser.py 1 Apr 2005 19:31:22 -0000 1.7 *************** *** 234,238 **** flags = self.func_flags(fd.wFuncFlags) flags += self.inv_kind(fd.invkind) ! mth = typedesc.ComMethod(fd.invkind, func_name, returns, flags) mth.doc = func_doc for p in range(fd.cParams): --- 234,238 ---- flags = self.func_flags(fd.wFuncFlags) flags += self.inv_kind(fd.invkind) ! mth = typedesc.ComMethod(fd.memid, fd.invkind, func_name, returns, flags) mth.doc = func_doc for p in range(fd.cParams): *************** *** 544,547 **** --- 544,550 ---- ## path = r"C:\Dokumente und Einstellungen\thomas\Desktop\tlb\threadapi.tlb" + # Ha! hnetcfg.dll contains more than one typelib, they can be opened with + # hnetcfg.dll\2 and hnetcfg.dll\3 + known_symbols = {} for name in ("comtypes.automation", "comtypes", "ctypes"): Index: typedesc.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/tools/typedesc.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** typedesc.py 4 Feb 2005 21:19:41 -0000 1.1 --- typedesc.py 1 Apr 2005 19:31:22 -0000 1.2 *************** *** 3,9 **** from ctypes.wrap.typedesc import * ! class ComMethod(object): ! # custom COM method, parsed from typelib ! def __init__(self, invkind, name, returns, idlflags): self.invkind = invkind self.name = name --- 3,9 ---- from ctypes.wrap.typedesc import * ! class _Method(object): ! def __init__(self, dispid, invkind, name, returns, idlflags): ! self.dispid = dispid self.invkind = invkind self.name = name *************** *** 15,30 **** self.arguments.append((typ, name, idlflags, default)) class DispMethod(object): # dispatchable COM method, parsed from typelib ! def __init__(self, dispid, invkind, name, returns, idlflags): ! self.dispid = dispid ! self.invkind = invkind ! self.name = name ! self.returns = returns ! self.idlflags = idlflags ! self.arguments = [] ! def add_argument(self, typ, name, idlflags, default): ! self.arguments.append((typ, name, idlflags, default)) class DispProperty(object): --- 15,36 ---- self.arguments.append((typ, name, idlflags, default)) + + class ComMethod(_Method): + # custom COM method, parsed from typelib + pass + class DispMethod(object): # dispatchable COM method, parsed from typelib ! pass ! ## def __init__(self, dispid, invkind, name, returns, idlflags): ! ## self.dispid = dispid ! ## self.invkind = invkind ! ## self.name = name ! ## self.returns = returns ! ## self.idlflags = idlflags ! ## self.arguments = [] ! ## def add_argument(self, typ, name, idlflags, default): ! ## self.arguments.append((typ, name, idlflags, default)) class DispProperty(object): |
From: Thomas H. <th...@us...> - 2005-04-01 19:30:21
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28926 Modified Files: ChangeLog Log Message: Record changes. Index: ChangeLog =================================================================== RCS file: /cvsroot/ctypes/ctypes/ChangeLog,v retrieving revision 1.86 retrieving revision 1.87 diff -C2 -d -r1.86 -r1.87 *** ChangeLog 18 Mar 2005 18:09:41 -0000 1.86 --- ChangeLog 1 Apr 2005 19:29:43 -0000 1.87 *************** *** 1,2 **** --- 1,39 ---- + 2005-04-01 Thomas Heller <th...@py...> + + * Changed version number to 0.9.7beta + + * Changed the way CData_FromBaseObj() works. Instead of calling + the type with a _basespec_ keyword argument, the instance is + created in the normal way, and the base object and buffer attached + afterwards. Again, this gave a large speedup - see + unittests/com/test_perf.py. + + * Added a small buffer (16 bytes) to the CDataObject structure. + This allows to skip the call to PyMem_Malloc() in the + GenericCData_new constructor for small C types. Together with a + small optimization in Simple_init() it speeds up instance creation + a lot: c_int() now takes 0.5 us instead of 1.2 us. + + 2005-03-31 Thomas Heller <th...@py...> + + * Lots and lots of refactoring. All types now have a setfunc and + getfunc in their stgdict. This allowed to remove a lot of + typechecks spread all around the code. + + CFieldObjects no longer have the getfunc and setfunc fields, they + are now using the functions from their fieldtype's stgdict. + + Hopefully no change in behaviour - at least the testsuite runs as + before. + + 2005-03-24 Thomas Heller <th...@py...> + + * source\cfield.c: Refactored the code to always use the + CFieldObject's getfunc to get field contents. This makes it easy + to enhance the code so that this function can be overridden from + Python. + + These enhancements are currently marked #ifdef EXPERIMENTAL. + 2005-03-18 Thomas Heller <th...@py...> |
From: Thomas H. <th...@us...> - 2005-04-01 19:29:31
|
Update of /cvsroot/ctypes/ctypes/comtypes/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28578 Modified Files: codegenerator.py Log Message: Emit the dispid for COMMETHOD. Index: codegenerator.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/tools/codegenerator.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** codegenerator.py 16 Mar 2005 14:22:41 -0000 1.6 --- codegenerator.py 1 Apr 2005 19:29:16 -0000 1.7 *************** *** 103,107 **** # typ, name, idlflags, default code = " COMMETHOD(%r, %s, '%s'" % ( ! m.idlflags, self.type_name(m.returns), m.name) --- 103,107 ---- # typ, name, idlflags, default code = " COMMETHOD(%r, %s, '%s'" % ( ! [m.dispid] + m.idlflags, self.type_name(m.returns), m.name) *************** *** 162,168 **** self.type_name(prop.typ), prop.name) - - # shortcut for development - if __name__ == "__main__": - import tlbparser - tlbparser.main() --- 162,163 ---- |
From: Thomas H. <th...@us...> - 2005-04-01 18:35:57
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28923 Modified Files: _ctypes.c Log Message: Add todo comment. Remove unused code. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.272 retrieving revision 1.273 diff -C2 -d -r1.272 -r1.273 *** _ctypes.c 1 Apr 2005 17:54:29 -0000 1.272 --- _ctypes.c 1 Apr 2005 18:35:47 -0000 1.273 *************** *** 1212,1215 **** --- 1212,1222 ---- c_char_p_from_param(PyObject *type, PyObject *value) { + /* This should use setfunc in the same way as SimpleType_from_param does it. + setfunc (which is z_set) handles None, String, and Unicode, + but not Array, Pointer, c_char_p, and CArgObject. + Instead (!) it accepts integers as well, which seems wrong. + + And fixing this would be a severe api change. + */ if (value == Py_None) { Py_INCREF(Py_None); *************** *** 2046,2080 **** assert(dict->setfunc); return dict->setfunc(ptr, value, size, type); - /* Seems this code is unused */ - #if 0 - /* - If value is a tuple, we try to call the type with the tuple - and use the result! - */ - assert(PyType_Check(type)); - if (PyTuple_Check(value)) { - PyObject *ob; - PyObject *result; - ob = PyObject_CallObject(type, value); - if (ob == NULL) { - Extend_Error_Info(PyExc_RuntimeError, "(%s) ", - ((PyTypeObject *)type)->tp_name); - return NULL; - } - result = _CData_set(ptr, ob, size, type); - Py_DECREF(ob); - return result; - } else if (value == Py_None && PointerTypeObject_Check(type)) { - *(void **)ptr = NULL; - Py_INCREF(Py_None); - return Py_None; - } else { - PyErr_Format(PyExc_TypeError, - "expected %s instance, got %s", - ((PyTypeObject *)type)->tp_name, - value->ob_type->tp_name); - return NULL; - } - #endif } src = (CDataObject *)value; --- 2053,2056 ---- *************** *** 2090,2118 **** return value; } - - /* Seems this code is unused */ - #if 0 - if (PointerTypeObject_Check(type) - && ArrayObject_Check(value)) { - StgDictObject *p1, *p2; - p1 = PyObject_stgdict(value); - p2 = PyType_stgdict(type); - - /* Should probably use issubclass instead of == ... */ - if (p1->proto != p2->proto) { - PyErr_Format(PyExc_TypeError, - "incompatible types, %s instance instead of %s instance", - value->ob_type->tp_name, - ((PyTypeObject *)type)->tp_name); - return NULL; - } - *(void **)ptr = src->b_ptr; - /* We are assigning an array object to a field representing a - pointer. We need to keep the array object alive, not only - its b_objects. - */ - return (PyObject *)src; - } - #endif PyErr_Format(PyExc_TypeError, "incompatible types, %s instance instead of %s instance", --- 2066,2069 ---- |
From: Thomas H. <th...@us...> - 2005-04-01 18:20:01
|
Update of /cvsroot/ctypes/ctypes/unittests/com In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20727 Modified Files: test_perf.py Log Message: Make it run on linux too. Index: test_perf.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/com/test_perf.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_perf.py 1 Apr 2005 17:46:24 -0000 1.5 --- test_perf.py 1 Apr 2005 18:19:41 -0000 1.6 *************** *** 64,94 **** timeit("-s", "from test_perf import RECT; rect = RECT()", "rect.lr") ! timeit("-s", "from test_perf import get_fd; fd = get_fd()", ! "fd.lprgelemdescParam") ! timeit("-s", "from test_perf import get_fd; fd = get_fd()", ! "fd.lprgelemdescParam[0]") ! timeit("-s", "from test_perf import get_fd; fd = get_fd()", ! "fd.lprgelemdescParam[1]") ! timeit("-s", "from test_perf import get_fd; fd = get_fd()", ! "fd.lprgelemdescParam[1].tdesc") ! timeit("-s", "from test_perf import get_fd; fd = get_fd()", ! "fd.lprgelemdescParam[1].tdesc.vt") ! timeit("-s", "from test_perf import get_fd; fd = get_fd()", ! "fd.lprgelemdescParam[1].tdesc._.lptdesc[0].vt") timeit('-s', "from ctypes import c_int", "c_int()") timeit('-s', "from ctypes import c_int", "c_int(42)") ! timeit('-s', "from ctypes.com.automation import VARIANT", ! "VARIANT() # ctypes.com") ! timeit('-s', "from ctypes.com.automation import VARIANT; variant = VARIANT(3)", ! "variant.value # ctypes.com") ! timeit('-s', "from ctypes.com.automation import VARIANT; variant = VARIANT()", ! "variant.value = 3.14 # ctypes.com") ! try: ! import comtypes ! except ImportError: ! pass ! else: timeit('-s', "from comtypes.automation import VARIANT", --- 64,91 ---- timeit("-s", "from test_perf import RECT; rect = RECT()", "rect.lr") ! if sys.platform == "win32": ! timeit("-s", "from test_perf import get_fd; fd = get_fd()", ! "fd.lprgelemdescParam") ! timeit("-s", "from test_perf import get_fd; fd = get_fd()", ! "fd.lprgelemdescParam[0]") ! timeit("-s", "from test_perf import get_fd; fd = get_fd()", ! "fd.lprgelemdescParam[1]") ! timeit("-s", "from test_perf import get_fd; fd = get_fd()", ! "fd.lprgelemdescParam[1].tdesc") ! timeit("-s", "from test_perf import get_fd; fd = get_fd()", ! "fd.lprgelemdescParam[1].tdesc.vt") ! timeit("-s", "from test_perf import get_fd; fd = get_fd()", ! "fd.lprgelemdescParam[1].tdesc._.lptdesc[0].vt") timeit('-s', "from ctypes import c_int", "c_int()") timeit('-s', "from ctypes import c_int", "c_int(42)") ! if sys.platform == "win32": ! timeit('-s', "from ctypes.com.automation import VARIANT", ! "VARIANT() # ctypes.com") ! timeit('-s', "from ctypes.com.automation import VARIANT; variant = VARIANT(3)", ! "variant.value # ctypes.com") ! timeit('-s', "from ctypes.com.automation import VARIANT; variant = VARIANT()", ! "variant.value = 3.14 # ctypes.com") timeit('-s', "from comtypes.automation import VARIANT", |
From: Thomas H. <th...@us...> - 2005-04-01 17:54:49
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7039 Modified Files: _ctypes.c Log Message: Clearer code, less code, much greater performance. The short-term todo list is done. Lots of performance gained by reworking CData_FromBaseObj. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.271 retrieving revision 1.272 diff -C2 -d -r1.271 -r1.272 *** _ctypes.c 1 Apr 2005 15:10:36 -0000 1.271 --- _ctypes.c 1 Apr 2005 17:54:29 -0000 1.272 *************** *** 1,11 **** /* - Short-term todo list: - - - For faster instance creation with b_base, the _basespec_ trick should be - avoided. - */ - - - /* ToDo: --- 1,3 ---- *************** *** 1958,2001 **** }; ! /* ! * Trick #17: Pass a PyCObject named _basespec_ to the tp_new constructor, ! * then let tp_new remove it from the keyword dict, so that tp_init doesn't ! * get confused by it. ! * ! */ ! ! /* ! * If base is NULL, index is ignored, and baseofs is cast to a pointer ! * and used as the buffer of the new instance. ! * ! * If base is not NULL, it must be a CDataObject. ! * The new instance is a kind of 'slice' of the base object. ! * It shares base's pointer at offset baseofs, and uses index ! * in the base's object list to keep its references. ! * ! * In the latter case, the new instance shares the buffer of base. ! * ! * Box a memory block into a CData instance: ! * CData_AtAddress(PyObject *type, void *buf); ! * ! * Create a CData instance as 'slice' of a base object: ! * CData_FromBaseObj(PyObject *type, PyObject *base, int index, int baseofs); ! * ! */ - /* - XXX: The trick above is slow... Much faster is it, as it seems, to create - the new instance as if it were standalone, and then patch it afterwards - - even if this means we must PyMem_Free the just allocated memory. - - Fix later. - */ PyObject * CData_FromBaseObj(PyObject *type, PyObject *base, int index, char *adr) { ! struct basespec spec; ! PyObject *cobj; ! PyObject *mem; ! PyObject *args, *kw; if (base && !CDataObject_Check(base)) { --- 1950,1975 ---- }; ! /* Allocate memory (or not) for a CDataObject instance */ ! static void CData_MallocBuffer(CDataObject *obj, StgDictObject *dict) ! { ! if (dict->size <= sizeof(obj->b_value)) { ! /* No need to call malloc, can use the default buffer */ ! obj->b_ptr = (char *)&obj->b_value; ! obj->b_needsfree = 0; ! } else { ! /* In python 2.4, and ctypes 0.9.6, the malloc call took about ! 33% of the creation time for c_int(). ! */ ! obj->b_ptr = PyMem_Malloc(dict->size); ! obj->b_needsfree = 1; ! memset(obj->b_ptr, 0, dict->size); ! } ! obj->b_size = dict->size; ! } PyObject * CData_FromBaseObj(PyObject *type, PyObject *base, int index, char *adr) { ! CDataObject *cmem; if (base && !CDataObject_Check(base)) { *************** *** 2005,2028 **** } ! spec.base = (CDataObject *)base; ! spec.adr = adr; ! spec.index = index; ! cobj = PyCObject_FromVoidPtrAndDesc(&spec, basespec_string, NULL); ! kw = Py_BuildValue("{s:O}", "_basespec_", cobj); ! args = PyTuple_New(0); ! mem = PyObject_Call(type, args, kw); ! Py_DECREF(kw); ! Py_DECREF(args); ! /* the pointer in it points to memory local to this func. */ ! assert(cobj->ob_refcnt == 1); ! Py_DECREF(cobj); ! return mem; } ! /* We cannot call CData_FromBaseObj, because we have no base object. So, we ! create an empty instance, free the memory it contains, and fill in the ! memory pointer afterwards. */ static PyObject * --- 1979,2010 ---- } ! cmem = (CDataObject *)PyObject_CallFunctionObjArgs(type, NULL); ! if (cmem == NULL) ! return NULL; ! if (cmem->b_needsfree) ! PyMem_Free(cmem->b_ptr); ! cmem->b_ptr = NULL; ! if (base) { /* use base's buffer */ ! cmem->b_ptr = adr; ! cmem->b_needsfree = 0; ! Py_INCREF(base); ! cmem->b_base = (CDataObject *)base; ! cmem->b_index = index; ! } else { /* copy contents of adr */ ! StgDictObject *dict = PyType_stgdict(type); ! CData_MallocBuffer(cmem, PyType_stgdict(type)); ! memcpy(cmem->b_ptr, adr, dict->size); ! cmem->b_index = index; ! } ! return (PyObject *)cmem; } ! /* ! Box a memory block into a CData instance. ! ! We create an new instance, free the memory it contains, and fill in the ! memory pointer afterwards. */ static PyObject * *************** *** 2142,2167 **** /******************************************************************/ - static void CData_MallocBuffer(CDataObject *obj, StgDictObject *dict) - { - if (dict->size <= sizeof(obj->b_value)) { - /* No need to call malloc, can use the default buffer */ - obj->b_ptr = (char *)&obj->b_value; - obj->b_needsfree = 0; - } else { - /* In python 2.4, and ctypes 0.9.6, the malloc call took about - 33% of the creation time for c_int(). - */ - obj->b_ptr = PyMem_Malloc(dict->size); - obj->b_needsfree = 1; - memset(obj->b_ptr, 0, dict->size); - } - obj->b_size = dict->size; - } - static PyObject * GenericCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { CDataObject *obj; - PyObject *basespec = NULL; int size, align, length; StgDictObject *dict; --- 2124,2131 ---- *************** *** 2178,2246 **** length = dict->length; - if (kwds) - basespec = PyDict_GetItemString(kwds, "_basespec_"); - obj = (CDataObject *)type->tp_alloc(type, 0); if (!obj) return NULL; - /* Three different cases: - * - no basespec object in kwds: Allocate new memory - * - basespec->base is set: - * This is the base object owning the buffer, - * index and offset must be set - * - basespec->base is NULL: - * index is ignored, offset contains the buffer address to use. - */ - - if (basespec) { - struct basespec *spec; - void *descr; - - descr = PyCObject_GetDesc(basespec); - if (!descr) { - Py_DECREF(obj); - return NULL; - } - if (descr != basespec_string) { - PyErr_SetString(PyExc_TypeError, "invalid object"); - Py_DECREF(obj); - return NULL; - } - spec = PyCObject_AsVoidPtr(basespec); - - if (spec->base) { - Py_INCREF(spec->base); - obj->b_base = spec->base; - obj->b_index = spec->index; ! obj->b_objects = NULL; ! obj->b_length = length; ! ! obj->b_ptr = spec->adr; ! 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; ! ! CData_MallocBuffer(obj, dict); ! memcpy(obj->b_ptr, spec->adr, size); ! } ! /* don't pass this to tp_init! */ ! if (-1 == PyDict_DelItemString(kwds, "_basespec_")) { ! Py_DECREF(obj); ! return NULL; ! } ! ! } else { ! obj->b_base = NULL; ! obj->b_index = 0; ! obj->b_objects = NULL; ! obj->b_length = length; ! CData_MallocBuffer(obj, dict); ! } return (PyObject *)obj; } --- 2142,2155 ---- length = dict->length; obj = (CDataObject *)type->tp_alloc(type, 0); if (!obj) return NULL; ! obj->b_base = NULL; ! obj->b_index = 0; ! obj->b_objects = NULL; ! obj->b_length = length; ! CData_MallocBuffer(obj, dict); return (PyObject *)obj; } *************** *** 2555,2561 **** THUNK thunk; ! if (kwds && PyDict_GetItemString(kwds, "_basespec_")) { return GenericCData_new(type, args, kwds); - } if (2 <= PyTuple_GET_SIZE(args)) { --- 2464,2470 ---- THUNK thunk; ! /* We're retrieved from a structure field or C result, maybe */ ! if (PyTuple_GET_SIZE(args) == 0) return GenericCData_new(type, args, kwds); if (2 <= PyTuple_GET_SIZE(args)) { |
From: Thomas H. <th...@us...> - 2005-04-01 17:46:41
|
Update of /cvsroot/ctypes/ctypes/unittests/com In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2090 Modified Files: test_perf.py Log Message: Change get_fd() to return a FUNCDESC from a typelib, not from a live IE com object. Record lots of performance improvements. Ja! Index: test_perf.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/com/test_perf.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_perf.py 9 Mar 2005 20:29:09 -0000 1.4 --- test_perf.py 1 Apr 2005 17:46:24 -0000 1.5 *************** *** 29,38 **** pass def get_fd(): # get a FUNCDESC instance ! from ctypes.com.client import Dispatch ! d = Dispatch("InternetExplorer.Application") ! return d.Navigate.fd ################################################################ --- 29,50 ---- pass + class ClassWithInit(object): + def __init__(self): + pass def get_fd(): # get a FUNCDESC instance ! ## from ctypes.com.client import Dispatch ! ## d = Dispatch("InternetExplorer.Application") ! ## return d.Navigate.fd ! # no longer from a 'live' IE object, from the typelib instead ! from comtypes.typeinfo import LoadTypeLibEx ! from comtypes import GUID ! tlib = LoadTypeLibEx("shdocvw.dll") ! # IWebBrowser interface ! tinfo = tlib.GetTypeInfoOfGuid(GUID("{EAB22AC1-30C1-11CF-A7EB-0000C05BAE0B}")) ! tcomp = tinfo.GetTypeComp() ! kind, fd = tcomp.Bind("Navigate") ! return fd ################################################################ *************** *** 63,67 **** "fd.lprgelemdescParam[1].tdesc.vt") timeit("-s", "from test_perf import get_fd; fd = get_fd()", ! "fd.lprgelemdescParam[1].tdesc.u.lptdesc[0].vt") timeit('-s', "from ctypes import c_int", "c_int()") --- 75,79 ---- "fd.lprgelemdescParam[1].tdesc.vt") timeit("-s", "from test_perf import get_fd; fd = get_fd()", ! "fd.lprgelemdescParam[1].tdesc._.lptdesc[0].vt") timeit('-s', "from ctypes import c_int", "c_int()") *************** *** 130,131 **** --- 142,212 ---- ## 4.99: variant.value # comtypes ## 11.40: variant.value = 3.14 # comtypes + + ##ctypes version: 0.9.6 + ##python version: 2.4.1 (#65, Mar 30 2005, 09:13:57) [MSC v.1310 32 bit (Intel)] + ## 0.39: Class() + ## 0.99: POINT() + ## 1.02: RECT() + ## 0.25: point.y + ## 2.02: rect.lr + ## 6.76: fd.lprgelemdescParam + ## 9.43: fd.lprgelemdescParam[0] + ## 9.35: fd.lprgelemdescParam[1] + ## 11.60: fd.lprgelemdescParam[1].tdesc + ## 12.20: fd.lprgelemdescParam[1].tdesc.vt + ## 21.40: fd.lprgelemdescParam[1].tdesc.u.lptdesc[0].vt + ## 1.19: c_int() + ## 1.41: c_int(42) + ## 2.24: VARIANT() # ctypes.com + ## 5.05: variant.value # ctypes.com + ## 11.90: variant.value = 3.14 # ctypes.com + ## 1.98: VARIANT() # comtypes + ## 4.90: variant.value # comtypes + ## 11.20: variant.value = 3.14 # comtypes + + # Hm, variant.value did get slower! + + ##ctypes version: CVS 2005/04/01 + ##python version: 2.4.1 (#65, Mar 30 2005, 09:13:57) [MSC v.1310 32 bit (Intel)] + ## 0.43: Class() + ## 0.50: POINT() + ## 0.52: RECT() + ## 0.28: point.y + ## 2.04: rect.lr + ## 2.22: fd.lprgelemdescParam + ## 4.21: fd.lprgelemdescParam[0] + ## 4.18: fd.lprgelemdescParam[1] + ## 6.21: fd.lprgelemdescParam[1].tdesc + ## 6.43: fd.lprgelemdescParam[1].tdesc.vt + ## 12.60: fd.lprgelemdescParam[1].tdesc._.lptdesc[0].vt + ## 0.52: c_int() + ## 0.74: c_int(42) + ## 1.72: VARIANT() # ctypes.com + ## 7.81: variant.value # ctypes.com + ## 10.60: variant.value = 3.14 # ctypes.com + ## 1.51: VARIANT() # comtypes + ## 7.86: variant.value # comtypes + ## 11.70: variant.value = 3.14 # comtypes + + ##ctypes version: CVS 2005/04/01 (evening) + ##python version: 2.4.1 (#65, Mar 30 2005, 09:13:57) [MSC v.1310 32 bit (Intel)] + ## 0.40: Class() + ## 0.51: POINT() + ## 0.53: RECT() + ## 0.27: point.y + ## 0.63: rect.lr + ## 0.81: fd.lprgelemdescParam + ## 1.34: fd.lprgelemdescParam[0] + ## 1.46: fd.lprgelemdescParam[1] + ## 2.18: fd.lprgelemdescParam[1].tdesc + ## 2.45: fd.lprgelemdescParam[1].tdesc.vt + ## 4.69: fd.lprgelemdescParam[1].tdesc._.lptdesc[0].vt + ## 0.48: c_int() + ## 0.70: c_int(42) + ## 1.78: VARIANT() # ctypes.c + ## 3.36: variant.value # ctypes.c + ## 8.06: variant.value = 3.14 # ctypes.c + ## 1.55: VARIANT() # comtypes + ## 3.31: variant.value # comtypes + ## 9.30: variant.value = 3.14 # comtypes + |
From: Thomas H. <th...@us...> - 2005-04-01 15:26:58
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20270 Modified Files: stgdict.c Log Message: Minor changes. Index: stgdict.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/stgdict.c,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** stgdict.c 14 Mar 2005 08:03:47 -0000 1.32 --- stgdict.c 1 Apr 2005 15:26:22 -0000 1.33 *************** *** 16,22 **** StgDict_init(StgDictObject *self, PyObject *args, PyObject *kwds) { ! if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0) ! return -1; ! return 0; } --- 16,20 ---- StgDict_init(StgDictObject *self, PyObject *args, PyObject *kwds) { ! return PyDict_Type.tp_init((PyObject *)self, args, kwds); } *************** *** 284,287 **** --- 282,286 ---- case FFI_TYPE_SINT16: case FFI_TYPE_SINT32: + /* These can be ints, char, or wchar_t */ if (dict->getfunc != getentry("c")->getfunc #ifdef CTYPES_UNICODE |