ctypes-commit Mailing List for ctypes (Page 69)
Brought to you by:
theller
You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
(8) |
May
(90) |
Jun
(143) |
Jul
(106) |
Aug
(94) |
Sep
(84) |
Oct
(163) |
Nov
(60) |
Dec
(58) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(128) |
Feb
(79) |
Mar
(227) |
Apr
(192) |
May
(179) |
Jun
(41) |
Jul
(53) |
Aug
(103) |
Sep
(28) |
Oct
(38) |
Nov
(81) |
Dec
(17) |
2006 |
Jan
(184) |
Feb
(111) |
Mar
(188) |
Apr
(67) |
May
(58) |
Jun
(123) |
Jul
(73) |
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
From: Thomas H. <th...@us...> - 2005-03-11 19:23:46
|
Update of /cvsroot/ctypes/ctypes/comtypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20108 Modified Files: test_basic.py Log Message: Clean up. Test that com interface methods cannot be set before the baseclass methods are set. Index: test_basic.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/unittests/test_basic.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_basic.py 24 Feb 2005 16:51:15 -0000 1.4 --- test_basic.py 11 Mar 2005 19:23:34 -0000 1.5 *************** *** 76,111 **** # the IUnknown class has the actual methods: self.failUnless(IUnknown.__dict__.get("QueryInterface")) ! ## def test_identity(self): ! ## p = POINTER(IUnknown)() ! #### p[0] ! ## windll.oleaut32.CreateTypeLib(1, u"blabla", byref(p)) ! ! ## p = p.QueryInterface(IUnknown) ! ## other = p.QueryInterface(IUnknown) ! ! ## print other == p ! ## print other is p ! ## print "A" ! ## print "?", p[0] ! ## print "B" ! #### p[0] = 42 ! ## print "C" ! ## print dir(p) ! ## from ctypes import cast, c_int ! ## print cast(other, c_int).value ! ## print cast(p, c_int).value ! ! ## x = POINTER(IUnknown)() ! ## windll.oleaut32.CreateTypeLib(1, u"blabla_2", byref(x)) ! ## x = x.QueryInterface(IUnknown) ! ## print cast(x, c_int).value ! ## print "D" ! ## del p ! ## print "E" ! ## del other ! ## print "F" if __name__ == "__main__": --- 76,97 ---- # the IUnknown class has the actual methods: self.failUnless(IUnknown.__dict__.get("QueryInterface")) + # but we can call it on the pointer instance + POINTER(IUnknown).QueryInterface ! def test_make_methods(self): ! class IBase(IUnknown): ! _iid_ = GUID.create_new() ! class IDerived(IBase): ! _iid_ = GUID.create_new() ! # We cannot assign _methods_ to IDerived before IBase has it's _methods_: ! self.assertRaises(TypeError, lambda: setattr(IDerived, "_methods_", [])) ! # Make sure that setting _methods_ failed completely. ! self.assertRaises(KeyError, lambda: IDerived.__dict__["_methods_"]) ! IBase._methods_ = [] ! # Now it works: ! IDerived._methods_ = [] ! ## def test_identity(self): if __name__ == "__main__": |
From: Thomas H. <th...@us...> - 2005-03-11 17:52:37
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28084 Modified Files: __init__.py Log Message: If _make_methods_ fails, __setattr__ should also NOT set it. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** __init__.py 11 Mar 2005 17:34:23 -0000 1.20 --- __init__.py 11 Mar 2005 17:52:21 -0000 1.21 *************** *** 102,109 **** def __setattr__(self, name, value): type.__setattr__(self, name, value) - if name != "_methods_": - return - self._make_methods(value) def __get_baseinterface_methodcount(self): --- 102,108 ---- def __setattr__(self, name, value): + if name == "_methods_": + self._make_methods(value) type.__setattr__(self, name, value) def __get_baseinterface_methodcount(self): |
From: Thomas H. <th...@us...> - 2005-03-11 17:35:54
|
Update of /cvsroot/ctypes/ctypes/comtypes/samples In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23343 Modified Files: mstask.py Log Message: Problem solved: cannot set _methods_ on an interface when the baseclass doesn't have it's _methods_. Index: mstask.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/samples/mstask.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** mstask.py 11 Mar 2005 15:44:16 -0000 1.1 --- mstask.py 11 Mar 2005 17:35:39 -0000 1.2 *************** *** 27,40 **** # refcount leaks! # - # - # A problem in the com metaclass: - # - # ITask derives from IScheduledWorkItems. - # - # When ITask._methods_ = [...] is executed BEFORE - # IScheduledWorkItems._methods_ = [...], the COM methods will get the - # wrong vtable indexes! - # - # Not sure how to solve that. from ctypes import * --- 27,30 ---- *************** *** 435,439 **** print scheduler.Enum().Clone() ! for i in range (5000): for item in scheduler: pass # leaks 10 refs per loop --- 425,429 ---- print scheduler.Enum().Clone() ! for i in range (50): for item in scheduler: pass # leaks 10 refs per loop |
From: Thomas H. <th...@us...> - 2005-03-11 17:34:34
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23013 Modified Files: __init__.py Log Message: Make sure that the base interface already has it's _methods_ defined when _methods_ is set. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** __init__.py 11 Mar 2005 15:38:15 -0000 1.19 --- __init__.py 11 Mar 2005 17:34:23 -0000 1.20 *************** *** 109,114 **** def __get_baseinterface_methodcount(self): "Return the number of com methods in the base interfaces" ! return sum([len(itf.__dict__.get("_methods_", ())) ! for itf in self.__mro__[1:]]) def _make_methods(self, methods): --- 109,119 ---- def __get_baseinterface_methodcount(self): "Return the number of com methods in the base interfaces" ! try: ! return sum([len(itf.__dict__["_methods_"]) ! for itf in self.__mro__[1:-1]]) ! except KeyError, (name,): ! if name == "_methods_": ! raise TypeError, "baseinterface '%s' has no _methods_" % itf.__name__ ! raise def _make_methods(self, methods): |
From: Thomas H. <th...@us...> - 2005-03-11 15:44:26
|
Update of /cvsroot/ctypes/ctypes/comtypes/samples In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27224 Added Files: mstask.py Log Message: Task scheduler sample (work in progress). --- NEW FILE: mstask.py --- # This sample wraps several custom COM interfaces, for which no # typelibrary is present. The interfaces are declared in the MSVC # MSTASK.H include file. # # generated by 'xml2py' # flags 'mstask.xml -r ITask.* -m comtypes -o mstask.py' # # and then: # - reordered manually # - removed the HWND and HWND__ definitions, replaced with 'HWND = c_void_p' # # - filled in _iid_ entries, and completed the idl attributes and # parameter names in the COMMETHOD definitions by looking into the # header file # # - fixed the LPCWSTR and LPWSTR definitions # # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # PROBLEMS: # # memory leaks: Must call CoTaskMemFree in the methods returning # LPWSTR items. See MSDN docs. # Should this be solved by using subclasses of c_wchar_p, with a customized # _from_outarg_ slot? # # refcount leaks! # # # A problem in the com metaclass: # # ITask derives from IScheduledWorkItems. # # When ITask._methods_ = [...] is executed BEFORE # IScheduledWorkItems._methods_ = [...], the COM methods will get the # wrong vtable indexes! # # Not sure how to solve that. from ctypes import * from comtypes import IUnknown from comtypes import HRESULT from comtypes import IID from comtypes import STDMETHOD, GUID, COMMETHOD from comtypes import DWORD from comtypes import defaultvalue ##WCHAR = c_wchar LPCWSTR = c_wchar_p #POINTER(WCHAR) LPWSTR = c_wchar_p #POINTER(WCHAR) BYTE = c_ubyte HWND = c_void_p # XXX WORD = c_ushort ################################################################ CLSID_CTaskScheduler = GUID("{148BD52A-A2AB-11CE-B11F-00AA00530503}") class ITaskScheduler(IUnknown): _iid_ = GUID('{148BD527-A2AB-11CE-B11F-00AA00530503}') def __iter__(self): return self.Enum() def NewWorkItem(self, name): task = self._NewWorkItem(name, byref(CLSID_CTask), byref(ITask._iid_)) return task.QueryInterface(ITask) class IScheduledWorkItem(IUnknown): _iid_ = GUID('{a6b952f0-a4b1-11d0-997d-00aa006887ec}') class ITaskTrigger(IUnknown): _iid_ = GUID('{148BD52B-A2AB-11CE-B11F-00AA00530503}') class IEnumWorkItems(IUnknown): _iid_ = GUID('{148BD528-A2AB-11CE-B11F-00AA00530503}') def __iter__(self): return self def next(self): arr, fetched = self.Next(1) if fetched == 0: raise StopIteration result = arr[0] ## windll.ole32.CoTaskMemFree(arr) return result CLSID_CTask = GUID("{148BD520-A2AB-11CE-B11F-00AA00530503}") class ITask(IScheduledWorkItem): _iid_ = GUID('{148BD524-A2AB-11CE-B11F-00AA00530503}') ################################################################ ITaskScheduler._methods_ = [ COMMETHOD([], HRESULT, 'SetTargetComputer', ( ["in"], LPCWSTR ) ), COMMETHOD([], HRESULT, 'GetTargetComputer', ( ["out"], POINTER(LPWSTR) ), ), COMMETHOD([], HRESULT, 'Enum', ( ["out"], POINTER(POINTER(IEnumWorkItems)), "ppEnumWorkItems" ), ), COMMETHOD([], HRESULT, 'Activate', ( ["in"], LPCWSTR, "pwszName" ), ( ["in"], POINTER(IID), "riid" ), ( ["out"], POINTER(POINTER(IUnknown)), "ppUnk" ), ), COMMETHOD([], HRESULT, 'Delete', ( ["in"], LPCWSTR, "pwszName" ), ), COMMETHOD([], HRESULT, 'NewWorkItem', ( ["in"], LPCWSTR, "pwszTaskName" ), ( ["in"], POINTER(IID), "rclsid"), ( ["in"], POINTER(IID), "riid"), ( ["out"], POINTER(POINTER(IUnknown)), "ppUnk"), ), COMMETHOD([], HRESULT, 'AddWorkItem', ( ["in"], LPCWSTR, "pwszTaskName" ), ( ["in"], POINTER(IScheduledWorkItem), "pWorkItem" ), ), COMMETHOD([], HRESULT, 'IsOfType', ( ["in"], LPCWSTR, "pwszName" ), ( ["in"], POINTER(IID), "riid"), ), ] class _TASK_TRIGGER(Structure): # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 185 pass PTASK_TRIGGER = POINTER(_TASK_TRIGGER) ITaskTrigger._methods_ = [ # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 228 # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 231 COMMETHOD([], HRESULT, 'SetTrigger', ( [], PTASK_TRIGGER ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 234 COMMETHOD([], HRESULT, 'GetTrigger', ( [], PTASK_TRIGGER ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 237 COMMETHOD([], HRESULT, 'GetTriggerString', ( [], POINTER(LPWSTR) ), ), ] _TASK_TRIGGER_TYPE = c_int # enum TASK_TIME_TRIGGER_ONCE = 0 TASK_TIME_TRIGGER_DAILY = 1 TASK_TIME_TRIGGER_WEEKLY = 2 TASK_TIME_TRIGGER_MONTHLYDATE = 3 TASK_TIME_TRIGGER_MONTHLYDOW = 4 TASK_EVENT_TRIGGER_ON_IDLE = 5 TASK_EVENT_TRIGGER_AT_SYSTEMSTART = 6 TASK_EVENT_TRIGGER_AT_LOGON = 7 TASK_TRIGGER_TYPE = _TASK_TRIGGER_TYPE class _TRIGGER_TYPE_UNION(Union): # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 177 pass class _DAILY(Structure): # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 153 pass _DAILY._fields_ = [ # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 153 ('DaysInterval', WORD), ] assert sizeof(_DAILY) == 2, sizeof(_DAILY) assert alignment(_DAILY) == 2, alignment(_DAILY) DAILY = _DAILY class _WEEKLY(Structure): # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 158 pass _WEEKLY._fields_ = [ # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 158 ('WeeksInterval', WORD), ('rgfDaysOfTheWeek', WORD), ] assert sizeof(_WEEKLY) == 4, sizeof(_WEEKLY) assert alignment(_WEEKLY) == 2, alignment(_WEEKLY) WEEKLY = _WEEKLY class _MONTHLYDATE(Structure): # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 164 pass _MONTHLYDATE._fields_ = [ # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 164 ('rgfDays', DWORD), ('rgfMonths', WORD), ] assert sizeof(_MONTHLYDATE) == 8, sizeof(_MONTHLYDATE) assert alignment(_MONTHLYDATE) == 4, alignment(_MONTHLYDATE) MONTHLYDATE = _MONTHLYDATE class _MONTHLYDOW(Structure): # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 170 pass _MONTHLYDOW._fields_ = [ # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 170 ('wWhichWeek', WORD), ('rgfDaysOfTheWeek', WORD), ('rgfMonths', WORD), ] assert sizeof(_MONTHLYDOW) == 6, sizeof(_MONTHLYDOW) assert alignment(_MONTHLYDOW) == 2, alignment(_MONTHLYDOW) MONTHLYDOW = _MONTHLYDOW _TRIGGER_TYPE_UNION._fields_ = [ # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 177 ('Daily', DAILY), ('Weekly', WEEKLY), ('MonthlyDate', MONTHLYDATE), ('MonthlyDOW', MONTHLYDOW), ] assert sizeof(_TRIGGER_TYPE_UNION) == 8, sizeof(_TRIGGER_TYPE_UNION) assert alignment(_TRIGGER_TYPE_UNION) == 4, alignment(_TRIGGER_TYPE_UNION) TRIGGER_TYPE_UNION = _TRIGGER_TYPE_UNION _TASK_TRIGGER._fields_ = [ # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 185 ('cbTriggerSize', WORD), ('Reserved1', WORD), ('wBeginYear', WORD), ('wBeginMonth', WORD), ('wBeginDay', WORD), ('wEndYear', WORD), ('wEndMonth', WORD), ('wEndDay', WORD), ('wStartHour', WORD), ('wStartMinute', WORD), ('MinutesDuration', DWORD), ('MinutesInterval', DWORD), ('rgFlags', DWORD), ('TriggerType', TASK_TRIGGER_TYPE), ('Type', TRIGGER_TYPE_UNION), ('Reserved2', WORD), ('wRandomMinutesInterval', WORD), ] assert sizeof(_TASK_TRIGGER) == 48, sizeof(_TASK_TRIGGER) assert alignment(_TASK_TRIGGER) == 4, alignment(_TASK_TRIGGER) IEnumWorkItems._methods_ = [ COMMETHOD([], HRESULT, 'Next', ( ["in", defaultvalue(1)], DWORD, "celt"), ( ["out"], POINTER(POINTER(LPWSTR)), "rgpwszNames" ), ( ["out"], POINTER(DWORD), "pceltFetched" ), ), COMMETHOD([], HRESULT, 'Skip', ( ["in"], DWORD )), COMMETHOD([], HRESULT, 'Reset'), COMMETHOD([], HRESULT, 'Clone', ( ["out"], POINTER(POINTER(IEnumWorkItems)) )) ] class _SYSTEMTIME(Structure): # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/winbase.h 270 _fields_ = [ ('wYear', WORD), ('wMonth', WORD), ('wDayOfWeek', WORD), ('wDay', WORD), ('wHour', WORD), ('wMinute', WORD), ('wSecond', WORD), ('wMilliseconds', WORD), ] LPSYSTEMTIME = POINTER(_SYSTEMTIME) SYSTEMTIME = _SYSTEMTIME assert sizeof(_SYSTEMTIME) == 16, sizeof(_SYSTEMTIME) assert alignment(_SYSTEMTIME) == 2, alignment(_SYSTEMTIME) IScheduledWorkItem._methods_ = [ # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 373 # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 377 COMMETHOD([], HRESULT, 'CreateTrigger', ( [], POINTER(WORD) ), ( [], POINTER(POINTER(ITaskTrigger)) ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 380 COMMETHOD([], HRESULT, 'DeleteTrigger', ( [], WORD ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 383 COMMETHOD([], HRESULT, 'GetTriggerCount', ( ["out"], POINTER(WORD), "pwCount")), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 387 COMMETHOD([], HRESULT, 'GetTrigger', ( [], WORD ), ( [], POINTER(POINTER(ITaskTrigger)) ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 391 COMMETHOD([], HRESULT, 'GetTriggerString', ( [], WORD ), ( [], POINTER(LPWSTR) ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 397 COMMETHOD([], HRESULT, 'GetRunTimes', ( [], LPSYSTEMTIME ), ( [], LPSYSTEMTIME ), ( [], POINTER(WORD) ), ( [], POINTER(LPSYSTEMTIME) ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 400 COMMETHOD([], HRESULT, 'GetNextRunTime', ( [], POINTER(SYSTEMTIME) ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 404 COMMETHOD([], HRESULT, 'SetIdleWait', ( [], WORD ), ( [], WORD ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 408 COMMETHOD([], HRESULT, 'GetIdleWait', ( [], POINTER(WORD) ), ( [], POINTER(WORD) ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 410 COMMETHOD([], HRESULT, 'Run', ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 412 COMMETHOD([], HRESULT, 'Terminate', ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 416 COMMETHOD([], HRESULT, 'EditWorkItem', ( [], HWND ), ( [], DWORD ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 419 COMMETHOD([], HRESULT, 'GetMostRecentRunTime', ( [], POINTER(SYSTEMTIME) ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 422 COMMETHOD([], HRESULT, 'GetStatus', ( [], POINTER(HRESULT) ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 425 COMMETHOD([], HRESULT, 'GetExitCode', ( [], POINTER(DWORD) ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 428 COMMETHOD([], HRESULT, 'SetComment', ( [], LPCWSTR ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 431 COMMETHOD([], HRESULT, 'GetComment', ( [], POINTER(LPWSTR) ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 434 COMMETHOD([], HRESULT, 'SetCreator', ( [], LPCWSTR ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 437 COMMETHOD([], HRESULT, 'GetCreator', ( [], POINTER(LPWSTR) ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 441 COMMETHOD([], HRESULT, 'SetWorkItemData', ( [], WORD ), ( [], POINTER(BYTE) ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 445 COMMETHOD([], HRESULT, 'GetWorkItemData', ( [], POINTER(WORD) ), ( [], POINTER(POINTER(BYTE)) ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 448 COMMETHOD([], HRESULT, 'SetErrorRetryCount', ( [], WORD ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 451 COMMETHOD([], HRESULT, 'GetErrorRetryCount', ( [], POINTER(WORD) ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 454 COMMETHOD([], HRESULT, 'SetErrorRetryInterval', ( [], WORD ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 457 COMMETHOD([], HRESULT, 'GetErrorRetryInterval', ( [], POINTER(WORD) ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 460 COMMETHOD([], HRESULT, 'SetFlags', ( [], DWORD ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 463 COMMETHOD([], HRESULT, 'GetFlags', ( [], POINTER(DWORD) ), ), # C:/PROGRA~1/MICROS~3.NET/Vc7/PLATFO~1/Include/mstask.h 467 COMMETHOD([], HRESULT, 'SetAccountInformation', ( [], LPCWSTR ), ( [], LPCWSTR ), ), COMMETHOD([], HRESULT, 'GetAccountInformation', ( ["out"], POINTER(LPWSTR), "ppwszAccountName" )), ] # THIS CODE MUST BE EXECUTED AFTER IScheduledWorkItem._methods_ = ... !!! ITask._methods_ = [ COMMETHOD([], HRESULT, 'SetApplicationName', ( ["in"], LPCWSTR )), COMMETHOD([], HRESULT, 'GetApplicationName', ( ["out"], POINTER(LPWSTR) )), COMMETHOD([], HRESULT, 'SetParameters', ( ["in"], LPCWSTR )), COMMETHOD([], HRESULT, 'GetParameters', ( ["out"], POINTER(LPWSTR) )), COMMETHOD([], HRESULT, 'SetWorkingDirectory', ( ["int"], LPCWSTR )), COMMETHOD([], HRESULT, 'GetWorkingDirectory', ( ["out"], POINTER(LPWSTR) )), COMMETHOD([], HRESULT, 'SetPriority', ( ["in"], DWORD )), COMMETHOD([], HRESULT, 'GetPriority', ( ["out"], POINTER(DWORD) )), COMMETHOD([], HRESULT, 'SetTaskFlags', ( ["in"], DWORD )), COMMETHOD([], HRESULT, 'GetTaskFlags', ( ["out"], POINTER(DWORD) )), COMMETHOD([], HRESULT, 'SetMaxRunTime', ( ["in"], DWORD )), COMMETHOD([], HRESULT, 'GetMaxRunTime', ( ["out"], POINTER(DWORD) )) ] if __name__ == "__main__": from comtypes import CoCreateInstance scheduler = CoCreateInstance(CLSID_CTaskScheduler, ITaskScheduler) for taskname in scheduler.Enum(): print "%s:" % taskname, task = scheduler.Activate(taskname, byref(ITask._iid_)) task = task.QueryInterface(ITask) print task.GetTriggerCount(), task.GetMaxRunTime(), task.GetApplicationName() print scheduler.Enum() print scheduler.Enum().Clone() for i in range (5000): for item in scheduler: pass # leaks 10 refs per loop print scheduler.AddRef(), scheduler.Release() |
From: Thomas H. <th...@us...> - 2005-03-11 15:41:57
|
Update of /cvsroot/ctypes/ctypes/comtypes/samples In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26581 Added Files: __init__.py .cvsignore Log Message: comtypes samples. --- NEW FILE: .cvsignore --- *.pyc *.pyo --- NEW FILE: __init__.py --- # comtypes.samples package |
From: Thomas H. <th...@us...> - 2005-03-11 15:40:56
|
Update of /cvsroot/ctypes/ctypes/ctypes/wrap In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26379 Modified Files: codegenerator.py Log Message: Detect an 'Enum' com method, and create an __iter__ method in this class. Detect a COM enumerator by checking for the 4 Enum methods, in the correct order, and make this class a Python iterator by generating __iter__() and next() methods. IMO it's better to do this in the generated code than to mix in another class. Index: codegenerator.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/wrap/codegenerator.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** codegenerator.py 11 Mar 2005 10:18:02 -0000 1.4 --- codegenerator.py 11 Mar 2005 15:40:44 -0000 1.5 *************** *** 3,6 **** --- 3,14 ---- # $Log$ + # Revision 1.5 2005/03/11 15:40:44 theller + # Detect an 'Enum' com method, and create an __iter__ method in this class. + # + # Detect a COM enumerator by checking for the 4 Enum methods, in the + # correct order, and make this class a Python iterator by generating + # __iter__() and next() methods. IMO it's better to do this in the + # generated code than to mix in another class. + # # Revision 1.4 2005/03/11 10:18:02 theller # Various fixes. And autodetect whether to generate ctypes.com or *************** *** 277,285 **** --- 285,308 ---- self.generate(struct.get_head()) self.more.add(struct) + if head.struct.location: + print >> self.stream, "# %s %s" % head.struct.location basenames = [self.type_name(b) for b in head.struct.bases] if basenames: self.need_GUID() + method_names = [m.name for m in head.struct.members if type(m) is typedesc.Method] print >> self.stream, "class %s(%s):" % (head.struct.name, ", ".join(basenames)) print >> self.stream, " _iid_ = GUID('{}') # please look up iid and fill in!" + if "Enum" in method_names: + print >> self.stream, " def __iter__(self):" + print >> self.stream, " return self.Enum()" + elif method_names == "Next Skip Reset Clone".split(): + print >> self.stream, " def __iter__(self):" + print >> self.stream, " return self" + print >> self.stream + print >> self.stream, " def next(self):" + print >> self.stream, " arr, fetched = self.Next(1)" + print >> self.stream, " if fetched == 0:" + print >> self.stream, " raise StopIteration" + print >> self.stream, " return arr[0]" else: methods = [m for m in head.struct.members if type(m) is typedesc.Method] *************** *** 292,298 **** elif type(head.struct) == typedesc.Union: print >> self.stream, "class %s(Union):" % head.struct.name ! if head.struct.location: ! print >> self.stream, " # %s %s" % head.struct.location ! print >> self.stream, " pass" self.names.add(head.struct.name) --- 315,319 ---- elif type(head.struct) == typedesc.Union: print >> self.stream, "class %s(Union):" % head.struct.name ! print >> self.stream, " pass" self.names.add(head.struct.name) |
From: Thomas H. <th...@us...> - 2005-03-11 15:38:26
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25743 Modified Files: __init__.py Log Message: Expose high level methods with an underscore prepended if the class already has a custom implementation. Add a defaultvalue class. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** __init__.py 11 Mar 2005 11:05:22 -0000 1.18 --- __init__.py 11 Mar 2005 15:38:15 -0000 1.19 *************** *** 163,168 **** # property accessor. And we make sure we don't overwrite # a property that's already present in the class. ! if not is_prop and not hasattr(self, name): ! setattr(self, name, mth) # create public properties / attribute accessors --- 163,171 ---- # property accessor. And we make sure we don't overwrite # a property that's already present in the class. ! if not is_prop: ! if hasattr(self, name): ! setattr(self, "_" + name, mth) ! else: ! setattr(self, name, mth) # create public properties / attribute accessors *************** *** 222,233 **** ################################################################ - # Memory mamagement of BSTR is broken. - # - # The way we do them here, it is not possible to transfer the - # ownership of a BSTR instance. ctypes allocates the memory with - # SysAllocString if we call the constructor with a string, and the - # instance calls SysFreeString when it is destroyed. - # So BSTR's received from dll function calls will never be freed, - # and BSTR's we pass to functions are freed too often ;-( from ctypes import _SimpleCData --- 225,228 ---- *************** *** 238,245 **** return "%s(%r)" % (self.__class__.__name__, self.value) ! def STDMETHOD(restype, name, argtypes=()): ! "Specifies a COM method slot" ! # restype, name, argtypes, paramflags, idlflags, docstring ! return restype, name, argtypes, None, (), None PARAMFLAGS = { --- 233,247 ---- return "%s(%r)" % (self.__class__.__name__, self.value) ! ################################################################ ! ! class helpstring(object): ! def __init__(self, text): ! self.text = text ! ! class defaultvalue(object): ! def __init__(self, value): ! self.value = value ! ! ################################################################ PARAMFLAGS = { *************** *** 249,257 **** } - - class helpstring(object): - def __init__(self, text): - self.text = text - def encode_idl(names): # sum up all values found in PARAMFLAGS, ignoring all others. --- 251,254 ---- *************** *** 260,263 **** --- 257,261 ---- def COMMETHOD(idlflags, restype, methodname, *argspec): + "Specifies a COM method slot with idlflags" paramflags = [] argtypes = [] *************** *** 331,335 **** if 2 & pflags: rettype = typ._type_ - print "COM?", rettype, issubclass(rettype, POINTER(IUnknown)) paramflags.append((pflags, argname)) argtypes.append(typ) --- 329,332 ---- *************** *** 340,343 **** --- 337,345 ---- return restype, methodname, tuple(argtypes), tuple(paramflags), tuple(idlflags), helptext + def STDMETHOD(restype, name, argtypes=()): + "Specifies a COM method slot without idlflags" + # restype, name, argtypes, paramflags, idlflags, docstring + return restype, name, argtypes, None, (), None + ################################################################ |
From: Thomas H. <th...@us...> - 2005-03-11 11:05:31
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14126 Modified Files: __init__.py Log Message: Rename COMMETHOD2 -> COMMETHOD Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** __init__.py 10 Mar 2005 21:22:36 -0000 1.17 --- __init__.py 11 Mar 2005 11:05:22 -0000 1.18 *************** *** 259,263 **** return result & 3 # that's what _ctypes accept ! def COMMETHOD2(idlflags, restype, methodname, *argspec): paramflags = [] argtypes = [] --- 259,263 ---- return result & 3 # that's what _ctypes accept ! def COMMETHOD(idlflags, restype, methodname, *argspec): paramflags = [] argtypes = [] |
From: Thomas H. <th...@us...> - 2005-03-11 11:04:51
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13912 Modified Files: _ctypes.c Log Message: Accept paramflags value of 0. Better conversion of out parameters. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.219 retrieving revision 1.220 diff -C2 -d -r1.219 -r1.220 *** _ctypes.c 10 Mar 2005 13:56:55 -0000 1.219 --- _ctypes.c 11 Mar 2005 11:04:34 -0000 1.220 *************** *** 2326,2329 **** --- 2326,2330 ---- } switch (flag) { + case 0: case PARAMFLAG_FIN: case PARAMFLAG_FOUT: *************** *** 2773,2782 **** } - /* - For simple objects like c_int and friends, call dict->getfunc. - Otherwise, return object itself. - - Hm, it's not that simple: For a VARIANT, we would like .value as well. - */ static PyObject * _get_one(PyObject *obj) --- 2774,2777 ---- *************** *** 2786,2789 **** --- 2781,2794 ---- StgDictObject *dict = PyObject_stgdict(result); + /* + XXX See comments in comtypes::COMMETHOD2. Urgent need to clean this up: + replace with a _from_outparam_ slot call. + */ + if (dict-> proto && PyString_CheckExact(dict->proto)) { + char *tag = PyString_AS_STRING(dict->proto); + /* simple data type, but no pointer */ + if (tag[0] == 'P') + return result; + } if (dict->getfunc) { CDataObject *c = (CDataObject *)result; |
From: Thomas H. <th...@us...> - 2005-03-11 10:23:54
|
Update of /cvsroot/ctypes/ctypes/ctypes/wrap In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3426 Modified Files: gccxmlparser.py Log Message: Less printing. Index: gccxmlparser.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/wrap/gccxmlparser.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** gccxmlparser.py 4 Feb 2005 17:01:24 -0000 1.1 --- gccxmlparser.py 11 Mar 2005 10:23:44 -0000 1.2 *************** *** 332,336 **** else: # not known ! print "skip %s = %s" % (name, value) def get_result(self): --- 332,337 ---- else: # not known ! ## print "skip %s = %s" % (name, value) ! pass def get_result(self): |
From: Thomas H. <th...@us...> - 2005-03-11 10:19:46
|
Update of /cvsroot/ctypes/ctypes/comtypes/samples In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2166/samples Log Message: Directory /cvsroot/ctypes/ctypes/comtypes/samples added to the repository |
From: Thomas H. <th...@us...> - 2005-03-11 10:19:27
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2020 Added Files: ctypes-dev.el Log Message: Xemacs development helper - based on code I found in twisted. --- NEW FILE: ctypes-dev.el --- ;; In the ~/init.el file, write: ;; (setq load-path (cons "c:\\sf\\ctypes" load-path) ;; (require 'ctypes-dev) ;; ;; Try M-x customize-group ctypes-dev ;; ;; Based on twisted-dev.el (provide 'ctypes-dev) (setenv "PYTHONPATH" "c:\\sf\\ctypes") (defgroup ctypes-dev nil "Various ctypes development utilities" :group 'development) (defcustom ctypes-dev-directory "c:\\sf\\ctypes" "ctypes root directory" :group 'ctypes-dev :type 'string) (defmacro with-cd (dirname &rest code) `(let ((old-dirname default-directory) (start-buffer (current-buffer))) (cd ,dirname) (unwind-protect (progn ,@code) (let ((end-buffer (current-buffer))) ;; (cd ,dirname) (set-buffer start-buffer) (cd old-dirname) (set-buffer end-buffer))))) (defun ctypes-dev-build () (interactive) (with-cd ctypes-dev-directory (compile "python setup.py build"))) (defun ctypes-dev-build-debug () (interactive) (with-cd ctypes-dev-directory (compile "py_d setup.py build -g"))) (defun ctypes-dev-rebuild () (interactive) (with-cd ctypes-dev-directory (compile "python setup.py build -f"))) (defun ctypes-dev-test () (interactive) (with-cd "c:\\sf\\ctypes\\unittests" (compile "python runtests.py"))) (defun ctypes-dev-test-debug () (interactive) (with-cd "c:\\sf\\ctypes\\unittests" (compile "py_d runtests.py"))) (defun comtypes-test () (interactive) (with-cd "c:\\sf\\ctypes\\comtypes\\unittests" (compile "python runtests.py"))) (defun comtypes-test-debug () (interactive) (with-cd "c:\\sf\\ctypes\\comtypes\\unittests" (compile "py_d runtests.py"))) (define-minor-mode ctypes-dev-mode "Toggle ctypes-dev mode. With no argument, this command toggles the mode. Non-null prefix argument turns on the mode. Null prefix argument turns off the mode." ;; The initial value. nil ;; The indicator for the mode line. " ctypes" ;; The minor mode bindings. '( ;; ([f6] . ctypes-dev-genapidoc) ;; ([f7] . ctypes-dev-gendoc) ('(shift f8) . ctypes-dev-build-debug) ([f8] . ctypes-dev-build) ('(shift f9) . ctypes-dev-test-debug) ([f9] . ctypes-dev-test) ([f10] . comtypes-test) ('(shift f10) . comtypes-test-debug) ;; ([f11] . ctypes-dev-grep) ;; ([f12] . ctypes-dev-gendocs) )) (add-hook 'find-file-hooks (lambda () (let ((full-ctypes-path (expand-file-name ctypes-dev-directory))) (if (> (length (buffer-file-name)) (length full-ctypes-path)) (if (string= (substring (buffer-file-name) 0 (length full-ctypes-path)) full-ctypes-path) (ctypes-dev-mode) ))))) ;(add-hook ; 'python-mode-hook ; (lambda () ; (ctypes-dev-mode t))) |
From: Thomas H. <th...@us...> - 2005-03-11 10:18:20
|
Update of /cvsroot/ctypes/ctypes/ctypes/wrap In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1604 Modified Files: codegenerator.py Log Message: Various fixes. And autodetect whether to generate ctypes.com or comtypes wrapper code for com interfaces. Index: codegenerator.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/wrap/codegenerator.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** codegenerator.py 17 Feb 2005 19:22:54 -0000 1.3 --- codegenerator.py 11 Mar 2005 10:18:02 -0000 1.4 *************** *** 3,6 **** --- 3,10 ---- # $Log$ + # Revision 1.4 2005/03/11 10:18:02 theller + # Various fixes. And autodetect whether to generate ctypes.com or + # comtypes wrapper code for com interfaces. + # # Revision 1.3 2005/02/17 19:22:54 theller # Refactoring for easier dynamic code generation. *************** *** 275,283 **** basenames = [self.type_name(b) for b in head.struct.bases] if basenames: print >> self.stream, "class %s(%s):" % (head.struct.name, ", ".join(basenames)) else: methods = [m for m in head.struct.members if type(m) is typedesc.Method] if methods: ! self.need_cominterface() print >> self.stream, "class %s(_com_interface):" % head.struct.name elif type(head.struct) == typedesc.Structure: --- 279,290 ---- basenames = [self.type_name(b) for b in head.struct.bases] if basenames: + self.need_GUID() print >> self.stream, "class %s(%s):" % (head.struct.name, ", ".join(basenames)) + print >> self.stream, " _iid_ = GUID('{}') # please look up iid and fill in!" else: methods = [m for m in head.struct.members if type(m) is typedesc.Method] if methods: ! # Hm. We cannot generate code for IUnknown... ! print >> self.stream, "assert 0, 'cannot generate code for IUnknown'" print >> self.stream, "class %s(_com_interface):" % head.struct.name elif type(head.struct) == typedesc.Structure: *************** *** 442,446 **** if methods: ! self.need_STDMETHOD() # method definitions normally span several lines. # Before we generate them, we need to 'import' everything they need. --- 449,457 ---- if methods: ! # Ha! Autodetect ctypes.com or comtypes ;) ! if "COMMETHOD" in self.known_symbols: ! self.need_COMMETHOD() ! else: ! self.need_STDMETHOD() # method definitions normally span several lines. # Before we generate them, we need to 'import' everything they need. *************** *** 450,462 **** for a in m.arguments: self.type_name(a) ! print >> self.stream, "%s._methods_ = [" % body.struct.name if body.struct.location: print >> self.stream, "# %s %s" % body.struct.location ! for m in methods: ! args = [self.type_name(a) for a in m.arguments] ! print >> self.stream, " STDMETHOD(%s, '%s', [%s])," % ( ! self.type_name(m.returns), ! m.name, ! ", ".join(args)) print >> self.stream, "]" --- 461,495 ---- for a in m.arguments: self.type_name(a) ! if "COMMETHOD" in self.known_symbols: ! print >> self.stream, "%s._methods_ = [" % body.struct.name ! else: ! # ctypes.com needs baseclass methods listed as well ! if body.struct.bases: ! basename = body.struct.bases[0].name ! print >> self.stream, "%s._methods_ = %s._methods + [" % \ ! (body.struct.name, body.struct.bases[0].name) ! else: ! print >> self.stream, "%s._methods_ = [" % body.struct.name if body.struct.location: print >> self.stream, "# %s %s" % body.struct.location ! ! if "COMMETHOD" in self.known_symbols: ! for m in methods: ! if m.location: ! print >> self.stream, " # %s %s" % m.location ! print >> self.stream, " COMMETHOD([], %s, '%s'," % ( ! self.type_name(m.returns), ! m.name) ! for a in m.arguments: ! print >> self.stream, \ ! " ( [], %s, )," % self.type_name(a) ! print >> self.stream, " )," ! else: ! for m in methods: ! args = [self.type_name(a) for a in m.arguments] ! print >> self.stream, " STDMETHOD(%s, '%s', [%s])," % ( ! self.type_name(m.returns), ! m.name, ! ", ".join(args)) print >> self.stream, "]" *************** *** 489,509 **** name, ext = os.path.splitext(basename) self._loadedlibs[dllname] = name ! print >> self.stream, "%s = CDLL(%r)" % (name, dllname) return name - _cominterface_defined = False - def need_cominterface(self): - if self._cominterface_defined: - return - print >> self.imports, "from comtypes import _com_interface" - self._cominterface_defined = True - _STDMETHOD_defined = False def need_STDMETHOD(self): if self._STDMETHOD_defined: return ! print >> self.imports, "from comtypes import STDMETHOD" self._STDMETHOD_defined = True _functiontypes = 0 _notfound_functiontypes = 0 --- 522,552 ---- name, ext = os.path.splitext(basename) self._loadedlibs[dllname] = name ! # This should be handled in another way! ! ## print >> self.stream, "%s = CDLL(%r)" % (name, dllname) return name _STDMETHOD_defined = False def need_STDMETHOD(self): if self._STDMETHOD_defined: return ! print >> self.imports, "from ctypes.com import STDMETHOD" self._STDMETHOD_defined = True + _COMMETHOD_defined = False + def need_COMMETHOD(self): + if self._COMMETHOD_defined: + return + print >> self.imports, "from comtypes import COMMETHOD" + self._STDMETHOD_defined = True + + _GUID_defined = False + def need_GUID(self): + if self._GUID_defined: + return + self._GUID_defined = True + modname = self.known_symbols.get("GUID") + if modname: + print >> self.imports, "from %s import GUID" % modname + _functiontypes = 0 _notfound_functiontypes = 0 *************** *** 521,525 **** print >> self.stream if self.use_decorators: ! print >> self.stream, "@ %s(%s, %s, [%s])" % \ (cc, self.type_name(func.returns), libname, ", ".join(args)) argnames = ["p%d" % i for i in range(1, 1+len(args))] --- 564,568 ---- print >> self.stream if self.use_decorators: ! print >> self.stream, "@ %s(%s, '%s', [%s])" % \ (cc, self.type_name(func.returns), libname, ", ".join(args)) argnames = ["p%d" % i for i in range(1, 1+len(args))] *************** *** 530,534 **** print >> self.stream, " return %s._api_(%s)" % (func.name, ", ".join(argnames)) if not self.use_decorators: ! print >> self.stream, "%s = %s(%s, %s, [%s]) (%s)" % \ (func.name, cc, self.type_name(func.returns), libname, ", ".join(args), func.name) print >> self.stream --- 573,577 ---- print >> self.stream, " return %s._api_(%s)" % (func.name, ", ".join(argnames)) if not self.use_decorators: ! print >> self.stream, "%s = %s(%s, '%s', [%s]) (%s)" % \ (func.name, cc, self.type_name(func.returns), libname, ", ".join(args), func.name) print >> self.stream |
From: Thomas H. <th...@us...> - 2005-03-11 07:55:37
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30677 Modified Files: setup.py Log Message: print CRASHED when a remote test returns an error code Index: setup.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/setup.py,v retrieving revision 1.117 retrieving revision 1.118 diff -C2 -d -r1.117 -r1.118 *** setup.py 10 Mar 2005 13:40:22 -0000 1.117 --- setup.py 11 Mar 2005 07:55:26 -0000 1.118 *************** *** 156,160 **** if self.verbosity > 1: print "Running '%s run_remote_test.py %s'" % (sys.executable, path) ! os.system("%s run_remote_test.py %s" % (sys.executable, path)) cases = [] o = open("test.output") --- 156,162 ---- if self.verbosity > 1: print "Running '%s run_remote_test.py %s'" % (sys.executable, path) ! ret = os.system("%s run_remote_test.py %s" % (sys.executable, path)) ! if ret: ! print "CRASHED (%d)" % ret, path cases = [] o = open("test.output") |
From: Thomas H. <th...@us...> - 2005-03-10 21:22:55
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6414 Modified Files: __init__.py Log Message: The low level COM methods must not be given paramflags - otherwise they won't be low level anymore. Lots of thoughts... Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** __init__.py 10 Mar 2005 14:32:58 -0000 1.16 --- __init__.py 10 Mar 2005 21:22:36 -0000 1.17 *************** *** 123,135 **** setters = {} ! # create low level, and maybe high level, COM method implementations. for i, item in enumerate(methods): restype, name, argtypes, paramflags, idlflags, doc = item # the function prototype prototype = WINFUNCTYPE(restype, *argtypes) ! # function calling the COM method slot func = prototype(i + vtbl_offset, name, paramflags) func.__doc__ = doc ! # and an unbound method, so we don't have to pass 'self' mth = new.instancemethod(func, None, self) --- 123,146 ---- setters = {} ! # create private low level, and public high level methods for i, item in enumerate(methods): restype, name, argtypes, paramflags, idlflags, doc = item # the function prototype prototype = WINFUNCTYPE(restype, *argtypes) ! ! # a low level unbound method calling the com method. ! # attach it with a private name (__com_AddRef, for example), ! # so that custom method implementations can call it. ! # XXX MORE INFO ABOUT THE SIGNATURE NEEDED! ! raw_func = prototype(i + vtbl_offset, name) ! setattr(self, ! "_%s__com_%s" % (self.__name__, name), ! new.instancemethod(raw_func, None, self)) ! ! # a high level function calling the COM method func = prototype(i + vtbl_offset, name, paramflags) func.__doc__ = doc ! # make it an unbound method, so we don't have to pass 'self' ! # XXX MORE INFO ABOUT THE SIGNATURE NEEDED! mth = new.instancemethod(func, None, self) *************** *** 155,164 **** setattr(self, name, mth) ! # attach it with a private name (__com_AddRef, for example), ! # so that custom method implementations can call it. ! mthname = "_%s__com_%s" % (self.__name__, name) ! setattr(self, mthname, mth) ! ! # create properties for item in set(getters.keys()) | set(getters.keys()): name, doc, nargs = item --- 166,170 ---- setattr(self, name, mth) ! # create public properties / attribute accessors for item in set(getters.keys()) | set(getters.keys()): name, doc, nargs = item *************** *** 265,271 **** helptext = "".join(helptext) or None for item in argspec: idl, typ, argname = unpack(*item) ! paramflags.append((encode_idl(idl), argname)) argtypes.append(typ) if "propget" in idlflags: --- 271,336 ---- helptext = "".join(helptext) or None + # XXX some thoughts: + # + # In _ctypes.c::_get_one(), it is difficult to decide what to do. + # + # The _get_one() function is called for each [out] parameter, with + # an instance of a ctypes type. The argument 'type' we have in + # paramflags is actually a POINTER to this type. + # + # What are the possibilities, what are the problems? + # + # 1. Simple, intergral, non-pointer data type: call the type's + # stgdict->getfunc() to build the result. stgdict->proto in this + # case is a one character Python string containing the type tag + # from the formattable. + # Sample: + # def Get(self): + # temp = c_int() + # self.__com_Get(byref(temp)) + # return temp.value + # + # 1a. Same as before, but an instance that owns some resources, + # like BSTR. We have to call SysFreeString() to free the resources. + # Sample: + # def Get(self): + # temp = BSTR() + # self.__com_Get(byref(temp)) + # temp2 = temp.value + # temp._free_resources_() + # return temp2 + # + # 1b. A structure, like VARIANT, that actually represents an + # integral data type. Again, we should return it's .value + # attribute, and, as in 1a, we have to call VariantClear() to free + # resources. Sample code same as in 1a. + # + # 2. POINTER to cominterface: In this case we would like _get_one() + # to return the result itself. + # Sample: + # def Get(self): + # temp = POINTER(IUnknown)() + # self.__com_Get(byref(temp)) + # return temp + # + # Exactly here in the code is at least ONE place where all this + # info is available, and we can execute arbitrary complicated + # Python code much easier than in C. + # + # We could pass simple info (in form of integer flags) to + # _ctypes.c in the paramflags tuple (there are a lots of bits + # unused in the PARAMFLAGS enum), but complicated stuff would also + # be possible. + # + # Another possibility would be to have this info in the types itself. + # Something like _from_outarg_. + # for item in argspec: idl, typ, argname = unpack(*item) ! pflags = encode_idl(idl) ! if 2 & pflags: ! rettype = typ._type_ ! print "COM?", rettype, issubclass(rettype, POINTER(IUnknown)) ! paramflags.append((pflags, argname)) argtypes.append(typ) if "propget" in idlflags: |
From: Thomas H. <th...@us...> - 2005-03-10 16:05:07
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19873 Modified Files: custom.py Log Message: Adapt to recent changes. Index: custom.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/custom.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** custom.py 4 Mar 2005 20:52:49 -0000 1.5 --- custom.py 10 Mar 2005 16:04:53 -0000 1.6 *************** *** 2,9 **** import comtypes import comtypes.automation ! import comtypes.automation.typeinfo ################################################################ def get_type(ti, tdesc): # Return a ctypes type for a typedesc --- 2,38 ---- import comtypes import comtypes.automation ! import comtypes.typeinfo ################################################################ + # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + + # XXX This section is unneeded and wrong - no need for a function prototype to + # have paramflags as instance variable. Should be removed as soon as + # comtypes.custom is rewritten. + from _ctypes import CFuncPtr as _CFuncPtr, FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL + from ctypes import _win_functype_cache + + # For backward compatibility, the signature of WINFUNCTYPE cannot be + # changed, so we have to add this - which is basically the same, but + # allows to specify parameter flags from the win32 PARAMFLAGS + # enumeration. Maybe later we have to add optional default parameter + # values and parameter names as well. + def COMMETHODTYPE(restype, argtypes, paramflags): + flags = paramflags + try: + return _win_functype_cache[(restype, argtypes, flags)] + except KeyError: + class WinFunctionType(_CFuncPtr): + _argtypes_ = argtypes + _restype_ = restype + _flags_ = _FUNCFLAG_STDCALL + parmflags = flags + _win_functype_cache[(restype, argtypes, flags)] = WinFunctionType + return WinFunctionType + + # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + + def get_type(ti, tdesc): # Return a ctypes type for a typedesc *************** *** 25,29 **** flags = ed._.paramdesc.wParamFlags typ = get_type(ti, ed.tdesc) ! if flags & comtypes.automation.typeinfo.PARAMFLAG_FHASDEFAULT: var = ed._.paramdesc.pparamdescex[0].varDefaultValue return flags, typ, var.value --- 54,58 ---- flags = ed._.paramdesc.wParamFlags typ = get_type(ti, ed.tdesc) ! if flags & comtypes.typeinfo.PARAMFLAG_FHASDEFAULT: var = ed._.paramdesc.pparamdescex[0].varDefaultValue return flags, typ, var.value *************** *** 32,37 **** def method_proto(name, ti, fd): # return a function prototype with parmflags: an instance of COMMETHODTYPE ! assert fd.funckind == comtypes.automation.typeinfo.FUNC_PUREVIRTUAL, fd.funckind # FUNC_PUREVIRTUAL ! assert fd.callconv == comtypes.automation.typeinfo.CC_STDCALL, fd.callconv ## names = ti.GetNames(fd.memid, fd.cParams + 1) restype = param_info(ti, fd.elemdescFunc)[1] # result type of com method --- 61,66 ---- def method_proto(name, ti, fd): # return a function prototype with parmflags: an instance of COMMETHODTYPE ! assert fd.funckind == comtypes.typeinfo.FUNC_PUREVIRTUAL, fd.funckind # FUNC_PUREVIRTUAL ! assert fd.callconv == comtypes.typeinfo.CC_STDCALL, fd.callconv ## names = ti.GetNames(fd.memid, fd.cParams + 1) restype = param_info(ti, fd.elemdescFunc)[1] # result type of com method *************** *** 43,47 **** argtypes.append(typ) parmflags.append(flags) ! proto = comtypes.COMMETHODTYPE(restype, tuple(argtypes), tuple(parmflags)) return proto --- 72,76 ---- argtypes.append(typ) parmflags.append(flags) ! proto = COMMETHODTYPE(restype, tuple(argtypes), tuple(parmflags)) return proto *************** *** 55,67 **** typeinfo = comobj.GetTypeInfo() ta = typeinfo.GetTypeAttr() ! if ta.typekind == comtypes.automation.typeinfo.TKIND_INTERFACE: # correct typeinfo, still need to QI for this interface iid = ta.guid ! elif ta.typekind == comtypes.automation.typeinfo.TKIND_DISPATCH: # try to get the dual interface portion from a dispatch interface href = typeinfo.GetRefTypeOfImplType(-1) typeinfo = typeinfo.GetRefTypeInfo(href) ta = typeinfo.GetTypeAttr() ! if ta.typekind != comtypes.automation.typeinfo.TKIND_INTERFACE: # it didn't work raise TypeError, "could not get custom interface" --- 84,96 ---- typeinfo = comobj.GetTypeInfo() ta = typeinfo.GetTypeAttr() ! if ta.typekind == comtypes.typeinfo.TKIND_INTERFACE: # correct typeinfo, still need to QI for this interface iid = ta.guid ! elif ta.typekind == comtypes.typeinfo.TKIND_DISPATCH: # try to get the dual interface portion from a dispatch interface href = typeinfo.GetRefTypeOfImplType(-1) typeinfo = typeinfo.GetRefTypeInfo(href) ta = typeinfo.GetTypeAttr() ! if ta.typekind != comtypes.typeinfo.TKIND_INTERFACE: # it didn't work raise TypeError, "could not get custom interface" *************** *** 208,209 **** --- 237,248 ---- p = comtypes.CoCreateInstance(clsid, interface=interface, clsctx=clsctx) return _Dynamic(p) + + if __name__ == "__main__": + f = ActiveXObject("InternetExplorer.Application") + for n in "Name Visible Silent Offline ReadyState AddressBar Resizable".split(): + print n, getattr(f, n) + f.Visible = True + ## print f.ClientToWindow(1, 2) + import time + ## time.sleep(0.5) + f.Quit() |
From: Thomas H. <th...@us...> - 2005-03-10 14:38:05
|
Update of /cvsroot/ctypes/ctypes/comtypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30667 Modified Files: test_typeinfo.py Log Message: comtypes.automation.typeinfo -> comtypes.typeinfo. Index: test_typeinfo.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/unittests/test_typeinfo.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_typeinfo.py 25 Feb 2005 13:59:45 -0000 1.2 --- test_typeinfo.py 10 Mar 2005 14:37:52 -0000 1.3 *************** *** 3,7 **** from comtypes import GUID from comtypes.automation import DISPATCH_METHOD ! from comtypes.automation.typeinfo import LoadTypeLibEx, LoadRegTypeLib, \ QueryPathOfRegTypeLib, TKIND_INTERFACE, TKIND_DISPATCH, TKIND_ENUM --- 3,7 ---- from comtypes import GUID from comtypes.automation import DISPATCH_METHOD ! from comtypes.typeinfo import LoadTypeLibEx, LoadRegTypeLib, \ QueryPathOfRegTypeLib, TKIND_INTERFACE, TKIND_DISPATCH, TKIND_ENUM |
From: Thomas H. <th...@us...> - 2005-03-10 14:36:39
|
Update of /cvsroot/ctypes/ctypes/comtypes/automation In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30217 Removed Files: typeinfo.py __init__.py .cvsignore Log Message: Flat is better than nested. Make comtypes.automation a module again, and move comtypes.automation.typeinfo to comtypes.typeinfo. --- .cvsignore DELETED --- --- typeinfo.py DELETED --- --- __init__.py DELETED --- |
From: Thomas H. <th...@us...> - 2005-03-10 14:36:29
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30164 Added Files: typeinfo.py automation.py Log Message: Flat is better than nested. Make comtypes.automation a module again, and move comtypes.automation.typeinfo to comtypes.typeinfo. --- NEW FILE: typeinfo.py --- # generated by 'xml2py' # flags '..\tools\windows.xml -m comtypes -m comtypes.automation -w -r .*TypeLibEx -r .*TypeLib -o typeinfo.py' # then hacked manually import weakref from ctypes import * from comtypes import STDMETHOD from comtypes import _GUID, GUID from comtypes.automation import BSTR from comtypes.automation import DISPID from comtypes.automation import DISPPARAMS from comtypes.automation import DWORD from comtypes.automation import EXCEPINFO from comtypes.automation import HRESULT from comtypes.automation import IID from comtypes.automation import IUnknown from comtypes.automation import IUnknown from comtypes.automation import LCID from comtypes.automation import LONG from comtypes.automation import SCODE from comtypes.automation import UINT from comtypes.automation import VARIANT from comtypes.automation import VARIANTARG from comtypes.automation import VARTYPE from comtypes.automation import WCHAR from comtypes.automation import WORD from comtypes.automation import tagVARIANT BOOL = c_int HREFTYPE = DWORD INT = c_int MEMBERID = DISPID OLECHAR = WCHAR PVOID = c_void_p SHORT = c_short ULONG_PTR = c_ulong USHORT = c_ushort LPOLESTR = POINTER(OLECHAR) ################################################################ # enums tagSYSKIND = c_int # enum SYS_WIN16 = 0 SYS_WIN32 = 1 SYS_MAC = 2 SYS_WIN64 = 3 SYSKIND = tagSYSKIND tagREGKIND = c_int # enum REGKIND_DEFAULT = 0 REGKIND_REGISTER = 1 REGKIND_NONE = 2 REGKIND = tagREGKIND tagTYPEKIND = c_int # enum TKIND_ENUM = 0 TKIND_RECORD = 1 TKIND_MODULE = 2 TKIND_INTERFACE = 3 TKIND_DISPATCH = 4 TKIND_COCLASS = 5 TKIND_ALIAS = 6 TKIND_UNION = 7 TKIND_MAX = 8 TYPEKIND = tagTYPEKIND tagINVOKEKIND = c_int # enum INVOKE_FUNC = 1 INVOKE_PROPERTYGET = 2 INVOKE_PROPERTYPUT = 4 INVOKE_PROPERTYPUTREF = 8 INVOKEKIND = tagINVOKEKIND tagDESCKIND = c_int # enum DESCKIND_NONE = 0 DESCKIND_FUNCDESC = 1 DESCKIND_VARDESC = 2 DESCKIND_TYPECOMP = 3 DESCKIND_IMPLICITAPPOBJ = 4 DESCKIND_MAX = 5 DESCKIND = tagDESCKIND tagVARKIND = c_int # enum VAR_PERINSTANCE = 0 VAR_STATIC = 1 VAR_CONST = 2 VAR_DISPATCH = 3 VARKIND = tagVARKIND tagFUNCKIND = c_int # enum FUNC_VIRTUAL = 0 FUNC_PUREVIRTUAL = 1 FUNC_NONVIRTUAL = 2 FUNC_STATIC = 3 FUNC_DISPATCH = 4 FUNCKIND = tagFUNCKIND tagCALLCONV = c_int # enum CC_FASTCALL = 0 CC_CDECL = 1 CC_MSCPASCAL = 2 CC_PASCAL = 2 CC_MACPASCAL = 3 CC_STDCALL = 4 CC_FPFASTCALL = 5 CC_SYSCALL = 6 CC_MPWCDECL = 7 CC_MPWPASCAL = 8 CC_MAX = 9 CALLCONV = tagCALLCONV IMPLTYPEFLAG_FDEFAULT = 1 IMPLTYPEFLAG_FSOURCE = 2 IMPLTYPEFLAG_FRESTRICTED = 4 IMPLTYPEFLAG_FDEFAULTVTABLE = 8 tagTYPEFLAGS = c_int # enum TYPEFLAG_FAPPOBJECT = 1 TYPEFLAG_FCANCREATE = 2 TYPEFLAG_FLICENSED = 4 TYPEFLAG_FPREDECLID = 8 TYPEFLAG_FHIDDEN = 16 TYPEFLAG_FCONTROL = 32 TYPEFLAG_FDUAL = 64 TYPEFLAG_FNONEXTENSIBLE = 128 TYPEFLAG_FOLEAUTOMATION = 256 TYPEFLAG_FRESTRICTED = 512 TYPEFLAG_FAGGREGATABLE = 1024 TYPEFLAG_FREPLACEABLE = 2048 TYPEFLAG_FDISPATCHABLE = 4096 TYPEFLAG_FREVERSEBIND = 8192 TYPEFLAG_FPROXY = 16384 TYPEFLAGS = tagTYPEFLAGS tagFUNCFLAGS = c_int # enum FUNCFLAG_FRESTRICTED = 1 FUNCFLAG_FSOURCE = 2 FUNCFLAG_FBINDABLE = 4 FUNCFLAG_FREQUESTEDIT = 8 FUNCFLAG_FDISPLAYBIND = 16 FUNCFLAG_FDEFAULTBIND = 32 FUNCFLAG_FHIDDEN = 64 FUNCFLAG_FUSESGETLASTERROR = 128 FUNCFLAG_FDEFAULTCOLLELEM = 256 FUNCFLAG_FUIDEFAULT = 512 FUNCFLAG_FNONBROWSABLE = 1024 FUNCFLAG_FREPLACEABLE = 2048 FUNCFLAG_FIMMEDIATEBIND = 4096 FUNCFLAGS = tagFUNCFLAGS tagVARFLAGS = c_int # enum VARFLAG_FREADONLY = 1 VARFLAG_FSOURCE = 2 VARFLAG_FBINDABLE = 4 VARFLAG_FREQUESTEDIT = 8 VARFLAG_FDISPLAYBIND = 16 VARFLAG_FDEFAULTBIND = 32 VARFLAG_FHIDDEN = 64 VARFLAG_FRESTRICTED = 128 VARFLAG_FDEFAULTCOLLELEM = 256 VARFLAG_FUIDEFAULT = 512 VARFLAG_FNONBROWSABLE = 1024 VARFLAG_FREPLACEABLE = 2048 VARFLAG_FIMMEDIATEBIND = 4096 VARFLAGS = tagVARFLAGS PARAMFLAG_NONE = 0 PARAMFLAG_FIN = 1 PARAMFLAG_FOUT = 2 PARAMFLAG_FLCID = 4 PARAMFLAG_FRETVAL = 8 PARAMFLAG_FOPT = 16 PARAMFLAG_FHASDEFAULT = 32 PARAMFLAG_FHASCUSTDATA = 64 ################################################################ # interfaces class ITypeLib(IUnknown): _iid_ = GUID("{00020402-0000-0000-C000-000000000046}") def GetTypeInfoCount(self): "Return the number of type informations" return self.__com_GetTypeInfoCount() def GetTypeInfo(self, index): "Load type info by index" ti = POINTER(ITypeInfo)() self.__com_GetTypeInfo(index, byref(ti)) return ti def GetTypeInfoType(self, index): "Return the TYPEKIND of type information" tkind = TYPEKIND() self.__com_GetTypeInfoType(index, byref(tkind)) return tkind.value def GetTypeInfoOfGuid(self, guid): "Return type information for a guid" ti = POINTER(ITypeInfo)() self.__com_GetTypeInfoOfGuid(byref(guid), byref(ti)) return ti def GetLibAttr(self): "Return type library attributes" ptla = POINTER(TLIBATTR)() self.__com_GetLibAttr(byref(ptla)) result = ptla[0] result.__ref__ = weakref.ref(result, lambda dead: self.ReleaseTLibAttr(ptla)) return result def GetTypeComp(self): "Return an ITypeComp pointer." tc = POINTER(ITypeComp)() self.__com_GetTypeComp(byref(tc)) return tc def GetDocumentation(self, index): "Return documentation for a type description." name = BSTR() docstring = BSTR() helpcontext = DWORD() helpfile = BSTR() self.__com_GetDocumentation(index, byref(name), byref(docstring), byref(helpcontext), byref(helpfile)) return name.value, docstring.value, helpcontext.value, helpfile.value def IsName(self, name, lHashVal=0): "Check if there is type information for this name" result = BOOL() self.__com_IsName(name, lHashVal, byref(result)) return result.value def FindName(self, name, lHashVal=0): # Hm... found = c_ushort(1) tinfo = POINTER(ITypeInfo)() memid = MEMBERID() self.__com_FindName(name, lHashVal, byref(tinfo), byref(memid), byref(found)) if found.value: return memid.value, tinfo def ReleaseTLibAttr(self, ptla): "Release TLIBATTR" self.__com_ReleaseTLibAttr(ptla) ################ class ITypeInfo(IUnknown): _iid_ = GUID("{00020401-0000-0000-C000-000000000046}") def GetTypeAttr(self): "Return TYPEATTR for this type" pta = POINTER(TYPEATTR)() self.__com_GetTypeAttr(byref(pta)) result = pta[0] result.__ref__ = weakref.ref(result, lambda dead: self.ReleaseTypeAttr(pta)) return result def GetTypeComp(self): "Return ITypeComp pointer for this type" tc = POINTER(ITypeComp)() self.__com_GetTypeComp(byref(tc)) return tc def GetFuncDesc(self, index): "Return FUNCDESC for index" pfd = POINTER(FUNCDESC)() self.__com_GetFuncDesc(index, byref(pfd)) fd = pfd[0] fd.__ref__ = weakref.ref(fd, lambda dead: self.ReleaseFuncDesc(pfd)) return fd def GetVarDesc(self, index): "Return VARDESC for index" pvd = POINTER(VARDESC)() self.__com_GetVarDesc(index, byref(pvd)) vd = pvd[0] vd.__ref__ = weakref.ref(vd, lambda dead: self.ReleaseVarDesc(pvd)) return vd def GetNames(self, memid, count=1): "Return names for memid" names = (BSTR * count)() cnames = c_uint() self.__com_GetNames(memid, names, count, byref(cnames)) return names[:cnames.value] def GetRefTypeOfImplType(self, index): "Get the reftype of an implemented type" href = HREFTYPE() self.__com_GetRefTypeOfImplType(index, byref(href)) return href.value def GetImplTypeFlags(self, index): "Get IMPLTYPEFLAGS" flags = c_int() self.__com_GetImplTypeFlags(index, byref(flags)) return flags.value def GetIDsOfNames(self, *names): "Maps function and argument names to identifiers" rgsznames = (c_wchar_p * len(names))(*names) ids = (MEMBERID * len(names))() self.__com_GetIDsOfNames(rgsznames, len(names), ids) return ids[:] ## STDMETHOD(HRESULT, 'Invoke', [PVOID, MEMBERID, WORD, POINTER(DISPPARAMS), POINTER(VARIANT), POINTER(EXCEPINFO), POINTER(UINT)]), def GetDocumentation(self, memid): "Return documentation for a type" name = BSTR() docstring = BSTR() helpcontext = DWORD() helpfile = BSTR() self.__com_GetDocumentation(memid, byref(name), byref(docstring), byref(helpcontext), byref(helpfile)) return name.value, docstring.value, helpcontext.value, helpfile.value ## STDMETHOD(HRESULT, 'GetDllEntry', [MEMBERID, INVOKEKIND, POINTER(BSTR), POINTER(BSTR), POINTER(WORD)]), def GetRefTypeInfo(self, href): "Get type info for reftype" ti = POINTER(ITypeInfo)() self.__com_GetRefTypeInfo(href, byref(ti)) return ti ## STDMETHOD(HRESULT, 'AddressOfMember', [MEMBERID, INVOKEKIND, POINTER(PVOID)]), ## STDMETHOD(HRESULT, 'CreateInstance', [POINTER(IUnknown), POINTER(IID), POINTER(PVOID)]), def GetMops(self, index): "Get marshalling opcodes (whatever that is...)" mops = BSTR() self.__com_GetMops(index, byref(mops)) return mops.value def GetContainingTypeLib(self): "Return index into and the containing type lib itself" index = c_uint() tlib = POINTER(ITypeLib)() self.__com_GetContainingTypeLib(byref(tlib), byref(index)) return index.value, tlib def ReleaseTypeAttr(self, pta): self.__com_ReleaseTypeAttr(pta) def ReleaseFuncDesc(self, pfd): self.__com_ReleaseFuncDesc(pfd) def ReleaseVarDesc(self, pvd): self.__com_ReleaseVarDesc(pvd) ################ class ITypeComp(IUnknown): _iid_ = GUID("{00020403-0000-0000-C000-000000000046}") def Bind(self, name, flags=0, lHashVal=0): "Bind to a name" bindptr = BINDPTR() desckind = DESCKIND() ti = POINTER(ITypeInfo)() self.__com_Bind(name, lHashVal, flags, byref(ti), byref(desckind), byref(bindptr)) kind = desckind.value if kind == DESCKIND_FUNCDESC: fd = bindptr.lpfuncdesc[0] fd.__ref__ = weakref.ref(fd, lambda dead: ti.ReleaseFuncDesc(bindptr.lpfuncdesc)) return "function", fd elif kind == DESCKIND_VARDESC: vd = bindptr.lpvardesc[0] vd.__ref__ = weakref.ref(vd, lambda dead: ti.ReleaseVarDesc(bindptr.lpvardesc)) return "variable", vd elif kind == DESCKIND_TYPECOMP: return "type", bindptr.lptcomp elif kind == DESCKIND_IMPLICITAPPOBJ: raise "NYI" elif kind == DESCKIND_NONE: raise NameError, "Name %s not found" % name def BindType(self, name, lHashVal=0): "Bind a type, and return both the typeinfo and typecomp for it." ti = POINTER(ITypeInfo)() tc = POINTER(ITypeComp)() self.__com_BindType(name, lHashVal, byref(ti), byref(tc)) return ti, tc ################ class ICreateTypeLib(IUnknown): _iid_ = GUID("{00020406-0000-0000-C000-000000000046}") # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 2149 class ICreateTypeInfo(IUnknown): _iid_ = GUID("{00020405-0000-0000-C000-000000000046}") # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 915 ################################################################ # functions def LoadRegTypeLib(guid, wVerMajor, wVerMinor, lcid=0): "Load a registered type library" tlib = POINTER(ITypeLib)() LoadRegTypeLib._api_(byref(guid), wVerMajor, wVerMinor, lcid, byref(tlib)) return tlib LoadRegTypeLib = stdcall(HRESULT, 'oleaut32', [POINTER(GUID), c_ushort, c_ushort, c_ulong, POINTER(POINTER(ITypeLib))]) (LoadRegTypeLib) def LoadTypeLibEx(szFile, regkind=REGKIND_NONE): "Load, and optionally register a type library file" ptl = POINTER(ITypeLib)() LoadTypeLibEx._api_(szFile, regkind, byref(ptl)) return ptl LoadTypeLibEx = stdcall(HRESULT, 'oleaut32', [POINTER(OLECHAR), tagREGKIND, POINTER(POINTER(ITypeLib))]) (LoadTypeLibEx) def LoadTypeLib(szFile): "Load and register a type library file" tlib = POINTER(ITypeLib)() LoadTypeLib._api_(szFile, byref(tlib)) return tlib LoadTypeLib = stdcall(HRESULT, 'oleaut32', [POINTER(OLECHAR), POINTER(POINTER(ITypeLib))]) (LoadTypeLib) 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) def RegisterTypeLib(tlib, fullpath, helpdir=None): "Register a type library in the registry" return RegisterTypeLib._api_(tlib, fullpath, helpdir) RegisterTypeLib = stdcall(HRESULT, 'oleaut32', [POINTER(ITypeLib), POINTER(OLECHAR), POINTER(OLECHAR)]) (RegisterTypeLib) def CreateTypeLib(filename, syskind=SYS_WIN32): "Return a ICreateTypeLib pointer" ctlib = POINTER(ICreateTypeLib)() CreateTypeLib._api_(syskind, filename, byref(ctlib)) return ctlib CreateTypeLib = stdcall(HRESULT, 'oleaut32', [tagSYSKIND, POINTER(OLECHAR), POINTER(POINTER(ICreateTypeLib))]) (CreateTypeLib) def QueryPathOfRegTypeLib(libid, wVerMajor, wVerMinor, lcid=0): "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', [POINTER(GUID), c_ushort, c_ushort, c_ulong, POINTER(BSTR)]) (QueryPathOfRegTypeLib) ################################################################ # Structures class tagTLIBATTR(Structure): # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 4437 pass TLIBATTR = tagTLIBATTR class tagTYPEATTR(Structure): # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 672 pass TYPEATTR = tagTYPEATTR class tagFUNCDESC(Structure): # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 769 pass FUNCDESC = tagFUNCDESC class tagVARDESC(Structure): # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 803 pass VARDESC = tagVARDESC class tagBINDPTR(Union): # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 3075 pass BINDPTR = tagBINDPTR class tagTYPEDESC(Structure): # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 582 pass TYPEDESC = tagTYPEDESC class tagIDLDESC(Structure): # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 633 pass IDLDESC = tagIDLDESC class tagARRAYDESC(Structure): # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 594 pass ################################################################ # interface vtbl definitions ICreateTypeLib._methods_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 2149 STDMETHOD(HRESULT, 'CreateTypeInfo', [LPOLESTR, TYPEKIND, POINTER(POINTER(ICreateTypeInfo))]), STDMETHOD(HRESULT, 'SetName', [LPOLESTR]), STDMETHOD(HRESULT, 'SetVersion', [WORD, WORD]), STDMETHOD(HRESULT, 'SetGuid', [POINTER(GUID)]), STDMETHOD(HRESULT, 'SetDocString', [LPOLESTR]), STDMETHOD(HRESULT, 'SetHelpFileName', [LPOLESTR]), STDMETHOD(HRESULT, 'SetHelpContext', [DWORD]), STDMETHOD(HRESULT, 'SetLcid', [LCID]), STDMETHOD(HRESULT, 'SetLibFlags', [UINT]), STDMETHOD(HRESULT, 'SaveAllChanges', []), ] ITypeLib._methods_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 4455 STDMETHOD(UINT, 'GetTypeInfoCount', []), STDMETHOD(HRESULT, 'GetTypeInfo', [UINT, POINTER(POINTER(ITypeInfo))]), STDMETHOD(HRESULT, 'GetTypeInfoType', [UINT, POINTER(TYPEKIND)]), STDMETHOD(HRESULT, 'GetTypeInfoOfGuid', [POINTER(GUID), POINTER(POINTER(ITypeInfo))]), STDMETHOD(HRESULT, 'GetLibAttr', [POINTER(POINTER(TLIBATTR))]), STDMETHOD(HRESULT, 'GetTypeComp', [POINTER(POINTER(ITypeComp))]), STDMETHOD(HRESULT, 'GetDocumentation', [INT, POINTER(BSTR), POINTER(BSTR), POINTER(DWORD), POINTER(BSTR)]), STDMETHOD(HRESULT, 'IsName', [LPOLESTR, DWORD, POINTER(BOOL)]), STDMETHOD(HRESULT, 'FindName', [LPOLESTR, DWORD, POINTER(POINTER(ITypeInfo)), POINTER(MEMBERID), POINTER(USHORT)]), STDMETHOD(None, 'ReleaseTLibAttr', [POINTER(TLIBATTR)]), ] ITypeInfo._methods_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 3230 STDMETHOD(HRESULT, 'GetTypeAttr', [POINTER(POINTER(TYPEATTR))]), STDMETHOD(HRESULT, 'GetTypeComp', [POINTER(POINTER(ITypeComp))]), STDMETHOD(HRESULT, 'GetFuncDesc', [UINT, POINTER(POINTER(FUNCDESC))]), STDMETHOD(HRESULT, 'GetVarDesc', [UINT, POINTER(POINTER(VARDESC))]), STDMETHOD(HRESULT, 'GetNames', [MEMBERID, POINTER(BSTR), UINT, POINTER(UINT)]), STDMETHOD(HRESULT, 'GetRefTypeOfImplType', [UINT, POINTER(HREFTYPE)]), STDMETHOD(HRESULT, 'GetImplTypeFlags', [UINT, POINTER(INT)]), ## STDMETHOD(HRESULT, 'GetIDsOfNames', [POINTER(LPOLESTR), UINT, POINTER(MEMBERID)]), # this one changed, to accept c_wchar_p array STDMETHOD(HRESULT, 'GetIDsOfNames', [POINTER(c_wchar_p), UINT, POINTER(MEMBERID)]), STDMETHOD(HRESULT, 'Invoke', [PVOID, MEMBERID, WORD, POINTER(DISPPARAMS), POINTER(VARIANT), POINTER(EXCEPINFO), POINTER(UINT)]), STDMETHOD(HRESULT, 'GetDocumentation', [MEMBERID, POINTER(BSTR), POINTER(BSTR), POINTER(DWORD), POINTER(BSTR)]), STDMETHOD(HRESULT, 'GetDllEntry', [MEMBERID, INVOKEKIND, POINTER(BSTR), POINTER(BSTR), POINTER(WORD)]), STDMETHOD(HRESULT, 'GetRefTypeInfo', [HREFTYPE, POINTER(POINTER(ITypeInfo))]), STDMETHOD(HRESULT, 'AddressOfMember', [MEMBERID, INVOKEKIND, POINTER(PVOID)]), STDMETHOD(HRESULT, 'CreateInstance', [POINTER(IUnknown), POINTER(IID), POINTER(PVOID)]), STDMETHOD(HRESULT, 'GetMops', [MEMBERID, POINTER(BSTR)]), STDMETHOD(HRESULT, 'GetContainingTypeLib', [POINTER(POINTER(ITypeLib)), POINTER(UINT)]), STDMETHOD(None, 'ReleaseTypeAttr', [POINTER(TYPEATTR)]), STDMETHOD(None, 'ReleaseFuncDesc', [POINTER(FUNCDESC)]), STDMETHOD(None, 'ReleaseVarDesc', [POINTER(VARDESC)]), ] ITypeComp._methods_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 3090 STDMETHOD(HRESULT, 'Bind', [LPOLESTR, DWORD, WORD, POINTER(POINTER(ITypeInfo)), POINTER(DESCKIND), POINTER(BINDPTR)]), STDMETHOD(HRESULT, 'BindType', [LPOLESTR, DWORD, POINTER(POINTER(ITypeInfo)), POINTER(POINTER(ITypeComp))]), ] ICreateTypeInfo._methods_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 915 STDMETHOD(HRESULT, 'SetGuid', [POINTER(GUID)]), STDMETHOD(HRESULT, 'SetTypeFlags', [UINT]), STDMETHOD(HRESULT, 'SetDocString', [LPOLESTR]), STDMETHOD(HRESULT, 'SetHelpContext', [DWORD]), STDMETHOD(HRESULT, 'SetVersion', [WORD, WORD]), STDMETHOD(HRESULT, 'AddRefTypeInfo', [POINTER(ITypeInfo), POINTER(HREFTYPE)]), STDMETHOD(HRESULT, 'AddFuncDesc', [UINT, POINTER(FUNCDESC)]), STDMETHOD(HRESULT, 'AddImplType', [UINT, HREFTYPE]), STDMETHOD(HRESULT, 'SetImplTypeFlags', [UINT, INT]), STDMETHOD(HRESULT, 'SetAlignment', [WORD]), STDMETHOD(HRESULT, 'SetSchema', [LPOLESTR]), STDMETHOD(HRESULT, 'AddVarDesc', [UINT, POINTER(VARDESC)]), STDMETHOD(HRESULT, 'SetFuncAndParamNames', [UINT, POINTER(LPOLESTR), UINT]), STDMETHOD(HRESULT, 'SetVarName', [UINT, LPOLESTR]), STDMETHOD(HRESULT, 'SetTypeDescAlias', [POINTER(TYPEDESC)]), STDMETHOD(HRESULT, 'DefineFuncAsDllEntry', [UINT, LPOLESTR, LPOLESTR]), STDMETHOD(HRESULT, 'SetFuncDocString', [UINT, LPOLESTR]), STDMETHOD(HRESULT, 'SetVarDocString', [UINT, LPOLESTR]), STDMETHOD(HRESULT, 'SetFuncHelpContext', [UINT, DWORD]), STDMETHOD(HRESULT, 'SetVarHelpContext', [UINT, DWORD]), STDMETHOD(HRESULT, 'SetMops', [UINT, BSTR]), STDMETHOD(HRESULT, 'SetTypeIdldesc', [POINTER(IDLDESC)]), STDMETHOD(HRESULT, 'LayOut', []), ] ################################################################ # Structure fields tagTLIBATTR._fields_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 4437 ('guid', GUID), ('lcid', LCID), ('syskind', SYSKIND), ('wMajorVerNum', WORD), ('wMinorVerNum', WORD), ('wLibFlags', WORD), ] assert sizeof(tagTLIBATTR) == 32, sizeof(tagTLIBATTR) assert alignment(tagTLIBATTR) == 4, alignment(tagTLIBATTR) class N11tagTYPEDESC5DOLLAR_203E(Union): # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 584 pass N11tagTYPEDESC5DOLLAR_203E._fields_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 584 ('lptdesc', POINTER(tagTYPEDESC)), ('lpadesc', POINTER(tagARRAYDESC)), ('hreftype', HREFTYPE), ] assert sizeof(N11tagTYPEDESC5DOLLAR_203E) == 4, sizeof(N11tagTYPEDESC5DOLLAR_203E) assert alignment(N11tagTYPEDESC5DOLLAR_203E) == 4, alignment(N11tagTYPEDESC5DOLLAR_203E) tagTYPEDESC._fields_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 582 # Unnamed field renamed to '_' ('_', N11tagTYPEDESC5DOLLAR_203E), ('vt', VARTYPE), ] assert sizeof(tagTYPEDESC) == 8, sizeof(tagTYPEDESC) assert alignment(tagTYPEDESC) == 4, alignment(tagTYPEDESC) tagIDLDESC._fields_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 633 ('dwReserved', ULONG_PTR), ('wIDLFlags', USHORT), ] assert sizeof(tagIDLDESC) == 8, sizeof(tagIDLDESC) assert alignment(tagIDLDESC) == 4, alignment(tagIDLDESC) tagTYPEATTR._fields_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 672 ('guid', GUID), ('lcid', LCID), ('dwReserved', DWORD), ('memidConstructor', MEMBERID), ('memidDestructor', MEMBERID), ('lpstrSchema', LPOLESTR), ('cbSizeInstance', DWORD), ('typekind', TYPEKIND), ('cFuncs', WORD), ('cVars', WORD), ('cImplTypes', WORD), ('cbSizeVft', WORD), ('cbAlignment', WORD), ('wTypeFlags', WORD), ('wMajorVerNum', WORD), ('wMinorVerNum', WORD), ('tdescAlias', TYPEDESC), ('idldescType', IDLDESC), ] assert sizeof(tagTYPEATTR) == 76, sizeof(tagTYPEATTR) assert alignment(tagTYPEATTR) == 4, alignment(tagTYPEATTR) class N10tagVARDESC5DOLLAR_205E(Union): # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 807 pass N10tagVARDESC5DOLLAR_205E._fields_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 807 ('oInst', DWORD), ('lpvarValue', POINTER(VARIANT)), ] assert sizeof(N10tagVARDESC5DOLLAR_205E) == 4, sizeof(N10tagVARDESC5DOLLAR_205E) assert alignment(N10tagVARDESC5DOLLAR_205E) == 4, alignment(N10tagVARDESC5DOLLAR_205E) class tagELEMDESC(Structure): # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 661 pass class N11tagELEMDESC5DOLLAR_204E(Union): # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 663 pass class tagPARAMDESC(Structure): # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 609 pass class tagPARAMDESCEX(Structure): # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 601 pass LPPARAMDESCEX = POINTER(tagPARAMDESCEX) tagPARAMDESC._fields_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 609 ('pparamdescex', LPPARAMDESCEX), ('wParamFlags', USHORT), ] assert sizeof(tagPARAMDESC) == 8, sizeof(tagPARAMDESC) assert alignment(tagPARAMDESC) == 4, alignment(tagPARAMDESC) PARAMDESC = tagPARAMDESC N11tagELEMDESC5DOLLAR_204E._fields_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 663 ('idldesc', IDLDESC), ('paramdesc', PARAMDESC), ] assert sizeof(N11tagELEMDESC5DOLLAR_204E) == 8, sizeof(N11tagELEMDESC5DOLLAR_204E) assert alignment(N11tagELEMDESC5DOLLAR_204E) == 4, alignment(N11tagELEMDESC5DOLLAR_204E) tagELEMDESC._fields_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 661 ('tdesc', TYPEDESC), # Unnamed field renamed to '_' ('_', N11tagELEMDESC5DOLLAR_204E), ] assert sizeof(tagELEMDESC) == 16, sizeof(tagELEMDESC) assert alignment(tagELEMDESC) == 4, alignment(tagELEMDESC) ELEMDESC = tagELEMDESC tagVARDESC._fields_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 803 ('memid', MEMBERID), ('lpstrSchema', LPOLESTR), # Unnamed field renamed to '_' ('_', N10tagVARDESC5DOLLAR_205E), ('elemdescVar', ELEMDESC), ('wVarFlags', WORD), ('varkind', VARKIND), ] assert sizeof(tagVARDESC) == 36, sizeof(tagVARDESC) assert alignment(tagVARDESC) == 4, alignment(tagVARDESC) tagBINDPTR._fields_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 3075 ('lpfuncdesc', POINTER(FUNCDESC)), ('lpvardesc', POINTER(VARDESC)), ('lptcomp', POINTER(ITypeComp)), ] assert sizeof(tagBINDPTR) == 4, sizeof(tagBINDPTR) assert alignment(tagBINDPTR) == 4, alignment(tagBINDPTR) tagFUNCDESC._fields_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 769 ('memid', MEMBERID), ('lprgscode', POINTER(SCODE)), ('lprgelemdescParam', POINTER(ELEMDESC)), ('funckind', FUNCKIND), ('invkind', INVOKEKIND), ('callconv', CALLCONV), ('cParams', SHORT), ('cParamsOpt', SHORT), ('oVft', SHORT), ('cScodes', SHORT), ('elemdescFunc', ELEMDESC), ('wFuncFlags', WORD), ] assert sizeof(tagFUNCDESC) == 52, sizeof(tagFUNCDESC) assert alignment(tagFUNCDESC) == 4, alignment(tagFUNCDESC) tagPARAMDESCEX._fields_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 601 ('cBytes', DWORD), ('varDefaultValue', VARIANTARG), ] assert sizeof(tagPARAMDESCEX) == 24, sizeof(tagPARAMDESCEX) assert alignment(tagPARAMDESCEX) == 8, alignment(tagPARAMDESCEX) class tagSAFEARRAYBOUND(Structure): # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 226 _fields_ = [ ('cElements', DWORD), ('lLbound', LONG), ] assert sizeof(tagSAFEARRAYBOUND) == 8, sizeof(tagSAFEARRAYBOUND) assert alignment(tagSAFEARRAYBOUND) == 4, alignment(tagSAFEARRAYBOUND) SAFEARRAYBOUND = tagSAFEARRAYBOUND tagARRAYDESC._fields_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 594 ('tdescElem', TYPEDESC), ('cDims', USHORT), ('rgbounds', SAFEARRAYBOUND * 1), ] assert sizeof(tagARRAYDESC) == 20, sizeof(tagARRAYDESC) assert alignment(tagARRAYDESC) == 4, alignment(tagARRAYDESC) --- NEW FILE: automation.py --- # comtypes.automation module from ctypes import * from _ctypes import CopyComPointer from comtypes import IUnknown, GUID, IID, STDMETHOD, BSTR import datetime # for VT_DATE, standard in Python 2.3 and up try: import decimal # standard in Python 2.4 and up except ImportError: decimal = None from ctypes import _SimpleCData class VARIANT_BOOL(_SimpleCData): _type_ = "v" def __repr__(self): return "%s(%r)" % (self.__class__.__name__, self.value) assert(sizeof(VARIANT_BOOL) == 2) # these may be moved elsewhere... WORD = c_ushort UINT = c_uint DWORD = c_ulong LONG = c_long WCHAR = c_wchar LCID = DWORD DISPID = LONG SCODE = LONG VARTYPE = c_ushort DISPATCH_METHOD = 1 DISPATCH_PROPERTYGET = 2 DISPATCH_PROPERTYPUT = 4 DISPATCH_PROPERTYPUTREF = 8 tagINVOKEKIND = c_int INVOKE_FUNC = DISPATCH_METHOD INVOKE_PROPERTYGET = DISPATCH_PROPERTYGET INVOKE_PROPERTYPUT = DISPATCH_PROPERTYPUT INVOKE_PROPERTYPUTREF = DISPATCH_PROPERTYPUTREF INVOKEKIND = tagINVOKEKIND ################################ # helper constants IID_NULL = GUID() riid_null = byref(IID_NULL) _oleaut32 = oledll.oleaut32 # 30. December 1899, midnight. For VT_DATE. _com_null_date = datetime.datetime(1899, 12, 30, 0, 0, 0) ################################################################ # VARIANT, in all it's glory. VARENUM = c_int # enum VT_EMPTY = 0 VT_NULL = 1 VT_I2 = 2 VT_I4 = 3 VT_R4 = 4 VT_R8 = 5 VT_CY = 6 VT_DATE = 7 VT_BSTR = 8 VT_DISPATCH = 9 VT_ERROR = 10 VT_BOOL = 11 VT_VARIANT = 12 VT_UNKNOWN = 13 VT_DECIMAL = 14 VT_I1 = 16 VT_UI1 = 17 VT_UI2 = 18 VT_UI4 = 19 VT_I8 = 20 VT_UI8 = 21 VT_INT = 22 VT_UINT = 23 VT_VOID = 24 VT_HRESULT = 25 VT_PTR = 26 VT_SAFEARRAY = 27 VT_CARRAY = 28 VT_USERDEFINED = 29 VT_LPSTR = 30 VT_LPWSTR = 31 VT_RECORD = 36 VT_INT_PTR = 37 VT_UINT_PTR = 38 VT_FILETIME = 64 VT_BLOB = 65 VT_STREAM = 66 VT_STORAGE = 67 VT_STREAMED_OBJECT = 68 VT_STORED_OBJECT = 69 VT_BLOB_OBJECT = 70 VT_CF = 71 VT_CLSID = 72 VT_VERSIONED_STREAM = 73 VT_BSTR_BLOB = 4095 VT_VECTOR = 4096 VT_ARRAY = 8192 VT_BYREF = 16384 VT_RESERVED = 32768 VT_ILLEGAL = 65535 VT_ILLEGALMASKED = 4095 VT_TYPEMASK = 4095 class tagCY(Structure): _fields_ = [("int64", c_longlong)] CY = tagCY CURRENCY = CY class tagVARIANT(Structure): # The C Header file defn of VARIANT is much more complicated, but # this is the ctypes version - functional as well. class U_VARIANT(Union): _fields_ = [ ("VT_BOOL", VARIANT_BOOL), ("VT_I1", c_byte), ("VT_I2", c_short), ("VT_I4", c_long), ("VT_INT", c_int), ("VT_UI1", c_ubyte), ("VT_UI2", c_ushort), ("VT_UI4", c_ulong), ("VT_UINT", c_uint), ("VT_R4", c_float), ("VT_R8", c_double), ("VT_CY", c_longlong), ("c_wchar_p", c_wchar_p), ("c_void_p", c_void_p), ("bstrVal", BSTR), ] _fields_ = [("vt", VARTYPE), ("wReserved1", c_ushort), ("wReserved2", c_ushort), ("wReserved3", c_ushort), ("_", U_VARIANT) ] def __init__(self, *args): if args: self.value = args[0] # see also c:/sf/pywin32/com/win32com/src/oleargs.cpp 54 def _set_value(self, value): _oleaut32.VariantClear(byref(self)) if value is None: self.vt = VT_NULL elif isinstance(value, int): self.vt = VT_I4 self._.VT_I4 = value elif isinstance(value, long): self.vt = VT_I4 u = self._ u.VT_I4 = value if u.VT_I4 != value: self.vt = VT_R8 u.VT_R8 = float(value) elif isinstance(value, float): self.vt = VT_R8 self._.VT_R8 = value elif isinstance(value, unicode): self.vt = VT_BSTR self._.c_void_p = _oleaut32.SysAllocStringLen(value, len(value)) elif isinstance(value, str): self.vt = VT_BSTR value = unicode(value) self._.c_void_p = _oleaut32.SysAllocStringLen(value, len(value)) elif isinstance(value, bool): self.vt = VT_BOOL self._.VT_BOOL = value elif isinstance(value, datetime.datetime): delta = value - _com_null_date # a day has 24 * 60 * 60 = 86400 seconds com_days = delta.days + (delta.seconds + delta.microseconds * 1e-6) / 86400. self.vt = VT_DATE self._.VT_R8 = com_days elif decimal is not None and isinstance(value, decimal.Decimal): self._.VT_CY = int(round(value * 10000)) elif isinstance(value, POINTER(IDispatch)): CopyComPointer(value, byref(self._)) self.vt = VT_DISPATCH elif isinstance(value, POINTER(IUnknown)): CopyComPointer(value, byref(self._)) self.vt = VT_UNKNOWN else: raise "NYI", value # buffer -> SAFEARRAY of VT_UI1 ? # c:/sf/pywin32/com/win32com/src/oleargs.cpp 197 def _get_value(self): vt = self.vt if vt in (VT_EMPTY, VT_NULL): return None elif vt == VT_I1: return self._.VT_I1 elif vt == VT_I2: return self._.VT_I2 elif vt == VT_I4: return self._.VT_I4 elif vt == VT_INT: return self._.VT_INT elif vt == VT_UI1: return self._.VT_UI1 elif vt == VT_UI2: return self._.VT_UI2 elif vt == VT_UI4: return self._.VT_UI4 elif vt == VT_UINT: return self._.VT_UINT elif vt == VT_R4: return self._.VT_R4 elif vt == VT_R8: return self._.VT_R8 elif vt == VT_BOOL: return self._.VT_BOOL elif vt == VT_BSTR: return self._.bstrVal or u'' elif vt == VT_DATE: days = self._.VT_R8 return datetime.timedelta(days=days) + _com_null_date elif vt == VT_CY: if decimal is not None: return self._.VT_CY / decimal.Decimal("10000") else: return self._.VT_CY / 10000. else: raise "NYI", vt # these are missing: ## getter[VT_ERROR] ## getter[VT_ARRAY] ## getter[VT_BYREF|VT_UI1] ## getter[VT_BYREF|VT_I2] ## getter[VT_BYREF|VT_I4] ## getter[VT_BYREF|VT_R4] ## getter[VT_BYREF|VT_R8] ## getter[VT_BYREF|VT_BOOL] ## getter[VT_BYREF|VT_ERROR] ## getter[VT_BYREF|VT_CY] ## getter[VT_BYREF|VT_DATE] ## getter[VT_BYREF|VT_BSTR] ## getter[VT_BYREF|VT_UNKNOWN] ## getter[VT_BYREF|VT_DISPATCH] ## getter[VT_BYREF|VT_ARRAY] ## getter[VT_BYREF|VT_VARIANT] ## getter[VT_BYREF] ## getter[VT_BYREF|VT_DECIMAL] ## getter[VT_BYREF|VT_I1] ## getter[VT_BYREF|VT_UI2] ## getter[VT_BYREF|VT_UI4] ## getter[VT_BYREF|VT_INT] ## getter[VT_BYREF|VT_UINT] value = property(_get_value, _set_value) VARIANT = tagVARIANT VARIANTARG = VARIANT ##from _ctypes import VARIANT_set ##import new ##VARIANT.value = property(VARIANT._get_value, new.instancemethod(VARIANT_set, None, VARIANT)) class tagEXCEPINFO(Structure): pass tagEXCEPINFO._fields_ = [ ('wCode', WORD), ('wReserved', WORD), ('bstrSource', BSTR), ('bstrDescription', BSTR), ('bstrHelpFile', BSTR), ('dwHelpContext', DWORD), ('pvReserved', c_void_p), ('pfnDeferredFillIn', WINFUNCTYPE(HRESULT, POINTER(tagEXCEPINFO))), ('scode', SCODE), ] assert sizeof(tagEXCEPINFO) == 32, sizeof(tagEXCEPINFO) assert alignment(tagEXCEPINFO) == 4, alignment(tagEXCEPINFO) EXCEPINFO = tagEXCEPINFO class tagDISPPARAMS(Structure): _fields_ = [ # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 696 ('rgvarg', POINTER(VARIANTARG)), ('rgdispidNamedArgs', POINTER(DISPID)), ('cArgs', UINT), ('cNamedArgs', UINT), ] assert sizeof(tagDISPPARAMS) == 16, sizeof(tagDISPPARAMS) assert alignment(tagDISPPARAMS) == 4, alignment(tagDISPPARAMS) DISPPARAMS = tagDISPPARAMS DISPID_VALUE = 0 DISPID_UNKNOWN = -1 DISPID_PROPERTYPUT = -3 DISPID_NEWENUM = -4 DISPID_EVALUATE = -5 DISPID_CONSTRUCTOR = -6 DISPID_DESTRUCTOR = -7 DISPID_COLLECT = -8 class IDispatch(IUnknown): _iid_ = GUID("{00020400-0000-0000-C000-000000000046}") _methods_ = [ STDMETHOD(HRESULT, 'GetTypeInfoCount', [POINTER(UINT)]), STDMETHOD(HRESULT, 'GetTypeInfo', [UINT, LCID, POINTER(c_void_p)]), STDMETHOD(HRESULT, 'GetIDsOfNames', [POINTER(IID), POINTER(c_wchar_p), UINT, LCID, POINTER(DISPID)]), STDMETHOD(HRESULT, 'Invoke', [DISPID, POINTER(IID), LCID, WORD, POINTER(DISPPARAMS), POINTER(VARIANT), POINTER(EXCEPINFO), POINTER(UINT)]), ] def GetTypeInfoCount(self): r = c_uint() self.__com_GetTypeInfoCount(byref(r)) return r.value def GetTypeInfo(self, index=0, lcid=0): "Return typeinfo" # index=0 specifies typeinfo for IDispatch from typeinfo import ITypeInfo p = POINTER(ITypeInfo)() self.__com_GetTypeInfo(index, lcid, byref(p)) return p def GetIDsOfNames(self, *names, **kw): lcid = kw.pop("lcid", 0) assert not kw arr = (c_wchar_p * len(names))(*names) ids = (DISPID * len(names))() self.__com_GetIDsOfNames(riid_null, arr, len(names), lcid, ids) return [i for i in ids] def Invoke(self, dispid, *args, **kw): _invkind = kw.pop("_invkind", 1) # DISPATCH_METHOD _lcid = kw.pop("_lcid", 0) result = VARIANT() excepinfo = EXCEPINFO() argerr = c_uint() if _invkind == 1: # method dp = DISPPARAMS() dp.cArgs = len(args) dp.cNamedArgs = 0 dp.rgvarg = (VARIANT * len(args))() for i, a in enumerate(args): dp.rgvarg[len(args) - i - 1].value = a elif _invkind == 4: # propput assert len(args) == 1 dp = DISPPARAMS() dp.cArgs = 1 dp.cNamedArgs = 1 dp.rgvarg = pointer(VARIANT()) dp.rgvarg[0].value = args[0] dp.rgdispidNamedArgs = pointer(DISPID(DISPID_PROPERTYPUT)) try: self.__com_Invoke(dispid, riid_null, _lcid, _invkind, byref(dp), byref(result), byref(excepinfo), byref(argerr)) except WindowsError: # , details: # we should parse exception information now, depending on # the errno we got. XXX Problem (?): error numbers are # signed integers, although in C the HRESULT values are # normally written in hex notation. raise # 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 = { VT_R4: c_float, VT_R8: c_double, VT_I4: c_long, VT_INT: c_int, VT_UI4: c_ulong, VT_VOID: None, VT_BSTR: BSTR, VT_DISPATCH: POINTER(IDispatch), VT_HRESULT: HRESULT, VT_VARIANT: VARIANT, VT_BOOL: VARIANT_BOOL, } ################################################################ if 0 and __name__ == "__main__": oledll.ole32.CoInitialize(None) p = POINTER(IDispatch)() clsid = GUID.from_progid("InternetExplorer.Application") # Internet.Explorer oledll.ole32.CoCreateInstance(byref(clsid), None, 7, # CLSCTX byref(p._iid_), byref(p)) for i in range(p.GetTypeInfoCount()): print p.GetTypeInfo(i) id_quit = p.GetIDsOfNames("Quit")[0] id_visible = p.GetIDsOfNames("Visible")[0] id_navigate = p.GetIDsOfNames("Navigate2")[0] print p.GetIDsOfNames("Navigate2", "URL", "Flags", "TargetFrameName", "PostData", "Headers") try: ## p.Invoke(id_visible, True, wFlags = 4) ## p.Invoke(id_navigate, "http://www.python.org/", 1) import time ## time.sleep(3) print p.Invoke(id_quit) ## p.Invoke(id_quit, True, wFlags = 1) finally: oledll.ole32.CoUninitialize() |
From: Thomas H. <th...@us...> - 2005-03-10 14:33:09
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29178 Modified Files: __init__.py Log Message: Integrate recent _ctypes improvements, use paramflags to create high level com wrappers. STDMETHOD is still backwards compatible. COMMETHOD implements the full functionality. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** __init__.py 7 Mar 2005 09:25:37 -0000 1.15 --- __init__.py 10 Mar 2005 14:32:58 -0000 1.16 *************** *** 1,4 **** --- 1,10 ---- # requires ctypes 0.9.3 or later import new + + try: + set + except NameError: + from sets import Set as set + from ctypes import * from comtypes.GUID import GUID *************** *** 64,90 **** ################################################################ - - from _ctypes import CFuncPtr as _CFuncPtr, FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL - from ctypes import _win_functype_cache - - # For backward compatibility, the signature of WINFUNCTYPE cannot be - # changed, so we have to add this - which is basically the same, but - # allows to specify parameter flags from the win32 PARAMFLAGS - # enumeration. Maybe later we have to add optional default parameter - # values and parameter names as well. - def COMMETHODTYPE(restype, argtypes, paramflags): - flags = paramflags - try: - return _win_functype_cache[(restype, argtypes, flags)] - except KeyError: - class WinFunctionType(_CFuncPtr): - _argtypes_ = argtypes - _restype_ = restype - _flags_ = _FUNCFLAG_STDCALL - parmflags = flags - _win_functype_cache[(restype, argtypes, flags)] = WinFunctionType - return WinFunctionType - - ################################################################ # The metaclasses... --- 70,73 ---- *************** *** 97,101 **** # XXX ??? First assign the _methods_, or first create the POINTER class? # or does it not matter? ! if methods: setattr(cls, "_methods_", methods) --- 80,84 ---- # XXX ??? First assign the _methods_, or first create the POINTER class? # or does it not matter? ! if methods is not None: setattr(cls, "_methods_", methods) *************** *** 130,134 **** def _make_methods(self, methods): ! # we insist on an _iid_ in THIS class" try: self.__dict__["_iid_"] --- 113,117 ---- def _make_methods(self, methods): ! # we insist on an _iid_ in THIS class! try: self.__dict__["_iid_"] *************** *** 136,152 **** raise AttributeError, "must define _iid_" vtbl_offset = self.__get_baseinterface_methodcount() ! for i, (restype, name, argtypes) in enumerate(methods): # the function prototype prototype = WINFUNCTYPE(restype, *argtypes) ! mth = prototype(i + vtbl_offset, name) ! mth = new.instancemethod(mth, None, self) ! impl = getattr(self, name, None) ! if impl is None: ! # don't overwrite a custom implementation setattr(self, name, mth) ! # attach it with a private name (__com_AddRef, for example) mthname = "_%s__com_%s" % (self.__name__, name) setattr(self, mthname, mth) # metaclass for COM interface pointer classes class _compointer_meta(type(c_void_p), _cominterface_meta): --- 119,176 ---- raise AttributeError, "must define _iid_" vtbl_offset = self.__get_baseinterface_methodcount() ! ! getters = {} ! setters = {} ! ! # create low level, and maybe high level, COM method implementations. ! for i, item in enumerate(methods): ! restype, name, argtypes, paramflags, idlflags, doc = item # the function prototype prototype = WINFUNCTYPE(restype, *argtypes) ! # function calling the COM method slot ! func = prototype(i + vtbl_offset, name, paramflags) ! func.__doc__ = doc ! # and an unbound method, so we don't have to pass 'self' ! mth = new.instancemethod(func, None, self) ! ! # is it a property set or property get? ! is_prop = False ! # The following code assumes that the docstrings for ! # propget and propput are identical. ! if "propget" in idlflags: ! assert name.startswith("_get_") ! propname = name[len("_get_"):] ! getters[propname, doc, len(argtypes)] = func ! is_prop = True ! elif "propput" in idlflags: ! assert name.startswith("_set_") ! propname = name[len("_set_"):] ! setters[propname, doc, len(argtypes)] = func ! is_prop = True ! ! # We install the method in the class, except when it's a ! # property accessor. And we make sure we don't overwrite ! # a property that's already present in the class. ! if not is_prop and not hasattr(self, name): setattr(self, name, mth) ! ! # attach it with a private name (__com_AddRef, for example), ! # so that custom method implementations can call it. mthname = "_%s__com_%s" % (self.__name__, name) setattr(self, mthname, mth) + # create properties + for item in set(getters.keys()) | set(getters.keys()): + name, doc, nargs = item + if nargs == 1: + prop = property(getters.get(item), setters.get(item), doc=doc) + else: + # Hm, must be a descriptor where the __get__ method + # returns a bound object having __getitem__ and + # __setitem__ methods. + ## prop = named_property(getters.get(item), setters.get(item), doc=doc) + raise "Not Yet Implemented" + setattr(self, name, prop) + # metaclass for COM interface pointer classes class _compointer_meta(type(c_void_p), _cominterface_meta): *************** *** 163,167 **** # Hm, shouldn't this be in c_void_p ? def __nonzero__(self): ! # get the value property of the baseclass, this is the pointer value # both variants below do the same, and both are equally unreadable ;-) return bool(super(_compointer_base, self).value) --- 187,191 ---- # Hm, shouldn't this be in c_void_p ? def __nonzero__(self): ! # get the .value property of the baseclass, this is the pointer value # both variants below do the same, and both are equally unreadable ;-) return bool(super(_compointer_base, self).value) *************** *** 170,173 **** --- 194,201 ---- def __eq__(self, other): # COM identity rule + # + # XXX To compare COM interface pointers, should we + # automatically QueryInterface for IUnknown on both items, and + # compare the pointer values? if not isinstance(other, _compointer_base): return False *************** *** 179,182 **** --- 207,211 ---- # for symmetry with other ctypes types # XXX explain + # XXX check if really needed def __get_value(self): return self *************** *** 205,209 **** def STDMETHOD(restype, name, argtypes=()): "Specifies a COM method slot" ! return restype, name, argtypes ################################################################ --- 234,277 ---- def STDMETHOD(restype, name, argtypes=()): "Specifies a COM method slot" ! # restype, name, argtypes, paramflags, idlflags, docstring ! return restype, name, argtypes, None, (), None ! ! PARAMFLAGS = { ! "in": 1, ! "out": 2, ! "retval": 8, ! } ! ! ! class helpstring(object): ! def __init__(self, text): ! self.text = text ! ! def encode_idl(names): ! # sum up all values found in PARAMFLAGS, ignoring all others. ! result = sum([PARAMFLAGS.get(n, 0) for n in names]) ! return result & 3 # that's what _ctypes accept ! ! def COMMETHOD2(idlflags, restype, methodname, *argspec): ! paramflags = [] ! argtypes = [] ! ! def unpack(idl, typ, name=None): ! return idl, typ, name ! ! # collect all helpstring instances ! helptext = [t.text for t in idlflags if isinstance(t, helpstring)] ! # join them together(does this make sense?) and replace by None if empty. ! helptext = "".join(helptext) or None ! ! for item in argspec: ! idl, typ, argname = unpack(*item) ! paramflags.append((encode_idl(idl), argname)) ! argtypes.append(typ) ! if "propget" in idlflags: ! methodname = "_get_%s" % methodname ! elif "propput" in idlflags: ! methodname = "_put_%s" % methodname ! return restype, methodname, tuple(argtypes), tuple(paramflags), tuple(idlflags), helptext ################################################################ *************** *** 228,231 **** --- 296,301 ---- return p + # these are only so that they get a docstring. + # XXX There should be other ways to install a docstring. def AddRef(self): "Increase the internal refcount by one" |
From: Thomas H. <th...@us...> - 2005-03-10 14:03:31
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20588 Modified Files: test_paramflags.py Log Message: Make the test actually work. Index: test_paramflags.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_paramflags.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_paramflags.py 10 Mar 2005 13:57:27 -0000 1.5 --- test_paramflags.py 10 Mar 2005 14:03:21 -0000 1.6 *************** *** 166,170 **** We construct two functions having the same signature: ! >>> def p(a, b, c, d): return a+c, b+d >>> f = get_inout_args_func() >>> f(a=1, b=3) # ctypes function --- 166,172 ---- We construct two functions having the same signature: ! >>> def p(a, b, c, d): ! ... return a+c, b+d ! ... >>> f = get_inout_args_func() >>> f(a=1, b=3) # ctypes function *************** *** 197,210 **** ... TypeError: int expected instead of str instance ! HU? >>> f(a=1, b="y", p1=3, p2=4) Traceback (most recent call last): ... ArgumentError: argument 3: exceptions.TypeError: int expected instead of str instance - HU? >>> f(a=1, b=2, p1="3", p2=4) Traceback (most recent call last): ... ! ArgumentError: argument 3: exceptions.TypeError: int expected instead of str instance >>> """ --- 199,214 ---- ... TypeError: int expected instead of str instance ! >>> ! ! # The following examples show problems with the error messages: ! >>> f(a=1, b="y", p1=3, p2=4) Traceback (most recent call last): ... ArgumentError: argument 3: exceptions.TypeError: int expected instead of str instance >>> f(a=1, b=2, p1="3", p2=4) Traceback (most recent call last): ... ! TypeError: int expected instead of str instance >>> """ |
From: Thomas H. <th...@us...> - 2005-03-10 13:57:39
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18987 Modified Files: test_paramflags.py Log Message: Accept None as paramflags, and accept None as parametername. Makes the api more convenient. Index: test_paramflags.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_paramflags.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_paramflags.py 9 Mar 2005 16:43:12 -0000 1.4 --- test_paramflags.py 10 Mar 2005 13:57:27 -0000 1.5 *************** *** 46,49 **** --- 46,71 ---- self.failUnlessRaises(TypeError, lambda: proto("TwoOutArgs", dll, ((2,),))) + # These are correct + 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 + proto("TwoOutArgs", dll, None) + # and we CAN pass None instead of the parameter names + proto("TwoOutArgs", dll, + ((1, None),) + ) + proto("TwoOutArgs", dll, + ((1, None, 'DefaultVal'),) + ) + + def test_usage_sample(self): import _ctypes_test *************** *** 134,137 **** --- 156,220 ---- self.assertRaises(TypeError, lambda: func(a=1, b=3, p1=3)) + def get_inout_args_func(): + """ + Error messages may be somewhat confusing, when parameters are + missing. This example shows how the error messsages differ from + normal Python functions. The reason is the way arguments are + processed when paramflags are present, and named arguments are + used. + + We construct two functions having the same signature: + + >>> def p(a, b, c, d): return a+c, b+d + >>> f = get_inout_args_func() + >>> f(a=1, b=3) # ctypes function + Traceback (most recent call last): + ... + TypeError: required argument 'p1' missing + >>> p(a=1, b=3) # normal python function + Traceback (most recent call last): + ... + TypeError: p() takes exactly 4 non-keyword arguments (2 given) + >>> + >>> f(1, 2) + Traceback (most recent call last): + ... + TypeError: required argument 'b' missing + >>> f(1, 2, 3, 4) + (3, 7) + >>> f(x=1, y=2) + Traceback (most recent call last): + ... + TypeError: required argument 'a' missing + >>> p(x=1, y=2) + Traceback (most recent call last): + ... + TypeError: p() got an unexpected keyword argument 'x' + >>> + + >>> f("x", "y") + Traceback (most recent call last): + ... + TypeError: int expected instead of str instance + HU? + >>> f(a=1, b="y", p1=3, p2=4) + Traceback (most recent call last): + ... + ArgumentError: argument 3: exceptions.TypeError: int expected instead of str instance + HU? + >>> f(a=1, b=2, p1="3", p2=4) + Traceback (most recent call last): + ... + ArgumentError: argument 3: exceptions.TypeError: int expected instead of str instance + >>> + """ + import _ctypes_test + dll = CDLL(_ctypes_test.__file__) + # 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"))) + return func + + if __name__ == "__main__": unittest.main() |
From: Thomas H. <th...@us...> - 2005-03-10 13:57:06
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18826 Modified Files: _ctypes.c Log Message: Accept None as paramflags, and accept None as parametername. Makes the api more convenient. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.218 retrieving revision 1.219 diff -C2 -d -r1.218 -r1.219 *** _ctypes.c 10 Mar 2005 08:52:56 -0000 1.218 --- _ctypes.c 10 Mar 2005 13:56:55 -0000 1.219 *************** *** 2292,2295 **** --- 2292,2301 ---- return 1; + if (!PyTuple_Check(paramflags)) { + PyErr_SetString(PyExc_TypeError, + "paramflags must be a tuple or None"); + return 0; + } + len = PyTuple_GET_SIZE(paramflags); if (len != PyTuple_GET_SIZE(dict->argtypes)) { *************** *** 2305,2309 **** PyObject *defval; PyObject *typ; ! if (!PyArg_ParseTuple(item, "i|sO", &flag, &name, &defval)) { PyErr_SetString(PyExc_TypeError, "paramflags must be a sequence of (int [,string [,value]]) tuples"); --- 2311,2315 ---- PyObject *defval; PyObject *typ; ! if (!PyArg_ParseTuple(item, "i|zO", &flag, &name, &defval)) { PyErr_SetString(PyExc_TypeError, "paramflags must be a sequence of (int [,string [,value]]) tuples"); *************** *** 2345,2350 **** PyObject *paramflags = NULL; ! if (!PyArg_ParseTuple(args, "sO|O!", &name, &dll, &PyTuple_Type, ¶mflags)) return NULL; obj = PyObject_GetAttrString(dll, "_handle"); --- 2351,2358 ---- PyObject *paramflags = NULL; ! if (!PyArg_ParseTuple(args, "sO|O", &name, &dll, ¶mflags)) return NULL; + if (paramflags == Py_None) + paramflags = NULL; obj = PyObject_GetAttrString(dll, "_handle"); *************** *** 2413,2418 **** PyObject *paramflags = NULL; ! if (!PyArg_ParseTuple(args, "is|O!", &index, &name, &PyTuple_Type, ¶mflags)) return NULL; if (!_validate_paramflags(type, paramflags)) --- 2421,2428 ---- PyObject *paramflags = NULL; ! if (!PyArg_ParseTuple(args, "is|O", &index, &name, ¶mflags)) return NULL; + if (paramflags == Py_None) + paramflags = NULL; if (!_validate_paramflags(type, paramflags)) *************** *** 2647,2651 **** char *name = NULL; PyObject *defval = NULL; ! if (!PyArg_ParseTuple(item, "i|sO", &flag, &name, &defval)) { /* Hm. Either we should raise a more specific error here, or we should validate the paramflags tuple --- 2657,2661 ---- 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 |
From: Thomas H. <th...@us...> - 2005-03-10 13:40:33
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15008 Modified Files: setup.py Log Message: Document the test commands. Index: setup.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/setup.py,v retrieving revision 1.116 retrieving revision 1.117 diff -C2 -d -r1.116 -r1.117 *** setup.py 9 Mar 2005 20:35:26 -0000 1.116 --- setup.py 10 Mar 2005 13:40:22 -0000 1.117 *************** *** 41,45 **** # Original version of this class posted # by Berthold Hoellmann to dis...@py... ! description = "test the distribution prior to install" user_options = [ --- 41,45 ---- # Original version of this class posted # by Berthold Hoellmann to dis...@py... ! description = "run unittests each in a separate process" user_options = [ *************** *** 198,201 **** --- 198,204 ---- class test_local(test): + description = "run the unittests (includes doctests)" + + # This also runs doctest testcases contained in the test modules def run(self): import glob, unittest, doctest, new |