[scripting] DOpusFactory does not provide methods (Python)

Methods are not visible in DOpusFactory object. It seems there has been already a similar (and fixed) problem once with Python.

Script:

[code]@script python

def OnClick(ClickData):

factory = DOpus.Create()
DOpus.Output('Factory type: ' + str(type(factory)))
try:
myvec = factory.Vector()
except Exception as e:
DOpus.Output('Vector: ' + str(e))
try:
myvec = factory.StringSetI()
except Exception as e:
DOpus.Output('StringSetI: ' + str(e))
try:
myvec = factory.StringSet()
except Exception as e:
DOpus.Output('StringSet: ' + str(e))
try:
myvec = factory.Map()
except Exception as e:
DOpus.Output('Map: ' + str(e))
try:
myvec = factory.Date()
except Exception as e:
DOpus.Output('Date: ' + str(e))
try:
myvec = factory.Command()
except Exception as e:
DOpus.Output('Command: ' + str(e))
try:
myvec = factory.Blob()
except Exception as e:
DOpus.Output('Blob: ' + str(e))
[/code]

Output:

[quote]Factory type: <class 'win32com.client.dynamic.CDispatch'>
Vector: .Vector
StringSetI: .StringSetI
StringSet: .StringSet
Map: .Map
Date: .Date
Command: .Command
Blob: .Blob[/quote]

Full exception message:

[quote]myvec = factory.Blob()
^
Traceback (most recent call last):
File "", line 33, in OnClick
myvec = factory.Blob()
File "C:\Python34\lib\site-packages\win32com\client\dynamic.py", line 522, in getattr
raise AttributeError("%s.%s" % (self.username, attr))
AttributeError: .Blob
(0x80020009)
[/quote]

What similar problem are you referring to?

After searching, I think my memory joined two cases - DOpus object not accessible fixed in 11.3.1 and Vars.Exists() malfunctioning fixed in 11.4.2. So while the problem may be similar, it's no exact copy of any of the earlier ones.

It looks like you have to tell Python that methods with no arguments are actually methods; otherwise it assumes they're properties. See e.g. this Stack Overflow question.

The following seems to work:

DOpus._FlagAsMethod("Create") factory = DOpus.Create() DOpus.Output('Factory type: ' + str(type(factory))) try: myvec = factory._make_method_("Vector") except Exception as e: DOpus.Output('Vector: ' + str(e)) try: myvec = factory._make_method_("StringSetI") except Exception as e: DOpus.Output('StringSetI: ' + str(e))

Seriously, you really should be looking at using JScript for this. Python is far more trouble than it's worth.

Hello,

This is not quite true, see (note commented out third to last line):

[code]@script python

def OnClick(ClickData):

DOpus._FlagAsMethod("Create")
factory = DOpus.Create()
DOpus.Output('Factory type: ' + str(type(factory)))
factory._FlagAsMethod("Vector")
myvec = factory.Vector(7)
DOpus.Output('Vector capacity: ' + str(myvec.capacity))
#myvec._FlagAsMethod("reserve")
myvec.reserve(300)
DOpus.Output('Vector capacity: ' + str(myvec.capacity))[/code]

This writes only:

[quote]Factory type: <class 'win32com.client.dynamic.CDispatch'>
Vector capacity: 7
[/quote]
plus throws debug:

[quote]pythoncom error: Python error invoking COM method.

Traceback (most recent call last):
File "C:\Python34\lib\site-packages\win32com\server\policy.py", line 278, in Invoke
return self.invoke(dispid, lcid, wFlags, args)
File "C:\Python34\lib\site-packages\win32com\server\policy.py", line 688, in invoke
return S_OK, -1, self.invokeex(dispid, lcid, wFlags, args, None, None)
File "C:\Python34\lib\site-packages\win32com\server\policy.py", line 699, in invokeex
return self.obj.dynamic(name, lcid, wFlags, args)
File "C:\Python34\lib\site-packages\win32comext\axscript\client\scriptdispatch.py", line 49, in dynamic
return self.engine.ApplyInScriptedSection(None, func, tuple(realArgs))
File "C:\Python34\lib\site-packages\win32comext\axscript\client\framework.py", line 858, in ApplyInScriptedSection
self.HandleException(codeBlock)
File "C:\Python34\lib\site-packages\win32comext\axscript\client\framework.py", line 945, in HandleException
if issubclass(pythoncom.com_error, exc_type) and exc_value[0]==axscript.SCRIPT_E_REPORTED:
TypeError: 'com_error' object does not support indexing
[/quote]

After uncommenting the line code works as expected.

