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