ctypes-commit Mailing List for ctypes (Page 32)
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...> - 2006-01-04 19:21:50
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11074 Modified Files: Tag: branch_1_0 ChangeLog Log Message: Index: ChangeLog =================================================================== RCS file: /cvsroot/ctypes/ctypes/ChangeLog,v retrieving revision 1.86.2.33 retrieving revision 1.86.2.34 diff -C2 -d -r1.86.2.33 -r1.86.2.34 *** ChangeLog 2 Jan 2006 18:58:39 -0000 1.86.2.33 --- ChangeLog 4 Jan 2006 19:21:37 -0000 1.86.2.34 *************** *** 1,4 **** --- 1,8 ---- 2006-01-02 Thomas Heller <th...@py...> + * Subtypes of simple types (the c_int and c_char variations, + c_void_p, c_char_p and c_wchar_p) behave different now. XXX More + explanations needed. + * Removed the complete ctypes.com package, which lived (in CVS) in the ctypes\win32\com directory. |
From: Thomas H. <th...@us...> - 2006-01-04 19:18:35
|
Update of /cvsroot/ctypes/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10003 Modified Files: Tag: branch_1_0 __init__.py Log Message: Preliminary changes for Windows CE. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/__init__.py,v retrieving revision 1.61.2.21 retrieving revision 1.61.2.22 diff -C2 -d -r1.61.2.21 -r1.61.2.22 *** __init__.py 2 Jan 2006 19:11:55 -0000 1.61.2.21 --- __init__.py 4 Jan 2006 19:18:26 -0000 1.61.2.22 *************** *** 101,104 **** --- 101,106 ---- from _ctypes import FUNCFLAG_HRESULT as _FUNCFLAG_HRESULT, \ FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL + if _os.name == "ce": + _FUNCFLAG_STDCALL = _FUNCFLAG_CDECL _win_functype_cache = {} *************** *** 275,279 **** class CDLL(object): ! class _CdeclFuncPtr(_CFuncPtr): _flags_ = _FUNCFLAG_CDECL _restype_ = c_int # default, can be overridden in instances --- 277,281 ---- class CDLL(object): ! class _FuncPtr(_CFuncPtr): _flags_ = _FUNCFLAG_CDECL _restype_ = c_int # default, can be overridden in instances *************** *** 294,300 **** def __getattr__(self, name): ! if name[:2] == '__' and name[-2:] == '__': raise AttributeError, name ! func = self._CdeclFuncPtr(name, self) func.__name__ = name setattr(self, name, func) --- 296,302 ---- def __getattr__(self, name): ! if name.startswith('__') and name.endswith('__'): raise AttributeError, name ! func = self._FuncPtr(name, self) func.__name__ = name setattr(self, name, func) *************** *** 320,338 **** _restype_ = c_int # default, can be overridden in instances ! if _os.name == "nt": class WinDLL(CDLL): ! class _StdcallFuncPtr(_CFuncPtr): _flags_ = _FUNCFLAG_STDCALL _restype_ = c_int # default, can be overridden in instances - def __getattr__(self, name): - if name[:2] == '__' and name[-2:] == '__': - raise AttributeError, name - func = self._StdcallFuncPtr(name, self) - func.__name__ = name - setattr(self, name, func) - return func - # XXX Hm, what about HRESULT as normal parameter? # Mustn't it derive from c_long then? --- 322,332 ---- _restype_ = c_int # default, can be overridden in instances ! if _os.name in ("nt", "ce"): class WinDLL(CDLL): ! class _FuncPtr(_CFuncPtr): _flags_ = _FUNCFLAG_STDCALL _restype_ = c_int # default, can be overridden in instances # XXX Hm, what about HRESULT as normal parameter? # Mustn't it derive from c_long then? *************** *** 474,482 **** ! if _os.name == "nt": windll = _DLLS(WinDLL) oledll = _DLLS(OleDLL) ! GetLastError = windll.kernel32.GetLastError def WinError(code=None, descr=None): --- 468,479 ---- ! if _os.name in ("nt", "ce"): windll = _DLLS(WinDLL) oledll = _DLLS(OleDLL) ! if _os.name == "nt": ! GetLastError = windll.kernel32.GetLastError ! else: ! GetLastError = windll.coredll.GetLastError def WinError(code=None, descr=None): |
From: Thomas H. <th...@us...> - 2006-01-04 19:18:26
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9952 Modified Files: Tag: branch_1_0 _comobject.py __init__.py Log Message: Preliminary changes for Windows CE. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.25.2.37 retrieving revision 1.25.2.38 diff -C2 -d -r1.25.2.37 -r1.25.2.38 *** __init__.py 2 Jan 2006 19:11:25 -0000 1.25.2.37 --- __init__.py 4 Jan 2006 19:18:18 -0000 1.25.2.38 *************** *** 1,7 **** # requires ctypes 0.9.8 or later ! import new ! ##import warnings ! import types ! import sys from ctypes import * --- 1,4 ---- # requires ctypes 0.9.8 or later ! import new, types, sys, os from ctypes import * *************** *** 82,86 **** return if flags is None: ! flags = getattr(sys, "coinit_flags", COINIT_APARTMENTTHREADED) __inited = True logger.debug("CoInitializeEx(None, %s)", flags) --- 79,86 ---- return if flags is None: ! if os.name == "ce": ! flags = getattr(sys, "coinit_flags", COINIT_MULTITHREADED) ! else: ! flags = getattr(sys, "coinit_flags", COINIT_APARTMENTTHREADED) __inited = True logger.debug("CoInitializeEx(None, %s)", flags) Index: _comobject.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/Attic/_comobject.py,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** _comobject.py 2 Jan 2006 19:11:25 -0000 1.1.2.3 --- _comobject.py 4 Jan 2006 19:18:18 -0000 1.1.2.4 *************** *** 2,5 **** --- 2,6 ---- from comtypes.hresult import * + import os import logging logger = logging.getLogger(__name__) *************** *** 78,85 **** ################################################################ ! ! ! _InterlockedIncrement = windll.kernel32.InterlockedIncrement ! _InterlockedDecrement = windll.kernel32.InterlockedDecrement class COMObject(object): --- 79,88 ---- ################################################################ ! if os.name == "ce": ! _InterlockedIncrement = windll.coredll.InterlockedIncrement ! _InterlockedDecrement = windll.coredll.InterlockedDecrement ! else: ! _InterlockedIncrement = windll.kernel32.InterlockedIncrement ! _InterlockedDecrement = windll.kernel32.InterlockedDecrement class COMObject(object): |
From: Thomas H. <th...@us...> - 2006-01-04 18:28:34
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21668 Modified Files: Tag: branch_1_0 _ctypes.c Log Message: Remove unused static function. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.226.2.42 retrieving revision 1.226.2.43 diff -C2 -d -r1.226.2.42 -r1.226.2.43 *** _ctypes.c 4 Jan 2006 18:15:36 -0000 1.226.2.42 --- _ctypes.c 4 Jan 2006 18:28:26 -0000 1.226.2.43 *************** *** 2911,2931 **** */ /* - XXX BUG: [in, out] parameters MUST be returned as-is. - */ - static PyObject * - _get_one(PyObject *obj) - { - if (PyCArg_CheckExact(obj)) { - PyCArgObject *arg = (PyCArgObject *)obj; - obj = arg->obj; - } - /* - __ctypes_from_outparam__ lets of specify how 'out' parameters are retrieved - from COM method class. - */ - return PyObject_CallMethod(obj, "__ctypes_from_outparam__", NULL); - } - - /* Build return value of a function. --- 2911,2914 ---- |
From: Thomas H. <th...@us...> - 2006-01-04 18:15:47
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16808 Modified Files: Tag: branch_1_0 _ctypes.c Log Message: Fix a compiler warning about 'tup' may be uninitialized in _build_result(). Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.226.2.41 retrieving revision 1.226.2.42 diff -C2 -d -r1.226.2.41 -r1.226.2.42 *** _ctypes.c 2 Jan 2006 19:02:52 -0000 1.226.2.41 --- _ctypes.c 4 Jan 2006 18:15:36 -0000 1.226.2.42 *************** *** 2937,2941 **** { int i, index, bit; ! PyObject *tup; if (callargs == NULL) --- 2937,2941 ---- { int i, index, bit; ! PyObject *tup = NULL; if (callargs == NULL) |
From: Thomas H. <th...@us...> - 2006-01-03 19:51:39
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12968 Modified Files: Tag: branch_1_0 callproc.c Log Message: Fix a small bug. Index: callproc.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callproc.c,v retrieving revision 1.127.2.17 retrieving revision 1.127.2.18 diff -C2 -d -r1.127.2.17 -r1.127.2.18 *** callproc.c 2 Jan 2006 19:02:52 -0000 1.127.2.17 --- callproc.c 3 Jan 2006 19:51:31 -0000 1.127.2.18 *************** *** 80,84 **** static TCHAR *FormatError(DWORD code) { ! char *lpMsgBuf; DWORD n; n = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, --- 80,84 ---- static TCHAR *FormatError(DWORD code) { ! TCHAR *lpMsgBuf; DWORD n; n = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, *************** *** 94,98 **** lpMsgBuf[n] = '\0'; /* rstrip() */ } ! return (TCHAR *)lpMsgBuf; } --- 94,98 ---- lpMsgBuf[n] = '\0'; /* rstrip() */ } ! return lpMsgBuf; } |
From: Thomas H. <th...@us...> - 2006-01-02 19:14:57
|
Update of /cvsroot/ctypes/ctypes/comtypes/server In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6037 Added Files: Tag: branch_1_0 .cvsignore Log Message: --- NEW FILE: .cvsignore --- *.pyc *.pyo |
From: Thomas H. <th...@us...> - 2006-01-02 19:12:11
|
Update of /cvsroot/ctypes/ctypes/ctypes/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5101 Modified Files: Tag: branch_1_0 test_simplesubclasses.py test_paramflags.py test_libc.py test_leaks.py test_functions.py test_checkretval.py __init__.py Log Message: Sync with upstream version. Index: test_functions.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/test/Attic/test_functions.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_functions.py 2 Jan 2006 15:09:01 -0000 1.1.2.2 --- test_functions.py 2 Jan 2006 19:12:01 -0000 1.1.2.3 *************** *** 5,10 **** Later... """ ! import sys, unittest from ctypes import * try: --- 5,11 ---- Later... """ ! from ctypes import * + import sys, unittest try: Index: test_simplesubclasses.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/test/Attic/test_simplesubclasses.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_simplesubclasses.py 3 Nov 2005 19:49:19 -0000 1.1.2.1 --- test_simplesubclasses.py 2 Jan 2006 19:12:01 -0000 1.1.2.2 *************** *** 2,8 **** from ctypes import * - from ctypes.test import requires, is_resource_enabled - requires("devel") - class MyInt(c_int): def __cmp__(self, other): --- 2,5 ---- Index: test_checkretval.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/test/Attic/test_checkretval.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_checkretval.py 3 Nov 2005 19:49:19 -0000 1.1.2.1 --- test_checkretval.py 2 Jan 2006 19:12:01 -0000 1.1.2.2 *************** *** 10,14 **** class CHECKED(c_int): def _check_retval_(value): ! return str(value) _check_retval_ = staticmethod(_check_retval_) --- 10,15 ---- class CHECKED(c_int): def _check_retval_(value): ! # Receives a CHECKED instance. ! return str(value.value) _check_retval_ = staticmethod(_check_retval_) Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/test/Attic/__init__.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 *** __init__.py 4 Nov 2005 07:36:35 -0000 1.1.2.2 --- __init__.py 2 Jan 2006 19:12:01 -0000 1.1.2.3 *************** *** 16,22 **** if sys._getframe().f_back.f_globals.get("__name__") == "__main__": return True ! return use_resources is not None and \ (resource in use_resources or "*" in use_resources) def requires(resource, msg=None): """Raise ResourceDenied if the specified resource is not available. --- 16,26 ---- if sys._getframe().f_back.f_globals.get("__name__") == "__main__": return True ! result = use_resources is not None and \ (resource in use_resources or "*" in use_resources) + if not result: + _unavail[resource] = None + return result + _unavail = {} def requires(resource, msg=None): """Raise ResourceDenied if the specified resource is not available. *************** *** 108,116 **** self.stream.writeln(result.separator2) run = result.testsRun ! if skipped: self.stream.writeln("Ran %d test%s in %.3fs (%s module%s skipped)" % (run, run != 1 and "s" or "", timeTaken, len(skipped), ! len(skipped) > 1 and "s" or "")) else: self.stream.writeln("Ran %d test%s in %.3fs" % --- 112,123 ---- self.stream.writeln(result.separator2) run = result.testsRun ! if _unavail: #skipped: ! requested = _unavail.keys() ! requested.sort() self.stream.writeln("Ran %d test%s in %.3fs (%s module%s skipped)" % (run, run != 1 and "s" or "", timeTaken, len(skipped), ! len(skipped) != 1 and "s" or "")) ! self.stream.writeln("Unavailable resources: %s" % ", ".join(requested)) else: self.stream.writeln("Ran %d test%s in %.3fs" % *************** *** 131,135 **** ! def main(package): try: opts, args = getopt.getopt(sys.argv[1:], "rqvu:") --- 138,142 ---- ! def main(*packages): try: opts, args = getopt.getopt(sys.argv[1:], "rqvu:") *************** *** 158,162 **** mask = args[0] ! run_tests(package, mask, verbosity, search_leaks) --- 165,170 ---- mask = args[0] ! for package in packages: ! run_tests(package, mask, verbosity, search_leaks) Index: test_libc.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/test/Attic/test_libc.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_libc.py 22 Dec 2005 20:34:57 -0000 1.1.2.2 --- test_libc.py 2 Jan 2006 19:12:01 -0000 1.1.2.3 *************** *** 15,19 **** self.failUnlessEqual(libm.sqrt(2.0), math.sqrt(2.0)) ! def SKIP_test_cdecl_decorator(self): # @ cdecl(c_double, "libm", [c_double]) --- 15,19 ---- self.failUnlessEqual(libm.sqrt(2.0), math.sqrt(2.0)) ! def test_cdecl_decorator(self): # @ cdecl(c_double, "libm", [c_double]) *************** *** 21,25 **** return sqrt._api_(value) # Oh well, compatibility with Python 2.3 ! sqrt = cdecl(c_double, "libm", [c_double]) (sqrt) self.failUnlessEqual(sqrt(4.0), 2.0) --- 21,25 ---- return sqrt._api_(value) # Oh well, compatibility with Python 2.3 ! sqrt = cdecl(c_double, "m", [c_double]) (sqrt) self.failUnlessEqual(sqrt(4.0), 2.0) *************** *** 37,42 **** self.failUnlessEqual(chars.raw, " ,,aaaadmmmnpppsss\x00") ! def SKIP_test_qsort_decorator(self): ! from ctypes.decorators import cdecl, name_library CMPFUNC = CFUNCTYPE(c_int, c_void_p, c_void_p) --- 37,42 ---- self.failUnlessEqual(chars.raw, " ,,aaaadmmmnpppsss\x00") ! def test_qsort_decorator(self): ! from ctypes.decorators import cdecl CMPFUNC = CFUNCTYPE(c_int, c_void_p, c_void_p) *************** *** 46,50 **** itemsize = sizeof(sequence) / len(sequence) qsort._api_(sequence, len(sequence), itemsize, CMPFUNC(cmp_func)) ! qsort = cdecl(None, "libc", [c_void_p, c_int, c_int, CMPFUNC])(qsort) def sortfunc(a, b): --- 46,50 ---- itemsize = sizeof(sequence) / len(sequence) qsort._api_(sequence, len(sequence), itemsize, CMPFUNC(cmp_func)) ! qsort = cdecl(None, "c", [c_void_p, c_int, c_int, CMPFUNC])(qsort) def sortfunc(a, b): Index: test_paramflags.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/test/Attic/test_paramflags.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_paramflags.py 3 Nov 2005 19:49:19 -0000 1.1.2.1 --- test_paramflags.py 2 Jan 2006 19:12:01 -0000 1.1.2.2 *************** *** 1,4 **** --- 1,5 ---- import unittest, os from ctypes import * + from ctypes.test import is_resource_enabled class RECT(Structure): *************** *** 20,25 **** return cmp((self.left, self.top, self.right, self.bottom), (other.left, other.top, other.right, other.bottom)) - - class BOOL(c_long): def check_retval(self, val): --- 21,24 ---- *************** *** 30,33 **** --- 29,38 ---- _check_retval_ = classmethod(check_retval) + # paramflag values + IN = 1 + OUT = 2 + RETVAL = 8 + INOUT = IN + OUT + class Test(unittest.TestCase): *************** *** 56,66 **** proto = CFUNCTYPE(c_int, POINTER(c_int)) proto("TwoOutArgs", dll, ! ((1,),) ) proto("TwoOutArgs", dll, ! ((1, "paramname"),) ) proto("TwoOutArgs", dll, ! ((1, "paramname", 'DefaultVal'),) ) # We CAN pass None instead of the paramflags tuple --- 61,71 ---- proto = CFUNCTYPE(c_int, POINTER(c_int)) proto("TwoOutArgs", dll, ! ((IN,),) ) proto("TwoOutArgs", dll, ! ((IN, "paramname"),) ) proto("TwoOutArgs", dll, ! ((IN, "paramname", 'DefaultVal'),) ) # We CAN pass None instead of the paramflags tuple *************** *** 68,75 **** # and we CAN pass None instead of the parameter names proto("TwoOutArgs", dll, ! ((1, None),) ) proto("TwoOutArgs", dll, ! ((1, None, 'DefaultVal'),) ) --- 73,80 ---- # and we CAN pass None instead of the parameter names proto("TwoOutArgs", dll, ! ((IN, None),) ) proto("TwoOutArgs", dll, ! ((IN, None, 'DefaultVal'),) ) *************** *** 80,84 **** proto = CFUNCTYPE(BOOL, c_long, POINTER(RECT)) ! func = proto("GetRectangle", dll, ((1, "hwnd"), (2,))) # returns a RECT instance... --- 85,89 ---- proto = CFUNCTYPE(BOOL, c_long, POINTER(RECT)) ! func = proto("GetRectangle", dll, ((IN, "hwnd"), (OUT,))) # returns a RECT instance... *************** *** 99,109 **** dll = CDLL(_ctypes_test.__file__) ! def checker(retval, func, args, *opt): if retval == 0: raise ValueError(args[0]) ! return args[1]._obj proto = CFUNCTYPE(c_int, c_long, POINTER(RECT)) ! func = proto("GetRectangle", dll, ((1, "hwnd"), (2,))) func.errcheck = checker --- 104,114 ---- dll = CDLL(_ctypes_test.__file__) ! def checker(retval, func, args): if retval == 0: raise ValueError(args[0]) ! return args[1] proto = CFUNCTYPE(c_int, c_long, POINTER(RECT)) ! func = proto("GetRectangle", dll, ((IN, "hwnd"), (OUT,))) func.errcheck = checker *************** *** 130,134 **** proto = WINFUNCTYPE(BOOL, c_long, POINTER(RECT)) ! func = proto("GetWindowRect", windll.user32, ((1, "hwnd"), (2,))) # returns a RECT instance... --- 135,139 ---- proto = WINFUNCTYPE(BOOL, c_long, POINTER(RECT)) ! func = proto("GetWindowRect", windll.user32, ((IN, "hwnd"), (OUT,))) # returns a RECT instance... *************** *** 152,156 **** proto = WINFUNCTYPE(c_long, c_wchar_p) func = proto("GetModuleHandleW", windll.kernel32, ! ((1, "lpModuleName", None),)) func(lpModuleName="kernel32") func("kernel32") --- 157,161 ---- proto = WINFUNCTYPE(c_long, c_wchar_p) func = proto("GetModuleHandleW", windll.kernel32, ! ((IN, "lpModuleName", None),)) func(lpModuleName="kernel32") func("kernel32") *************** *** 163,186 **** #func(a=1) - ## def test_BSTR_inout(self): - ## # test BSTR [in, out] parameter - ## import _ctypes_test - ## dll = CDLL(_ctypes_test.__file__) - - ## from _ctypes import _SimpleCData - - ## class BSTR(_SimpleCData): - ## _type_ = "X" - ## def __repr__(self): - ## return "%s(%r)" % (self.__class__.__name__, self.value) - ## def __del__(self, _free=windll.oleaut32.SysFreeString): - ## if not self._b_base_: - ## _free(self) - - ## proto = CFUNCTYPE(None, BSTR) - ## func = proto("GetBSTR", dll, ((3, "p1"),)) - - ## self.failUnlessEqual(func("SPAM"), "XPAM") - ## def test_c_wchar_p_out(self): ## # XXX XXX XXX XXX XXX Doesn't this modify a Python string??? YES, it does. --- 168,171 ---- *************** *** 202,209 **** # void TwoOutArgs([in] int a, [out] int *p1, [in] int b, [out] int *p2); proto = CFUNCTYPE(None, c_int, POINTER(c_int), c_int, POINTER(c_int)) ! func = proto("TwoOutArgs", dll, ((1, "a"), (2, "p1"), (1, "b"), (2, "p2"))) self.failUnlessEqual((1, 2), func(1, 2)) self.failUnlessEqual((1, 2), func(b=2, a=1)) def test_inout_args(self): import _ctypes_test --- 187,210 ---- # void TwoOutArgs([in] int a, [out] int *p1, [in] int b, [out] int *p2); proto = CFUNCTYPE(None, c_int, POINTER(c_int), c_int, POINTER(c_int)) ! func = proto("TwoOutArgs", dll, ((IN, "a"), (OUT, "p1"), (IN, "b"), (OUT, "p2"))) self.failUnlessEqual((1, 2), func(1, 2)) self.failUnlessEqual((1, 2), func(b=2, a=1)) + def test_COMPTR_inout(self): + # test POINTER(interface) [in, out] parameter + import _ctypes_test + dll = CDLL(_ctypes_test.__file__) + + from comtypes import IUnknown + + proto = CFUNCTYPE(None, POINTER(IUnknown)) + func = proto("_testfunc_p_p", dll, ((IN | OUT, "p1"),)) + + from comtypes.errorinfo import CreateErrorInfo + ei = CreateErrorInfo() + + self.failUnlessEqual(func(ei), ei) + + def test_inout_args(self): import _ctypes_test *************** *** 213,224 **** # void TwoOutArgs([in] int a, [in, out] int *p1, [in] int b, [in, out] int *p2); proto = CFUNCTYPE(None, c_int, POINTER(c_int), c_int, POINTER(c_int)) ! func = proto("TwoOutArgs", dll, ((1, "a"), (3, "p1"), (1, "b"), (3, "p2"))) # The function returns ((a + p1), (b + p2)) ! self.failUnlessEqual((3, 7), func(1, 2, 3, 4)) ! self.failUnlessEqual((10, 14), func(a=1, b=3, p1=9, p2=11)) # TypeError: required argument 'p1' is missing self.assertRaises(TypeError, lambda: func(a=1, b=3)) # TypeError: required argument 'p2' is missing ! self.assertRaises(TypeError, lambda: func(a=1, b=3, p1=3)) def get_inout_args_func(): --- 214,263 ---- # void TwoOutArgs([in] int a, [in, out] int *p1, [in] int b, [in, out] int *p2); proto = CFUNCTYPE(None, c_int, POINTER(c_int), c_int, POINTER(c_int)) ! func = proto("TwoOutArgs", dll, ((IN, "a"), (INOUT, "p1"), (IN, "b"), (INOUT, "p2"))) # The function returns ((a + p1), (b + p2)) ! p1 = c_int(2) ! p2 = c_int(4) ! self.failUnlessEqual((p1, p2), func(1, p1, 3, p2)) ! self.failUnlessEqual((p1, p2), func(a=1, b=3, p1=p1, p2=p2)) # TypeError: required argument 'p1' is missing self.assertRaises(TypeError, lambda: func(a=1, b=3)) # TypeError: required argument 'p2' is missing ! self.assertRaises(TypeError, lambda: func(a=1, b=3, p1=p1)) ! ! def test_array_out_args(self): ! ! @ dllimport(c_ulong, "kernel32", ! ((['in'], c_ulong, "hModule"), ! (['out'], c_wchar * 256, "lpFilename"), ! (['in'], c_ulong, "nSize", 256))) ! def GetModuleFileName(retval, func, (hModule, lpFileName, nSize)): ! if retval == 0: ! raise WinError(GetLastError()) ! return lpFileName[:retval] ! ! import sys ! print GetModuleFileName(0) ! print GetModuleFileName(sys.dllhandle) ! ! # XXX Cleanup. ! from ctypes import * ! # XXX hack: we use COMMETHOD for parsing. ! from comtypes import COMMETHOD ! ! def dllimport(restype, dllname, argspec, ! cc="stdcall"): ! # COMMETHOD returns: ! # restype, methodname, tuple(argtypes), tuple(paramflags), tuple(idlflags), helptext ! restype, _, argtypes, paramflags, _, _ = COMMETHOD([], restype, "", *argspec) ! if cc == "stdcall": ! proto = WINFUNCTYPE(restype, *argtypes) ! elif cc == "cdecl": ! proto = CFUNCTYPE(restype, *argtypes) ! dll = getattr(windll, dllname) ! def decorate(func): ! result = proto(func.__name__ + "W", getattr(windll, dllname), paramflags) ! result.errcheck = func ! return result ! return decorate def get_inout_args_func(): Index: test_leaks.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/test/Attic/test_leaks.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_leaks.py 3 Nov 2005 19:49:19 -0000 1.1.2.1 --- test_leaks.py 2 Jan 2006 19:12:01 -0000 1.1.2.2 *************** *** 15,19 **** ("br", POINT)] ! if 0 and hasattr(sys, "gettotalrefcount"): def test_no_cycles_refcount(self): --- 15,19 ---- ("br", POINT)] ! if hasattr(sys, "gettotalrefcount"): def test_no_cycles_refcount(self): *************** *** 54,58 **** del _pointer_type_cache[LIST] # XXX should this be a weakkeydict? ! if 0 and hasattr(sys, "gettotalrefcount"): def test_cycles_refcount(self): --- 54,58 ---- del _pointer_type_cache[LIST] # XXX should this be a weakkeydict? ! if hasattr(sys, "gettotalrefcount"): def test_cycles_refcount(self): |
From: Thomas H. <th...@us...> - 2006-01-02 19:12:05
|
Update of /cvsroot/ctypes/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5053 Modified Files: Tag: branch_1_0 decorators.py __init__.py Log Message: Sync with upstream version. Index: decorators.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/decorators.py,v retrieving revision 1.6.2.2 retrieving revision 1.6.2.3 diff -C2 -d -r1.6.2.2 -r1.6.2.3 *** decorators.py 18 Apr 2005 09:58:41 -0000 1.6.2.2 --- decorators.py 2 Jan 2006 19:11:55 -0000 1.6.2.3 *************** *** 12,38 **** import ctypes - _library_map = {} # map short name to so-name - _loaded_libs = {} # map so-names to DLL instance - - - def name_library(name, so_name): - """ - name_library(name, so_name) - - Register the <so_name> for a library. The library will be loaded - if <name> is referenced in a decorator. - """ - _library_map[name] = so_name - _library_map[so_name] = so_name - - - def _get_library(name): - # load and return a library. The library is cached. - soname = _library_map.get(name, name) - try: - return _loaded_libs[soname] - except KeyError: - return _loaded_libs.setdefault(soname, ctypes.CDLL(soname)) - def cdecl(restype, dllname, argtypes, logging=False): """cdecl(restype, dllname, argtypes, logging=False) -> decorator. --- 12,15 ---- *************** *** 50,54 **** """ def decorate(func): ! library = _get_library(dllname) api = ctypes.CFUNCTYPE(restype, *argtypes)(func.func_name, library) func._api_ = api --- 27,31 ---- """ def decorate(func): ! library = ctypes.cdll.find(dllname, False) api = ctypes.CFUNCTYPE(restype, *argtypes)(func.func_name, library) func._api_ = api *************** *** 80,84 **** """ def decorate(func): ! library = _get_library(dllname) api = ctypes.WINFUNCTYPE(restype, *argtypes)(func.func_name, library) func._api_ = api --- 57,61 ---- """ def decorate(func): ! library = ctypes.windll.find(dllname, False) api = ctypes.WINFUNCTYPE(restype, *argtypes)(func.func_name, library) func._api_ = api *************** *** 115,127 **** assert(sys.executable == GetModuleFileNameA()) - if os.name == "nt": - name_library("libm", "msvcrt") - else: - name_library("libm", "libm") - #@ cdecl(c_double, 'libm', [c_double]) def sqrt(value): return sqrt._api_(value) ! sqrt = cdecl(c_double, 'libm', [c_double])(sqrt) assert sqrt(4.0) == 2.0 --- 92,99 ---- assert(sys.executable == GetModuleFileNameA()) #@ cdecl(c_double, 'libm', [c_double]) def sqrt(value): return sqrt._api_(value) ! sqrt = cdecl(c_double, 'm', [c_double])(sqrt) assert sqrt(4.0) == 2.0 Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/__init__.py,v retrieving revision 1.61.2.20 retrieving revision 1.61.2.21 diff -C2 -d -r1.61.2.20 -r1.61.2.21 *** __init__.py 2 Jan 2006 14:58:39 -0000 1.61.2.20 --- __init__.py 2 Jan 2006 19:11:55 -0000 1.61.2.21 *************** *** 335,340 **** return func ! from _ctypes import _check_HRESULT ! class HRESULT(c_long): # _check_retval_ is called with the function's result when it # is used as restype. It checks for the FAILED bit, and --- 335,343 ---- return func ! # XXX Hm, what about HRESULT as normal parameter? ! # Mustn't it derive from c_long then? ! from _ctypes import _check_HRESULT, _SimpleCData ! class HRESULT(_SimpleCData): ! _type_ = "l" # _check_retval_ is called with the function's result when it # is used as restype. It checks for the FAILED bit, and *************** *** 345,349 **** # when it raises an error - that is what we want (and Python # doesn't have a way to raise an exception in the caller's ! # frame. _check_retval_ = _check_HRESULT --- 348,352 ---- # when it raises an error - that is what we want (and Python # doesn't have a way to raise an exception in the caller's ! # frame). _check_retval_ = _check_HRESULT |
From: Thomas H. <th...@us...> - 2006-01-02 19:11:59
|
Update of /cvsroot/ctypes/ctypes/comtypes/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4970 Modified Files: Tag: branch_1_0 typedesc.py tlbparser.py codegenerator.py Log Message: Sync with upstream version. Index: tlbparser.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/tools/tlbparser.py,v retrieving revision 1.4.2.22 retrieving revision 1.4.2.23 diff -C2 -d -r1.4.2.22 -r1.4.2.23 *** tlbparser.py 23 Aug 2005 19:42:20 -0000 1.4.2.22 --- tlbparser.py 2 Jan 2006 19:11:49 -0000 1.4.2.23 *************** *** 268,272 **** iid=str(ta.guid), idlflags=self.interface_type_flags(ta.wTypeFlags)) ! itf.doc = str(doc) self._register(itf_name, itf) --- 268,273 ---- iid=str(ta.guid), idlflags=self.interface_type_flags(ta.wTypeFlags)) ! if doc is not None: ! itf.doc = str(doc.split("\0")[0]) self._register(itf_name, itf) *************** *** 424,429 **** # version, control, hidden, and appobject coclass_name, doc = tinfo.GetDocumentation(-1)[0:2] ! ## print tinfo.GetContainingTypeLib()[0].GetLibAttr().guid, coclass_name ! coclass = typedesc.CoClass(coclass_name, str(ta.guid), self.coclass_type_flags(ta.wTypeFlags)) if doc is not None: coclass.doc = doc --- 425,433 ---- # version, control, hidden, and appobject coclass_name, doc = tinfo.GetDocumentation(-1)[0:2] ! tlibattr = tinfo.GetContainingTypeLib()[0].GetLibAttr() ! coclass = typedesc.CoClass(coclass_name, ! str(ta.guid), ! self.coclass_type_flags(ta.wTypeFlags), ! tlibattr) if doc is not None: coclass.doc = doc *************** *** 555,559 **** "Parses a type library from a file" def __init__(self, path): ! self.tlib = typeinfo.LoadTypeLibEx(path, regkind=typeinfo.REGKIND_REGISTER) self.items = {} --- 559,564 ---- "Parses a type library from a file" def __init__(self, path): ! # XXX DOESN'T LOOK CORRECT: We should NOT register the typelib. ! self.tlib = typeinfo.LoadTypeLibEx(path)#, regkind=typeinfo.REGKIND_REGISTER) self.items = {} *************** *** 623,626 **** --- 628,637 ---- return None + def _py2exe_hint(): + # If the tlbparser is frozen, we need to include these + import comtypes.persist + import comtypes.typeinfo + import comtypes.automation + def generate_module(tlib, ofi, make_module, name_module): known_symbols = {} Index: codegenerator.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/tools/codegenerator.py,v retrieving revision 1.6.2.21 retrieving revision 1.6.2.22 diff -C2 -d -r1.6.2.21 -r1.6.2.22 *** codegenerator.py 20 Oct 2005 17:17:48 -0000 1.6.2.21 --- codegenerator.py 2 Jan 2006 19:11:49 -0000 1.6.2.22 *************** *** 72,77 **** if self._COMMETHOD_defined: return ! if __debug__: ! print >> self.imports, "from comtypes import helpstring" super(Generator, self).need_COMMETHOD() --- 72,76 ---- if self._COMMETHOD_defined: return ! print >> self.imports, "from comtypes import helpstring" super(Generator, self).need_COMMETHOD() *************** *** 80,87 **** if self._DISPMETHOD_defined: return ! if __debug__: ! print >> self.imports, "from comtypes import DISPMETHOD, DISPPROPERTY, helpstring" ! else: ! print >> self.imports, "from comtypes import DISPMETHOD, DISPPROPERTY" self._DISPMETHOD_defined = True --- 79,83 ---- if self._DISPMETHOD_defined: return ! print >> self.imports, "from comtypes import DISPMETHOD, DISPPROPERTY, helpstring" self._DISPMETHOD_defined = True *************** *** 158,161 **** --- 154,162 ---- print >> self.stream, " _idlflags_ = %s" % coclass.idlflags ##X print >> self.stream, "POINTER(%s).__ctypes_from_outparam__ = wrap" % coclass.name + + libid = coclass.tlibattr.guid + wMajor, wMinor = coclass.tlibattr.wMajorVerNum, coclass.tlibattr.wMinorVerNum + print >> self.stream, " _reg_typelib_ = (%r, %s, %s)" % (str(libid), wMajor, wMinor) + for itf, idlflags in coclass.interfaces: self.generate(itf.get_head()) *************** *** 169,176 **** --- 170,179 ---- print >> self.stream, "%s._outgoing_interfaces_ = [%s]" % (coclass.name, ", ".join(sources)) print >> self.stream + self.names.add(coclass.name) def ComInterface(self, itf): self.generate(itf.get_head()) self.generate(itf.get_body()) + self.names.add(itf.name) def _is_enuminterface(self, itf): *************** *** 197,200 **** --- 200,204 ---- self.need_GUID() print >> self.stream, "class %s(%s):" % (head.itf.name, basename) + print >> self.stream, " _case_insensitive_ = True" doc = getattr(head.itf, "doc", None) if doc: *************** *** 265,268 **** --- 269,273 ---- self.generate(itf.get_head()) self.generate(itf.get_body()) + self.names.add(itf.name) def DispInterfaceHead(self, head): *************** *** 272,275 **** --- 277,281 ---- self.need_GUID() print >> self.stream, "class %s(%s):" % (head.itf.name, basename) + print >> self.stream, " _case_insensitive_ = True" doc = getattr(head.itf, "doc", None) if doc: Index: typedesc.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/tools/typedesc.py,v retrieving revision 1.1.2.10 retrieving revision 1.1.2.11 diff -C2 -d -r1.1.2.10 -r1.1.2.11 *** typedesc.py 24 Aug 2005 11:49:29 -0000 1.1.2.10 --- typedesc.py 2 Jan 2006 19:11:49 -0000 1.1.2.11 *************** *** 117,124 **** class CoClass(object): ! def __init__(self, name, clsid, idlflags): self.name = name self.clsid = clsid self.idlflags = idlflags self.interfaces = [] --- 117,125 ---- class CoClass(object): ! def __init__(self, name, clsid, idlflags, tlibattr): self.name = name self.clsid = clsid self.idlflags = idlflags + self.tlibattr = tlibattr self.interfaces = [] |
From: Thomas H. <th...@us...> - 2006-01-02 19:11:51
|
Update of /cvsroot/ctypes/ctypes/comtypes/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4896 Modified Files: Tag: branch_1_0 test_msscript.py test_createwrappers.py runtests.py __init__.py Added Files: Tag: branch_1_0 test_dyndispatch.py Log Message: Sync with upstream version. Index: test_createwrappers.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/test/Attic/test_createwrappers.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_createwrappers.py 8 Nov 2005 20:43:38 -0000 1.1.2.1 --- test_createwrappers.py 2 Jan 2006 19:11:43 -0000 1.1.2.2 *************** *** 21,37 **** def add_test(fname): try: comtypes.typeinfo.LoadTypeLibEx(fname) except WindowsError: return - global number def test(self): ! try: ! comtypes.client.GetModule(fname) ! except TypeError, detail: ! # work around the bug that arrays and simple pointer ! # types are not supported as 'out' parameters ! if not str(detail).startswith("'out' parameter"): ! raise test.__doc__ = "test GetModule(%r)" % fname --- 21,31 ---- def add_test(fname): + global number try: comtypes.typeinfo.LoadTypeLibEx(fname) except WindowsError: return def test(self): ! comtypes.client.GetModule(fname) test.__doc__ = "test GetModule(%r)" % fname *************** *** 42,50 **** add_test(fname) - # MSCALDEV.TLB - UnicodeEncodeError in COM method name for fname in glob.glob(r"c:\windows\system32\*.tlb"): add_test(fname) - # msvbvm60.dll Ignoring _HiddenInterface which has no base interface for fname in glob.glob(r"c:\windows\system32\*.dll"): add_test(fname) --- 36,42 ---- --- NEW FILE: test_dyndispatch.py --- import unittest from comtypes.safearray import SafeArray_FromSequence from comtypes.client import CreateObject from comtypes.client.dynamic import _Dispatch import logging class Test(unittest.TestCase): def test(self): d = CreateObject("MSScriptControl.ScriptControl") d.Language = "jscript" d.AddCode('function x() { return [3, "spam foo", 3.14]; };') result = d.Run("x", SafeArray_FromSequence([])) self.failUnless(isinstance(result, _Dispatch)) self.failUnlessEqual(result[0], 3) self.failUnlessEqual(result[1], "spam foo") self.failUnlessEqual(result[2], 3.14) self.assertRaises(IndexError, lambda: result[3]) if __name__ == "__main__": unittest.main() Index: runtests.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/test/Attic/runtests.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 *** runtests.py 8 Nov 2005 20:43:38 -0000 1.1.2.1 --- runtests.py 2 Jan 2006 19:11:43 -0000 1.1.2.2 *************** *** 1,14 **** - """Usage: runtests.py [-q] [-r] [-v] [-u resources] [mask] - - Run all tests found in this directory, and print a summary of the results. - Command line flags: - -q quiet mode: don't prnt anything while the tests are running - -r run tests repeatedly, look for refcount leaks - -u<resources> - Add resources to the lits of allowed resources. '*' allows all - resources. - -v verbose mode: print the test currently executed - mask mask to select filenames containing testcases, wildcards allowed - """ import sys import ctypes.test --- 1,2 ---- Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/test/Attic/__init__.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 *** __init__.py 8 Nov 2005 20:43:38 -0000 1.1.2.1 --- __init__.py 2 Jan 2006 19:11:43 -0000 1.1.2.2 *************** *** 1 **** ! # comtypes.unittest package. --- 1 ---- ! # comtypes.test package. Index: test_msscript.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/test/Attic/test_msscript.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_msscript.py 8 Nov 2005 20:43:38 -0000 1.1.2.1 --- test_msscript.py 2 Jan 2006 19:11:43 -0000 1.1.2.2 *************** *** 37,41 **** # typeinfo is really a temporary thing. ! res = engine.Eval("[1, 2, 3, 4]") # comtypes.client works around this bug, by not trying to --- 37,41 ---- # typeinfo is really a temporary thing. ! res = engine.Eval("[1, 2, 3, 4]")._comobj # comtypes.client works around this bug, by not trying to *************** *** 44,50 **** self.failUnlessEqual(type(res), POINTER(IDispatch)) ! tinfo_1 = engine.Eval("[1, 2, 3]").GetTypeInfo(0) ! tinfo_2 = engine.Eval("[1, 2, 3, 4]").GetTypeInfo(0) ! tinfo_3 = engine.Eval("[1, 2, 3, 4, 5]").GetTypeInfo(0) --- 44,50 ---- self.failUnlessEqual(type(res), POINTER(IDispatch)) ! tinfo_1 = engine.Eval("[1, 2, 3]")._comobj.GetTypeInfo(0) ! tinfo_2 = engine.Eval("[1, 2, 3, 4]")._comobj.GetTypeInfo(0) ! tinfo_3 = engine.Eval("[1, 2, 3, 4, 5]")._comobj.GetTypeInfo(0) |
From: Thomas H. <th...@us...> - 2006-01-02 19:11:46
|
Update of /cvsroot/ctypes/ctypes/comtypes/server In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4829 Added Files: Tag: branch_1_0 w_getopt.py register.py inprocserver.py connectionpoints.py automation.py __init__.py Log Message: Sync with upstream version. --- NEW FILE: automation.py --- import logging from ctypes import * from comtypes.hresult import * from comtypes import COMObject, IUnknown from comtypes.typeinfo import LoadRegTypeLib, IProvideClassInfo, IProvideClassInfo2 from comtypes.automation import IEnumVARIANT logger = logging.getLogger(__name__) _oleaut32 = windll.oleaut32 __all__ = ["DualDispImplMixin", "VARIANTEnumerator"] class DualDispImplMixin(object): # a mixin class to implement a dual dispatch interface. # Needs a _reg_typelib_ attribute in the subclass. # # Also implements IProvideClassInfo2. XXX Where should this # really go? And: XXX Can we load the typelib in the CoClass # baseclass? def __init__(self): super(DualDispImplMixin, self).__init__() tlib = LoadRegTypeLib(*self._reg_typelib_) # XXX This works only if the default dispatch interface is # also the default interface. We should either search for the # first dispatch interface, or raise an error if the first is # no default disp interface. self.__dispatch_iid = self._com_interfaces_[0]._iid_ self.__tinfo = tlib.GetTypeInfoOfGuid(self.__dispatch_iid) if hasattr(self, "_reg_clsid_"): self.__coclass_tinfo = tlib.GetTypeInfoOfGuid(self._reg_clsid_) def IDispatch_GetTypeInfoCount(self, this, pctinfo): if not pctinfo: return E_POINTER pctinfo[0] = 1 return S_OK def IDispatch_GetTypeInfo(self, this, itinfo, lcid, pptinfo): if not pptinfo: return E_POINTER # Doesn't work, unless POINTER(POINTER(<interface>)).__setitem__ is overridden correctly. ## pptinfo[0] = self.__tinfo ## return S_OK from _ctypes import CopyComPointer return CopyComPointer(self.__tinfo, pptinfo) def IDispatch_GetIDsOfNames(self, this, riid, rgszNames, cNames, lcid, rgDispId): return _oleaut32.DispGetIDsOfNames(self.__tinfo, rgszNames, cNames, rgDispId) def IDispatch_Invoke(self, this, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr): impl = self._com_pointers_[self.__dispatch_iid] return _oleaut32.DispInvoke(impl, self.__tinfo, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr) def IProvideClassInfo_GetClassInfo(self, this, ppTI): if not ppTI: return E_POINTER logger.debug("GetClassInfo called for %s", self._reg_clsid_) from _ctypes import CopyComPointer return CopyComPointer(self.__coclass_tinfo, ppTI) def IProvideClassInfo2_GetGUID(self, this, dwGuidKind, pGUID): if not pGUID: return E_POINTER GUIDKIND_DEFAULT_SOURCE_DISP_IID = 1 if dwGuidKind != GUIDKIND_DEFAULT_SOURCE_DISP_IID: return E_INVALIDARG # XXX MSDN: The outgoing interface in question must be derived from IDispatch. iid = self._outgoing_interfaces_[0]._iid_ memmove(pGUID, iid, sizeof(iid)) logger.debug("IProvideClassInfo2::GetGUID -> %s", iid) return S_OK ################################################################ class VARIANTEnumerator(COMObject): _com_interfaces_ = [IEnumVARIANT] def __init__(self, itemtype, jobs): self.jobs = jobs # keep, so that we can restore our iterator (in Reset, and Clone). self.itemtype = itemtype self.item_interface = itemtype._com_interfaces_[0] self.seq = iter(self.jobs) super(VARIANTEnumerator, self).__init__() def Next(self, this, celt, rgVar, pCeltFetched): if not rgVar: return E_POINTER if not pCeltFetched: pCeltFetched = [None] pCeltFetched[0] = 0 try: for index in range(celt): job = self.itemtype(self.seq.next()) p = POINTER(self.item_interface)() job.IUnknown_QueryInterface(None, pointer(p._iid_), byref(p)) rgVar[index].value = p pCeltFetched[0] += 1 except StopIteration: pass if pCeltFetched[0] == celt: return S_OK return S_FALSE def Skip(self, this, celt): # skip some elements. try: for _ in range(celt): self.seq.next() except StopIteration: return S_FALSE return S_OK def Reset(self, this): self.seq = iter(self.jobs) return S_OK # Clone ################################################################ class COMCollection(COMObject): """Abstract base class which implements Count, Item, and _NewEnum.""" def __init__(self, itemtype, collection): self.collection = collection self.itemtype = itemtype super(COMCollection, self).__init__() def _get_Item(self, this, pathname, pitem): if not pitem: return E_POINTER item = self.itemtype(pathname) return item.IUnknown_QueryInterface(None, pointer(pitem[0]._iid_), pitem) def _get_Count(self, this, pcount): if not pcount: return E_POINTER pcount[0] = len(self.collection) return S_OK def _get__NewEnum(self, this, penum): if not penum: return E_POINTER enum = VARIANTEnumerator(self.itemtype, self.collection) return enum.IUnknown_QueryInterface(None, pointer(IUnknown._iid_), penum) --- NEW FILE: __init__.py --- from ctypes import * from comtypes import IUnknown, GUID, STDMETHOD, HRESULT ################################################################ # Interfaces class IClassFactory(IUnknown): _iid_ = GUID("{00000001-0000-0000-C000-000000000046}") _methods_ = [ STDMETHOD(HRESULT, "CreateInstance", [c_int, POINTER(GUID), POINTER(c_ulong)]), STDMETHOD(HRESULT, "LockServer", [c_int])] class IExternalConnection(IUnknown): _iid_ = GUID("{00000019-0000-0000-C000-000000000046}") _methods_ = [ STDMETHOD(HRESULT, "AddConnection", [c_ulong, c_ulong]), STDMETHOD(HRESULT, "ReleaseConnection", [c_ulong, c_ulong, c_ulong])] --- NEW FILE: connectionpoints.py --- from ctypes import * from comtypes import IUnknown, COMObject, COMError from comtypes.hresult import * from comtypes.typeinfo import LoadRegTypeLib from comtypes.connectionpoints import IConnectionPoint from comtypes.automation import IDispatch import logging logger = logging.getLogger(__name__) __all__ = ["ConnectableObjectMixin"] class ConnectionPointImpl(COMObject): """This object implements a connectionpoint""" _com_interfaces_ = [IConnectionPoint] def __init__(self, sink_interface, sink_typeinfo): super(ConnectionPointImpl, self).__init__() self._connections = {} self._cookie = 0 self._sink_interface = sink_interface self._typeinfo = sink_typeinfo # per MSDN, all interface methods *must* be implemented, E_NOTIMPL # is no allowed return value def IConnectionPoint_Advise(self, this, pUnk, pdwCookie): if not pUnk or not pdwCookie: return E_POINTER logger.info("Advise") try: ptr = pUnk.QueryInterface(self._sink_interface) except COMError: return CONNECT_E_CANNOTCONNECT pdwCookie[0] = self._cookie = self._cookie + 1 self._connections[self._cookie] = ptr return S_OK def IConnectionPoint_Unadvise(self, this, dwCookie): logger.info("Unadvise %s", dwCookie) try: del self._connections[dwCookie] except KeyError: return CONNECT_E_NOCONNECTION return S_OK def IConnectionPoint_GetConnectionPointContainer(self, this, ppCPC): return E_NOTIMPL def IConnectionPoint_GetConnectionInterface(self, this, pIID): return E_NOTIMPL def _call_sinks(self, name, *args, **kw): logger.info("_call_sinks(%s, %s, *%s, **%s)", self, name, args, kw) # Is it an IDispatch derived interface? Then, events have to be delivered # via Invoke calls (even if it is a dual interface). if hasattr(self._sink_interface, "Invoke"): # for better performance, we could cache the dispids. dispid = self._typeinfo.GetIDsOfNames(name)[0] for p in self._connections.values(): p.Invoke(dispid, *args, **kw) else: for p in self._connections.values(): getattr(p, name)(*args, **kw) class ConnectableObjectMixin(object): """Mixin which implements IConnectionPointContainer. Call Fire_Event(interface, methodname, *args, **kw) to fire an event. <interface> can either be the source interface, or an integer index into the _outgoing_interfaces_ list. """ def __init__(self): super(ConnectableObjectMixin, self).__init__() self.__connections = {} tlib = LoadRegTypeLib(*self._reg_typelib_) for itf in self._outgoing_interfaces_: typeinfo = tlib.GetTypeInfoOfGuid(itf._iid_) self.__connections[itf] = ConnectionPointImpl(itf, typeinfo) def IConnectionPointContainer_EnumConnectionPoints(self, this, ppEnum): # according to MSDN, E_NOTIMPL is specificially disallowed # because, without typeinfo, there's no way for the caller to # find out. return E_NOTIMPL def IConnectionPointContainer_FindConnectionPoint(self, this, refiid, ppcp): iid = refiid[0] logger.info("FindConnectionPoint %s", iid) if not ppcp: return E_POINTER for itf in self._outgoing_interfaces_: if itf._iid_ == iid: # 'byref' will not work in this case, since the QueryInterface # method implementation is called on Python directly. There's # no C layer between which will convert the second parameter # from byref() to pointer(). conn = self.__connections[itf] result = conn.IUnknown_QueryInterface(None, pointer(IConnectionPoint._iid_), ppcp) logger.info("connectionpoint found, QI() -> %s", result) return result logger.info("No connectionpoint found") return CONNECT_E_NOCONNECTION def Fire_Event(self, itf, name, *args, **kw): # Fire event 'name' with arguments *args and **kw. # Accepts either an interface index or an interface as first argument. logger.info("Fire_Event(%s, %s, *%s, **%s)", itf, name, args, kw) if isinstance(itf, int): itf = self._outgoing_interfaces_[itf] self.__connections[itf]._call_sinks(name, *args, **kw) --- NEW FILE: inprocserver.py --- import ctypes from comtypes import COMObject, GUID from comtypes.server import IClassFactory from comtypes.hresult import * import sys, _winreg, logging logger = logging.getLogger(__name__) _debug = logger.debug _critical = logger.critical ################################################################ g_cLocks = 0 class ClassFactory(COMObject): _com_interfaces_ = [IClassFactory] def __init__(self, cls): super(ClassFactory, self).__init__() self._cls = cls def IClassFactory_CreateInstance(self, this, punkOuter, riid, ppv): _debug("ClassFactory.CreateInstance(%s)", riid[0]) result = self._cls().IUnknown_QueryInterface(None, riid, ppv) _debug("CreateInstance() -> %s", result) return result def IClassFactory_LockServer(self, this, fLock): global g_cLocks if fLock: g_cLocks += 1 else: g_cLocks -= 1 return S_OK def inproc_find_class(clsid): key = _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, "CLSID\\%s\\InprocServer32" % clsid) try: pathdir = _winreg.QueryValueEx(key, "PythonPath")[0] except: _debug("NO path to insert") else: if not pathdir in sys.path: sys.path.insert(0, str(pathdir)) _debug("insert path %r", pathdir) else: _debug("Already in path %r", pathdir) pythonclass = _winreg.QueryValueEx(key, "PythonClass")[0] parts = pythonclass.split(".") modname = ".".join(parts[:-1]) classname = parts[-1] _debug("modname: %s, classname %s", modname, classname) __import__(modname) mod = sys.modules[modname] result = getattr(mod, classname) _debug("Found class %s", result) return result _logging_configured = False def _setup_logging(clsid): """Read from the registry, and configure the logging module. Currently, the handler (NTDebugHandler) is hardcoded. """ global _logging_configured if _logging_configured: return _logging_configured = True try: hkey = _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, r"CLSID\%s\Logging" % clsid) except WindowsError: return from comtypes.logutil import NTDebugHandler handler = NTDebugHandler() try: val, typ = _winreg.QueryValueEx(hkey, "format") formatter = logging.Formatter(val) except: formatter = logging.Formatter("(Thread %(thread)s):%(levelname)s:%(message)s") handler.setFormatter(formatter) logging.root.addHandler(handler) try: values, typ = _winreg.QueryValueEx(hkey, "levels") except: return if typ == _winreg.REG_SZ: values = [values] elif typ != _winreg.REG_MULTI_SZ: # this is an error return for val in values: name, level = val.split("=") level = getattr(logging, level) logging.getLogger(name).setLevel(level) def DllGetClassObject(rclsid, riid, ppv): iid = GUID.from_address(riid) clsid = GUID.from_address(rclsid) if not _logging_configured: _setup_logging(clsid) # This function is directly called by C code, and receives C # integers as parameters. rcslid is a pointer to the CLSID for the # coclass we want to be created, riid is a pointer to the # requested interface. try: _debug("DllGetClassObject(clsid=%s, iid=%s)", clsid, iid) cls = inproc_find_class(clsid) if not cls: return CLASS_E_CLASSNOTAVAILABLE result = ClassFactory(cls).IUnknown_QueryInterface(None, ctypes.pointer(iid), ppv) _debug("DllGetClassObject() -> %s", result) return result except Exception: _critical("DllGetClassObject", exc_info=True) return E_FAIL def DllCanUnloadNow(): from comtypes._comobject import COMObject result = S_OK if g_cLocks: result = S_FALSE elif COMObject._instances_: result = S_FALSE _debug("DllCanUnloadNow %d locks, %d instances -> result %s", g_cLocks, len(COMObject._instances_), result) return result --- NEW FILE: register.py --- """comtypes.server.register - register and unregister a COM object. Exports the UseCommandLine function. UseCommandLine is called with the COM object classes that a module exposes. It parses the Windows command line and takes the appropriate actions. These command line options are supported: /regserver - register the classes with COM. /unregserver - unregister the classes with COM. /nodebug - remove all logging configuration from the registry. /l <name>=<level> - configure the logging level for the standard Python loggind module, this option may be used several times. /f <formatter> - specify the formatter string. Note: Registering and unregistering the objects does remove logging entries. Configuring the logging does not change other registry entries, so it is possible to freeze a comobject with py2exe, register it, then configure logging afterwards to debug it, and delete the logging config afterwards. Sample usage: Register the COM object: python mycomobj.py /regserver Configure logging info: python mycomobj.py /l comtypes=INFO /l comtypes.server=DEBUG /f %(message)s Now, debug the object, and when done delete logging info: python mycomobj.py /nodebug """ import sys, os import _winreg import logging import comtypes from comtypes.typeinfo import LoadTypeLibEx, UnRegisterTypeLib, REGKIND_REGISTER from comtypes.hresult import * from comtypes.server import w_getopt from ctypes import windll, c_ulong, c_wchar_p, WinError, sizeof, create_string_buffer _debug = logging.getLogger(__name__).debug # a SHDeleteKey function, will remove a registry key with all subkeys. def _non_zero(retval, func, args): if retval: raise WinError(retval) SHDeleteKey = windll.shlwapi.SHDeleteKeyW SHDeleteKey.errcheck = _non_zero SHDeleteKey.argtypes = c_ulong, c_wchar_p try: Set = set except NameError: from sets import Set #as set _KEYS = {_winreg.HKEY_CLASSES_ROOT: "HKCR", _winreg.HKEY_LOCAL_MACHINE: "HKLM", _winreg.HKEY_CURRENT_USER: "HKCU"} def _explain(hkey): return _KEYS.get(hkey, hkey) class Registrar(object): def nodebug(self, cls): """Delete logging entries from the registry.""" clsid = cls._reg_clsid_ try: _debug('DeleteKey( %s\\CLSID\\%s\\Logging"' % \ (_explain(_winreg.HKEY_CLASSES_ROOT), clsid)) hkey = _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, r"CLSID\%s" % clsid) _winreg.DeleteKey(hkey, "Logging") except WindowsError, detail: if detail.errno != 2: raise def debug(self, cls, levels, format): """Write entries in the registry to setup logging for this clsid.""" # handlers # format clsid = cls._reg_clsid_ _debug('CreateKey( %s\\CLSID\\%s\\Logging"' % \ (_explain(_winreg.HKEY_CLASSES_ROOT), clsid)) hkey = _winreg.CreateKey(_winreg.HKEY_CLASSES_ROOT, r"CLSID\%s\Logging" % clsid) for item in levels: name, value = item.split("=") v = getattr(logging, value) assert isinstance(v, int) _debug('SetValueEx(levels, %s)' % levels) _winreg.SetValueEx(hkey, "levels", None, _winreg.REG_MULTI_SZ, levels) if format: _debug('SetValueEx(format, %s)' % format) _winreg.SetValueEx(hkey, "format", None, _winreg.REG_SZ, format) else: _debug('DeleteValue(format)') try: _winreg.DeleteValue(hkey, "format") except WindowsError, detail: if detail.errno != 2: raise def register(self, cls): """Register the COM server class.""" # First, we unregister the object with force=True, to force removal # of all registry entries, even if we would not write them. # Second, we create new entries. # It seems ATL does the same. self.unregister(cls, force=True) table = self._registry_entries(cls) table.sort() _debug("Registering %s", cls) for hkey, subkey, valuename, value in table: _debug ('[%s\\%s]', _explain(hkey), subkey) _debug('%s="%s"', valuename or "@", value) k = _winreg.CreateKey(hkey, subkey) _winreg.SetValueEx(k, valuename, None, _winreg.REG_SZ, str(value)) tlib = getattr(cls, "_reg_typelib_", None) if tlib is not None: if hasattr(sys, "frozendllhandle"): dll = self._get_serverdll() _debug("LoadTypeLibEx(%s, REGKIND_REGISTER)", dll) LoadTypeLibEx(dll, REGKIND_REGISTER) else: path = cls._typelib_path_ _debug("LoadTypeLibEx(%s, REGKIND_REGISTER)", path) LoadTypeLibEx(path, REGKIND_REGISTER) _debug("Done") def unregister(self, cls, force=False): """Unregister the COM server class.""" # If force==False, we only remove those entries that we # actually would have written. It seems ATL does the same. table = [t[:2] for t in self._registry_entries(cls)] # only unique entries table = list(set(table)) table.sort() table.reverse() _debug("Unregister %s", cls) for hkey, subkey in table: try: if force: _debug("SHDeleteKey %s\\%s", _explain(hkey), subkey) SHDeleteKey(hkey, subkey) else: _debug("DeleteKey %s\\%s", _explain(hkey), subkey) _winreg.DeleteKey(hkey, subkey) except WindowsError, detail: if detail.errno != 2: raise tlib = getattr(cls, "_reg_typelib_", None) if tlib is not None: try: _debug("UnRegisterTypeLib(%s, %s, %s)", *tlib) UnRegisterTypeLib(*tlib) except WindowsError, detail: if not detail.errno in (TYPE_E_REGISTRYACCESS, TYPE_E_CANTLOADLIBRARY): raise _debug("Done") def _get_serverdll(self): """Return the pathname of the dll hosting the COM object.""" handle = getattr(sys, "frozendllhandle", None) if handle is not None: buf = create_string_buffer(260) windll.kernel32.GetModuleFileNameA(handle, buf, sizeof(buf)) return buf[:] import _ctypes return _ctypes.__file__ def _get_full_classname(self, cls): """Return <modulename>.<classname> for 'cls'.""" modname = cls.__module__ if modname == "__main__": modname = os.path.splitext(os.path.basename(sys.argv[0]))[0] return "%s.%s" % (modname, cls.__name__) def _get_pythonpath(self, cls): """Return the filesystem path of the module containing 'cls'.""" modname = cls.__module__ dirname = os.path.dirname(sys.modules[modname].__file__) return os.path.abspath(dirname) def _registry_entries(self, cls): """Return a sequence of tuples containing registry entries. The tuples must be (key, subkey, name, value). Required entries: ================= _reg_clsid_ - a string or GUID instance _reg_clsctx_ - server type(s) to register Optional entries: ================= _reg_desc_ - a string _reg_progid_ - a string naming the progid, typically 'MyServer.MyObject.1' _reg_novers_progid_ - version independend progid, typically 'MyServer.MyObject' _reg_typelib_ - an tuple (libid, majorversion, minorversion) specifying a typelib. _reg_threading_ - a string specifying the threading model Note that the first part of the progid string is typically the IDL library name of the type library containing the coclass. """ HKCR = _winreg.HKEY_CLASSES_ROOT # table format: rootkey, subkey, valuename, value table = [] append = lambda *args: table.append(args) # basic entry - names the comobject reg_clsid = str(cls._reg_clsid_) # that's the only required attribute for registration reg_desc = getattr(cls, "_reg_desc_", "") append(HKCR, "CLSID\\%s" % reg_clsid, "", reg_desc) reg_progid = getattr(cls, "_reg_progid_", None) if reg_progid: # for ProgIDFromCLSID: append(HKCR, "CLSID\\%s\\ProgID" % reg_clsid, "", reg_progid) # 1 # for CLSIDFromProgID if reg_desc: append(HKCR, reg_progid, "", reg_desc) # 2 append(HKCR, "%s\\CLSID" % reg_progid, "", reg_clsid) # 3 reg_novers_progid = getattr(cls, "_reg_novers_progid_", None) if reg_novers_progid: append(HKCR, "CLSID\\%s\\VersionIndependendProgID" % reg_clsid, # 1a "", reg_novers_progid) if reg_desc: append(HKCR, reg_novers_progid, "", reg_desc) # 2a append(HKCR, "%s\\CurVer" % reg_novers_progid, "", reg_progid) # append(HKCR, "%s\\CLSID" % reg_novers_progid, "", reg_clsid) # 3a clsctx = getattr(cls, "_reg_clsctx_", 0) if clsctx & comtypes.CLSCTX_LOCAL_SERVER and not hasattr(sys, "frozendllhandle"): exe = sys.executable script = __import__(cls.__module__).__file__ if " " in exe: exe = '"%s"' % exe if " " in script: script = '"%s"' % script append(HKCR, "CLSID\\%s\\LocalServer32" % reg_clsid, "", "%s %s" % (exe, script)) if clsctx & comtypes.CLSCTX_INPROC_SERVER: append(HKCR, "CLSID\\%s\\InprocServer32" % reg_clsid, "", self._get_serverdll()) # only for inproc servers append(HKCR, "CLSID\\%s\\InprocServer32" % reg_clsid, "PythonClass", self._get_full_classname(cls)) # only for non-frozen inproc servers the PythonPath is needed. if not hasattr(sys, "frozendllhandle"): append(HKCR, "CLSID\\%s\\InprocServer32" % reg_clsid, "PythonPath", self._get_pythonpath(cls)) reg_threading = getattr(cls, "_reg_threading_", None) if reg_threading is not None: append(HKCR, "CLSID\\%s\\InprocServer32" % reg_clsid, "ThreadingModel", reg_threading) reg_tlib = getattr(cls, "_reg_typelib_", None) if reg_tlib is not None: append(HKCR, "CLSID\\%s\\Typelib" % reg_clsid, "", reg_tlib[0]) return table ################################################################ def register(cls): Registrar().register(cls) def unregister(cls): Registrar().unregister(cls) def UseCommandLine(*classes): usage = """Usage: %s [-regserver] [-unregserver] [-nodebug] [-f logformat] [-l loggername=level]""" % sys.argv[0] opts, args = w_getopt.w_getopt(sys.argv[1:], ## "regserver unregserver embedding l: f: nodebug") "regserver unregserver l: f: nodebug") if not opts: sys.stderr.write(usage) return 0 # nothing for us to do levels = [] format = None nodebug = False for option, value in opts: if option == "regserver": for cls in classes: register(cls) elif option == "unregserver": for cls in classes: unregister(cls) ## elif option == "embedding": ## if len(classes) == 1: ## localserver(classes[0]) ## else: ## raise ValueError, "more than one class not yet supported" elif option == "f": format = value elif option == "l": levels.append(value) elif option == "nodebug": nodebug = True if levels or format is not None: for cls in classes: Registrar().debug(cls, levels, format) if nodebug: for cls in classes: Registrar().nodebug(cls) return 1 # we have done something if __name__ == "__main__": UseCommandLine() --- NEW FILE: w_getopt.py --- class GetoptError(Exception): pass def w_getopt(args, options): """A getopt for Windows. Options may start with either '-' or '/', the option names may have more than one letter (/tlb or -RegServer), and option names are case insensitive. Returns two elements, just as getopt.getopt. The first is a list of (option, value) pairs in the same way getopt.getopt does, but there is no '-' or '/' prefix to the option name, and the option name is always lower case. The second is the list of arguments which do not belong to an option. Different from getopt.getopt, a single argument not belonging to an option does not terminate parsing. """ opts = [] arguments = [] while args: if args[0][:1] in "/-": arg = args[0][1:] # strip the '-' or '/' arg = arg.lower() if arg + ':' in options: try: opts.append((arg, args[1])) except IndexError: raise GetoptError, "option '%s' requires an argument" % args[0] args = args[1:] elif arg in options: opts.append((arg, '')) else: raise GetoptError, "invalid option '%s'" % args[0] args = args[1:] else: arguments.append(args[0]) args = args[1:] return opts, arguments if __debug__: if __name__ == "__main__": import unittest class TestCase(unittest.TestCase): def test_1(self): args = "-embedding spam /RegServer foo /UnregSERVER blabla".split() opts, args = w_getopt(args, "regserver unregserver embedding".split()) self.assertEqual(opts, [('embedding', ''), ('regserver', ''), ('unregserver', '')]) self.assertEqual(args, ["spam", "foo", "blabla"]) def test_2(self): args = "/TLB Hello.Tlb HELLO.idl".split() opts, args = w_getopt(args, ["tlb:"]) self.assertEqual(opts, [('tlb', 'Hello.Tlb')]) self.assertEqual(args, ['HELLO.idl']) def test_3(self): # Invalid option self.assertRaises(GetoptError, w_getopt, "/TLIB hello.tlb hello.idl".split(), ["tlb:"]) def test_4(self): # Missing argument self.assertRaises(GetoptError, w_getopt, "/TLB".split(), ["tlb:"]) unittest.main() |
From: Thomas H. <th...@us...> - 2006-01-02 19:11:42
|
Update of /cvsroot/ctypes/ctypes/comtypes/client In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4721 Modified Files: Tag: branch_1_0 __init__.py Added Files: Tag: branch_1_0 dynamic.py Log Message: Sync with upstream version. --- NEW FILE: dynamic.py --- import ctypes import comtypes.automation import comtypes.client def Dispatch(obj): # Wrap an object in a Dispatch instance, exposing methods and properties # via fully dynamic dispatch if isinstance(obj, _Dispatch): return obj if isinstance(obj, ctypes.POINTER(comtypes.automation.IDispatch)): return _Dispatch(obj) return obj class _Dispatch(object): # Expose methods and properties via fully dynamic dispatch def __init__(self, comobj): self._comobj = comobj def __enum(self): e = self._comobj.Invoke(-4) return e.QueryInterface(comtypes.automation.IEnumVARIANT) def __getitem__(self, index): enum = self.__enum() if index > 0: if 0 != enum.Skip(index): raise IndexError, "index out of range" item, fetched = enum.Next(1) if not fetched: raise IndexError, "index out of range" return item def __iter__(self): return _Collection(self.__enum()) ## def __setitem__(self, index, value): ## self._comobj.Invoke(-3, index, value, ## _invkind=comtypes.automation.DISPATCH_PROPERTYPUT|comtypes.automation.DISPATCH_PROPERTYPUTREF) class _Collection(object): def __init__(self, enum): self.enum = enum def next(self): item, fetched = self.enum.Next(1) if fetched: return item raise StopIteration def __iter__(self): return self __all__ = ["Dispatch"] Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/client/Attic/__init__.py,v retrieving revision 1.1.2.10 retrieving revision 1.1.2.11 diff -C2 -d -r1.1.2.10 -r1.1.2.11 *** __init__.py 20 Oct 2005 17:16:13 -0000 1.1.2.10 --- __init__.py 2 Jan 2006 19:11:32 -0000 1.1.2.11 *************** *** 23,31 **** --- 23,34 ---- import comtypes + from comtypes.hresult import * import comtypes.automation import comtypes.connectionpoints import comtypes.typeinfo + import comtypes.client.dynamic import logging + logger = logging.getLogger(__name__) __all__ = ["CreateObject", "GetActiveObject", "CoGetObject", *************** *** 38,51 **** # Creates the directory if it doesn't exist - if possible. def _find_gen_dir(): ! if hasattr(sys, "frozen"): try: ! import comtypes.gen except ImportError: - import comtypes module = sys.modules["comtypes.gen"] = new.module("comtypes.gen") comtypes.gen = module return None # determine the place where generated modules live - import comtypes comtypes_path = os.path.join(comtypes.__path__[0], "gen") if not os.path.exists(comtypes_path): --- 41,52 ---- # Creates the directory if it doesn't exist - if possible. def _find_gen_dir(): ! if not os.path.isfile(comtypes.__file__): try: ! from comtypes import gen except ImportError: module = sys.modules["comtypes.gen"] = new.module("comtypes.gen") comtypes.gen = module return None # determine the place where generated modules live comtypes_path = os.path.join(comtypes.__path__[0], "gen") if not os.path.exists(comtypes_path): *************** *** 103,106 **** --- 104,110 ---- (libid, wMajorVerNum, wMinorVerNum, lcid=0) + + Or it can be an object with _reg_libid_ and _reg_version_ + attributes. This function determines the module name from the typelib *************** *** 134,138 **** tlib = comtypes.typeinfo.LoadTypeLibEx(tlib) elif isinstance(tlib, (tuple, list)): ! tlib = comtypes.typeinfo.LoadRegTypeLib(*tlib) # determine the Python module name fullname = _name_module(tlib) --- 138,145 ---- tlib = comtypes.typeinfo.LoadTypeLibEx(tlib) elif isinstance(tlib, (tuple, list)): ! tlib = comtypes.typeinfo.LoadRegTypeLib(comtypes.GUID(tlib[0]), *tlib[1:]) ! elif hasattr(tlib, "_reg_libid_"): ! tlib = comtypes.typeinfo.LoadRegTypeLib(comtypes.GUID(tlib._reg_libid_), ! *tlib._reg_version_) # determine the Python module name fullname = _name_module(tlib) *************** *** 223,239 **** return punk # or should we return None? # find the typelib and the interface name try: pci = punk.QueryInterface(comtypes.typeinfo.IProvideClassInfo) tinfo = pci.GetClassInfo() # TypeInfo for the CoClass # find the interface marked as default ! for index in range(tinfo.GetTypeAttr().cImplTypes): if tinfo.GetImplTypeFlags(index) == 1: break else: ! # should we simply use the first interface now? ! raise TypeError, "No default interface found" href = tinfo.GetRefTypeOfImplType(index) tinfo = tinfo.GetRefTypeInfo(href) except comtypes.COMError: try: pdisp = punk.QueryInterface(comtypes.automation.IDispatch) --- 230,254 ---- return punk # or should we return None? # find the typelib and the interface name + logger.info("wrap(%s)", punk) try: pci = punk.QueryInterface(comtypes.typeinfo.IProvideClassInfo) + logger.info("Does implement IProvideClassInfo") tinfo = pci.GetClassInfo() # TypeInfo for the CoClass # find the interface marked as default ! ta = tinfo.GetTypeAttr() ! for index in range(ta.cImplTypes): if tinfo.GetImplTypeFlags(index) == 1: break else: ! if ta.cImplTypes != 1: ! # Hm, should we use dynamic now? ! raise TypeError, "No default interface found" ! # Only one interface implemented, use that (even if ! # not marked as default). ! index = 0 href = tinfo.GetRefTypeOfImplType(index) tinfo = tinfo.GetRefTypeInfo(href) except comtypes.COMError: + logger.info("Does NOT implement IProvideClassInfo") try: pdisp = punk.QueryInterface(comtypes.automation.IDispatch) *************** *** 241,252 **** # no further chance to find typeinfo, and IDispatch is # more useful than IUnknown. ! return pdisp tinfo = pdisp.GetTypeInfo(0) except comtypes.COMError: ! return punk try: punk.QueryInterface(comtypes.IUnknown, tinfo.GetTypeAttr().guid) except comtypes.COMError: ! return punk itf_name = tinfo.GetDocumentation(-1)[0] # interface name --- 256,271 ---- # no further chance to find typeinfo, and IDispatch is # more useful than IUnknown. ! logger.info("IDispatch without typeinfo, using dynamic") ! return comtypes.client.dynamic.Dispatch(pdisp) ! logger.info("IDispatch with typeinfo") tinfo = pdisp.GetTypeInfo(0) except comtypes.COMError: ! logger.info("Without typeinfo, using dynamic") ! return comtypes.client.dynamic.Dispatch(punk) try: punk.QueryInterface(comtypes.IUnknown, tinfo.GetTypeAttr().guid) except comtypes.COMError: ! logger.info("Does not seem to implement default interface from typeinfo, using dynamic") ! return comtypes.client.dynamic.Dispatch(punk) itf_name = tinfo.GetDocumentation(-1)[0] # interface name *************** *** 257,260 **** --- 276,280 ---- # Python interface class interface = getattr(mod, itf_name) + logger.info("Implements default interface from typeinfo %s", interface) # QI for this interface # XXX *************** *** 269,273 **** # Could the above code, as an optimization, check that QI works, # *before* generating the wraper module? ! return punk.QueryInterface(interface) # Should we do this for POINTER(IUnknown) also? --- 289,295 ---- # Could the above code, as an optimization, check that QI works, # *before* generating the wraper module? ! result = punk.QueryInterface(interface) ! logger.info("Final result is %s", result) ! return result # Should we do this for POINTER(IUnknown) also? *************** *** 316,320 **** # makes sense is to use IProvideClassInfo2 to get the default # source interface. - logger = logging.getLogger("comtypes.events") if interface is None: --- 338,341 ---- *************** *** 346,350 **** dispmap[memid] = mth ! class EventReceiver(comtypes.COMObject): _com_interfaces_ = [interface] --- 367,371 ---- dispmap[memid] = mth ! class DispEventReceiver(comtypes.COMObject): _com_interfaces_ = [interface] *************** *** 357,361 **** return 0 ! rcv = EventReceiver() rcv.dispmap = dispmap else: --- 378,394 ---- return 0 ! def GetTypeInfoCount(self, this, presult): ! if not presult: ! return E_POINTER ! presult[0] = 0 ! return S_OK ! ! def GetTypeInfo(self, this, itinfo, lcid, pptinfo): ! return E_NOTIMPL ! ! def GetIDsOfNames(self, this, riid, rgszNames, cNames, lcid, rgDispId): ! return E_NOTIMPL ! ! rcv = DispEventReceiver() rcv.dispmap = dispmap else: *************** *** 371,378 **** rcv = EventReceiver() ! cpc = source.QueryInterface(comtypes.connectionpoints.IConnectionPointContainer) ! cp = cpc.FindConnectionPoint(ctypes.byref(interface._iid_)) ! logger.debug("Start advise %s", interface) ! cookie = cp.Advise(rcv) def release(ref): --- 404,419 ---- rcv = EventReceiver() ! # XXX All of these (QI, FindConnectionPoint, Advise) can also fail ! # (for buggy objects?), and we should raise an appropriate error ! # then. ! ! try: ! cpc = source.QueryInterface(comtypes.connectionpoints.IConnectionPointContainer) ! cp = cpc.FindConnectionPoint(ctypes.byref(interface._iid_)) ! logger.debug("Start advise %s", interface) ! cookie = cp.Advise(rcv) ! except: ! logger.error("Could not connect to object:", exc_info=True) ! raise def release(ref): *************** *** 458,464 **** --- 499,510 ---- """ clsid = comtypes.GUID.from_progid(progid) + logger.debug("%s -> %s", progid, clsid) if machine is None: + logger.debug("CoCreateInstance(%s, clsctx=%s, interface=%s)", + clsid, clsctx, interface) obj = comtypes.CoCreateInstance(clsid, clsctx=clsctx, interface=interface) else: + logger.debug("CoCreateInstanceEx(%s, clsctx=%s, interface=%s, machine=%s)", + clsid, clsctx, interface, machine) obj = comtypes.CoCreateInstanceEx(clsid, clsctx=clsctx, interface=interface, machine=machine) return _manage(obj, clsid, |
From: Thomas H. <th...@us...> - 2006-01-02 19:11:34
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4656 Modified Files: Tag: branch_1_0 typeinfo.py safearray.py persist.py hresult.py connectionpoints.py automation.py _comobject.py __init__.py GUID.py Added Files: Tag: branch_1_0 logutil.py git.py errorinfo.py Log Message: Sync with upstream version. --- NEW FILE: logutil.py --- # logutil.py import logging, ctypes class NTDebugHandler(logging.Handler): def emit(self, record, writeA=ctypes.windll.kernel32.OutputDebugStringA, writeW=ctypes.windll.kernel32.OutputDebugStringW): text = self.format(record) if isinstance(text, str): writeA(text + "\n") else: writeW(text + u"\n") logging.NTDebugHandler = NTDebugHandler def setup_logging(*pathnames): import ConfigParser parser = ConfigParser.ConfigParser() parser.optionxform = str # use case sensitive option names! parser.read(pathnames) DEFAULTS = {"handler": "StreamHandler()", "format": "%(levelname)s:%(name)s:%(message)s", "level": "WARNING"} def get(section, option): try: return parser.get(section, option, True) except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): return DEFAULTS[option] levelname = get("logging", "level") format = get("logging", "format") handlerclass = get("logging", "handler") # convert level name to level value level = getattr(logging, levelname) # create the handler instance handler = eval(handlerclass, vars(logging)) formatter = logging.Formatter(format) handler.setFormatter(formatter) logging.root.addHandler(handler) logging.root.setLevel(level) try: for name, value in parser.items("logging.levels", True): value = getattr(logging, value) logging.getLogger(name).setLevel(value) except ConfigParser.NoSectionError: pass Index: hresult.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/Attic/hresult.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 *** hresult.py 23 Aug 2005 19:40:24 -0000 1.1.2.1 --- hresult.py 2 Jan 2006 19:11:25 -0000 1.1.2.2 *************** *** 18,23 **** CLASS_E_CLASSNOTAVAILABLE = -2147221231 #0x80040111L - TYPE_E_ELEMENTNOTFOUND = -2147352077 #0x8002802BL - CO_E_CLASSSTRING = -2147221005 #0x800401F3L --- 18,21 ---- *************** *** 27,29 **** CONNECT_E_NOCONNECTION = -2147220992 ! # DISP_E_... constants are in comtypes.automation --- 25,50 ---- CONNECT_E_NOCONNECTION = -2147220992 ! TYPE_E_ELEMENTNOTFOUND = -2147352077 #0x8002802BL ! ! TYPE_E_REGISTRYACCESS = -2147319780 #0x8002801CL ! TYPE_E_CANTLOADLIBRARY = -2147312566 #0x80029C4AL ! ! # all the DISP_E_ values from windows.h ! DISP_E_BUFFERTOOSMALL = -2147352557 ! DISP_E_DIVBYZERO = -2147352558 ! DISP_E_NOTACOLLECTION = -2147352559 ! DISP_E_BADCALLEE = -2147352560 ! DISP_E_PARAMNOTOPTIONAL = -2147352561 ! DISP_E_BADPARAMCOUNT = -2147352562 ! DISP_E_ARRAYISLOCKED = -2147352563 ! DISP_E_UNKNOWNLCID = -2147352564 ! DISP_E_BADINDEX = -2147352565 ! DISP_E_OVERFLOW = -2147352566 ! DISP_E_EXCEPTION = -2147352567 ! DISP_E_BADVARTYPE = -2147352568 ! DISP_E_NONAMEDARGS = -2147352569 ! DISP_E_UNKNOWNNAME = -2147352570 ! DISP_E_TYPEMISMATCH = -2147352571 ! DISP_E_PARAMNOTFOUND = -2147352572 ! DISP_E_MEMBERNOTFOUND = -2147352573 ! DISP_E_UNKNOWNINTERFACE = -2147352575 Index: GUID.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/GUID.py,v retrieving revision 1.6.2.5 retrieving revision 1.6.2.6 diff -C2 -d -r1.6.2.5 -r1.6.2.6 *** GUID.py 29 Sep 2005 13:11:16 -0000 1.6.2.5 --- GUID.py 2 Jan 2006 19:11:25 -0000 1.6.2.6 *************** *** 12,18 **** _CLSIDFromString = _ole32.CLSIDFromString _CLSIDFromProgID = _ole32.CLSIDFromProgID - _IsEqualGUID = _ole32.IsEqualGUID _CoCreateGuid = _ole32.CoCreateGuid class GUID(Structure): _fields_ = [("Data1", DWORD), --- 12,20 ---- _CLSIDFromString = _ole32.CLSIDFromString _CLSIDFromProgID = _ole32.CLSIDFromProgID _CoCreateGuid = _ole32.CoCreateGuid + # Note: Comparing GUID instances by comparing their buffers + # is slightly faster than using ole32.IsEqualGUID. + class GUID(Structure): _fields_ = [("Data1", DWORD), *************** *** 25,34 **** _CLSIDFromString(unicode(name), byref(self)) - def hashcode(self): - # hashcode returns a hashable object that uniquely identifies - # the GUID. GUID instances itself are unhashable because they - # are mutable. - return unicode(self) - def __repr__(self): return u'GUID("%s")' % unicode(self) --- 27,30 ---- *************** *** 44,48 **** def __cmp__(self, other): if isinstance(other, GUID): ! return not _IsEqualGUID(byref(self), byref(other)) return -1 --- 40,44 ---- def __cmp__(self, other): if isinstance(other, GUID): ! return cmp(buffer(self), buffer(other)) return -1 *************** *** 52,59 **** def __eq__(self, other): return isinstance(other, GUID) and \ ! _IsEqualGUID(byref(self), byref(other)) ! ## def __hash__(self): ! ## return hash(repr(self)) def copy(self): --- 48,56 ---- def __eq__(self, other): return isinstance(other, GUID) and \ ! buffer(self) == buffer(other) ! def __hash__(self): ! # We make GUID instances hashable, although they are mutable. ! return hash(buffer(self)) def copy(self): Index: _comobject.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/Attic/_comobject.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 *** _comobject.py 7 Dec 2005 19:41:57 -0000 1.1.2.2 --- _comobject.py 2 Jan 2006 19:11:25 -0000 1.1.2.3 *************** *** 3,6 **** --- 3,9 ---- import logging + logger = logging.getLogger(__name__) + _debug = logger.debug + _warning = logger.warning ################################################################ *************** *** 8,14 **** from _ctypes import CopyComPointer - def _not_impl(*args): - return -2147467263 # E_NOTIMPL, 0x80004001L - def prepare_comobject(inst): # When a CoClass instance is created, COM pointers to all --- 11,14 ---- *************** *** 25,37 **** make_interface_pointer(inst, itf) def make_interface_pointer(inst, itf, ! _debug=logging.getLogger("comtypes.impl").debug): methods = [] # method implementations fields = [] # (name, prototype) for virtual function table ! iids = [] # hashcode for interface identifiers. # iterate over interface inheritance in reverse order to build the # virtual function table, and leave out the 'object' base class. for interface in itf.__mro__[-2::-1]: ! iids.append(interface._iid_.hashcode()) for m in interface._methods_: restype, mthname, argtypes, paramflags, idlflags, helptext = m --- 25,56 ---- make_interface_pointer(inst, itf) + from comtypes.errorinfo import ReportException + + def catch_errors(obj, mth, interface): + iid = interface._iid_ + clsid = getattr(obj, "_reg_clsid_", None) + def func(*args, **kw): + try: + return mth(*args, **kw) + except Exception: + _warning("%s", interface, exc_info=True) + return ReportException(E_FAIL, iid, clsid=clsid) + return func + + def _do_implement(interface_name, method_name): + def mth(*args): + _debug("unimplemented method %s_%s called", interface_name, method_name) + return E_NOTIMPL + return mth + def make_interface_pointer(inst, itf, ! _debug=_debug): methods = [] # method implementations fields = [] # (name, prototype) for virtual function table ! iids = [] # interface identifiers. # iterate over interface inheritance in reverse order to build the # virtual function table, and leave out the 'object' base class. for interface in itf.__mro__[-2::-1]: ! iids.append(interface._iid_) for m in interface._methods_: restype, mthname, argtypes, paramflags, idlflags, helptext = m *************** *** 42,48 **** if mth is None: # qualified name, like 'IUnknown_QueryInterface' ! mth = getattr(inst, "%s_%s" % (interface.__name__, mthname), _not_impl) ! if mth is _not_impl: _debug("%r: %s.%s not implemented", inst, interface.__name__, mthname) methods.append(proto(mth)) class Vtbl(Structure): --- 61,71 ---- if mth is None: # qualified name, like 'IUnknown_QueryInterface' ! mth = getattr(inst, "%s_%s" % (interface.__name__, mthname), None) ! if mth is None: ! mth = _do_implement(interface.__name__, mthname) ! # XXX Should we try harder for case-insensitive lookup of methods? _debug("%r: %s.%s not implemented", inst, interface.__name__, mthname) + else: + mth = catch_errors(inst, mth, interface) methods.append(proto(mth)) class Vtbl(Structure): *************** *** 50,55 **** Vtbl.__name__ = "Vtbl_%s" % itf.__name__ vtbl = Vtbl(*methods) ! for hashcode in iids: ! inst._com_pointers_[hashcode] = pointer(pointer(vtbl)) ################################################################ --- 73,78 ---- Vtbl.__name__ = "Vtbl_%s" % itf.__name__ vtbl = Vtbl(*methods) ! for iid in iids: ! inst._com_pointers_[iid] = pointer(pointer(vtbl)) ################################################################ *************** *** 77,82 **** # IUnknown methods implementations def IUnknown_AddRef(self, this, ! _debug=logging.getLogger("comtypes.refcount").debug): ! result = _InterlockedIncrement(byref(self._refcnt)) if result == 1: # keep reference to the object in a class variable. --- 100,106 ---- # IUnknown methods implementations def IUnknown_AddRef(self, this, ! __InterlockedIncrement=_InterlockedIncrement, ! _debug=_debug): ! result = __InterlockedIncrement(byref(self._refcnt)) if result == 1: # keep reference to the object in a class variable. *************** *** 87,102 **** def IUnknown_Release(self, this, ! InterlockedDecrement=_InterlockedDecrement, _byref=byref, ! _debug=logging.getLogger("comtypes.refcount").debug): # If this is called at COM shutdown, byref() and # _InterlockedDecrement() must still be available, although # module level variables may have been deleted already - so we # supply them as default arguments. ! result = InterlockedDecrement(_byref(self._refcnt)) _debug("%r.Release() -> %s", self, result) if result == 0: ! del COMObject._instances_[self] ! _debug("%d active COM objects: Removed %r", len(COMObject._instances_), self) if self._factory is not None: self._factory.LockServer(None, 0) --- 111,132 ---- def IUnknown_Release(self, this, ! __InterlockedDecrement=_InterlockedDecrement, _byref=byref, ! _debug=_debug): # If this is called at COM shutdown, byref() and # _InterlockedDecrement() must still be available, although # module level variables may have been deleted already - so we # supply them as default arguments. ! result = __InterlockedDecrement(_byref(self._refcnt)) _debug("%r.Release() -> %s", self, result) if result == 0: ! # For whatever reasons, at cleanup it may be that ! # COMObject is already cleaned (set to None) ! try: ! del COMObject._instances_[self] ! except AttributeError: ! _debug("? active COM objects: Removed %r", self) ! else: ! _debug("%d active COM objects: Removed %r", len(COMObject._instances_), self) if self._factory is not None: self._factory.LockServer(None, 0) *************** *** 104,110 **** def IUnknown_QueryInterface(self, this, riid, ppvObj, ! _debug=logging.getLogger("comtypes.QueryInterface").debug): iid = riid[0] ! ptr = self._com_pointers_.get(iid.hashcode(), None) if ptr is not None: # CopyComPointer(src, dst) calls AddRef! --- 134,142 ---- def IUnknown_QueryInterface(self, this, riid, ppvObj, ! _debug=_debug): ! # XXX This is probably too slow. ! # riid[0].hashcode() alone takes 33 us! iid = riid[0] ! ptr = self._com_pointers_.get(iid, None) if ptr is not None: # CopyComPointer(src, dst) calls AddRef! *************** *** 114,116 **** --- 146,155 ---- return E_NOINTERFACE + ################################################################ + # ISupportErrorInfo method implementation + def ISupportErrorInfo_InterfaceSupportsErrorInfo(self, this, riid): + if riid[0] in self._com_pointers_: + return S_OK + return S_FALSE + __all__ = ["COMObject"] Index: automation.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/automation.py,v retrieving revision 1.12.2.16 retrieving revision 1.12.2.17 diff -C2 -d -r1.12.2.16 -r1.12.2.17 *** automation.py 29 Sep 2005 12:48:17 -0000 1.12.2.16 --- automation.py 2 Jan 2006 19:11:25 -0000 1.12.2.17 *************** *** 2,6 **** from ctypes import * from _ctypes import CopyComPointer ! from comtypes import IUnknown, GUID, IID, STDMETHOD, BSTR, COMMETHOD, dispid, COMError import datetime # for VT_DATE, standard in Python 2.3 and up import array --- 2,7 ---- from ctypes import * from _ctypes import CopyComPointer ! from comtypes import IUnknown, GUID, IID, STDMETHOD, BSTR, COMMETHOD, COMError ! from comtypes.hresult import * import datetime # for VT_DATE, standard in Python 2.3 and up import array *************** *** 219,230 **** elif isinstance(value, (list, tuple)): from comtypes.safearray import SafeArray_FromSequence ! self._.c_void_p = SafeArray_FromSequence(value) self.vt = VT_ARRAY | VT_VARIANT elif isinstance(value, array.array): from comtypes.safearray import SafeArray_FromArray ! typecode, self._.c_void_p = SafeArray_FromArray(value) self.vt = VT_ARRAY | typecode else: ! raise "NYI", value # buffer -> SAFEARRAY of VT_UI1 ? --- 220,232 ---- elif isinstance(value, (list, tuple)): from comtypes.safearray import SafeArray_FromSequence ! self._.c_void_p = cast(SafeArray_FromSequence(value), c_void_p) self.vt = VT_ARRAY | VT_VARIANT elif isinstance(value, array.array): from comtypes.safearray import SafeArray_FromArray ! typecode, psa = SafeArray_FromArray(value) ! self._.c_void_p = cast(psa, c_void_p) self.vt = VT_ARRAY | typecode else: ! raise "VARIANT _set_value, NYI", value # buffer -> SAFEARRAY of VT_UI1 ? *************** *** 273,280 **** # from the __repr__ of it. return None # XXX? ! ptr = cast(val, POINTER(IUnknown)).__ctypes_from_outparam__() # cast doesn't call AddRef (it should, imo!) ptr.AddRef() ! return ptr elif vt == VT_DISPATCH: val = self._.c_void_p --- 275,282 ---- # from the __repr__ of it. return None # XXX? ! ptr = cast(val, POINTER(IUnknown)) # cast doesn't call AddRef (it should, imo!) ptr.AddRef() ! return ptr.__ctypes_from_outparam__() elif vt == VT_DISPATCH: val = self._.c_void_p *************** *** 282,289 **** # See above. return None # XXX? ! ptr = cast(val, POINTER(IDispatch)).__ctypes_from_outparam__() # cast doesn't call AddRef (it should, imo!) ptr.AddRef() ! return ptr # see also c:/sf/pywin32/com/win32com/src/oleargs.cpp elif vt == VT_BYREF|VT_VARIANT: --- 284,291 ---- # See above. return None # XXX? ! ptr = cast(val, POINTER(IDispatch)) # cast doesn't call AddRef (it should, imo!) ptr.AddRef() ! return ptr.__ctypes_from_outparam__() # see also c:/sf/pywin32/com/win32com/src/oleargs.cpp elif vt == VT_BYREF|VT_VARIANT: *************** *** 330,334 **** def __ctypes_from_outparam__(self): ! return self.value VARIANT = tagVARIANT --- 332,345 ---- def __ctypes_from_outparam__(self): ! # XXX Manual resource management, because of the VARIANT bug: ! result = self.value ! self.value = None ! return result ! ! def ChangeType(self, typecode): ! oledll.oleaut32.VariantChangeType(byref(self), ! byref(self), ! 0, ! typecode) VARIANT = tagVARIANT *************** *** 381,394 **** def next(self): ! var = VARIANT() ! fetched = self.Next(1, byref(var)) if fetched: ! result = var.value ! # XXX workaround for a bug in VARIANT.__del__ ! var.value = None ! return result raise StopIteration def __getitem__(self, index): var = VARIANT() self.Reset() --- 392,405 ---- def next(self): ! item, fetched = self.Next(1) if fetched: ! # XXX This should read 'return item[0]', since Next() ! # always returns a pointer to an array. ! # Oder wie oder was... ! return item raise StopIteration def __getitem__(self, index): + # XXX Simplify me!!! var = VARIANT() self.Reset() *************** *** 399,412 **** raise IndexError, index - from comtypes.automation import VARIANT IEnumVARIANT._methods_ = [ ! COMMETHOD([dispid(1610678272)], HRESULT, 'Next', ( ['in'], c_ulong, 'celt' ), ! ( ['in'], POINTER(VARIANT), 'rgvar' ), ( ['out'], POINTER(c_ulong), 'pceltFetched' )), ! COMMETHOD([dispid(1610678273)], HRESULT, 'Skip', ( ['in'], c_ulong, 'celt' )), ! COMMETHOD([dispid(1610678274)], HRESULT, 'Reset'), ! COMMETHOD([dispid(1610678275)], HRESULT, 'Clone', ( ['out'], POINTER(POINTER(IEnumVARIANT)), 'ppenum' )), ] --- 410,422 ---- raise IndexError, index IEnumVARIANT._methods_ = [ ! COMMETHOD([], HRESULT, 'Next', ( ['in'], c_ulong, 'celt' ), ! ( ['out'], POINTER(VARIANT), 'rgvar' ), ( ['out'], POINTER(c_ulong), 'pceltFetched' )), ! COMMETHOD([], HRESULT, 'Skip', ( ['in'], c_ulong, 'celt' )), ! COMMETHOD([], HRESULT, 'Reset'), ! COMMETHOD([], HRESULT, 'Clone', ( ['out'], POINTER(POINTER(IEnumVARIANT)), 'ppenum' )), ] *************** *** 518,533 **** argerr = c_uint() ! if _invkind == DISPATCH_METHOD: ! array = (VARIANT * len(args))() ! ! for i, a in enumerate(args[::-1]): ! array[i].value = a ! dp = DISPPARAMS() ! dp.cArgs = len(args) ! dp.cNamedArgs = 0 ! dp.rgvarg = array ! ! elif _invkind == DISPATCH_PROPERTYGET: array = (VARIANT * len(args))() --- 528,539 ---- argerr = c_uint() ! if _invkind == DISPATCH_PROPERTYPUT: # propput ! assert len(args) == 1 dp = DISPPARAMS() ! dp.cArgs = 1 ! dp.cNamedArgs = 1 ! dp.rgvarg = pointer(VARIANT(args[0])) ! dp.rgdispidNamedArgs = pointer(DISPID(DISPID_PROPERTYPUT)) ! else: array = (VARIANT * len(args))() *************** *** 539,550 **** dp.cNamedArgs = 0 dp.rgvarg = array - - elif _invkind == DISPATCH_PROPERTYPUT: # propput - assert len(args) == 1 - dp = DISPPARAMS() - dp.cArgs = 1 - dp.cNamedArgs = 1 - dp.rgvarg = pointer(VARIANT(args[0])) - dp.rgdispidNamedArgs = pointer(DISPID(DISPID_PROPERTYPUT)) try: --- 545,548 ---- *************** *** 578,600 **** # XXX Would separate methods for _METHOD, _PROPERTYGET and _PROPERTYPUT be better? - # all the DISP_E_ values from windows.h - DISP_E_BUFFERTOOSMALL = -2147352557 - DISP_E_DIVBYZERO = -2147352558 - DISP_E_NOTACOLLECTION = -2147352559 - DISP_E_BADCALLEE = -2147352560 - DISP_E_PARAMNOTOPTIONAL = -2147352561 - DISP_E_BADPARAMCOUNT = -2147352562 - DISP_E_ARRAYISLOCKED = -2147352563 - DISP_E_UNKNOWNLCID = -2147352564 - DISP_E_BADINDEX = -2147352565 - DISP_E_OVERFLOW = -2147352566 - DISP_E_EXCEPTION = -2147352567 - DISP_E_BADVARTYPE = -2147352568 - DISP_E_NONAMEDARGS = -2147352569 - DISP_E_UNKNOWNNAME = -2147352570 - DISP_E_TYPEMISMATCH = -2147352571 - DISP_E_PARAMNOTFOUND = -2147352572 - DISP_E_MEMBERNOTFOUND = -2147352573 - DISP_E_UNKNOWNINTERFACE = -2147352575 VT2CTYPE = { --- 576,579 ---- Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.25.2.36 retrieving revision 1.25.2.37 diff -C2 -d -r1.25.2.36 -r1.25.2.37 *** __init__.py 8 Nov 2005 20:42:09 -0000 1.25.2.36 --- __init__.py 2 Jan 2006 19:11:25 -0000 1.25.2.37 *************** *** 1,3 **** ! # requires ctypes 0.9.9.0 or later import new ##import warnings --- 1,3 ---- ! # requires ctypes 0.9.8 or later import new ##import warnings *************** *** 6,22 **** from ctypes import * - from ctypes import __version__ as _ctypes_version from _ctypes import COMError - __version__ = "0.1.1" - - _ctypes_required = "0.9.9.0" - - if _ctypes_version.split(".") < _ctypes_required.split("."): - raise ImportError("requires ctypes %s or later, not %s" % (_ctypes_required, _ctypes_version)) - import logging ! logger = logging.getLogger("comtypes") ! ##class IDLWarning(UserWarning): --- 6,13 ---- from ctypes import * from _ctypes import COMError import logging ! logger = logging.getLogger(__name__) ##class IDLWarning(UserWarning): *************** *** 28,31 **** --- 19,24 ---- DWORD = c_ulong + wireHWND = c_ulong + from comtypes.hresult import E_NOINTERFACE *************** *** 77,100 **** COINIT_SPEED_OVER_MEMORY = 0x8 ! _ole32.CoInitializeEx(None, getattr(sys, "coinit_flags", COINIT_APARTMENTTHREADED)) ! class _Cleaner(object): ! def __del__(self, func=_ole32.CoUninitialize): ! # Sometimes, CoUnititialize, running at Python shutdown, ! # raises an exception. We suppress this when __debug__ is ! # False. ! if __debug__: ! func() else: ! try: func() ! except WindowsError: pass ! __cleaner = _Cleaner() ! del _Cleaner ! # Make sure no COM pointers stay in exception frames at first step of ! # shutdown. ! import atexit ! atexit.register(sys.exc_clear) ################################################################ --- 70,120 ---- COINIT_SPEED_OVER_MEMORY = 0x8 ! def CoInitialize(): ! return CoInitializeEx(COINIT_APARTMENTTHREADED) ! # Yet another try at COM shutdown. ! ! # XXX Does currently not support multiple appartments, ! # because it relies on global, thread-shared data. ! def CoInitializeEx(flags=None): ! global __inited ! if __inited: ! return ! if flags is None: ! flags = getattr(sys, "coinit_flags", COINIT_APARTMENTTHREADED) ! __inited = True ! logger.debug("CoInitializeEx(None, %s)", flags) ! try: ! _ole32.CoInitializeEx(None, flags) ! except WindowsError, details: ! if details.errno != -2147417850: ! logger.debug("CoInitializeEx(): WindowsError, %s", details) ! raise else: ! logger.debug("CoInitializeEx(): RPC_CHANGED_MODE ignored") ! else: ! def shutdown(func=_ole32.CoUninitialize, ! _debug=logger.debug): ! # Make sure no COM pointers stay in exception frames. ! sys.exc_clear() ! # Sometimes, CoUnititialize, running at Python shutdown, ! # raises an exception. We suppress this when __debug__ is ! # False. ! _debug("Calling CoUnititialize()") ! if __debug__: ! func() ! else: ! try: func() ! except WindowsError: pass ! global __inited ! __inited = False ! _debug("CoUnititialize() done.") ! import atexit ! atexit.register(shutdown) ! __inited = False ! ! CoInitializeEx() ################################################################ *************** *** 165,184 **** try: # a kind of QueryInterface ! return table[str(klass._iid_)] except KeyError: raise TypeError("Interface %s not supported" % klass._iid_) return value.QueryInterface(cls) ! def __ctypes_from_outparam__(self): ! return self # The interface 'cls' is used as a mixin. p = type(_compointer_base)("POINTER(%s)" % cls.__name__, _ptr_bases, ! {"__ctypes_from_outparam__": __ctypes_from_outparam__, ! "from_param": classmethod(from_param), ! "__com_interface__": cls}) from ctypes import _pointer_type_cache _pointer_type_cache[cls] = p return cls --- 185,256 ---- try: # a kind of QueryInterface ! return table[klass._iid_] except KeyError: raise TypeError("Interface %s not supported" % klass._iid_) return value.QueryInterface(cls) ! # case insensitive attributes for COM methods and properties ! def __getattr__(self, name): ! try: ! name = self.__map_case__[name.lower()] ! except KeyError: ! raise AttributeError(name) ! else: ! return getattr(self, name) ! ! # XXX __setattr__ is pretty heavy-weight, because it is called for ! # EVERY attribute assignment. Settings a non-com attribute ! # through this function takes 8.6 usec, while without this ! # function it takes 0.7 sec - 12 times slower. Maybe there should ! # be a way to enable this method only for code that needs it ! # (i.e., generated from a typelib)? ! # ! # Maybe triggered by a special attribute __case_insensitive__ ? ! # ! # How much faster would this be if implemented in C? ! def __setattr__(self, name, value): ! object.__setattr__(self, ! self.__map_case__.get(name.lower(), name), ! value) ! ! namespace = {"from_param": classmethod(from_param), ! "__com_interface__": cls, ! "_needs_com_addref_": None} ! ! CASE_INSENSITIVE = getattr(cls, "_case_insensitive_", False) ! ! if CASE_INSENSITIVE: ! namespace["__setattr__"] = __setattr__ ! namespace["__getattr__"] = __getattr__ # The interface 'cls' is used as a mixin. p = type(_compointer_base)("POINTER(%s)" % cls.__name__, _ptr_bases, ! namespace) from ctypes import _pointer_type_cache _pointer_type_cache[cls] = p + + # XXX These changes break something, unfortunately. + # XXX Find out what! + ## # This looks more and more weird. We override the + ## # __setitem__ method of the POINTER(POINTER(interface)) type. + ## # + ## # This is so that we can implement COM methods that have to + ## # return COM pointers more easily and consistent. Instead of + ## # using CopyComPointer in the method implementation, we can + ## # simply do: + ## # + ## # def GetTypeInfo(self, this, ..., pptinfo): + ## # if not pptinfo: return E_POINTER + ## # pptinfo[0] = a_com_interface_pointer + ## # return S_OK + + ## from _ctypes import CopyComPointer + ## def ppi_setitem(self, index, value): + ## if index != 0: + ## raise IndexError("Invalid index %s, must be 0" % index) + ## CopyComPointer(value, self) + ## POINTER(p).__setitem__ = ppi_setitem + return cls *************** *** 433,438 **** def __del__(self): "Release the COM refcount we own." ! if self: # calls __nonzero__ ! self.Release() def __cmp__(self, other): --- 505,520 ---- def __del__(self): "Release the COM refcount we own." ! if self: ! # XXX comtypes now calls CoUnititialize() when the atexit ! # handlers run. OTOH, the __main__ namespace (and maybe ! # others) may still have instances of com pointers around. ! # CoUnititialize() has finalized them when it returns, so ! # these com pointers are stale. Catching the WindowsError ! # here gets rid of error messages during shutting of Python. ! try: ! self.Release() ! except WindowsError: ! if __inited: ! raise def __cmp__(self, other): *************** *** 462,488 **** def __repr__(self): ! return "<%s instance at %x>" % (self.__class__.__name__, id(self)) ! ! # case insensitive attributes for COM methods and properties ! def __getattr__(self, name): ! try: ! name = self.__map_case__[name.lower()] ! except KeyError: ! raise AttributeError(name) ! else: ! return getattr(self, name) ! ! # XXX __setattr__ is pretty heavy-weight, because it is called for ! # EVERY attribute assignment. Settings a non-com attribute ! # through this function takes 8.6 usec, while without this ! # function it takes 0.7 sec - 12 times slower. Maybe there should ! # be a way to enable this method only for code that needs it ! # (i.e., generated from a typelib)? ! # ! # Maybe triggered by a special attribute __case_insensitive__ ? ! def __setattr__(self, name, value): ! object.__setattr__(self, ! self.__map_case__.get(name.lower(), name), ! value) ################################################################ --- 544,548 ---- def __repr__(self): ! return "<%s object %x>" % (self.__class__.__name__, id(self)) ################################################################ Index: persist.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/Attic/persist.py,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -C2 -d -r1.1.2.3 -r1.1.2.4 *** persist.py 20 Oct 2005 17:13:42 -0000 1.1.2.3 --- persist.py 2 Jan 2006 19:11:25 -0000 1.1.2.4 *************** *** 1,2 **** --- 1,14 ---- + """This module defines the following interfaces: + + IErrorLog + IPersist + IPropertyBag + IPersistPropertyBag + IPropertyBag2 + IPersistPropertyBag2 + + The 'DictPropertyBag' class is a class implementing the IPropertyBag + interface, useful in client code. + """ from ctypes import * from comtypes import GUID, IUnknown, COMMETHOD, HRESULT, dispid *************** *** 4,8 **** # XXX Replace by canonical solution!!! ! POINTER_c_wchar = c_wchar_p class IErrorLog(IUnknown): --- 16,20 ---- # XXX Replace by canonical solution!!! ! WSTRING = c_wchar_p class IErrorLog(IUnknown): *************** *** 11,15 **** _methods_ = [ COMMETHOD([], HRESULT, 'AddError', ! ( ['in'], POINTER_c_wchar, 'pszPropName' ), ( ['in'], POINTER(tagEXCEPINFO), 'pExcepInfo' )), ] --- 23,27 ---- _methods_ = [ COMMETHOD([], HRESULT, 'AddError', ! ( ['in'], WSTRING, 'pszPropName' ), ( ['in'], POINTER(tagEXCEPINFO), 'pExcepInfo' )), ] *************** *** 27,36 **** _idlflags_ = [] _methods_ = [ COMMETHOD([], HRESULT, 'Read', ! ( ['in'], POINTER_c_wchar, 'pszPropName' ), ! ( ['out'], POINTER(VARIANT), 'pVar' ), ( ['in'], POINTER(IErrorLog), 'pErrorLog' )), COMMETHOD([], HRESULT, 'Write', ! ( ['in'], POINTER_c_wchar, 'pszPropName' ), ( ['in'], POINTER(VARIANT), 'pVar' )), ] --- 39,53 ---- _idlflags_ = [] _methods_ = [ + # XXX Note: According to MSDN, pVar and pErrorLog are ['in', 'out'] parameters. + # + # XXX ctypes does NOT yet accept POINTER(IErrorLog) as 'out' parameter: + # TypeError: 'out' parameter 3 must be a pointer type, not POINTER(IErrorLog) COMMETHOD([], HRESULT, 'Read', ! ( ['in'], WSTRING, 'pszPropName' ), ! ( ['in', 'out'], POINTER(VARIANT), 'pVar' ), ( ['in'], POINTER(IErrorLog), 'pErrorLog' )), + ## ( ['in', 'out'], POINTER(IErrorLog), 'pErrorLog' )), COMMETHOD([], HRESULT, 'Write', ! ( ['in'], WSTRING, 'pszPropName' ), ( ['in'], POINTER(VARIANT), 'pVar' )), ] *************** *** 67,71 **** ('cfType', CLIPFORMAT), ('dwHint', c_ulong), ! ('pstrName', POINTER_c_wchar), ('clsid', GUID), ] --- 84,88 ---- ('cfType', CLIPFORMAT), ('dwHint', c_ulong), ! ('pstrName', WSTRING), ('clsid', GUID), ] *************** *** 95,99 **** ( ['out'], POINTER(c_ulong), 'pcProperties' )), COMMETHOD([], HRESULT, 'LoadObject', ! ( ['in'], POINTER_c_wchar, 'pstrName' ), ( ['in'], c_ulong, 'dwHint' ), ( ['in'], POINTER(IUnknown), 'punkObject' ), --- 112,116 ---- ( ['out'], POINTER(c_ulong), 'pcProperties' )), COMMETHOD([], HRESULT, 'LoadObject', ! ( ['in'], WSTRING, 'pstrName' ), ( ['in'], c_ulong, 'dwHint' ), ( ['in'], POINTER(IUnknown), 'punkObject' ), *************** *** 116,117 **** --- 133,169 ---- ] + + from comtypes import COMObject + from comtypes.hresult import * + class DictPropertyBag(COMObject): + """An object implementing the IProperty interface on a dictionary. + + Pass named values in the constructor for the client to Read(), or + retrieve from the .values instance variable after the client has + called Load(). + """ + _com_interfaces_ = [IPropertyBag] + + def __init__(self, **kw): + super(DictPropertyBag, self).__init__() + self.values = kw + + def Read(self, this, name, pVar, errorlog): + try: + val = self.values[name] + except KeyError: + return E_INVALIDARG + # The caller did provide info about the type that is expected + # with the pVar[0].vt typecode, except when this is VT_EMPTY. + var = pVar[0] + typecode = var.vt + var.value = val + if typecode: + var.ChangeType(typecode) + return S_OK + + def Write(self, this, name, var): + val = var[0].value + self.values[name] = val + return S_OK + --- NEW FILE: git.py --- """comtypes.git - access the process wide global interface table The global interface table provides a way to marshal interface pointers between different threading appartments. """ from ctypes import * from comtypes import IUnknown, STDMETHOD, COMMETHOD, \ GUID, HRESULT, CoCreateInstance, CLSCTX_INPROC_SERVER DWORD = c_ulong class IGlobalInterfaceTable(IUnknown): _iid_ = GUID("{00000146-0000-0000-C000-000000000046}") _methods_ = [ STDMETHOD(HRESULT, "RegisterInterfaceInGlobal", [POINTER(IUnknown), POINTER(GUID), POINTER(DWORD)]), STDMETHOD(HRESULT, "RevokeInterfaceFromGlobal", [DWORD]), STDMETHOD(HRESULT, "GetInterfaceFromGlobal", [DWORD, POINTER(GUID), POINTER(POINTER(IUnknown))]), ] def RegisterInterfaceInGlobal(self, obj): cookie = DWORD() self.__com_RegisterInterfaceInGlobal(obj, obj._iid_, cookie) return cookie.value def GetInterfaceFromGlobal(self, cookie, interface=IUnknown): ptr = POINTER(interface)() self.__com_GetInterfaceFromGlobal(cookie, interface._iid_, ptr) return ptr def RevokeInterfaceFromGlobal(self, cookie): self.__com_RevokeInterfaceFromGlobal(cookie) # It was a pain to get this CLSID: it's neither in the registry, nor # in any header files. I had to compile a C program, and find it out # with the debugger. Apparently it is in uuid.lib. CLSID_StdGlobalInterfaceTable = GUID("{00000323-0000-0000-C000-000000000046}") git = CoCreateInstance(CLSID_StdGlobalInterfaceTable, interface=IGlobalInterfaceTable, clsctx=CLSCTX_INPROC_SERVER) RevokeInterfaceFromGlobal = git.RevokeInterfaceFromGlobal RegisterInterfaceInGlobal = git.RegisterInterfaceInGlobal GetInterfaceFromGlobal = git.GetInterfaceFromGlobal __all__ = ["RegisterInterfaceInGlobal", "RevokeInterfaceFromGlobal", "GetInterfaceFromGlobal"] if __name__ == "__main__": from comtypes.typeinfo import CreateTypeLib, ICreateTypeLib tlib = CreateTypeLib("foo.bar") # we don not save it later assert (tlib.AddRef(), tlib.Release()) == (2, 1) cookie = RegisterInterfaceInGlobal(tlib) assert (tlib.AddRef(), tlib.Release()) == (3, 2) GetInterfaceFromGlobal(cookie, ICreateTypeLib) GetInterfaceFromGlobal(cookie, ICreateTypeLib) GetInterfaceFromGlobal(cookie) assert (tlib.AddRef(), tlib.Release()) == (3, 2) RevokeInterfaceFromGlobal(cookie) assert (tlib.AddRef(), tlib.Release()) == (2, 1) Index: safearray.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/Attic/safearray.py,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -C2 -d -r1.1.2.4 -r1.1.2.5 *** safearray.py 18 Aug 2005 14:42:04 -0000 1.1.2.4 --- safearray.py 2 Jan 2006 19:11:25 -0000 1.1.2.5 *************** *** 44,52 **** # BTW: A C program has the same behaviour. def SafeArray_FromSequence(seq): """Create a one dimensional safearray of type VT_VARIANT from a sequence of Python objects """ ! psa = oledll.oleaut32.SafeArrayCreateVectorEx(VT_VARIANT, 0, len(seq), None) for index, elem in enumerate(seq): oledll.oleaut32.SafeArrayPutElement(psa, byref(c_long(index)), byref(VARIANT(elem))) --- 44,54 ---- # BTW: A C program has the same behaviour. + windll.oleaut32.SafeArrayCreateVectorEx.restype = POINTER(SAFEARRAY) + def SafeArray_FromSequence(seq): """Create a one dimensional safearray of type VT_VARIANT from a sequence of Python objects """ ! psa = windll.oleaut32.SafeArrayCreateVectorEx(VT_VARIANT, 0, len(seq), None) for index, elem in enumerate(seq): oledll.oleaut32.SafeArrayPutElement(psa, byref(c_long(index)), byref(VARIANT(elem))) Index: typeinfo.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/typeinfo.py,v retrieving revision 1.3.2.9 retrieving revision 1.3.2.10 diff -C2 -d -r1.3.2.9 -r1.3.2.10 *** typeinfo.py 19 Aug 2005 18:51:26 -0000 1.3.2.9 --- typeinfo.py 2 Jan 2006 19:11:25 -0000 1.3.2.10 *************** *** 376,380 **** "Load a registered type library" tlib = POINTER(ITypeLib)() ! LoadRegTypeLib._api_(byref(guid), wVerMajor, wVerMinor, lcid, byref(tlib)) return tlib LoadRegTypeLib = stdcall(HRESULT, 'oleaut32', --- 376,380 ---- "Load a registered type library" tlib = POINTER(ITypeLib)() ! LoadRegTypeLib._api_(byref(GUID(guid)), wVerMajor, wVerMinor, lcid, byref(tlib)) return tlib LoadRegTypeLib = stdcall(HRESULT, 'oleaut32', *************** *** 397,401 **** def UnRegisterTypeLib(libID, wVerMajor, wVerMinor, lcid=0, syskind=SYS_WIN32): "Unregister a registered type library" ! return UnRegisterTypeLib._api_(byref(libID), wVerMajor, wVerMinor, lcid, syskind) UnRegisterTypeLib = stdcall(HRESULT, 'oleaut32', [POINTER(GUID), c_ushort, c_ushort, c_ulong, tagSYSKIND]) (UnRegisterTypeLib) --- 397,401 ---- def UnRegisterTypeLib(libID, wVerMajor, wVerMinor, lcid=0, syskind=SYS_WIN32): "Unregister a registered type library" ! return UnRegisterTypeLib._api_(byref(GUID(libID)), wVerMajor, wVerMinor, lcid, syskind) UnRegisterTypeLib = stdcall(HRESULT, 'oleaut32', [POINTER(GUID), c_ushort, c_ushort, c_ulong, tagSYSKIND]) (UnRegisterTypeLib) *************** *** 418,422 **** "Return the path of a registered type library" pathname = BSTR() ! QueryPathOfRegTypeLib._api_(byref(libid), wVerMajor, wVerMinor, lcid, byref(pathname)) return pathname.value QueryPathOfRegTypeLib = stdcall(HRESULT, 'oleaut32', --- 418,422 ---- "Return the path of a registered type library" pathname = BSTR() ! QueryPathOfRegTypeLib._api_(byref(GUID(libid)), wVerMajor, wVerMinor, lcid, byref(pathname)) return pathname.value QueryPathOfRegTypeLib = stdcall(HRESULT, 'oleaut32', Index: connectionpoints.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/Attic/connectionpoints.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 *** connectionpoints.py 18 Aug 2005 14:42:04 -0000 1.1.2.2 --- connectionpoints.py 2 Jan 2006 19:11:25 -0000 1.1.2.3 *************** *** 49,55 **** IConnectionPointContainer._methods_ = [ ! COMMETHOD([dispid(1610678272)], HRESULT, 'EnumConnectionPoints', ( ['out'], POINTER(POINTER(IEnumConnectionPoints)), 'ppEnum' )), ! COMMETHOD([dispid(1610678273)], HRESULT, 'FindConnectionPoint', ( ['in'], POINTER(_GUID), 'riid' ), ( ['out'], POINTER(POINTER(IConnectionPoint)), 'ppCP' )), --- 49,55 ---- IConnectionPointContainer._methods_ = [ ! COMMETHOD([], HRESULT, 'EnumConnectionPoints', ( ['out'], POINTER(POINTER(IEnumConnectionPoints)), 'ppEnum' )), ! COMMETHOD([], HRESULT, 'FindConnectionPoint', ( ['in'], POINTER(_GUID), 'riid' ), ( ['out'], POINTER(POINTER(IConnectionPoint)), 'ppCP' )), *************** *** 57,94 **** IConnectionPoint._methods_ = [ ! COMMETHOD([dispid(1610678272)], HRESULT, 'GetConnectionInterface', ( ['out'], POINTER(_GUID), 'pIID' )), ! COMMETHOD([dispid(1610678273)], HRESULT, 'GetConnectionPointContainer', ( ['out'], POINTER(POINTER(IConnectionPointContainer)), 'ppCPC' )), ! COMMETHOD([dispid(1610678274)], HRESULT, 'Advise', ( ['in'], POINTER(IUnknown), 'pUnkSink' ), ( ['out'], POINTER(c_ulong), 'pdwCookie' )), ! COMMETHOD([dispid(1610678275)], HRESULT, 'Unadvise', ( ['in'], c_ulong, 'dwCookie' )), ! COMMETHOD([dispid(1610678276)], HRESULT, 'EnumConnections', ( ['out'], POINTER(POINTER(IEnumConnections)), 'ppEnum' )), ] IEnumConnections._methods_ = [ ! COMMETHOD([dispid(1610678272)], HRESULT, 'Next', ( ['in'], c_ulong, 'cConnections' ), ( ['out'], POINTER(tagCONNECTDATA), 'rgcd' ), ( ['out'], POINTER(c_ulong), 'pcFetched' )), ! COMMETHOD([dispid(1610678273)], HRESULT, 'Skip', ( ['in'], c_ulong, 'cConnections' )), ! COMMETHOD([dispid(1610678274)], HRESULT, 'Reset'), ! COMMETHOD([dispid(1610678275)], HRESULT, 'Clone', ( ['out'], POINTER(POINTER(IEnumConnections)), 'ppEnum' )), ] IEnumConnectionPoints._methods_ = [ ! COMMETHOD([dispid(1610678272)], HRESULT, 'Next', ( ['in'], c_ulong, 'cConnections' ), ( ['out'], POINTER(POINTER(IConnectionPoint)), 'ppCP' ), ( ['out'], POINTER(c_ulong), 'pcFetched' )), ! COMMETHOD([dispid(1610678273)], HRESULT, 'Skip', ( ['in'], c_ulong, 'cConnections' )), ! COMMETHOD([dispid(1610678274)], HRESULT, 'Reset'), ! COMMETHOD([dispid(1610678275)], HRESULT, 'Clone', ( ['out'], POINTER(POINTER(IEnumConnectionPoints)), 'ppEnum' )), ] --- 57,94 ---- IConnectionPoint._methods_ = [ ! COMMETHOD([], HRESULT, 'GetConnectionInterface', ( ['out'], POINTER(_GUID), 'pIID' )), ! COMMETHOD([], HRESULT, 'GetConnectionPointContainer', ( ['out'], POINTER(POINTER(IConnectionPointContainer)), 'ppCPC' )), ! COMMETHOD([], HRESULT, 'Advise', ( ['in'], POINTER(IUnknown), 'pUnkSink' ), ( ['out'], POINTER(c_ulong), 'pdwCookie' )), ! COMMETHOD([], HRESULT, 'Unadvise', ( ['in'], c_ulong, 'dwCookie' )), ! COMMETHOD([], HRESULT, 'EnumConnections', ( ['out'], POINTER(POINTER(IEnumConnections)), 'ppEnum' )), ] IEnumConnections._methods_ = [ ! COMMETHOD([], HRESULT, 'Next', ( ['in'], c_ulong, 'cConnections' ), ( ['out'], POINTER(tagCONNECTDATA), 'rgcd' ), ( ['out'], POINTER(c_ulong), 'pcFetched' )), ! COMMETHOD([], HRESULT, 'Skip', ( ['in'], c_ulong, 'cConnections' )), ! COMMETHOD([], HRESULT, 'Reset'), ! COMMETHOD([], HRESULT, 'Clone', ( ['out'], POINTER(POINTER(IEnumConnections)), 'ppEnum' )), ] IEnumConnectionPoints._methods_ = [ ! COMMETHOD([], HRESULT, 'Next', ( ['in'], c_ulong, 'cConnections' ), ( ['out'], POINTER(POINTER(IConnectionPoint)), 'ppCP' ), ( ['out'], POINTER(c_ulong), 'pcFetched' )), ! COMMETHOD([], HRESULT, 'Skip', ( ['in'], c_ulong, 'cConnections' )), ! COMMETHOD([], HRESULT, 'Reset'), ! COMMETHOD([], HRESULT, 'Clone', ( ['out'], POINTER(POINTER(IEnumConnectionPoints)), 'ppEnum' )), ] --- NEW FILE: errorinfo.py --- import sys from ctypes import * from comtypes import IUnknown, HRESULT, COMMETHOD, GUID, BSTR from comtypes.hresult import * LPCOLESTR = c_wchar_p DWORD = c_ulong class ICreateErrorInfo(IUnknown): _iid_ = GUID("{22F03340-547D-101B-8E65-08002B2BD119}") _methods_ = [ COMMETHOD([], HRESULT, 'SetGUID', (['in'], POINTER(GUID), "rguid")), COMMETHOD([], HRESULT, 'SetSource', (['in'], LPCOLESTR, "szSource")), COMMETHOD([], HRESULT, 'SetDescription', (['in'], LPCOLESTR, "szDescription")), COMMETHOD([], HRESULT, 'SetHelpFile', (['in'], LPCOLESTR, "szHelpFile")), COMMETHOD([], HRESULT, 'SetHelpContext', (['in'], DWORD, "dwHelpContext")) ] class IErrorInfo(IUnknown): _iid_ = GUID("{1CF2B120-547D-101B-8E65-08002B2BD119}") _methods_ = [ COMMETHOD([], HRESULT, 'GetGUID', (['out'], POINTER(GUID), "pGUID")), COMMETHOD([], HRESULT, 'GetSource', (['out'], POINTER(BSTR), "pBstrSource")), COMMETHOD([], HRESULT, 'GetDescription', (['out'], POINTER(BSTR), "pBstrDescription")), COMMETHOD([], HRESULT, 'GetHelpFile', (['out'], POINTER(BSTR), "pBstrHelpFile")), COMMETHOD([], HRESULT, 'GetHelpContext', (['out'], POINTER(DWORD), "pdwHelpContext")), ] class ISupportErrorInfo(IUnknown): _iid_ = GUID("{DF0B3D60-548F-101B-8E65-08002B2BD119}") _methods_ = [ COMMETHOD([], HRESULT, 'InterfaceSupportsErrorInfo', (['in'], POINTER(GUID), 'riid')) ] ################################################################ _oleaut32 = oledll.oleaut32 def CreateErrorInfo(): cei = POINTER(ICreateErrorInfo)() _oleaut32.CreateErrorInfo(byref(cei)) return cei def GetErrorInfo(): """Get the error information for the current thread.""" errinfo = POINTER(IErrorInfo)() if S_OK == _oleaut32.GetErrorInfo(0, byref(errinfo)): return errinfo return None def SetErrorInfo(errinfo): """Set error information for the current thread.""" return _oleaut32.SetErrorInfo(0, errinfo) def ReportError(text, iid, clsid=None, helpfile=None, helpcontext=0, hresult=DISP_E_EXCEPTION): """Report a COM error. Returns the passed in hresult value.""" ei = CreateErrorInfo() ei.SetDescription(text) ei.SetGUID(iid) if helpfile is not None: ei.SetHelpFile(helpfile) if helpcontext is not None: ei.SetHelpContext(helpcontext) if clsid is not None: if isinstance(clsid, basestring): clsid = GUID(clsid) try: progid = clsid.as_progid() except WindowsError: pass else: ei.SetSource(progid) # progid for the class or application that created the error _oleaut32.SetErrorInfo(0, ei) return hresult def ReportException(hresult, iid, clsid=None, helpfile=None, helpcontext=None): """Report a COM exception. Returns the passed in hresult value.""" text = u"%s: %s" % sys.exc_info()[:2] return ReportError(text, iid, clsid=clsid, helpfile=helpfile, helpcontext=helpcontext) __all__ = ["ICreateErrorInfo", "IErrorInfo", "ISupportErrorInfo", "ReportError", "ReportException", "SetErrorInfo", "GetErrorInfo", "CreateErrorInfo"] |
From: Thomas H. <th...@us...> - 2006-01-02 19:08:28
|
Update of /cvsroot/ctypes/ctypes/comtypes/server In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2771/server Log Message: Directory /cvsroot/ctypes/ctypes/comtypes/server added to the repository --> Using per-directory sticky tag `branch_1_0' |
From: Thomas H. <th...@us...> - 2006-01-02 19:07:59
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2672 Modified Files: Tag: branch_1_0 setup.py Log Message: Removed ctypes.com package. Index: setup.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/setup.py,v retrieving revision 1.122.2.9 retrieving revision 1.122.2.10 diff -C2 -d -r1.122.2.9 -r1.122.2.10 *** setup.py 30 Nov 2005 09:36:01 -0000 1.122.2.9 --- setup.py 2 Jan 2006 19:07:50 -0000 1.122.2.10 *************** *** 44,48 **** # Original version of this class posted # by Berthold Hoellmann to dis...@py... ! description = "run unittests each in a separate process" user_options = [ --- 44,48 ---- # Original version of this class posted # by Berthold Hoellmann to dis...@py... ! description = "run tests" user_options = [ *************** *** 59,68 **** def initialize_options(self): self.build_base = 'build' - ## self.test_prefix = 'test_' self.use_resources = "" ! self.refcounts = 0 if sys.platform == "win32": ! self.tests = "ctypes.test,ctypes.com.test,comtypes.test" ! ## self.tests = "ctypes.test,ctypes.com.test" else: self.tests = "ctypes.test" --- 59,66 ---- def initialize_options(self): self.build_base = 'build' self.use_resources = "" ! self.refcounts = False if sys.platform == "win32": ! self.tests = "ctypes.test,comtypes.test" else: self.tests = "ctypes.test" *************** *** 272,289 **** ################################################################ ! # the ctypes.com package ! # ! if sys.platform == "win32": ! packages.append("ctypes.com") ! package_dir["ctypes.com"] = "win32/com" ! ! packages.append("ctypes.com.tools") ! package_dir["ctypes.com.tools"] = "win32/com/tools" ! ! packages.append("ctypes.com.test") ! package_dir["ctypes.com.test"] = "win32/com/test" ! ! ################################################################ ! # options for distutils, and ctypes.com samples # setup_options = {} --- 270,274 ---- ################################################################ ! # options for distutils # setup_options = {} *************** *** 296,323 **** setup_options["sdist"] = {"template": "MANIFEST.windows.in", "force_manifest": 1} - - import glob - data_files = [("ctypes/com/samples", - glob.glob("win32/com/samples/*.py") + - glob.glob("win32/com/samples/*.txt")), - - ("ctypes/com/samples/server", - glob.glob("win32/com/samples/server/*.py") + - glob.glob("win32/com/samples/server/*.txt")), - - ("ctypes/com/samples/server/control", - glob.glob("win32/com/samples/server/control/*.py") + - glob.glob("win32/com/samples/server/control/*.txt") + - glob.glob("win32/com/samples/server/control/*.html")), - - ("ctypes/com/samples/server/IExplorer", - glob.glob("win32/com/samples/server/IExplorer/*.py") + - glob.glob("win32/com/samples/server/IExplorer/*.txt") + - glob.glob("win32/com/samples/server/IExplorer/*.html")), - ] - else: setup_options["sdist"] = {"template": "MANIFEST.other.in", "force_manifest": 1} ! data_files = [] ################################################################ --- 281,287 ---- setup_options["sdist"] = {"template": "MANIFEST.windows.in", "force_manifest": 1} else: setup_options["sdist"] = {"template": "MANIFEST.other.in", "force_manifest": 1} ! data_files = [] ################################################################ |
From: Thomas H. <th...@us...> - 2006-01-02 19:03:13
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1328 Modified Files: Tag: branch_1_0 ctypes.h callproc.c callbacks.c _ctypes.c Log Message: Subtypes of simple types (the c_int and c_char variations, c_void_p, c_char_p and c_wchar_p) behave different now. XXX More explanations needed. Index: ctypes.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v retrieving revision 1.74.2.7 retrieving revision 1.74.2.8 diff -C2 -d -r1.74.2.7 -r1.74.2.8 *** ctypes.h 29 Nov 2005 20:15:17 -0000 1.74.2.7 --- ctypes.h 2 Jan 2006 19:02:52 -0000 1.74.2.8 *************** *** 377,380 **** --- 377,384 ---- extern PyObject *CData_FromBaseObj(PyObject *type, PyObject *base, int index, char *adr); + /* XXX better name needed! */ + extern int IsSimpleSubType(PyObject *obj); + + #ifdef MS_WIN32 extern PyObject *ComError; Index: callbacks.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callbacks.c,v retrieving revision 1.71.2.7 retrieving revision 1.71.2.8 diff -C2 -d -r1.71.2.7 -r1.71.2.8 *** callbacks.c 30 Dec 2005 17:22:49 -0000 1.71.2.7 --- callbacks.c 2 Jan 2006 19:02:52 -0000 1.71.2.8 *************** *** 151,155 **** } ! if (dict && dict->getfunc) { PyObject *v = dict->getfunc(*pArgs, dict->size); if (!v) { --- 151,155 ---- } ! if (dict && dict->getfunc && !IsSimpleSubType(cnv)) { PyObject *v = dict->getfunc(*pArgs, dict->size); if (!v) { Index: callproc.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callproc.c,v retrieving revision 1.127.2.16 retrieving revision 1.127.2.17 diff -C2 -d -r1.127.2.16 -r1.127.2.17 *** callproc.c 30 Dec 2005 17:22:49 -0000 1.127.2.16 --- callproc.c 2 Jan 2006 19:02:52 -0000 1.127.2.17 *************** *** 24,30 **** COM method, are 'paramflags' available). ! 3. If [out] parameters are present in paramflags, _build_callargs also ! creates and returns another object, which is either a single object or a ! tuple, whcih will later be used to build the function return value. 4. _CallProc is then called with the 'callargs' tuple. _CallProc first --- 24,30 ---- COM method, are 'paramflags' available). ! 3. _build_callargs also calculates bitarrays containing indexes into ! the callargs tuple, specifying how to build the return value(s) of ! the function. 4. _CallProc is then called with the 'callargs' tuple. _CallProc first *************** *** 716,720 **** return PyObject_CallFunction(restype, "i", *(int *)result); ! if (dict->getfunc) retval = dict->getfunc(result, dict->size); else --- 716,720 ---- return PyObject_CallFunction(restype, "i", *(int *)result); ! if (dict->getfunc && !IsSimpleSubType(restype)) retval = dict->getfunc(result, dict->size); else *************** *** 807,813 **** progid = NULL; - #ifndef _WIN32_WCE ProgIDFromCLSID(&guid, &progid); - #endif /* XXX Is COMError derived from WindowsError or not? */ --- 807,811 ---- *************** *** 1028,1032 **** name = PyString_AsString(nameobj); if(!name) ! return NULL; #endif --- 1026,1030 ---- name = PyString_AsString(nameobj); if(!name) ! return NULL; #endif *************** *** 1387,1391 **** static char set_conversion_mode_doc[] = ! "set_conversion_mode(encoding, errors) -> (previous-encoding, previous-errors)\n\ \n\ Set the encoding and error handling ctypes uses when converting\n\ --- 1385,1389 ---- static char set_conversion_mode_doc[] = ! "FormatError(encoding, errors) -> (previous-encoding, previous-errors)\n\ \n\ Set the encoding and error handling ctypes uses when converting\n\ Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.226.2.40 retrieving revision 1.226.2.41 diff -C2 -d -r1.226.2.40 -r1.226.2.41 *** _ctypes.c 2 Jan 2006 15:06:40 -0000 1.226.2.40 --- _ctypes.c 2 Jan 2006 19:02:52 -0000 1.226.2.41 *************** *** 2024,2042 **** } PyObject * CData_get(PyObject *type, GETFUNC getfunc, PyObject *src, int index, int size, char *adr) { if (getfunc) return getfunc(adr, size); ! if (type) { ! StgDictObject *dict; ! dict = PyType_stgdict(type); ! if (dict && dict->getfunc) ! return dict->getfunc(adr, size); ! return CData_FromBaseObj(type, src, index, adr); ! } ! assert (getfunc); ! return getfunc(adr, size); } --- 2024,2053 ---- } + /* + This function returns TRUE for c_int, c_void_p, and these kind of + classes. FALSE otherwise FALSE also for subclasses of c_int and + such. + */ + int IsSimpleSubType(PyObject *obj) + { + PyTypeObject *type = (PyTypeObject *)obj; + + if (SimpleTypeObject_Check(type)) + return type->tp_base != &Simple_Type; + return 0; + } + PyObject * CData_get(PyObject *type, GETFUNC getfunc, PyObject *src, int index, int size, char *adr) { + StgDictObject *dict; if (getfunc) return getfunc(adr, size); ! assert(type); ! dict = PyType_stgdict(type); ! if (dict && dict->getfunc && !IsSimpleSubType(type)) ! return dict->getfunc(adr, size); ! return CData_FromBaseObj(type, src, index, adr); } *************** *** 2369,2400 **** #endif ! /* Return 1 if usable, 0 else. */ static int _check_outarg_type(PyObject *arg, int index) { - #if 0 StgDictObject *dict; - #endif if (PointerTypeObject_Check(arg)) return 1; ! #if 0 ! /* This is also disabled, because _build_callargs does not handle ! these correctly. */ if (ArrayTypeObject_Check(arg)) return 1; ! #endif ! #if 0 ! /* This is also disabled, because _build_callargs does not handle ! these correctly. */ dict = PyType_stgdict(arg); ! if (dict) { ! if (PyString_Check(dict->proto) ! && (strchr("sPzUZXO", PyString_AS_STRING(dict->proto)[0]))) { ! /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */ ! return 1; ! } } ! #endif PyErr_Format(PyExc_TypeError, "'out' parameter %d must be a pointer type, not %s", --- 2380,2404 ---- #endif ! /* Return 1 if usable, 0 else and exception set. */ static int _check_outarg_type(PyObject *arg, int index) { StgDictObject *dict; if (PointerTypeObject_Check(arg)) return 1; ! if (ArrayTypeObject_Check(arg)) return 1; ! dict = PyType_stgdict(arg); ! if (dict ! /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */ ! && PyString_Check(dict->proto) ! /* We only allow c_void_p, c_char_p and c_wchar_p as a simple output parameter type */ ! && (strchr("PzZ", PyString_AS_STRING(dict->proto)[0]))) { ! return 1; } ! PyErr_Format(PyExc_TypeError, "'out' parameter %d must be a pointer type, not %s", *************** *** 2446,2452 **** case PARAMFLAG_FIN: case PARAMFLAG_FIN | PARAMFLAG_FLCID: break; case PARAMFLAG_FOUT: - case (PARAMFLAG_FIN | PARAMFLAG_FOUT): if (!_check_outarg_type(typ, i+1)) return 0; --- 2450,2456 ---- case PARAMFLAG_FIN: case PARAMFLAG_FIN | PARAMFLAG_FLCID: + case PARAMFLAG_FIN | PARAMFLAG_FOUT: break; case PARAMFLAG_FOUT: if (!_check_outarg_type(typ, i+1)) return 0; *************** *** 2743,2758 **** missing in the function call. ! Note: keyword args not yet implemented! ! ! This function builds a new tuple 'callargs' which contains the parameters to ! use in the call. Items on this tuple are copied from the 'inargs' tuple for ! 'in' parameters, and constructed from the 'argtypes' tuple for 'out' ! parameters. ! */ static PyObject * _build_callargs(CFuncPtrObject *self, PyObject *argtypes, PyObject *inargs, PyObject *kwds, ! PyObject **poutargs) { PyObject *paramflags = self->paramflags; --- 2747,2763 ---- missing in the function call. ! This function builds and returns a new tuple 'callargs' which contains the ! parameters to use in the call. Items on this tuple are copied from the ! 'inargs' tuple for 'in' and 'in, out' parameters, and constructed from the ! 'argtypes' tuple for 'out' parameters. It also calculates numretvals which ! is the number of return values for the function, outmask/inoutmask are ! bitmasks containing indexes into the callargs tuple specifying which ! parameters have to be returned. _build_result builds the return value of the ! function. */ static PyObject * _build_callargs(CFuncPtrObject *self, PyObject *argtypes, PyObject *inargs, PyObject *kwds, ! int *poutmask, int *pinoutmask, int *pnumretvals) { PyObject *paramflags = self->paramflags; *************** *** 2761,2765 **** int i, len; int inargs_index = 0; - int outmask = 0; /* It's a little bit difficult to determine how many arguments the function call requires/accepts. For simplicity, we count the consumed --- 2766,2769 ---- *************** *** 2767,2771 **** int actual_args; ! *poutargs = NULL; /* Trivial cases, where we either return inargs itself, or a slice of it. */ if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) { --- 2771,2778 ---- int actual_args; ! *poutmask = 0; ! *pinoutmask = 0; ! *pnumretvals = 0; ! /* Trivial cases, where we either return inargs itself, or a slice of it. */ if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) { *************** *** 2791,2811 **** for (i = 0; i < len; ++i) { PyObject *item = PyTuple_GET_ITEM(paramflags, i); ! PyObject *ob, *v; int flag; char *name = NULL; PyObject *defval = NULL; ! if (!PyArg_ParseTuple(item, "i|zO", &flag, &name, &defval)) { ! /* Hm. Either we should raise a more specific error ! here, or we should validate the paramflags tuple ! when it is set */ ! _AddTraceback("_build_callargs", __FILE__, __LINE__-4); ! goto error; ! } switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) { case PARAMFLAG_FIN | PARAMFLAG_FLCID: ! /* ['in', 'lcid'] parameeter. Always taken from defval */ Py_INCREF(defval); PyTuple_SET_ITEM(callargs, i, defval); break; case 0: case PARAMFLAG_FIN: --- 2798,2824 ---- for (i = 0; i < len; ++i) { PyObject *item = PyTuple_GET_ITEM(paramflags, i); ! PyObject *ob; int flag; char *name = NULL; PyObject *defval = NULL; ! ! /* This way seems to be ~2 us faster than the PyArg_ParseTuple ! calls below. */ ! /* We HAVE already checked that the tuple can be parsed with "i|zO", so... */ ! int tsize = PyTuple_GET_SIZE(item); ! flag = PyInt_AS_LONG(PyTuple_GET_ITEM(item, 0)); ! name = tsize > 1 ? PyString_AS_STRING(PyTuple_GET_ITEM(item, 1)) : NULL; ! defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL; ! switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) { case PARAMFLAG_FIN | PARAMFLAG_FLCID: ! /* ['in', 'lcid'] parameter. Always taken from defval */ Py_INCREF(defval); PyTuple_SET_ITEM(callargs, i, defval); break; + case (PARAMFLAG_FIN | PARAMFLAG_FOUT): + *pinoutmask |= (1 << i); /* mark as inout arg */ + (*pnumretvals)++; + /* fall through to PARAMFLAG_FIN... */ case 0: case PARAMFLAG_FIN: *************** *** 2817,2833 **** break; case PARAMFLAG_FOUT: /* 'out' parameter. argtypes[i] must be a POINTER to a c type. */ ob = PyTuple_GET_ITEM(argtypes, i); dict = PyType_stgdict(ob); ! /* Create an instance of the pointed-to type */ ! ob = PyObject_CallObject(dict->proto, NULL); ! /* XXX The above only works as intended for POINTER ! types. For ARRAY types, we should create an ! intance of the type itself, not of the itemtype. ! ! But that is not enough: ! We must not pass a byref() to the array then but the array instance itself. Then, we cannot retrive --- 2830,2866 ---- break; case PARAMFLAG_FOUT: + /* XXX Refactor this code into a separate function. */ /* 'out' parameter. argtypes[i] must be a POINTER to a c type. + + Cannot by supplied in inargs, but a defval will be used + if available. XXX Should we support getting it from kwds? */ + if (defval) { + /* XXX Using mutable objects as defval will + make the function non-threadsafe, unless we + copy the object in each invocation */ + Py_INCREF(defval); + PyTuple_SET_ITEM(callargs, i, defval); + *poutmask |= (1 << i); /* mark as out arg */ + (*pnumretvals)++; + break; + } ob = PyTuple_GET_ITEM(argtypes, i); dict = PyType_stgdict(ob); ! if (PyString_Check(dict->proto)) { ! PyErr_Format( ! PyExc_TypeError, ! "%s 'out' parameter must be passed as default value", ! ((PyTypeObject *)ob)->tp_name); ! goto error; ! } ! if (ArrayTypeObject_Check(ob)) ! ob = PyObject_CallObject(ob, NULL); ! else ! /* Create an instance of the pointed-to type */ ! ob = PyObject_CallObject(dict->proto, NULL); ! /* ! XXX Is the following correct any longer? We must not pass a byref() to the array then but the array instance itself. Then, we cannot retrive *************** *** 2836,2872 **** if (ob == NULL) goto error; ! /* Insert as byref parameter */ ! ob = _byref(ob); ! if (ob == NULL) ! goto error; ! PyTuple_SET_ITEM(callargs, i, ob); ! outmask |= (1 << i); ! break; ! case (PARAMFLAG_FIN | PARAMFLAG_FOUT): ! /* for [in, out] parameters, we should probably ! - call _get_arg to get the [in] value ! - create an object with the [in] value as parameter ! - and then proceed in the same way as for an [out] parameter ! */ ! ob = PyTuple_GET_ITEM(argtypes, i); ! dict = PyType_stgdict(ob); ! /* Create an instance of the pointed-to type */ ! v = _get_arg(&inargs_index, name, defval, inargs, kwds); ! if (v == 0) ! goto error; ! /* XXX But this looks wrong. Shouldn't we call ! <type>.from_param(<value>) ? ! */ ! ob = PyObject_CallFunctionObjArgs(dict->proto, ! v, ! NULL); ! Py_DECREF(v); ! if (ob == 0) ! goto error; ! ob = _byref(ob); ! if (ob == NULL) ! goto error; PyTuple_SET_ITEM(callargs, i, ob); ! outmask |= (1 << i); break; default: --- 2869,2877 ---- if (ob == NULL) goto error; ! /* The .from_param call that will ocurr later will pass this ! as a byref parameter. */ PyTuple_SET_ITEM(callargs, i, ob); ! *poutmask |= (1 << i); /* mark as out arg */ ! (*pnumretvals)++; break; default: *************** *** 2896,2934 **** these indexes contain values to return. */ - - len = 0; - for (i = 0; i < 32; ++i) { - if (outmask & (1 << i)) - ++len; - } - - switch (len) { - int j; - case 0: - *poutargs = NULL; - break; - case 1: - for (i = 0; i < 32; ++i) { - if (outmask & (1 << i)) { - *poutargs = PyTuple_GET_ITEM(callargs, i); - Py_INCREF(*poutargs); - break; - } - } - break; - default: - *poutargs = PyTuple_New(len); - j = 0; - for (i = 0; i < 32; ++i) { - PyObject *ob; - if (outmask & (1 << i)) { - ob = PyTuple_GET_ITEM(callargs, i); - Py_INCREF(ob); - PyTuple_SET_ITEM(*poutargs, j, ob); - ++j; - } - } - } - return callargs; error: --- 2901,2904 ---- *************** *** 2940,2982 **** http://msdn.microsoft.com/library/en-us/com/html/769127a1-1a14-4ed4-9d38-7cf3e571b661.asp */ static PyObject * _get_one(PyObject *obj) { /* __ctypes_from_outparam__ lets of specify how 'out' parameters are retrieved from COM method class. */ ! PyCArgObject *arg = (PyCArgObject *)obj; ! return PyObject_CallMethod(arg->obj, "__ctypes_from_outparam__", NULL); } static PyObject * ! _build_result(PyObject *result, PyObject *outargs) { ! int i, len; ! if (outargs == NULL) return result; - if (result == NULL) { - Py_DECREF(outargs); - return NULL; } Py_DECREF(result); ! if (!PyTuple_CheckExact(outargs)) { ! PyObject *v = _get_one(outargs); ! Py_DECREF(outargs); ! return v; } ! assert (outargs->ob_refcnt == 1); ! /* We know we are sole owner of the outargs tuple. So, we can replace ! the values in it instead of allocating a new one. ! */ ! len = PyTuple_GET_SIZE(outargs); ! for (i = 0; i < len; ++i) { ! PyObject *ob = _get_one(PyTuple_GET_ITEM(outargs, i)); ! PyTuple_SetItem(outargs, i, ob); } ! return outargs; } --- 2910,2987 ---- http://msdn.microsoft.com/library/en-us/com/html/769127a1-1a14-4ed4-9d38-7cf3e571b661.asp */ + /* + XXX BUG: [in, out] parameters MUST be returned as-is. + */ static PyObject * _get_one(PyObject *obj) { + if (PyCArg_CheckExact(obj)) { + PyCArgObject *arg = (PyCArgObject *)obj; + obj = arg->obj; + } /* __ctypes_from_outparam__ lets of specify how 'out' parameters are retrieved from COM method class. */ ! return PyObject_CallMethod(obj, "__ctypes_from_outparam__", NULL); } + /* + Build return value of a function. + + Consumes the refcount on result and callargs. + */ static PyObject * ! _build_result(PyObject *result, PyObject *callargs, ! int outmask, int inoutmask, int numretvals) { ! int i, index, bit; ! PyObject *tup; ! if (callargs == NULL) ! return result; ! if (result == NULL || numretvals == 0) { ! Py_DECREF(callargs); return result; } Py_DECREF(result); ! /* allocate tuple to hold the result */ ! if (numretvals > 1) { ! tup = PyTuple_New(numretvals); ! if (tup == NULL) { ! Py_DECREF(callargs); ! return NULL; ! } } ! ! index = 0; ! for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) { ! PyObject *v; ! if (bit & inoutmask) { ! v = PyTuple_GET_ITEM(callargs, i); ! Py_INCREF(v); ! if (numretvals == 1) { ! Py_DECREF(callargs); ! return v; ! } ! PyTuple_SET_ITEM(tup, index, v); ! index++; ! } else if (bit & outmask) { ! v = PyTuple_GET_ITEM(callargs, i); ! v = PyObject_CallMethod(v, "__ctypes_from_outparam__", NULL); ! if (v == NULL || numretvals == 1) { ! Py_DECREF(callargs); ! return v; ! } ! PyTuple_SET_ITEM(tup, index, v); ! index++; ! } ! if (index == numretvals) ! break; } ! ! Py_DECREF(callargs); ! return tup; } *************** *** 2991,2995 **** PyObject *result; PyObject *callargs; - PyObject *outargs; PyObject *errcheck; #ifdef MS_WIN32 --- 2996,2999 ---- *************** *** 2998,3001 **** --- 3002,3009 ---- void *pProc = NULL; + int inoutmask; + int outmask; + int numretvals; + assert(dict); /* if not, it's a bug */ restype = self->restype ? self->restype : dict->restype; *************** *** 3039,3047 **** } #endif ! callargs = _build_callargs(self, argtypes, inargs, kwds, &outargs); ! if (callargs == NULL) { ! Py_XDECREF(outargs); return NULL; - } if (converters) { --- 3047,3055 ---- } #endif ! callargs = _build_callargs(self, argtypes, ! inargs, kwds, ! &outmask, &inoutmask, &numretvals); ! if (callargs == NULL) return NULL; if (converters) { *************** *** 3089,3106 **** self, callargs, - outargs, NULL); ! Py_DECREF(result); ! Py_DECREF(callargs); ! Py_XDECREF(outargs); ! return v; } ! Py_DECREF(callargs); ! /* _build_result assumes that we are the sole owner of the outargs ! tuple. Since _build_result is never called when errcheck is used ! (see above), this assumtion is still true. ! */ ! return _build_result(result, outargs); } --- 3097,3117 ---- self, callargs, NULL); ! /* If the errcheck funtion failed, return NULL. ! If the errcheck function returned callargs unchanged, ! continue normal processing. ! If the errcheck function returned something else, ! use that as result. ! */ ! if (v == NULL || v != callargs) { ! Py_DECREF(result); ! Py_DECREF(callargs); ! return v; ! } ! Py_DECREF(v); } ! return _build_result(result, callargs, ! outmask, inoutmask, numretvals); } *************** *** 3731,3736 **** Simple_get_value(CDataObject *self) { ! StgDictObject *dict = PyObject_stgdict((PyObject *)self); assert(dict->getfunc); return dict->getfunc(self->b_ptr, self->b_size); } --- 3742,3749 ---- Simple_get_value(CDataObject *self) { ! StgDictObject *dict; ! dict = PyObject_stgdict((PyObject *)self); assert(dict->getfunc); + dict = PyObject_stgdict((PyObject *)self); return dict->getfunc(self->b_ptr, self->b_size); } *************** *** 3771,3774 **** --- 3784,3791 ---- Simple_from_outparm(PyObject *self, PyObject *args) { + if (IsSimpleSubType((PyObject *)self->ob_type)) { + Py_INCREF(self); + return self; + } /* call stgdict->getfunc */ return Simple_get_value((CDataObject *)self); |
From: Thomas H. <th...@us...> - 2006-01-02 18:58:51
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32696 Modified Files: Tag: branch_1_0 ChangeLog Log Message: *** empty log message *** Index: ChangeLog =================================================================== RCS file: /cvsroot/ctypes/ctypes/ChangeLog,v retrieving revision 1.86.2.32 retrieving revision 1.86.2.33 diff -C2 -d -r1.86.2.32 -r1.86.2.33 *** ChangeLog 14 Dec 2005 22:14:46 -0000 1.86.2.32 --- ChangeLog 2 Jan 2006 18:58:39 -0000 1.86.2.33 *************** *** 1,2 **** --- 1,11 ---- + 2006-01-02 Thomas Heller <th...@py...> + + * Removed the complete ctypes.com package, which lived + (in CVS) in the ctypes\win32\com directory. + + 2005-12-30 Thomas Heller <th...@py...> + + * Changes for Windows CE, contributed by Luke Dunstan. + 2005-12-14 Thomas Heller <th...@py...> |
From: Thomas H. <th...@us...> - 2006-01-02 17:26:35
|
Update of /cvsroot/ctypes/ctypes/win32/com In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11054 Removed Files: Tag: branch_1_0 w_getopt.py storage.py shelllink.py server.py register.py persist.py oleobject.py ole.py moniker.py mallocspy.py hresult.py errorinfo.py connectionpoints.py client.py automation.py __init__.py ChangeLog .cvsignore Log Message: Remove the ctypes.com package. --- .cvsignore DELETED --- --- shelllink.py DELETED --- --- hresult.py DELETED --- --- ChangeLog DELETED --- --- oleobject.py DELETED --- --- automation.py DELETED --- --- __init__.py DELETED --- --- persist.py DELETED --- --- mallocspy.py DELETED --- --- ole.py DELETED --- --- register.py DELETED --- --- client.py DELETED --- --- server.py DELETED --- --- connectionpoints.py DELETED --- --- moniker.py DELETED --- --- errorinfo.py DELETED --- --- storage.py DELETED --- --- w_getopt.py DELETED --- |
From: Thomas H. <th...@us...> - 2006-01-02 17:26:29
|
Update of /cvsroot/ctypes/ctypes/win32/com/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11036 Removed Files: Tag: branch_1_0 readtlb.py __init__.py .cvsignore Log Message: Remove the ctypes.com package. --- .cvsignore DELETED --- --- __init__.py DELETED --- --- readtlb.py DELETED --- |
From: Thomas H. <th...@us...> - 2006-01-02 17:26:25
|
Update of /cvsroot/ctypes/ctypes/win32/com/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10990 Removed Files: Tag: branch_1_0 test_word.py test_variant.py test_sysalloc.py test_safearray.py test_perf.py test_comobject.py __init__.py .cvsignore Log Message: Remove the ctypes.com package. --- .cvsignore DELETED --- --- test_comobject.py DELETED --- --- test_perf.py DELETED --- --- __init__.py DELETED --- --- test_word.py DELETED --- --- test_sysalloc.py DELETED --- --- test_safearray.py DELETED --- --- test_variant.py DELETED --- |
From: Thomas H. <th...@us...> - 2006-01-02 17:26:22
|
Update of /cvsroot/ctypes/ctypes/win32/com/samples In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10938 Removed Files: Tag: branch_1_0 iexplorer.py ie6_gen.py .cvsignore Log Message: Remove the ctypes.com package. --- .cvsignore DELETED --- --- ie6_gen.py DELETED --- --- iexplorer.py DELETED --- |
From: Thomas H. <th...@us...> - 2006-01-02 17:26:15
|
Update of /cvsroot/ctypes/ctypes/win32/com/samples/server In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10917 Removed Files: Tag: branch_1_0 w32server.py w32_user.py w32_ct.py user.py test_w32.py sum_user.py sum_gen.py sum_cpp.cpp sum.tlb sum.py sum.idl setup_sum.py rt.cmd readme.txt .cvsignore Log Message: Remove the ctypes.com package. --- .cvsignore DELETED --- --- sum.tlb DELETED --- --- user.py DELETED --- --- w32_user.py DELETED --- --- w32server.py DELETED --- --- sum_cpp.cpp DELETED --- --- sum_gen.py DELETED --- --- sum.py DELETED --- --- w32_ct.py DELETED --- --- rt.cmd DELETED --- --- test_w32.py DELETED --- --- sum.idl DELETED --- --- setup_sum.py DELETED --- --- sum_user.py DELETED --- --- readme.txt DELETED --- |
From: Thomas H. <th...@us...> - 2006-01-02 17:26:08
|
Update of /cvsroot/ctypes/ctypes/win32/com/samples/server/control In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10890 Removed Files: Tag: branch_1_0 test.html stoplite.py common.py .cvsignore Log Message: Remove the ctypes.com package. --- .cvsignore DELETED --- --- stoplite.py DELETED --- --- test.html DELETED --- --- common.py DELETED --- |
From: Thomas H. <th...@us...> - 2006-01-02 17:26:00
|
Update of /cvsroot/ctypes/ctypes/win32/com/samples/server/IExplorer In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10859 Removed Files: Tag: branch_1_0 toolband.py .cvsignore Log Message: Remove the ctypes.com package. --- .cvsignore DELETED --- --- toolband.py DELETED --- |