import itertools
import xml.sax
import xml.parsers.expat
+import uuid
def autostart(func):
while True:
try:
item = yield
+ except StandardError, e:
+ for target in self._targets:
+ target.throw(e.__class__, e.message)
+ else:
for target in self._targets:
target.send(item)
+
+
+class CoSwitch(object):
+ """
+ >>> apr = printer_sink("a %r")
+ >>> bpr = printer_sink("b %r")
+ >>> cs = CoSwitch(["a", "b"])
+ >>> cs.register_sink("a", apr)
+ >>> cs.register_sink("b", bpr)
+ >>> cs.stage.send(("a", 1, 2, 3))
+ a ('a', 1, 2, 3)
+ >>> cs.stage.send(("b", 1, 2, 3))
+ b ('b', 1, 2, 3)
+ >>> cs.stage.send(("b", 1, 2, 3))
+ b ('b', 1, 2, 3)
+ """
+
+ def __init__(self, signalKeys, key = (lambda eventData: eventData[0])):
+ self.stage = self._stage()
+ self._key = key
+ self._targets = {}
+
+ for signalKey in signalKeys:
+ self._targets[signalKey] = {}
+
+ def register_sink(self, signalKey, sink):
+ id = uuid.uuid4()
+ self._targets[signalKey][id] = sink
+ return id
+
+ def unregister_sink(self, signalKey, id):
+ del self._targets[signalKey][id]
+
+ def restart(self):
+ self.stage = self._stage()
+
+ @autostart
+ def _stage(self):
+ while True:
+ try:
+ item = yield
except StandardError, e:
for target in self._targets:
target.throw(e.__class__, e.message)
+ else:
+ key = self._key(item)
+ for target in self._targets[key].itervalues():
+ target.send(item)
def _flush_queue(queue):
parser.ParseFile(f)
+def gtk_source(widget, signalName, target):
+ """
+ >>> import gtk
+ >>> widget = gtk.Button("Source")
+ >>> pr = printer_sink("%r")
+ >>> gtk_source(widget, "clicked", pr)
+ """
+
+ def on_signal(*args):
+ targetArgs = [signalName]
+ targetArgs.extend(args)
+ target.send(targetArgs)
+
+ return widget.connect(signalName, on_signal)
+
if __name__ == "__main__":
import doctest
doctest.testmod()