Re: [comtypes-users] the comtypes bug?
The error shows that comtypes.client code is using Python 3 syntax. Where did you get Comtypes 0.6.2 from? are you sure it was a Python 2 build and not a Python 3 one? Mick On 10/03/2013 1:45 PM, vic wrote: when i import comtypes.client i see : import comtypes.client Traceback (most recent call last): File pyshell#0, line 1, in module import comtypes.client File D:\program files (x86)\python27\lib\site-packages\comtypes\__init__.py, line 826 class _compointer_base(c_void_p, metaclass=_compointer_meta): ^ SyntaxError: invalid syntax i used win7 64bit python 2.7.3 comtypes 0.6.2 and anyone can help me? -- Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester Wave(TM): Endpoint Security, Q1 2013 and remains a good choice in the endpoint security space. For insight on selecting the right partner to tackle endpoint security challenges, access the full report. http://p.sf.net/sfu/symantec-dev2dev ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users -- -- Michael Curran Director, NV Access Limited Ph + 61 7 5667 8372 www.nvaccess.org -- Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester Wave(TM): Endpoint Security, Q1 2013 and remains a good choice in the endpoint security space. For insight on selecting the right partner to tackle endpoint security challenges, access the full report. http://p.sf.net/sfu/symantec-dev2dev ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Problem calling method
Hi, Recently we noticed the same problem with our project. We access the MS Word object model via IDispatch, but there is a GetPoint method which takes left, top, hight and width as byref arguments. As comtypes doesn't support vt_byref out of the box, our first idea was to rewrite the code for VARIANT._set_value(), and provide comtypes with a patch. However, looking at VARIANT._set_value(): There are lots of returns all the way through the function, so its clear it would have to be rewritten almost from the ground up. And since I'm not too skilled with all of the VARIANT types, I don't want to break any existing logic. So, what we currently do, is when our project imports comtypes at initialization time, we do the following: #Monkey patch comtypes to support byref in variants from comtypes.automation import VARIANT, VT_BYREF from ctypes import cast, c_void_p from _ctypes import _Pointer oldVARIANT_value_fset=VARIANT.value.fset def newVARIANT_value_fset(self,value): realValue=value if isinstance(value,_Pointer): try: value=value.contents except (NameError,AttributeError): pass oldVARIANT_value_fset(self,value) if realValue is not value: self.vt|=VT_BYREF self._.c_void_p=cast(realValue,c_void_p) VARIANT.value=property(VARIANT.value.fget,newVARIANT_value_fset,VARIANT.value.fdel) So, from then on, when ever passing an instance of a POINTER of a ctypes type, comtypes will automatically treet the value as byref. Some example code for GetPoint: from ctypes import c_long, pointer rangeLeft=c_long() rangeTop=c_long() rangeWidth=c_long() rangeHeight=c_long() self.obj.WinwordWindowObject.getPoint(pointer(rangeLeft),pointer(rangeTop),pointer(rangeWidth),pointer(rangeHeight),self._rangeObj) I would probably prefer that we use ctypes.byref, rather than ctypes.POINTER, as the name relates better to what its doing. But, ctypes.byref(x) yields an object who's type is something like type(cArgObject), which I can't find anywhere in ctypes or _ctypes. So, it would be a little hard for VARIANT._set_value to properly identify that value was a byref. Interestingly enough though, if comtypes compiles the actual COM interfaces for the MS Word object model, POINTER is used anyway, so I guess POINTER is ok. Mick On 13/02/2010 10:48 AM, Pablo Bianucci wrote: Hi Thomas! On Fri, 12 Feb 2010, Thomas Heller wrote: Exactly. I cannot provide a patch, but here's a code snippet that creates such a beast: Yes! It works!! This is the final working snippet: snip travel = c_float(0) v = VARIANT() v._.c_void_p = cast(pointer(travel), c_void_p) v.vt = VT_BYREF | VT_R4 mode = c_int(0) vm = VARIANT() vm._.c_void_p = cast(pointer(mode), c_void_p) vm.vt = VT_BYREF | VT_I4 try: piezo1.GetMaxTravel(APTPiezoLib.CHAN1_ID, v) piezo1.GetControlMode(APTPiezoLib.CHAN1_ID, vm) except Exception, e: print Exception:, e print travel.value, mode.value /snip If you are not careful when setting the types you get a Type Mismatch error (even though the protoypes in the help were the same, I had to use different types for the two funcions there). I wonder why you can't integrate this into the package. I'm fine as this, as this will let me write the program I need, but it would be more user friendly to be able use pointers as arguments for the method invocation. But I don't understand COM internals, so it could be that implementing that could lead to other problems. Thank you very much for your help! Bye Good Luck! Pablo. P.S.: If you visit Canada and stay at a city I happen to be living in, consider yourself invited to a drink. ;-) -- SOLARIS 10 is the OS for Data Centers - provides features such as DTrace, Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW http://p.sf.net/sfu/solaris-dev2dev ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users -- Michael Curran President, NV Access Inc Email: m...@nvaccess.org Website: www.nvaccess.org ABN 61773362390. -- SOLARIS 10 is the OS for Data Centers - provides features such as DTrace, Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW http://p.sf.net/sfu/solaris-dev2dev ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Proposal to add IServiceProvider to comtypes
Hi Thomas, Your definition of IServiceProvider works perfect for me. I am happy for it to go in comtypes/__init__.py, but for now though, again I have attached a servprov.py with your changes, plus testQueryService.py which is some code that shows how IServiceProvider can be used. running testQueryService.py starts Internet Explorer, navigates to 'about:blank', and query interface to IServiceProvider on the body element, and uses queryService to get to an IAccessible (MSAA) object. Hope this code will be useful enough to be made in to a testcase. Mick On 17/06/2009 5:01 AM, Thomas Heller wrote: Michael Curran schrieb: Hi, Attached is a module which contains a definition of the IServiceProvider interface. This interface is provided as an interface on COM objects to make it possible to switch to a different service, related to the object. For example given an IAccessible (MSAA) object, you can use its IServiceProvider interface to get to other things such as an IHTMLElement (when dealing with MSHTML), or IAccessible2 etc. Info on this interface can be found at: http://msdn.microsoft.com/en-us/library/cc678965%28VS.85%29.aspx Generally, the interface seems simple enough (only one method) and generic enough so that it is justified to add it to the comtypes\__init__.py module. It would also be great if you can supply a small code snippet that uses the IServiceProvider.QueryService method, so that I can make a simple test for it. IServiceProvider is defined in servprov.idl in the Microsoft Platform SDK. A part from providing a standard comtypes definition of the interface, I have also overridden the QueryService method, to be a little more pythonic, so that you can pass an interface as the second argument, rather than just an IID, and then it actually returns an instance of that interface, rather than just an IUnknown pointer. I propose that this module (servprov.py) be added to comtypes, so that others can make use of this, rather than having to code the definition manually. Note also that IServiceProvider is not included in any standard type library that I know of, so defining this interface specifically is the only way to use it. Hopefully I have formatted the file suitably for inclusion. # -*- coding: mbcs -*- from ctypes import * from comtypes import * class IServiceProvider(IUnknown): _case_insensitive_ = True _iid_ = GUID('{6D5140C1-7436-11CE-8034-00AA006009FA}') _idlflags_ = [] I'd suggest to remove the _case_insensitive_ and _idlflags_ attributes. #Overridden QueryService to make it nicer to use (passing it an interface and it returns a pointer to that interface) def QueryService(self,serviceIID,interface): if not issubclass(interface,IUnknown): raise ValueError(interface argument must be a COM interface) interfaceIID=interface._iid_ if not isinstance(serviceIID,GUID): raise ValueError(serviceIID argument must be a GUID) p=self._QueryService(byref(serviceIID),byref(interfaceIID)) return POINTER(interface)(p) I think the issubclass tests can also be omitted. IServiceProvider._methods_ = [ COMMETHOD([], HRESULT, 'QueryService', ( ['in'], POINTER(GUID), 'guidService' ), ( ['in'], POINTER(GUID), 'riid' ), ( ['out'], POINTER(c_void_p), 'ppvObject' )), COMMETHOD([], HRESULT, 'RemoteQueryService', ( ['in'], POINTER(GUID), 'guidService' ), ( ['in'], POINTER(GUID), 'riid' ), ( ['out'], POINTER(POINTER(IUnknown)), 'ppvObject' )), ] The definition for 'RemoteQueryService' must be removed. The IServiceProvider has only ONE method (the midl-compiler sometimes creates C/C++ wrapper methods called Remote..., but I guess these have somehow to do with marshalling or something like that). All in all, this is how I would write this interface: class IServiceProvider(IUnknown): _iid_ = GUID('{6D5140C1-7436-11CE-8034-00AA006009FA}') # Overridden QueryService to make it nicer to use (passing it an # interface and it returns a pointer to that interface) def QueryService(self, serviceIID, interface): p = POINTER(interface)() self._QueryService(byref(serviceIID), byref(interface._iid_), byref(p)) return p _methods_ = [ COMMETHOD([], HRESULT, 'QueryService', ( ['in'], POINTER(GUID), 'guidService' ), ( ['in'], POINTER(GUID), 'riid' ), ( ['in'], POINTER(c_void_p), 'ppvObject' )) ] Does this work for you? BTW: The reason that the third parameter must be declared 'in' is that still 'out' parameters are somewhat broken in comtypes. # -*- coding: mbcs -*- from ctypes import * from comtypes import * class IServiceProvider(IUnknown): _iid_ = GUID('{6D5140C1-7436-11CE-8034-00AA006009FA}') # Overridden QueryService to make it nicer to use (passing it an # interface and it returns
[comtypes-users] Proposal to add IServiceProvider to comtypes
Hi, Attached is a module which contains a definition of the IServiceProvider interface. This interface is provided as an interface on COM objects to make it possible to switch to a different service, related to the object. For example given an IAccessible (MSAA) object, you can use its IServiceProvider interface to get to other things such as an IHTMLElement (when dealing with MSHTML), or IAccessible2 etc. Info on this interface can be found at: http://msdn.microsoft.com/en-us/library/cc678965%28VS.85%29.aspx IServiceProvider is defined in servprov.idl in the Microsoft Platform SDK. A part from providing a standard comtypes definition of the interface, I have also overridden the QueryService method, to be a little more pythonic, so that you can pass an interface as the second argument, rather than just an IID, and then it actually returns an instance of that interface, rather than just an IUnknown pointer. I propose that this module (servprov.py) be added to comtypes, so that others can make use of this, rather than having to code the definition manually. Note also that IServiceProvider is not included in any standard type library that I know of, so defining this interface specifically is the only way to use it. Hopefully I have formatted the file suitably for inclusion. Thanks Mick # -*- coding: mbcs -*- from ctypes import * from comtypes import * class IServiceProvider(IUnknown): _case_insensitive_ = True _iid_ = GUID('{6D5140C1-7436-11CE-8034-00AA006009FA}') _idlflags_ = [] #Overridden QueryService to make it nicer to use (passing it an interface and it returns a pointer to that interface) def QueryService(self,serviceIID,interface): if not issubclass(interface,IUnknown): raise ValueError(interface argument must be a COM interface) interfaceIID=interface._iid_ if not isinstance(serviceIID,GUID): raise ValueError(serviceIID argument must be a GUID) p=self._QueryService(byref(serviceIID),byref(interfaceIID)) return POINTER(interface)(p) IServiceProvider._methods_ = [ COMMETHOD([], HRESULT, 'QueryService', ( ['in'], POINTER(GUID), 'guidService' ), ( ['in'], POINTER(GUID), 'riid' ), ( ['out'], POINTER(c_void_p), 'ppvObject' )), COMMETHOD([], HRESULT, 'RemoteQueryService', ( ['in'], POINTER(GUID), 'guidService' ), ( ['in'], POINTER(GUID), 'riid' ), ( ['out'], POINTER(POINTER(IUnknown)), 'ppvObject' )), ] -- Crystal Reports - New Free Runtime and 30 Day Trial Check out the new simplified licensing option that enables unlimited royalty-free distribution of the report engine for externally facing server and web deployment. http://p.sf.net/sfu/businessobjects___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] ITypeLib::ReleaseTLibAttr definition wrong in comtypes
Perhaps you can use None, I'm not sure. However, I used c_voidp, not c_void_p. c_voidp as far as I am aware means void parameter, not void pointer. c_voidp can be used in ctypes function declarations for the return type when it is void. c_void_p is void pointer. Mick On 15/03/2009 5:38 AM, Michael Eddington wrote: Correct me if I'm wrong, but I think you just defined it to return a void* (c_voidp). I think you just want to set the return type to None for a void. mike On Sat, Mar 14, 2009 at 3:14 AM, Michael Curran michaeldamiencur...@gmail.com wrote: Hi, I have noticed that the definition of ITypeLib::ReleaseTLibAttr seems to be wrong in typeinfo.py, in comtypes. In XP and Vista it works ok oddly enough, but in particular builds of Windows 7 it does not. In fact, in these builds, many times when it is called, it throws an _ctypes.COMError, with an error code of -65535. I think the reason for this is that it is defined in comtypes as returning an hresult, but it really returns void. Its definition in comtypes looks like this: COMMETHOD([], HRESULT, 'ReleaseTLibAttr', (['in'], POINTER(TLIBATTR))) ] But in OAIdl.idl, it looks like this: void ReleaseTLibAttr( [in] TLIBATTR * pTLibAttr ); So I think the comtypes definition should be: COMMETHOD([], c_voidp, 'ReleaseTLibAttr', (['in'], POINTER(TLIBATTR))) ] I have tested this change on the particular builds of Windows7 the problem occured on and it definitly fixes it. It also does not seem to cause any problems on Vista, but I havn't been testing for long. Thanks Mick -- Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are powering Web 2.0 with engaging, cross-platform capabilities. Quickly and easily build your RIAs with Flex Builder, the Eclipse(TM)based development software that enables intelligent coding and step-through debugging. Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users -- Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are powering Web 2.0 with engaging, cross-platform capabilities. Quickly and easily build your RIAs with Flex Builder, the Eclipse(TM)based development software that enables intelligent coding and step-through debugging. Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users -- Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are powering Web 2.0 with engaging, cross-platform capabilities. Quickly and easily build your RIAs with Flex Builder, the Eclipse(TM)based development software that enables intelligent coding and step-through debugging. Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Comtypes dynamic Dispatch and MSHTML interfaces
Hi, Here is a python script that shows the problem in action. By default the script raises an error when trying to retreave the offsetTop property. However, if you uncomment the commented line just before that, then it works. Also, if using win32com.client.Dispatch instead of comtypes.client.CreateObject(...,dynamic=True) the script also works. --Script-- import comtypes.client print starting IE... , appObj=comtypes.client.CreateObject('internetExplorer.Application',dynamic=True) print appObj appObj.Visible=True print Opening URL... , appObj.Navigate('about:blank') print done print fetching text range for body... , range=appObj.Document.body.createTextRange() #range=comtypes.client.dynamic._Dispatch(range._comobj) print range print OffsetTop property: , offsetTop=range.offsetTop print %s%offsetTop --end of script -- Mick On 16/01/2009 2:44 AM, Thomas Heller wrote: Michael Curran schrieb: Hi, I have been using comtypes 0.6 dynamic dispatch support with the MSHTML interfaces in Internet Explorer and Outlook Express. I have noticed that for some reason, comtypes is unable to find some properties, yet win32com can. Specifically, using a text range object retreaved by IHTMLElement::createTextRange(), I can not access any properties that exist on the IHTMLTextRangeMetrics interface. The text range object supports IHTMLTxtRange and IHTMLTextRangeMetrics, I'm not sure about any other interfaces. I can access any property on the IHTMLTxtRange interface, but not IHTMLTextRangeMetrics. Michael, can you please post some example code that does not work in comtypes but does work in pywin32? I have found a temporary solution to the problem, and that is: * In clude a comtypes.client.dynamic._Dispatch instance on the comtypes.client.lazybind.Dispatch instance, called something like '_dispatch'. *inlazybind.Dispatch.__bind: catch NameError as well as comtypes.COMError when calling iTypeComp.bind. *in lazybind.Dispatch.__getattr__: if a property can not be found with __bind (descr is None), then return getattr(self._dispatch,name). This will allow the name to be fetched using GetIDsOfNames etc. This solution fixes the problem for me, and I can now access some more of the properties. I have no idea why ITypeComp.bind cannot find the properties. Interested if anyone has any idea why this might occure, or whether this solution is appropriate. -- This SF.net email is sponsored by: SourcForge Community SourceForge wants to tell your story. http://p.sf.net/sfu/sf-spreadtheword ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
[comtypes-users] Comtypes dynamic Dispatch and MSHTML interfaces
Hi, I have been using comtypes 0.6 dynamic dispatch support with the MSHTML interfaces in Internet Explorer and Outlook Express. I have noticed that for some reason, comtypes is unable to find some properties, yet win32com can. Specifically, using a text range object retreaved by IHTMLElement::createTextRange(), I can not access any properties that exist on the IHTMLTextRangeMetrics interface. The text range object supports IHTMLTxtRange and IHTMLTextRangeMetrics, I'm not sure about any other interfaces. I can access any property on the IHTMLTxtRange interface, but not IHTMLTextRangeMetrics. I have found a temporary solution to the problem, and that is: * In clude a comtypes.client.dynamic._Dispatch instance on the comtypes.client.lazybind.Dispatch instance, called something like '_dispatch'. *inlazybind.Dispatch.__bind: catch NameError as well as comtypes.COMError when calling iTypeComp.bind. *in lazybind.Dispatch.__getattr__: if a property can not be found with __bind (descr is None), then return getattr(self._dispatch,name). This will allow the name to be fetched using GetIDsOfNames etc. This solution fixes the problem for me, and I can now access some more of the properties. I have no idea why ITypeComp.bind cannot find the properties. Interested if anyone has any idea why this might occure, or whether this solution is appropriate. Thanks Mick -- This SF.net email is sponsored by: SourcForge Community SourceForge wants to tell your story. http://p.sf.net/sfu/sf-spreadtheword ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] dyndispatch branch
Hi Thomas, Support for getEvents/showEvents would be great with dynDispatch. However I must admit, that I didn't realize that it was possible to support events purely with IDispatch. My project doesn't technically rely on support for COM events in the places where we use IDispatch, though that is not to say it won't in the future. But, I think that releasing a comtypes with dynDispatch so far is a great step forward, even with out events. Of course, then at a later stage if events were added that would also be great. Thanks Mick On 27/11/2008 8:06 AM, Thomas Heller wrote: Michael Curran schrieb: Thanks. Interested to know what the timeframe is now in regards to getting dyndispatch merged in to trunk? I've been trying dyndispatch as a replacement to win32com IDispatch for my own project, and performance is just the same, if not a little better. Were there any other features that needed to be added? I'm certainly happy with how it is at the moment. What I have added a few days ago was a way to access constants in a type library from objects exposing IDispatch::GetTypeInfo() and ITypeComp (in the dyndisp branch). It works for early bound, late bound, and lazy bound objects (are these correct names to a native english speaker?). There is now a function (actually a class) named comtypes.client.Constants. It can be used in this way: from comtypes.client import CreateObject, Constants x = CreateObject(Excel.Application) c = Constants(x) c.xlSaveChanges 1 c.xlDoNotSaveChanges 2 A nice improvement would of course be to make events (ShowEvents, GetEvents) work without generating the typelib wrapper, but that is too much work at the moment. Don't you need it? I'd be happy to help with writing tests and or documentation if that is something that has to be done before merging --- Obviously I am quite keen to see this merged :) My original plan was to work on compatibility with Python 3, and release then, but if you're really waiting for it I can as well release now. Mick Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] dyndispatch branch
Hi Thomas, In what svn revision did you add those changes you mentioned? (implemented __call__ and extended __getitem__ etc)? The last time comtypes/client/lazzybind.py was changed was in r450... is this correct? (svn tree is up to r459). I apologize if you just hadn't got around to committing it. Mick On 8/11/2008 7:49 AM, Thomas Heller wrote: Michael Curran schrieb: Hi, Thanks for the explanation. If comtypes is already using the [] syntax for early bound interfaces, and if that is the most suitable way, then that sounds ok to me. I agree that it is important to keep dyn dispatch interfaces as compatible with early bound interfaces as possible. So, I also in that case do also think that __call__ should be implemented. In order so that named properties with optional or needed arguments can be called with () for getting, even though you could also use the [] syntax as well. In our projects, and I suspect others, comtypes early bound propgets with arguments are called with (), I never new about []. Hm, I didn't remember it but property access syntax IS even documented for quite some time here: http://starship.python.net/crew/theller/comtypes/#accessing-properties Besides that, I have now in the dyndispatch-branch added the call syntax to get properties, and extended the __getitem__ and __setitem__ calls so that [...] property access (both get and put) works with one or more arguments, in the same way as the early bound case. Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] dyndispatch branch
Thanks. Interested to know what the timeframe is now in regards to getting dyndispatch merged in to trunk? I've been trying dyndispatch as a replacement to win32com IDispatch for my own project, and performance is just the same, if not a little better. Were there any other features that needed to be added? I'm certainly happy with how it is at the moment. I'd be happy to help with writing tests and or documentation if that is something that has to be done before merging --- Obviously I am quite keen to see this merged :) Mick On 20/11/2008 7:04 AM, Thomas Heller wrote: Michael Curran schrieb: Hi Thomas, In what svn revision did you add those changes you mentioned? (implemented __call__ and extended __getitem__ etc)? The last time comtypes/client/lazzybind.py was changed was in r450... is this correct? (svn tree is up to r459). Michael, sorry - indeed it had forgotten to commit it. It is now in, as svn revision 460. - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] dyndispatch branch
Hi, Thanks for the explanation. If comtypes is already using the [] syntax for early bound interfaces, and if that is the most suitable way, then that sounds ok to me. I agree that it is important to keep dyn dispatch interfaces as compatible with early bound interfaces as possible. So, I also in that case do also think that __call__ should be implemented. In order so that named properties with optional or needed arguments can be called with () for getting, even though you could also use the [] syntax as well. In our projects, and I suspect others, comtypes early bound propgets with arguments are called with (), I never new about []. Mick On 28/10/2008 6:06 AM, Thomas Heller wrote: Michael Curran schrieb: Hi Thomas, The new changes to the dyndispatch branch sound great. I'm definitely still interested in the branch, and am hoping that once its stable enough that it can be merged in to trunk so I can start using it properly in the NVDA project. I havn't fully tested out all the changes you mentioned yet, but from what you have written, they all sound ok to me. I'm also glad you decided against any early binding, as they really would have limited performance, specially if the user was not going to use a lot of the methods on a particular interface. One thing: comtypes.client.lazybind.NamedProperty. You ask in the comments whether or not to support __call__. I would definitely say yes, but I don't quite understand what you are doing with __getitem__. I assume that NamedProperties in COM can have more than one optional argument, and if this os so, then calling would be the only way to pass more than one argument. From what I can see, at the moment we're supposed to do something like bla.accName[0] rather than bla.accName(0)? Also, what happens if you want to not provide the optional argument at all? Obviously in python you can't write bla.accName[], but with __call__ you could at least do bla.accName() The idea was to use always use [...] notation for property accesses with arguments (what I call NamedProperties). This is because of the symmetry between getting and setting: print foo[a, b, c] foo[a, b, c] = something Normal properties (not taking arguments) are accessed in the usual way: print foo.attr foo.attr = something Ok, so the problem occurs when accessing a property which takes optional arguments, and you don't want to pass any. Obviously 'foo.attr()' does work, but how to set it - 'foo.attr() = something' is invalid syntax, but 'foo.attr[] = something' and 'print foo.attr[]' are invalid as well. AFAIK pywin32 solves that by creating separate setter functions like 'foo._setattr(something)' but I don't like this. So I decided to do it differently in comtypes (the approach I describe here is already implemented for the usual early bound COM calls, but not yet for the comtypes.client.lazybind or comtypes.client.dynamic module): Python lets you call __getitem__(self, index) with any number of arguments, although the syntax is a little bit strange first. It becomes clearer when you think of the signature __getitem__(self, *args). Here is an interactive session; it shows that you can call x[...] with more one or more arguments: class X(object): ... def __getitem__(self, *args): ... print __getitem__, args ... def __setitem__(self, *args): ... print __setitem__, args ... x = X() x[()] __getitem__ ((),) x[1] __getitem__ (1,) x[1, 2] __getitem__ ((1, 2),) x[1, 2, 3] __getitem__ ((1, 2, 3),) The strange thing is that calling 'x[()]' behaves in the same way as the hypothetical call 'x[]' had been made. BTW: the same holds for __setitem__(self, *args): x[()] = 42 __setitem__ ((), 42) x[1] = 42 __setitem__ (1, 42) x[1, 2] = 42 __setitem__ ((1, 2), 42) x[1, 2, 3] = 42 __setitem__ ((1, 2, 3), 42) x[()] = 42 __setitem__ ((), 42) x[1] = 42 __setitem__ (1, 42) x[1, 2] = 42 __setitem__ ((1, 2), 42) x[1, 2, 3] = 42 __setitem__ ((1, 2, 3), 42) One obvious fault of the above is that it is impossible to access properties with named arguments (but comtypes.client.dynamic and comtypes.client.lazybind does not accept named arguments anyway in methods currently). Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based
Re: [comtypes-users] dyndispatch branch
Hi Thomas, The new changes to the dyndispatch branch sound great. I'm definitely still interested in the branch, and am hoping that once its stable enough that it can be merged in to trunk so I can start using it properly in the NVDA project. I havn't fully tested out all the changes you mentioned yet, but from what you have written, they all sound ok to me. I'm also glad you decided against any early binding, as they really would have limited performance, specially if the user was not going to use a lot of the methods on a particular interface. One thing: comtypes.client.lazybind.NamedProperty. You ask in the comments whether or not to support __call__. I would definitely say yes, but I don't quite understand what you are doing with __getitem__. I assume that NamedProperties in COM can have more than one optional argument, and if this os so, then calling would be the only way to pass more than one argument. From what I can see, at the moment we're supposed to do something like bla.accName[0] rather than bla.accName(0)? Also, what happens if you want to not provide the optional argument at all? Obviously in python you can't write bla.accName[], but with __call__ you could at least do bla.accName() Perhaps I don't quite follow what your __getitem__ etc is doing. Would you be able to provide me with an explination on this? Thanks again Mick On 25/10/2008 5:09 AM, Thomas Heller wrote: Thomas Heller schrieb: Michael Curran schrieb: Hi, After testing with the dyndispatch svn branch of comtypes, I relised that there is a problem with dynamic Dispatch and IEnumVARIANT being used together. The problem is that If you enumerate a dynamic dispatch object (you get an IEnumVARIANT object some how from it), that IEnumVARIANT object doesn't know it has to provide dynamic=True to variant._get_value. So, the IEnumVARIANT's next method returns objects with fully generated interfaces, rather than just dynamic dispatch support. I would suggest that comtypes.automation.IEnumVARIANT have an instance variable called dynamic, which can be set to False by default. But if true, then the Next method should provide dynamic=True when getting variants. This suggestion is now implemented. Here is the current state of the dyndispatch branch (in case Michael or someone else still cares about this stuff, which I hope!): The comtypes.client.CreateObject() function accepts an optional keyword argument 'dynamic' that defaults to False. The behaviour of the function is unchanged if 'dynamic=False', comtypes tries to generate and then imports the wrapper code for the object it creates. When CreateObject(..., dynamic=True) is called then no wrapper code is generated (well, if the object supports the IDispatch interface). If the com object exposes NO type information, then, as before, an instance of comtypes.client.dynamic._Dispatch is returned supporting method calls and property access by pure dynamic dispatch calls (GetIDsOfNames, and Invoke calls). If the com object exposes type information (and supports the ITypeComp interface), then an instance of the new module comtypes.client.lazybind.Dispatch is returned. Methods and properties are then bound by name, using ITypeComp.Bind() calls. Distributing the code for dynamic dispatch with or without type info over two different modules make the code a lot cleaner. 3. Calling IDispatch.Invoke(...) is currently fairly slow. This is because packing the arguments into the DISPPARAMS instance with ctypes is very slow. This can probably be made a lot faster with a compiled comtypes extension module. Also, the signature of IDispatch.Invoke() in comtypes is wrong, it was a mistake to pass the invkind flags only as keyword dictionary (and I thought it was clever!). This remains, but can be solved later if it turns out that it is really a problem. I would very much like to keep comtypes without any extension module, pure python. 4. After playing around a little, I have the impression that it may be better to create a separate subclass of a _Dispatch base class for each COM object, and to generate the methods and properties in the __init__ method from typeinfo. The big advantage is that the resulting class has all methods (with parameter names!) and properties that are available in the COM object, so code completion, inspection, and so on will work. This I did not implement, it sounds much like early binding with all its problems that we want to get rid of. The dynamic dispatch code does everything on demand only (although I tried to cache the results of expensive calls to ITypeComp). - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin
Re: [comtypes-users] thoughts and a patch for dynamic IDispatch
Hi Thomas, I really appreciate you taking the time to look at my patch, many thanks. The idea about adding a dynamic keyword arg to createObject etc sounds fine to me. I had talked about this idea with another developer on my project, but we couldn't work out the best way to have invoke not generate code. Your idea about having a dyn_value on a variant sounds good. I'm sure this will all work with the way you have proposed, but I would like to note, just so it is taken in to consideration, that when we use comtypes in NVDA, we generally don't make use of CreateObject etc, but rather we create a NULL interface pointer for the interface we are interested in, and then using byref, we use particular win32 api functions such as AccessibleObjectFromEvent in oleacc.dll to place the real pointer value in our pointer. This is because much of the time we retreave COM pointers from particular Windows etc. So all I guess I'm saying here is that one of our use patterns with comtypes would be starting straight from an IDispatch which was arbitrarily retreaved, not necessarily through createObject etc. So as long as we can create a dynamic dispatch object with what ever means we see fit, and what ever attributes we ask for no code is generated, than this is fine. However, your solution fits this model ok, I just wanted to point that out for future reference that is all. Thanks again Mick Thomas Heller wrote: Michael Curran schrieb: In regards to use cases, I guess the reason why I want this functionality is for the main project I am working on, which is the NVDA screen reader, at http://www.nvda-project.org/ In that project we use comtypes very heavily, for MSAA, SAPI, RichEdit controls, etc. But for our support for MS Word and Excel etc, we currently use pywin32. Reason being that with comtypes the COM interfaces are just way too large and take way too long to generate. Pywin32 does a great job with dynamic dispatch, though its just annoying having to use two Python COM implementations in the same project. So this is why I would like to improve comtypes dynamic dispatch support. I have also updated the patch, again, now fixing a few little issues with the non-typeinfo dynamic dispatch support, and more importantly, I have added some more tests to test_dyndispatch.py which tests many of my code changes using MSAA objects. Michael, thanks for the patch and sorry for the late reply. I have now made up my mind and have a plan how I want to integrate this into comtypes. 1. I will add new named parameter to the object creation functions in comtypes.client, CreateObject, GetActiveObject, and CoGetObject. This parameter will be named 'dynamic' and will default to False. If one of these functions is called with 'dynamic = True', then a dynamic dispatch object will be returned (an instance of comtypes.client.dynamic._Dispatch). No wrapper code will be generated, and even if wrapper code is already there it will not be used. 2. It must be made sure that such an object will not trigger the code generation when an attribute is accessed or a method is called. Since all attribute and method access goes through the 'IDispatch.Invoke' implementation in comtypes.automation, the last line in this method (which now is ' return result.value') this is the place where it can be implemented. 'result' is a VARIANT instance, and I will add a new property - maybe result.dyn_value - that will return a dynamic dispatch object. 3. There are some good ideas in your patch for comtypes.client.dynamic - thanks for that. But it seems there are still also a few problems with it which need to be fixed. I will release the current code ASAP as comtypes-0.5.1 before starting with these changes, hopefully it is not too late for you. - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users