@@ -69,6 +69,45 @@ def formatvalue(self, value):
6969 return '=%s' % (value , )
7070
7171
72+ class ExceptionDialog (gtk .MessageDialog ):
73+ def __init__ (self , exc_type , exc_value , tb , text = 'An error occurred.' ):
74+ gtk .MessageDialog .__init__ (self , buttons = gtk .BUTTONS_CLOSE ,
75+ type = gtk .MESSAGE_ERROR ,
76+ message_format = text )
77+ self .set_resizable (True )
78+ import cgitb
79+ text = cgitb .text ((exc_type , exc_value , tb ), 5 )
80+ expander = gtk .Expander ('Exception details' )
81+ self .vbox .pack_start (expander )
82+ textview = gtk .TextView ()
83+ textview .get_buffer ().set_text (text )
84+ scrolled_window = gtk .ScrolledWindow ()
85+ scrolled_window .add (textview )
86+ expander .add (scrolled_window )
87+ self .show_all ()
88+
89+
90+ class ExceptionManager (object ):
91+ """
92+ A context manager which runs the dialog `DialogType` on error, with
93+ the exception's type, value, a traceback and a text to display as
94+ arguments.
95+ """
96+ def __init__ (self , DialogType , text = 'An error occurred.' ):
97+ self .DialogType = DialogType
98+ self .text = text
99+
100+ def __enter__ (self ):
101+ return self
102+
103+ def __exit__ (self , exc_type , exc_value , traceback ):
104+ if not (exc_value is None or
105+ issubclass (exc_type , (KeyboardInterrupt , SystemExit ))):
106+ dialog = self .DialogType (exc_type , exc_value , traceback , self .text )
107+ dialog .run ()
108+ dialog .destroy ()
109+
110+
72111class Nested (object ):
73112 """
74113 A helper class, inspired by a semaphore.
@@ -555,11 +594,16 @@ def set_cursor_to_valid_insert_position(self):
555594 self .text_buffer .place_cursor (line_start_iter )
556595
557596 def writetb (self , lines ):
558- string = '' .join (lines )
559- with self .editing :
560- self .text_buffer .insert_with_tags_by_name (self .get_cursor_iter (),
561- string , 'error' )
562- self .move_cursor (len (string ))
597+ with ExceptionManager (ExceptionDialog ,
598+ 'An error occured while trying to display '
599+ 'an error. Please contact the bpython '
600+ 'developers.' ):
601+ string = '' .join (lines )
602+ with self .editing :
603+ self .text_buffer .insert_with_tags_by_name (
604+ self .get_cursor_iter (), string , 'error'
605+ )
606+ self .move_cursor (len (string ))
563607
564608
565609def init_import_completion ():
0 commit comments