@@ -249,9 +249,12 @@ def __hash__(self):
249249 return self ._hash
250250
251251
252+ def _exception_printer (exc ):
253+ traceback .print_exc ()
254+
255+
252256class CallbackRegistry (object ):
253- """
254- Handle registering and disconnecting for a set of signals and
257+ """Handle registering and disconnecting for a set of signals and
255258 callbacks:
256259
257260 >>> def oneat(x):
@@ -286,8 +289,29 @@ class CallbackRegistry(object):
286289 functions). This technique was shared by Peter Parente on his
287290 `"Mindtrove" blog
288291 <http://mindtrove.info/python-weak-references/>`_.
292+
293+
294+ Parameters
295+ ----------
296+ exception_handler : callable, optional
297+ If provided must have signature ::
298+
299+ def handler(exception: Exception) -> None:
300+
301+ If not None this function will be called with any `Exception`
302+ subclass raised by the callbacks in `CallbackRegistry.process`.
303+ The handler may either consume the exception or re-raise.
304+
305+ The callable must be pickle-able.
306+
307+ The default handler is ::
308+
309+ def h(exc):
310+ traceback.print_exc()
311+
289312 """
290- def __init__ (self ):
313+ def __init__ (self , exception_handler = _exception_printer ):
314+ self .exception_handler = exception_handler
291315 self .callbacks = dict ()
292316 self ._cid = 0
293317 self ._func_cid_map = {}
@@ -301,10 +325,10 @@ def __init__(self):
301325 # http://bugs.python.org/issue12290).
302326
303327 def __getstate__ (self ):
304- return True
328+ return { 'exception_handler' : self . exception_handler }
305329
306330 def __setstate__ (self , state ):
307- self .__init__ ()
331+ self .__init__ (** state )
308332
309333 def connect (self , s , func ):
310334 """
@@ -365,6 +389,13 @@ def process(self, s, *args, **kwargs):
365389 proxy (* args , ** kwargs )
366390 except ReferenceError :
367391 self ._remove_proxy (proxy )
392+ # this does not capture KeyboardInterrupt, SystemExit,
393+ # and GeneratorExit
394+ except Exception as e :
395+ if self .exception_handler is not None :
396+ self .exception_handler (e )
397+ else :
398+ raise
368399
369400
370401class silent_list (list ):
0 commit comments