I have posted to pywin mailing list, maybe they will help a bit.

And as for learning JScript - this would be 5th language I use on a daily basis. Too much. And this: reddit.com/r/ProgrammerHumor ... ript_devs/ (yes, I know there should be '='s instead if '*'s) :laughing:

When I tried it, _FlagAsMethod only worked on the main DOpus object. I had to use make_method on the factory objects (as shown in the code I posted).

Hi,

My point was that not only parameterless functions are affected (myvec.reserve(300)). Actually it seems none works, EXCEPT for DOpus.Output working out of the box.

Also, actually your sample with make_method fails, just in another way than before - consumed exception looks like below. Otoh _FlagAsMethod seems to work universally.

Maybe this post will bring more info: mail.python.org/pipermail/pytho ... 00362.html

[quote]Traceback (most recent call last):
File "", line 5, in OnClick
myvec = factory.make_method("Vector")
File "C:\Python34\lib\site-packages\win32com\client\dynamic.py", line 317, in make_method
methodCodeList = self.olerepr.MakeFuncMethod(self.olerepr.mapFuncs[name], methodName,0)
KeyError: 'Vector'
(0x80020009)[/quote]

JScript works out of the box :slight_smile:

Not wanting to multiply posts on an edge subject, I will be putting Python problems in this post.
Admins, feel free to change topic subject.

ScriptColumnData.columns (I assume just all Maps) cannot be indexed with [] (TypeError("This object does not support enumeration")).
Function call format works - () - so no big deal.

Function syntax to access maps/vector items is special in scripting with DO, never seen that before.
You get used to it, though that syntax keeps looking strange at times, especially if you assign values to "method calls" - DO magic! o))

This has nothing to do with DO (except DO not implementing everything sometimes). This is how pywin works - both [] and () are legal for indexing COM collections.
Actually (from an old book - I expect it has changed), Map[key] should throw 'TypeError: Only integer indexes are supported for enumerators', so only () syntax is/once was supported for non-integer keys.
There is also difference when collections are indexed not from zero, which is apparently possible - [] gives the real position in collection, and () gives the position regarding possible indexing base change.

Ok, didn't know that using () may be more ok in python in some situations, in jscript it's not very usual at least.
I'm still researching this topic from time to time, just to learn. Unfortunately I have hard times finding related information on the net.
This thread e.g., looks like it's covering the [] vs () topic, don't know if the people where high when writing this though, weird language. o)
progtown.com/topic92768-impl ... r-wsh.html

This is offtopic, but just in case you Leo or Jon have some links or keywords at hand, which de-mystify the ()-syntax for me, I'd be excited to read them! cya, tbone o)

I don't really understand the continued confusion :slight_smile: The objects in question aren't JScript Arrays, they're COM objects with an IDispatch interface. Just think of it like calling a function with a single parameter - the parameter specifies the index of the item to return.

Sorry! o) So it has something to do with DISPATCH_PROPERTYPUT/GET flags maybe? o)

No they're handled as methods. Like I said, imagine they're functions.

function GetThing(x) { switch (x) { case 0: return thing[0]; case 1: return thing[1]; case 2: return thing[2]; default: throw "invalid index"; } }

I'm OK with oddities of calling COM, it's like normal when interfacing between languages/technologies etc.

But, the problem with function calling still bothers me and makes a real nuisance- you never know whether if it is your problem, or _FlagAsMethod missing :frowning:

Jon, is is possible that ITypeComp.Bind returns incorrect wFlags, with no INVOKE_FUNC set for functions or other INVOKEKIND flags set for it (let's take DOpus.Create for example)?

We don't implement ITypeComp (or have a type library). It's just a pure IDispatch interface.

In that case, I can see that IDispatch.Invoke for DOPus.Create called with wFlags set to DISPATCH_PROPERTYGET returns object, which is most probably the reason for it not working. It would work if it returned error.

Why? A property can be an object. In truth there's essentially no difference between a property (when getting) and a method with zero arguments.

Remember it all works fine in JScript and VBScript. It's Python that's getting things wrong here.

Well, even IDispatch provides clear differentiation capabilities by providing wFlags, which in turn point to the fact, that they should be differentiated. The first sentence is Microsoft's description of IDispatch says "Provides access to properties and methods exposed by an object."

I must check whether I have any problems with methods accepting arguments, as I may have mixed things in the course of this investigation.

The fact that JS and VBS work is rather accidental in this case, and probably related to how these languages internally work. In case of Python there is difference between function (which is of type <class 'function'>), and the value it returns (which is of type <class 'returned_object_type'>).