@@ -37,7 +37,27 @@ def __init__(self, app, name, debug=True, *args, **kwargs):
37
37
38
38
self .wrapper_layout .addLayout (self ._button_layout (), 1 , 0 )
39
39
40
- sys .excepthook = self ._excepthook
40
+ # This hack allows us to handle exceptions through the Puzzle in IPython.
41
+ # Normally when a cell is executed in an IPython InteractiveShell,
42
+ # sys.excepthook is overwritten with shell.excepthook, and then restored
43
+ # to sys.excepthook after the cell run finishes. Any changes we make to
44
+ # sys.excepthook in here directly will thus be overwritten as soon as the
45
+ # cell that defines the Puzzle finishes running.
46
+
47
+ # Instead, we schedule set_excepthook on a QTimer, meaning that it will
48
+ # execute in the Qt loop rather than in a cell, so it can modify
49
+ # sys.excepthook without risk of the changes being immediately overwritten,
50
+
51
+ # For bonus points, we could set _old_excepthook to shell.excepthook,
52
+ # which would result in all tracebacks appearing in the Notebook rather
53
+ # than the console, but I think that is not desireable.
54
+
55
+ # In normal Python, we could just say "sys.excepthook = self._excepthook"
56
+ # but this method works for both.
57
+ def set_excepthook ():
58
+ self ._old_excepthook = sys .excepthook
59
+ sys .excepthook = self ._excepthook
60
+ QtCore .QTimer .singleShot (0 , set_excepthook )
41
61
42
62
@property
43
63
def pieces (self ):
@@ -130,7 +150,7 @@ def run_worker(self, worker):
130
150
self ._threadpool .start (worker )
131
151
132
152
def _excepthook (self , exctype , value , traceback ):
133
- sys . __excepthook__ (exctype , value , traceback )
153
+ self . _old_excepthook (exctype , value , traceback )
134
154
135
155
# Stop any threads that may be running
136
156
self ._shutdown_threads .emit ()
@@ -341,6 +361,9 @@ def closeEvent(self, event):
341
361
if not self .debug :
342
362
for piece_name in self .pieces :
343
363
self .pieces [piece_name ].handle_close (event )
364
+
365
+ # Reinstate the original excepthook
366
+ sys .excepthook = self ._old_excepthook
344
367
super ().closeEvent (event )
345
368
346
369
0 commit comments