diff --git a/IPython/frontend/prefilterfrontend.py b/IPython/frontend/prefilterfrontend.py index 42f00b8..3e8bb4a 100644 --- a/IPython/frontend/prefilterfrontend.py +++ b/IPython/frontend/prefilterfrontend.py @@ -60,6 +60,7 @@ class PrefilterFrontEnd(LineFrontEndBase): def __init__(self, *args, **kwargs): LineFrontEndBase.__init__(self, *args, **kwargs) + self.save_output_hooks() # Instanciate an IPython0 interpreter to be able to use the # prefiltering. self.ipython0 = make_IPython() @@ -78,6 +79,8 @@ class PrefilterFrontEnd(LineFrontEndBase): # in our environment self.ipython0.magic_ls = mk_system_call(self.system_call, 'ls -CF') + # And now clean up the mess created by ipython0 + self.release_output() self.shell.output_trap = RedirectorOutputTrap( out_callback=self.write, err_callback=self.write, @@ -85,10 +88,6 @@ class PrefilterFrontEnd(LineFrontEndBase): self.shell.traceback_trap = SyncTracebackTrap( formatters=self.shell.traceback_trap.formatters, ) - # Capture and release the outputs, to make sure all the - # shadow variables are set - self.capture_output() - self.release_output() #-------------------------------------------------------------------------- # FrontEndBase interface @@ -109,18 +108,29 @@ class PrefilterFrontEnd(LineFrontEndBase): self.release_output() + def save_output_hooks(self): + """ Store all the output hooks we can think of, to be able to + restore them. + + We need to do this early, as starting the ipython0 instance will + screw ouput hooks. + """ + self.__old_cout_write = Term.cout.write + self.__old_cerr_write = Term.cerr.write + self.__old_stdout = sys.stdout + self.__old_stderr= sys.stderr + self.__old_help_output = pydoc.help.output + self.__old_display_hook = sys.displayhook + + def capture_output(self): """ Capture all the output mechanisms we can think of. """ - self.__old_cout_write = Term.cout.write - self.__old_err_write = Term.cerr.write + self.save_output_hooks() Term.cout.write = self.write Term.cerr.write = self.write - self.__old_stdout = sys.stdout - self.__old_stderr= sys.stderr sys.stdout = Term.cout sys.stderr = Term.cerr - self.__old_help_output = pydoc.help.output pydoc.help.output = self.shell.output_trap.out @@ -128,10 +138,11 @@ class PrefilterFrontEnd(LineFrontEndBase): """ Release all the different captures we have made. """ Term.cout.write = self.__old_cout_write - Term.cerr.write = self.__old_err_write + Term.cerr.write = self.__old_cerr_write sys.stdout = self.__old_stdout sys.stderr = self.__old_stderr pydoc.help.output = self.__old_help_output + sys.displayhook = self.__old_display_hook def complete(self, line): diff --git a/IPython/frontend/tests/test_prefilterfrontend.py b/IPython/frontend/tests/test_prefilterfrontend.py index fa92aea..a48a10c 100644 --- a/IPython/frontend/tests/test_prefilterfrontend.py +++ b/IPython/frontend/tests/test_prefilterfrontend.py @@ -15,6 +15,7 @@ __docformat__ = "restructuredtext en" from IPython.frontend.prefilterfrontend import PrefilterFrontEnd from cStringIO import StringIO import string +import sys class TestPrefilterFrontEnd(PrefilterFrontEnd): diff --git a/IPython/frontend/wx/console_widget.py b/IPython/frontend/wx/console_widget.py index 17d81a3..7fd84b3 100644 --- a/IPython/frontend/wx/console_widget.py +++ b/IPython/frontend/wx/console_widget.py @@ -133,8 +133,6 @@ class ConsoleWidget(editwindow.EditWindow): # XXX: do not put print statements to sys.stdout/sys.stderr in # this method, the print statements will call this method, as # you will end up with an infinit loop - if self.debug: - print >>sys.__stderr__, text title = self.title_pat.split(text) if len(title)>1: self.title = title[-2] diff --git a/IPython/frontend/wx/ipythonx.py b/IPython/frontend/wx/ipythonx.py index ac7bf34..8458a6f 100644 --- a/IPython/frontend/wx/ipythonx.py +++ b/IPython/frontend/wx/ipythonx.py @@ -12,7 +12,7 @@ class IPythonXController(WxController): bindings. """ - debug = False + debug = True def __init__(self, *args, **kwargs): WxController.__init__(self, *args, **kwargs) diff --git a/IPython/frontend/wx/wx_frontend.py b/IPython/frontend/wx/wx_frontend.py index cf66de6..9e455a4 100644 --- a/IPython/frontend/wx/wx_frontend.py +++ b/IPython/frontend/wx/wx_frontend.py @@ -42,12 +42,13 @@ from IPython.frontend.prefilterfrontend import PrefilterFrontEnd # Constants #------------------------------------------------------------------------------- -#_COMMAND_BG = '#FAFAF1' # Nice green -_RUNNING_BUFFER_BG = '#FDFFD3' # Nice yellow +_COMPLETE_BUFFER_BG = '#FAFAF1' # Nice green +_INPUT_BUFFER_BG = '#FDFFD3' # Nice yellow _ERROR_BG = '#FFF1F1' # Nice red -_RUNNING_BUFFER_MARKER = 31 +_COMPLETE_BUFFER_MARKER = 31 _ERROR_MARKER = 30 +_INPUT_MARKER = 29 prompt_in1 = \ '\n\x01\x1b[0;34m\x02In [\x01\x1b[1;34m\x02$number\x01\x1b[0;34m\x02]: \x01\x1b[0m\x02' @@ -124,6 +125,8 @@ class WxController(ConsoleWidget, PrefilterFrontEnd): # while it is being swapped _out_buffer_lock = Lock() + _markers = dict() + #-------------------------------------------------------------------------- # Public API #-------------------------------------------------------------------------- @@ -136,9 +139,12 @@ class WxController(ConsoleWidget, PrefilterFrontEnd): ConsoleWidget.__init__(self, parent, id, pos, size, style) PrefilterFrontEnd.__init__(self) - # Marker for running buffer. - self.MarkerDefine(_RUNNING_BUFFER_MARKER, stc.STC_MARK_BACKGROUND, - background=_RUNNING_BUFFER_BG) + # Marker for complete buffer. + self.MarkerDefine(_COMPLETE_BUFFER_MARKER, stc.STC_MARK_BACKGROUND, + background=_COMPLETE_BUFFER_BG) + # Marker for current input buffer. + self.MarkerDefine(_INPUT_MARKER, stc.STC_MARK_BACKGROUND, + background=_INPUT_BUFFER_BG) # Marker for tracebacks. self.MarkerDefine(_ERROR_MARKER, stc.STC_MARK_BACKGROUND, background=_ERROR_BG) @@ -148,6 +154,10 @@ class WxController(ConsoleWidget, PrefilterFrontEnd): self._buffer_flush_timer = wx.Timer(self, BUFFER_FLUSH_TIMER_ID) wx.EVT_TIMER(self, BUFFER_FLUSH_TIMER_ID, self._buffer_flush) + # Inject self in namespace, for debug + if self.debug: + self.shell.user_ns['self'] = self + def raw_input(self, prompt): """ A replacement from python's raw_input. @@ -258,7 +268,9 @@ class WxController(ConsoleWidget, PrefilterFrontEnd): end_line = self.current_prompt_line \ + max(1, len(raw_string.split('\n'))-1) for i in range(self.current_prompt_line, end_line): - self.MarkerAdd(i, _RUNNING_BUFFER_MARKER) + if i in self._markers: + self.MarkerDeleteHandle(self._markers[i]) + self._markers[i] = self.MarkerAdd(i, _COMPLETE_BUFFER_MARKER) # Update the display: wx.Yield() self.GotoPos(self.GetLength()) @@ -273,7 +285,7 @@ class WxController(ConsoleWidget, PrefilterFrontEnd): def release_output(self): __builtin__.raw_input = self.__old_raw_input - PrefilterFrontEnd.capture_output(self) + PrefilterFrontEnd.release_output(self) def after_execute(self): @@ -288,7 +300,7 @@ class WxController(ConsoleWidget, PrefilterFrontEnd): PrefilterFrontEnd.show_traceback(self) wx.Yield() for i in range(start_line, self.GetCurrentLine()): - self.MarkerAdd(i, _ERROR_MARKER) + self._markers[i] = self.MarkerAdd(i, _ERROR_MARKER) #-------------------------------------------------------------------------- @@ -403,6 +415,8 @@ class WxController(ConsoleWidget, PrefilterFrontEnd): """ if self.debug: print >>sys.__stdout__, repr(self.input_buffer) + i = self.GetLineCount() + self._markers[i] = self.MarkerAdd(i, _INPUT_MARKER) PrefilterFrontEnd._on_enter(self) diff --git a/IPython/kernel/core/output_trap.py b/IPython/kernel/core/output_trap.py index c16571f..3c1b4c2 100644 --- a/IPython/kernel/core/output_trap.py +++ b/IPython/kernel/core/output_trap.py @@ -68,10 +68,12 @@ class OutputTrap(object): """ Remove the hooks. """ - sys.stdout = self._out_save + if self.out_set: + sys.stdout = self._out_save self.out_set = False - sys.stderr = self._err_save + if self.err_set: + sys.stderr = self._err_save self.err_set = False def clear(self):