> > It seems backwards to me because because if I get the function > > definition wrong in the client site then I get a traceback to the > > callback site - which is meant to be an opaque library that the client > > should not have to know about. > > Yes, what you're asking makes sense: we want to "blame" the right party, > and if it's the callback provider that messed up, we should only > attribute them. (The same kind of problem happens in Tkinter, where > bugs in callbacks end up exposing Tkinter internals.)
Hi Don, As a quick-and-dirty hack, we can do a kind of wrapped exception handling to hide the internals of the system. Here's an example of this: ##################################################################### """A small example of attaching callbacks and wrapping exceptions.""" class CallbackError(Exception): pass class Announcer(object): def __init__(self): self.listeners = [] def add_listener(self, listener): self.listeners.append(listener) def shout(self, msg): try: self._internal_shout(msg) except Exception, e: raise CallbackError, str(e) def _internal_shout(self, msg): for l in self.listeners: l(msg) ##################################################################### Here's a small demonstration: ###### >>> announcer = Announcer() >>> def f1(x): ... print "f1 sees", x ... >>> def f2(x): ... 1 / 0 ... >>> announcer.add_listener(f1) >>> announcer.add_listener(f2) >>> announcer.shout("foo") f1 sees foo Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/tmp/python-213928MGH.py", line 16, in shout __main__.CallbackError: integer division or modulo by zero ###### The traceback we see here starts off at the entry point --- at shout() --- and because we're returning a new exception object at that point, we don't show that we were at _internal_shout(). If we look at the implementation of shout(): def shout(self, msg): try: self._internal_shout(msg) except Exception, e: raise CallbackError, str(e) then we can probably make this a little more sophisticated by properly extracting more information out of the original exception to make error debugging a little easier. However, if we're going to go through this sophisticated route, we'd better make extra sure not to discard useful debugging information. One thing that beginners will often do is something like: try: ... except: print "Something bad happened" which is just silly. *grin* There's a happy medium between error messages being too detailed and not detailed enough; I'd personally lean toward being too detailed at first, but maybe that's just me. I hope this helps! _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor