6.14.3. Multiplex Weaver

This class is used as a base for classes that represent multiple weavers. It supports only one operation: method call with no return value, because only this functionality is transparent; that is, operates the same for a single object, or a set for which the multiplexor is a proxy.

The multiplex weaver also supports list shortcuts.

The technology is unfortunately not re-entrant, the multiplex call method return must be invoked immediately. This makes multi-threaded calls to multiplexed objects unsafe. (Python lacks appropriate categorical constructions.) We could use a thread lock to fix this, but it doesn't seem worth the effort.

Start python section to interscript/weavers/multiplexor.py[1 /1 ]
     1: #line 95 "weavers.ipk"
     2: import traceback
     3: class multiplexor:
     4:   __class_protocols__ = ['weaver']
     5:   def __init__(self,pass_frame,base):
     6:     self.pass_frame = pass_frame
     7:     self.master = pass_frame.master
     8:     self.process= self.master.process
     9:     if 'weavers' in self.master.process.trace:
    10:       self.process.acquire_object(self,'MULTIPLEX WEAVER')
    11:     self.base=base
    12:     self.name = 'multiplexor v1'
    13:     # self.persistent_frame['name']=self.name
    14:     self.debug_missing_methods = 0
    15:     self.list_stack = []
    16: 
    17:   def __del__(self):
    18:     if 'weavers' in self.process.trace:
    19:       self.process.release_object(self)
    20:   def __nonzero__(self):
    21:     return 1
    22: 
    23:   def callit(self,*args, **kwds):
    24:     self._callit(self.temp,args,kwds)
    25: 
    26:   def _callit(self,at,args, kwds):
    27:     for b in self.base:
    28:       if hasattr(b,at):
    29:         try:
    30:           apply(getattr(b,at),args,kwds)
    31:         except KeyboardInterrupt:
    32:           raise KeyboardInterrupt
    33:         except:
    34:           protocol = 'No protocol attribute'
    35:           name = 'No name attribute'
    36:           if hasattr(b,'protocol'): protocol = b.protocol
    37:           if hasattr(b,'name'): name = b.name
    38:           print 'Error in call!'
    39:           print '  Method',at
    40:           print '  Args  ',args
    41:           print '  Kwds  ',kwds
    42:           print '  of    ',b.protocol,'weaver',b.name,'ignored'
    43:           traceback.print_exc()
    44:       elif self.debug_missing_methods:
    45:         protocol = 'No protocol attribute'
    46:         sinkname = 'No sink attribute'
    47:         if hasattr(b,'protocol'): protocol = b.protocol
    48:         if hasattr(b,'sink'):
    49:           sinkname = 'no sink name'
    50:           sink = b.sink
    51:           if hasattr(sink,'name'):
    52:             sinkname = sink.name
    53:         print 'Warning: missing method',at,'of weaver type',protocol,'for',sinkname,'ignored'
    54: 
    55:   def __getattr__(self,x):
    56:     self.temp = x
    57:     return self.callit
    58: 
    59:   def begin_list(self,style='bullet'):
    60:      if not style in ('bullet','numbered','keyed'):
    61:        style = 'bullet'
    62:      self.list_stack.append([style,0])
    63:      self._callit('begin_'+style+'_list',(),{})
    64: 
    65:   def end_list(self):
    66:     style, open_item = self.list_stack[-1]
    67:     del self.list_stack[-1]
    68:     if open_item:
    69:       self._callit('end_'+style+'_list_item',(),{})
    70:     self._callit('end_'+style+'_list',(),{})
    71: 
    72:   def item(self, *args, **kwds):
    73:     style, open_item = self.list_stack[-1]
    74:     if open_item:
    75:       self._callit('end_'+style+'_list_item',(),{})
    76:     else:
    77:       self.list_stack[-1][1]=1
    78:     self._callit('begin_'+style+'_list_item',args,kwds)
    79: 
End python section to interscript/weavers/multiplexor.py[1]