COM bites - help please

Karl Putland kperacles at geocities.com
Fri Jul 23 11:22:06 EDT 1999


Gordon McMillan <gmcm at hypernet.com> wrote in message news:1279389887-25608327 at hypernet.com...
> Karl Putland is frustrated:
> 
> > I've got a couple of pyCOM things that are kicking my @$$! 
> 
> Bill Tutt got most of 'em...
> 
> > 2. A computed attribute in __getattr__ does not want to be accessed
> > through com.  It is in the _public_attrs_  list but produces the
> > following error when attempting to access it.
> 
> Both you and the COM support are playing attribute games, and not 
> agreeing on how the game is played. Can you expose Get methods to 
> COM,  and play your games there? That way, COM will find something 
> real (a method object), and you can still do lazy evalutaion.
> 

Kind of works this way already.  field.value was just aliased to field.read.  No shift key and it was easier to read.


> BTW, I find it very helpful to use a separate (wrapper) object:
> 
>  class RealWork:
>    ...
> 
>  class COMRealWorkWrap:
>    _public_methods_ = [ ... ]
>    def __init__(self, real_obj):
>      ...
> 
> That also means I can put all my Unicode conversion in one place.

Hmmm... I might have to try this.  Does your method require that you mirror all of the functions and attributes of the RealWork in COMRealWorkWrap???  Right now I'm just using a procedure to add the attributes to the objects.  And I tried subclassing the root object that I wanted to expose.

class GMcomConnector(gmc.GMConnector):
    """COM wrapper of gmc.GMConnector"""
    _public_methods_ = ['Init', 'GMTable','cleanup']
    _public_attrs_ = ['DefaultDir','User']
    _reg_verprogid_ = "Python.GMConnector.1"
    _reg_progid_ = "Python.GMConnector"
    _reg_desc_ = "Python - GoldMine Connection Manager"
    _reg_clsid_ = "{8DAF3841-3E9B-11D3-A4DC-820D6CB34D6B}"
    _reg_class_spec_ = "gmCOM.GMcomConnector"

    def GMTable(self, table_name):
        """ Override the base to wrap the Table in a COM wrapper"""
        if debug:
            print "getting table=gmc.GMConnector.GMTable(self, TableName)", self, table_name
            print '\n', dir(table_name)
        try:
            # Another Unicode string conversion
            TableName=str(table_name)
            table=gmc.GMConnector.GMTable(self, TableName)
        except:
            import traceback
            traceback.print_exc()
            raw_input("Hit return to exit...")

        
        # set pythoncom specific attributes
        if debug: print "Wrapping Table"
        gm_com_table_prep(table)

        # turn table.fields into a collection
        table.fields=win32com.server.util.Collection(table.fields)

        # Return the COM wrapped table
        return win32com.server.util.wrap(table)
    def Init(self,
             DefaultDir='d:\\goldmine\\demo',
             User='MASTER',
             Password='ACCESS'):
        
        self.DefaultDir = DefaultDir
        self.User = User
        self.Password = Password


def gm_com_table_prep(table_inst):
    """Preppare for COM wrapper of gmtasble.GMTable

    Need to see if we can generate the COM specific attributes on a per
    instance basis.

    GMcomTable is not pulicly accesable.  GMTables are only created by
    the factory in GMcomConnector.  They get wrapped in the COM interface
    there

    """

    # Changes the date format to a string from a date tuple
    table_inst.COM = 1
    
    table_inst._public_methods_ = ['append',
                        'bottom',
                        'close',
                        'delete',
                        'filter',
                        'goto',
                        'is_sql',
                        'new',
                        'open',
                        'range',
                        'read',
                        'replace',
                        'search',
                        'seek',
                        'set_order',
                        'skip',
                        'tables',
                        'top',
                        'unlock']

    table_inst._public_attrs_ = ['name',
                                 'handle',
                                 'records',
                                 'rec_no',
                                 'fields',
                                 'fieldnames']
    if debug: print "\nLooping over fields to set _public_attrs_ for table", table_inst.name
    for name in table_inst.fieldnames:
        table_inst._public_attrs_.append(string.lower(name))
    if debug: print "\nWrapping Fields"
    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)
    table_inst.fields = tmpfields


> 
> - Gordon
> 
> 

Thanks

Karl Putland
kperacles at geocities.com






More information about the Python-list mailing list