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