Mailing List Archive

COM bites - Followup
WOW what a pain. Now I know and will share.

From original post.

[I am frustrated]
> 1. Trying to wrap a list of instances into a=20
> util.Collection. All instances have been prepped with=20
> _public_methods_ and _public_attrs_ and have been wrapped=20
> with a call to win32com.server.util.wrap(field) Trying to=20
> access the Collection from a com instance produces the=20
> following error.
>=20
[...]
> >>> c1.fields # This is a util.Collection(list of=20
> GMField instances)
> Traceback (innermost last):
> File "<pyshell#56>", line 1, in ?
> c1.fields
> File "D:\Python\win32com\client\dynamic.py", line 394, in=20
> __getattr__
> raise pythoncom.com_error, details
> com_error: (-2147467259, 'Unspecified error', None, None)
>=20

Here is what I was doing. The following function was wrapping up an =
object that contains other objects and a list of instances.

def gm_com_table_prep_and_wrap(table_inst):
...
[other table_inst prep]
...
tmpfields=3D[]
for field in table_inst.fields:
field._public_methods_ =3D ['read',
'write',
'append']
field._public_attrs_ =3D ['name',
'size',
'type'
'value']
name =3D string.lower(field.name)
field =3D win32com.server.util.wrap(field)
tmpfields.append(field)
setattr(table_inst, name, field)

# turn tmpfields into a collection
tmpfields=3Dwin32com.server.util.Collection(tmpfields,1)
setattr(table_inst, "fields", tmpfields)

# Return a wrapped table
wrappedtable=3Dwin32com.server.util.wrap(table_inst)
return wrappedtable


Where this went wrong is that =
"win32com.server.util.Collection(tmpfields,1)" returns a Collection =
instance READY to be wrapped. =20

So what finnally made the collection work from COM was the addition of =
ONE line

# turn tmpfields into a collection
tmpfields=3Dwin32com.server.util.Collection(tmpfields,1)
tmpfields=3Dwin32com.server.util.wrap(tmpfields) # This line mad =
it work!!!
setattr(table_inst, "fields", tmpfields)

Maybe for collections there should be a Factory that returns a wrapped =
instance

WrappedList=3Dwin32com.server.util.GetWrappedCollection(List, =
read_only=3D0)

I might do that here or now that I know I'll NEVER forget to wrap the =
Collection.

As for the other problems I had... The PyUnicode thing still suck but I =
understand it, and I haven't yet been able to hunt down the problem with =
exposing a computed attribute so there is a method that gets the =
attribute I want instead.

Thanks Bill, Gordon, and Mark.

Now if I can just understand the whole Type Library thing things will be =
hunky dorey.\

Finally-took-a-bite-out-of-COM-ly y'rs - Karl