[python-win32] Passing parameters to FoxPro COM methods

Richard Lawrence wyley.r at gmail.com
Wed Jan 5 19:11:19 CET 2011


Dear Pythonistas,

I still haven't figured out a way around this issue:

> 2) Regarding late binding: the way that attributes are looked up in
> win32com.client.dynamic.CDispatch.__getattr__ seems not to play nicely
> with Foxpro's way of responding to queries about the interface.  I
> think what's happening is that __getattr__('some_method') attempts
> first to call Invoke with pythoncom.INVOKE_PROPERTYGET as the
> invocation type.  As the win32com documentation indicates sometimes
> happens, Foxpro seems to respond to this by *calling* the method.

I can confirm that this is the problem I am having (or at least one of
them).  The way win32com.client.dynamic.CDispatch looks up attributes
-- by first trying an invocation with INVOKE_PROPERTYGET and only
building a method if that raises a pythoncom.com_error -- doesn't work
for me, because when the requested attribute is a method, this
invocation simply calls the method and returns the result, rather than
throwing an error.

(At least some of the methods on the component that I am interested in
using seem to be implemented in such a way that they have default
behavior when called with no arguments, though I am not sure if this
is the way Foxpro implements *all* method calls.  That is, I'm not
sure if my DLL's author simply provided fallback functionality on
these methods, where Foxpro would normally throw an error if these
methods were not called with the right number of arguments, or if
Foxpro itself simply assigns default values to all missing arguments,
and my DLL's author is working within that limitation.)

> This means that if, say, some_method returns a string, then a call
> like:
>
> c.d.some_method(param1, param2)
>
> blows up because __getattr__('some_method') returns a string value
> that results from calling some_method, rather than a reference to the
> method, so I get a TypeError to the effect that a string value is not
> callable; whereas
>
> c.d.some_method
>
> actually calls the method and returns a value, but of course I can't
> pass the call any parameters.

So, I'm still wondering: what's the best way to use PythonCOM with
late binding such that I can:

- prevent component *methods* from being mistakenly called (with no
arguments) by an Invoke with pythoncom.INVOKE_PROPERTYGET as the
invocation type
- call component methods (with arguments) using an Invoke with
python.INVOKE_FUNC as the invocation type
- continue to get component *properties* via an Invoke with
pythoncom.INVOKE_PROPERTYGET as the invocation type

Is overriding __getattr__ the way to go here?  Or is there a more
data-driven approach?

Thanks!

Richard


More information about the python-win32 mailing list