COM bites - Followup

Karl Putland kperacles at geocities.com
Mon Jul 26 23:41:12 EDT 1999


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

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=[]
    for field in table_inst.fields:
        field._public_methods_ = ['read',
                                  'write',
                                  'append']
        field._public_attrs_ = ['name',
                                'size',
                                'type'
                                'value']
        name = string.lower(field.name)
        field = win32com.server.util.wrap(field)
        tmpfields.append(field)
        setattr(table_inst, name, field)

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

    # Return a wrapped table
    wrappedtable=win32com.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.  

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

    # turn tmpfields into a collection
    tmpfields=win32com.server.util.Collection(tmpfields,1)
    tmpfields=win32com.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=win32com.server.util.GetWrappedCollection(List, read_only=0)

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






More information about the Python-list mailing list