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
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