The difference in behaviour of ITypeComp.Bind() is interesting, and I agree is the main problem here. However, from what you have said, I'm surprised that a makepy-backed implementation isn't working for you. The first thing we do when getting an object is ask for its type info so we can get the CLSID of the object. We then lookup the CLSID in our makepy/gencache map, and if we find it, the entire process you outline is skipped - we already know the dispid and flags for each of the attributes. Thus, given your objects implement most of the typeinfo stuff correctly, I'm surprised this isn't working for you.
Have you tried running makepy on your typelib? Cheers, Mark From: Obendorf, Keston [mailto:[EMAIL PROTECTED] Sent: Thursday, 18 September 2008 10:08 AM To: [EMAIL PROTECTED]; python-win32@python.org Subject: RE: [python-win32] COM: Parameterless functions seen as properties Thanks. I don't think the issue is that GetTypeInfo() is not returning anything, but it's returning something that cannot be used properly. I wrote another implementation of the parameterless function, this time in C++. The implementation in C++ works just fine: retStr = Dispatch("c++implementation").getNLType() --causes no exceptions and works as intended. I've been stepping through the CDispatch creation process, which on the account of both C# and C++ implementations seems to go OK. In both run-throughs, dynamic is able to get both typeinfo and typecomp. I judge that this happens because in both cases the _olerepr_ of the CDispatch object is a LazyDispatchItem not DispatchItem, which only happens if both typeinfo and typecomp are defined. The implementations diverge, however, in _getattr_, specifically when calling __LazyMap__. The C++ implementation returns a 1, whereas the C# implementation returns None. This is due to the fact that in _LazyAddAttr_ , typecomp.Bind returns (0, None) for all invoke types for the C# implementation whereas the C++ implementation binds to INVOKE_FUNC. (This leads me to conclude that the typecomp for the C# implementation is bad in some way. That is probably more an issue for a C# mailing list. I don't think it's Python's fault.) _getattr_ allows recovery from this issue with a last ditch effort, which you reference in your post as the second thing that could be going on. Unfortunately, it sets the invoke type by default to pythoncom.INVOKE_PROPERTYGET. C# does not seem to care that its function is not a property, and returns an evaluation of the function rather than throwing an exception. I don't know if there is a way to prevent this behavior. I feel like there's not much information in this posting for all its words. =( I figured out HOW it is failing, but not exactly WHY. It looks like this is a problem in the way C# handles IDispatch and ITypeInfo. P.S. I am new to this whole mailing-list thing, so I don't know exactly what e-mail addresses to send this post to. Let's hope it winds up in the right place. Thanks, Keston _____ From: Mark Hammond [mailto:[EMAIL PROTECTED] On Behalf Of Mark Hammond Sent: Monday, September 15, 2008 4:06 PM To: Obendorf, Keston; python-win32@python.org Subject: RE: [python-win32] COM: Parameterless functions seen as properties It looks like 2 things are going on: * Your object isn't returning typelib info to Python when it asks. If your IDispatch returned something from GetTypeInfo() we could use, this wouldn't happen. * Without a typelib, Python can't tell if a reference to 'a.foo' is going to end up being a method call or not (ie, from Python's POV, a.foo() is just a property fetch for 'foo' and then calling the result.) When making a property reference, win32com checks for the ERRORS_BAD_CONTEXT values defined in win32com\client\dynamic.py - if it sees one of those errors, it assumes it really hit a method and handles it accordgingly. But - in your case, your object is succeeding! The simplest thing to do here is to have your object refuse to work as a property using one of the standard error codes, and Python will then try it as a method. Mark From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Obendorf, Keston Sent: Tuesday, 16 September 2008 8:19 AM To: python-win32@python.org Subject: [python-win32] COM: Parameterless functions seen as properties I'm doing COM development in both Python and C#. Things are working well, but I'm running into an issue where trying to get parameterless function returns the return value of that function, which Python then tries to call, causing an error. The C# class is an implementation of an IDL-defined interface. //IDL interface IService : IDispatch { [id(101)] HRESULT foo([out, retval] BSTR * pstr); } //C# [ComImport] [Guid("/*GUID of IService*/")] interface IService{} [ComVisible(true)] [ProgId("bar")] [Guid("Valid GUID")] public class bar : IService { public bar(){} public string foo() { return "foo"; } } Now, getting a Dispatch of "bar" in Python is where the issue lies. from win32com.client import Dispatch bar = Dispatch("bar") str = bar.foo() >>TypeError: 'unicode' object is not callable This is only a problem with the C# class. If the interface is implemented in Pythong, the above code will work. Now, this issue can be fixed by adding in _FlagAsMethod before calling bar.foo() bar._FlagAsMethod("foo") I really don't want to have to do that every time I try to call a parameterless method of a C# COM-object from Python. That's a huge headache, especially because I am trying to keep the language any one component is written in a non-issue. I've started to dive into the source code of dynamic.py and other Client modules to try and figure out how I can make this distinction at Dispatch-time, but it's rough going understanding everything that's going on in there. Does anyone have any pointers or a straight up solution to this problem?
_______________________________________________ python-win32 mailing list python-win32@python.org http://mail.python.org/mailman/listinfo/python-win32