Discussion:
[python-win32] getting underlying OLE object identity for win32com objects
Dan Lenski
2014-10-01 17:17:19 UTC
Permalink
Hi all,
I'm trying to figure out if there is a canonical way to get the identity
of an object that has been wrapped by the win32com module, so that it
can be compared to other objects.

For example, I can use this code to get a handle to the same object
twice in the JMP application, but the two tables do not have the same
"object identity" at the Python level:

from win32com.client import gencache
mod = gencache.GetModuleForProgID("JMP.Application")
app = mod.Application()
table = app.GetTableHandleFromName("Table1")
same_table = app.GetTableHandleFromName("Table1")
print table
print same_table
print table is same_table
# <win32com.gen_py.DCD36DE0-78F8-11CF-9E68-
0020AF24E9FEx0x1x0.IAutoDataTable instance at 0x54418504>
# <win32com.gen_py.DCD36DE0-78F8-11CF-9E68-
0020AF24E9FEx0x1x0.IAutoDataTable instance at 0x54432456>
# False

It appears that all win32com OLE automation objects also have an
_oleobj_ property. _oleobj_ is a PyIDispatch object
(http://docs.activestate.com/activepython/3.1/pywin32/PyIDispatch.html),
which only has a few methods, none of which seem pertinent to the
question of object identity. However, the repr() of _oleobj_ seems to
point to the underlying OLE automation object:

print table._oleobj_
print same_table._oleobj_
# <PyIDispatch at 0x0000000003459530 with obj at 0x00000000003E2928>
# <PyIDispatch at 0x0000000003459620 with obj at 0x00000000003E2928>

In order to confirm that two objects refer to the same underlying OLE
object, I've resorted to parsing the `repr()` strings and comparing the
hexadecimal addresses ("`obj at 0x...`").

Is there a better way to do this?

Thanks,
Dan Lenski

ps- I also posted this on StackOverflow
(http://stackoverflow.com/questions/26068864) but it doesn't seem to
have gotten many eyeballs there.
Tim Roberts
2014-10-01 17:55:42 UTC
Permalink
Post by Dan Lenski
I'm trying to figure out if there is a canonical way to get the identity
of an object that has been wrapped by the win32com module, so that it
can be compared to other objects.
For example, I can use this code to get a handle to the same object
twice in the JMP application, but the two tables do not have the same
Right. They are two separate Python objects.

print table
print same_table
print table is same_table

"is" will obviously fail, because it is checking for two identical
Python objects. However, did you try the == operator? The source code
seems to imply that the __eq__ operator is delegated to the _oleobj_
properties, which do know about COM object identity.
Post by Dan Lenski
In order to confirm that two objects refer to the same underlying OLE
object, I've resorted to parsing the `repr()` strings and comparing the
hexadecimal addresses ("`obj at 0x...`").
Is there a better way to do this?
Assuming the straight "==" didn't work, I would think a better way would
be simply to compare the _oleobj_:

if table._oleobj_ == same_table._oleobj_:

The source code in dynamic.py says the _oleobj_ members know how to
compare themselves.
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
Dan Lenski
2014-10-01 18:06:43 UTC
Permalink
Post by Tim Roberts
Right. They are two separate Python objects.
print table
print same_table
print table is same_table
"is" will obviously fail, because it is checking for two identical
Python objects. However, did you try the == operator? The source code
seems to imply that the __eq__ operator is delegated to the _oleobj_
properties, which do know about COM object identity.
Assuming the straight "==" didn't work, I would think a better way would
The source code in dynamic.py says the _oleobj_ members know how to
compare themselves.
Thanks very much, Tim. I feel quite sheepish but didn't consider the ==
operator since I'm so used to using "is" for this purpose with Python
objects.

Both versions that you suggested do the trick: table==same_table and
table._oleobj_==same_table._oleobj_

Thanks,
Dan

Loading...