From 6070296202bc5614187f210fe646ca6f4c97d452 2008-07-15 04:06:49 From: Gael Varoquaux Date: 2008-07-15 04:06:49 Subject: [PATCH] Traceback capture now working. --- diff --git a/IPython/frontend/linefrontendbase.py b/IPython/frontend/linefrontendbase.py index f71dab2..a058122 100644 --- a/IPython/frontend/linefrontendbase.py +++ b/IPython/frontend/linefrontendbase.py @@ -31,6 +31,11 @@ class LineFrontEndBase(FrontEndBase): # Are we entering multi line input? multi_line_input = False + # We need to keep the prompt number, to be able to increment + # it when there is an exception. + prompt_number = 1 + + #-------------------------------------------------------------------------- # Public API #-------------------------------------------------------------------------- @@ -69,41 +74,67 @@ class LineFrontEndBase(FrontEndBase): self.output_prompt % result['number'], result['display']['pprint'] ) ) - - + + def render_error(self, failure): self.insert_text('\n\n'+str(failure)+'\n\n') return failure + + + def prefilter_input(self, string): + string = string.replace('\r\n', '\n') + string = string.replace('\t', 4*' ') + # Clean the trailing whitespace + string = '\n'.join(l.rstrip() for l in string.split('\n')) + return string + + + def is_complete(self, string): + if ( self.multi_line_input and not re.findall(r"\n[\t ]*$", string)): + return False + else: + return FrontEndBase.is_complete(self, string) + def execute(self, python_string, raw_string=None): + """ Send the python_string to the interpreter, stores the + raw_string in the history and starts a new prompt. + """ + if raw_string is None: + raw_string = string + # Create a false result, in case there is an exception + result = dict(number=self.prompt_number) + try: + self.history.input_cache[-1] = raw_string + result = self.shell.execute(python_string) + self.render_result(result) + except Exception, e: + self.show_traceback() + finally: + self.prompt_number += 1 + self.new_prompt(self.prompt % (result['number'] + 1)) + self.multi_line_input = False + # Start a new empty history entry + self._add_history(None, '') + # The result contains useful information that can be used + # elsewhere. + self.last_result = result + + def _on_enter(self): """ Called when the return key is pressed in a line editing buffer. """ current_buffer = self.get_current_edit_buffer() - current_buffer = current_buffer.replace('\r\n', '\n') - current_buffer = current_buffer.replace('\t', 4*' ') - cleaned_buffer = '\n'.join(l.rstrip() - for l in current_buffer.split('\n')) - if ( not self.multi_line_input - or re.findall(r"\n[\t ]*$", cleaned_buffer)): - if self.is_complete(cleaned_buffer): - self.history.input_cache[-1] = \ - current_buffer - result = self.shell.execute(cleaned_buffer) - self.render_result(result) - self.new_prompt(self.prompt % (result['number'] + 1)) - self.multi_line_input = False - # Start a new empty history entry - self._add_history(None, '') - else: - if self.multi_line_input: - self.write('\n' + self._get_indent_string(current_buffer)) - else: - self.multi_line_input = True - self.write('\n\t') + cleaned_buffer = self.prefilter_input(current_buffer) + if self.is_complete(cleaned_buffer): + self.execute(cleaned_buffer, raw_string=current_buffer) else: - self.write('\n'+self._get_indent_string(current_buffer)) + if self.multi_line_input: + self.write('\n' + self._get_indent_string(current_buffer)) + else: + self.multi_line_input = True + self.write('\n\t') #-------------------------------------------------------------------------- diff --git a/IPython/frontend/wx/console_widget.py b/IPython/frontend/wx/console_widget.py index a27e574..df5c663 100644 --- a/IPython/frontend/wx/console_widget.py +++ b/IPython/frontend/wx/console_widget.py @@ -297,7 +297,7 @@ class ConsoleWidget(editwindow.EditWindow): possibilities.sort() # Python sorts are case sensitive self.AutoCompSetIgnoreCase(False) self.AutoCompSetAutoHide(False) - #let compute the length ot last word + #let compute the length ot text)last word splitter = [' ', '(', '[', '{'] last_word = self.get_current_edit_buffer() for breaker in splitter: @@ -309,7 +309,7 @@ class ConsoleWidget(editwindow.EditWindow): maxrange = self.GetScrollRange(wx.VERTICAL) self.ScrollLines(maxrange) - def on_enter(self): + def _on_enter(self): """ Called when the return key is hit. """ pass diff --git a/IPython/frontend/wx/wx_frontend.py b/IPython/frontend/wx/wx_frontend.py index abf0272..92573cf 100644 --- a/IPython/frontend/wx/wx_frontend.py +++ b/IPython/frontend/wx/wx_frontend.py @@ -3,7 +3,7 @@ # ipython1.frontend.cocoa.tests.test_cocoa_frontend -*- """Classes to provide a Wx frontend to the -ipython1.kernel.engineservice.EngineService. +IPython.kernel.core.interpreter. """ @@ -24,16 +24,12 @@ __docformat__ = "restructuredtext en" import wx from console_widget import ConsoleWidget -from IPython.frontend.linefrontendbase import LineFrontEndBase +from IPython.frontend.prefilterfrontend import PrefilterFrontEnd #------------------------------------------------------------------------------- # Classes to implement the Wx frontend #------------------------------------------------------------------------------- - - - - -class IPythonWxController(LineFrontEndBase, ConsoleWidget): +class IPythonWxController(PrefilterFrontEnd, ConsoleWidget): output_prompt = \ '\n\x01\x1b[0;31m\x02Out[\x01\x1b[1;31m\x02%i\x01\x1b[0;31m\x02]: \x01\x1b[0m\x02' @@ -48,7 +44,7 @@ class IPythonWxController(LineFrontEndBase, ConsoleWidget): """ Create Shell instance. """ ConsoleWidget.__init__(self, parent, id, pos, size, style) - LineFrontEndBase.__init__(self) + PrefilterFrontEnd.__init__(self) # Capture Character keys self.Bind(wx.EVT_KEY_DOWN, self._on_key_down) diff --git a/IPython/kernel/core/traceback_trap.py b/IPython/kernel/core/traceback_trap.py index 7fd1d17..5d36b36 100644 --- a/IPython/kernel/core/traceback_trap.py +++ b/IPython/kernel/core/traceback_trap.py @@ -38,6 +38,8 @@ class TracebackTrap(object): def hook(self, *args): """ This method actually implements the hook. """ + import sys + print >>sys.stderr, "I have been raised" self.args = args