views:

1084

answers:

1

I need to pass exceptions across a thread boundary.

I'm using python embedded in a non thread safe app which has one thread safe call, post_event(callable), which calls callable from its main thread.

I am running a pygtk gui in a seperate thread, so when a button is clicked I post an event with post_event, and wait for it to finish before continuing. But I need the caller to know if the callee threw an exception, and raise it if so. I'm not too worried about the traceback, just the exception itself.

My code is roughly:

class Callback():
    def __init__(self,func,*args):
     self.func=func
     self.args=args
     self.event=threading.Event()
     self.result=None
     self.exception=None
    def __call__(self):
     gtk.gdk.threads_enter()
     try:
      self.result=self.func(*self.args)
     except:
      #what do I do here? How do I store the exception?
      pass
     finally:
      gtk.gdk.threads_leave()
      self.event.set()
    def post(self):
     post_event(self)
     gtk.gdk.threads_leave()
     self.event.wait()
     gtk.gdk.threads_enter()
     if self.exception:
      raise self.exception
     return self.result

Any help appreciated, thanks.

+6  A: 

#what do I do here? How do I store the exception?

Use sys.exc_info()[:2], see this wiki

Best way to communicate among threads is Queue. Have the main thread instantiate a Queue.Queue instance and pass it to subthreads; when a subthread has something to communicate back to the master it uses .put on that queue (e.g. a tuple with thread id, exception type, exception value -- or, other useful info, not necessarily exception-related, just make sure the first item of a tuple identifies the kind of info;-). The master can .get those info-units back when it wants, with various choices for synchronization and so on.

Alex Martelli
Exactly what I was after, thanks.Ordinarily I'd use queues, etc, but I'm 're-inventing the wheel' because only one thing should be running at any one time in my script, and I want stuff that runs on the app's thread to finish and give me a result before I take any further action in the gtk thread. I'm basically trying to fake single threading with two threads. Its annoying but it seems to be working ok.
DaedalusFall