6.4.3. Multiplex Weaver

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