From c291d5fa4c6f31c83200e8c517dff951b794aabb 2010-08-17 05:35:41 From: Brian Granger Date: 2010-08-17 05:35:41 Subject: [PATCH] Changing how IPython.utils.io.Term is handled. We used to create a module level IOTerm instance called IPython.utils.io.Term when IPython.utils.io was imported. We now delay this until InteractiveShell.init_io is called. This gives us a chance to override sys.stdout/sys.stderr first. All code that uses IPython.utils.io.Term must refer to by its full name: "IPython.utils.io.Term" and not hold references to it. --- diff --git a/IPython/core/debugger.py b/IPython/core/debugger.py index 6c422ec..9f80d24 100644 --- a/IPython/core/debugger.py +++ b/IPython/core/debugger.py @@ -32,7 +32,7 @@ import sys from IPython.utils import PyColorize from IPython.core import ipapi from IPython.utils import coloransi -from IPython.utils.io import Term +import IPython.utils.io from IPython.core.excolors import exception_colors # See if we can use pydb. @@ -171,7 +171,7 @@ class Pdb(OldPdb): # Parent constructor: if has_pydb and completekey is None: - OldPdb.__init__(self,stdin=stdin,stdout=Term.cout) + OldPdb.__init__(self,stdin=stdin,stdout=IPython.utils.io.Term.cout) else: OldPdb.__init__(self,completekey,stdin,stdout) @@ -279,7 +279,7 @@ class Pdb(OldPdb): def print_stack_entry(self,frame_lineno,prompt_prefix='\n-> ', context = 3): #frame, lineno = frame_lineno - print >>Term.cout, self.format_stack_entry(frame_lineno, '', context) + print >>IPython.utils.io.Term.cout, self.format_stack_entry(frame_lineno, '', context) # vds: >> frame, lineno = frame_lineno @@ -419,7 +419,7 @@ class Pdb(OldPdb): src.append(line) self.lineno = lineno - print >>Term.cout, ''.join(src) + print >>IPython.utils.io.Term.cout, ''.join(src) except KeyboardInterrupt: pass diff --git a/IPython/core/history.py b/IPython/core/history.py index e21a197..14ad06e 100644 --- a/IPython/core/history.py +++ b/IPython/core/history.py @@ -5,7 +5,8 @@ import fnmatch import os -from IPython.utils.io import Term, ask_yes_no +import IPython.utils.io +from IPython.utils.io import ask_yes_no from IPython.utils.warn import warn from IPython.core import ipapi @@ -62,7 +63,7 @@ def magic_history(self, parameter_s = ''): try: outfname = opts['f'] except KeyError: - outfile = Term.cout # default + outfile = IPython.utils.io.Term.cout # default # We don't want to close stdout at the end! close_at_end = False else: @@ -101,7 +102,7 @@ def magic_history(self, parameter_s = ''): init, final = map(int, args) else: warn('%hist takes 0, 1 or 2 arguments separated by spaces.') - print >> Term.cout, self.magic_hist.__doc__ + print >> IPython.utils.io.Term.cout, self.magic_hist.__doc__ return width = len(str(final)) diff --git a/IPython/core/hooks.py b/IPython/core/hooks.py index 97990c8..8639388 100644 --- a/IPython/core/hooks.py +++ b/IPython/core/hooks.py @@ -46,7 +46,7 @@ import sys from pprint import PrettyPrinter -from IPython.utils.io import Term +import IPython.utils.io from IPython.utils.process import shell from IPython.core.error import TryNext @@ -175,13 +175,13 @@ def result_display(self,arg): # So that multi-line strings line up with the left column of # the screen, instead of having the output prompt mess up # their first line. - Term.cout.write('\n') - print >>Term.cout, out + IPython.utils.io.Term.cout.write('\n') + print >>IPython.utils.io.Term.cout, out else: # By default, the interactive prompt uses repr() to display results, # so we should honor this. Users who'd rather use a different # mechanism can easily override this hook. - print >>Term.cout, repr(arg) + print >>IPython.utils.io.Term.cout, repr(arg) # the default display hook doesn't manipulate the value to put in history return None diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index 46272d9..94a0fdf 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -53,7 +53,8 @@ from IPython.utils import PyColorize from IPython.utils import pickleshare from IPython.utils.doctestreload import doctest_reload from IPython.utils.ipstruct import Struct -from IPython.utils.io import Term, ask_yes_no +import IPython.utils.io +from IPython.utils.io import ask_yes_no from IPython.utils.path import get_home_dir, get_ipython_dir, HomeDirError from IPython.utils.process import getoutput, getoutputerror from IPython.utils.strdispatch import StrDispatch @@ -250,6 +251,10 @@ class InteractiveShell(Configurable, Magic): self.init_syntax_highlighting() self.init_hooks() self.init_pushd_popd_magic() + # TODO: init_io() needs to happen before init_traceback handlers + # because the traceback handlers hardcode the stdout/stderr streams. + # This logic in in debugger.Pdb and should eventually be changed. + self.init_io() self.init_traceback_handlers(custom_exceptions) self.init_user_ns() self.init_logger() @@ -411,6 +416,17 @@ class InteractiveShell(Configurable, Magic): 'NoColor', self.object_info_string_level) + def init_io(self): + import IPython.utils.io + if sys.platform == 'win32' and readline.have_readline and \ + self.readline_use: + Term = IPython.utils.io.IOTerm( + cout=readline._outputfile,cerr=readline._outputfile + ) + else: + Term = IPython.utils.io.IOTerm() + IPython.utils.io.Term = Term + def init_prompts(self): # Initialize cache, set in/out prompts and printing system self.outputcache = CachedOutput(self, @@ -1997,12 +2013,12 @@ class InteractiveShell(Configurable, Magic): # TODO: This should be removed when Term is refactored. def write(self,data): """Write a string to the default output""" - Term.cout.write(data) + IPython.utils.io.Term.cout.write(data) # TODO: This should be removed when Term is refactored. def write_err(self,data): """Write a string to the default error output""" - Term.cerr.write(data) + IPython.utils.io.Term.cerr.write(data) def ask_yes_no(self,prompt,default=True): if self.quiet: diff --git a/IPython/core/macro.py b/IPython/core/macro.py index 8fb52a6..676e083 100644 --- a/IPython/core/macro.py +++ b/IPython/core/macro.py @@ -7,7 +7,7 @@ # the file COPYING, distributed as part of this software. #***************************************************************************** -from IPython.utils.io import Term +import IPython.utils.io from IPython.core.autocall import IPyAutocall class Macro(IPyAutocall): @@ -32,7 +32,7 @@ class Macro(IPyAutocall): return 'IPython.macro.Macro(%s)' % repr(self.value) def __call__(self,*args): - Term.cout.flush() + IPython.utils.io.Term.cout.flush() self._ip.user_ns['_margv'] = args self._ip.runlines(self.value) diff --git a/IPython/core/magic.py b/IPython/core/magic.py index fad3f6b..5cd7429 100644 --- a/IPython/core/magic.py +++ b/IPython/core/magic.py @@ -58,7 +58,8 @@ from IPython.lib.pylabtools import mpl_runner from IPython.lib.inputhook import enable_gui from IPython.external.Itpl import itpl, printpl from IPython.testing import decorators as testdec -from IPython.utils.io import Term, file_read, nlprint +from IPython.utils.io import file_read, nlprint +import IPython.utils.io from IPython.utils.path import get_py_filename from IPython.utils.process import arg_split, abbrev_cwd from IPython.utils.terminal import set_term_title @@ -3093,7 +3094,7 @@ Defaulting color scheme to 'NoColor'""" # If all looks ok, proceed out,err = self.shell.getoutputerror(cmd) if err: - print >> Term.cerr,err + print >> IPython.utils.io.Term.cerr, err if opts.has_key('l'): out = SList(out.split('\n')) else: @@ -3143,7 +3144,7 @@ Defaulting color scheme to 'NoColor'""" if parameter_s: out,err = self.shell.getoutputerror(parameter_s) if err: - print >> Term.cerr,err + print >> IPython.utils.io.Term.cerr, err return SList(out.split('\n')) def magic_r(self, parameter_s=''): diff --git a/IPython/core/oinspect.py b/IPython/core/oinspect.py index 91ac5a5..723acae 100644 --- a/IPython/core/oinspect.py +++ b/IPython/core/oinspect.py @@ -30,7 +30,7 @@ import types from IPython.core.page import page from IPython.external.Itpl import itpl from IPython.utils import PyColorize -from IPython.utils.io import Term +import IPython.utils.io from IPython.utils.text import indent from IPython.utils.wildcard import list_namespace from IPython.utils.coloransi import * @@ -249,7 +249,7 @@ class Inspector: if output is None: self.noinfo('definition header',oname) else: - print >>Term.cout, header,self.format(output), + print >>IPython.utils.io.Term.cout, header,self.format(output), def pdoc(self,obj,oname='',formatter = None): """Print the docstring for any object. diff --git a/IPython/core/page.py b/IPython/core/page.py index f26075a..e8a234e 100755 --- a/IPython/core/page.py +++ b/IPython/core/page.py @@ -36,7 +36,7 @@ from IPython.core import ipapi from IPython.core.error import TryNext from IPython.utils.cursesimport import use_curses from IPython.utils.data import chop -from IPython.utils.io import Term +import IPython.utils.io from IPython.utils.process import xsys from IPython.utils.terminal import get_terminal_size @@ -56,18 +56,18 @@ def page_dumb(strng, start=0, screen_lines=25): out_ln = strng.splitlines()[start:] screens = chop(out_ln,screen_lines-1) if len(screens) == 1: - print >>Term.cout, os.linesep.join(screens[0]) + print >>IPython.utils.io.Term.cout, os.linesep.join(screens[0]) else: last_escape = "" for scr in screens[0:-1]: hunk = os.linesep.join(scr) - print >>Term.cout, last_escape + hunk + print >>IPython.utils.io.Term.cout, last_escape + hunk if not page_more(): return esc_list = esc_re.findall(hunk) if len(esc_list) > 0: last_escape = esc_list[-1] - print >>Term.cout, last_escape + os.linesep.join(screens[-1]) + print >>IPython.utils.io.Term.cout, last_escape + os.linesep.join(screens[-1]) def page(strng, start=0, screen_lines=0, pager_cmd=None): @@ -156,7 +156,7 @@ def page(strng, start=0, screen_lines=0, pager_cmd=None): #print 'numlines',numlines,'screenlines',screen_lines # dbg if numlines <= screen_lines : #print '*** normal print' # dbg - print >>Term.cout, str_toprint + print >>IPython.utils.io.Term.cout, str_toprint else: # Try to open pager and default to internal one if that fails. # All failure modes are tagged as 'retval=1', to match the return @@ -262,13 +262,13 @@ if os.name == 'nt' and os.environ.get('TERM','dumb') != 'emacs': @return: True if need print more lines, False if quit """ - Term.cout.write('---Return to continue, q to quit--- ') + IPython.utils.io.Term.cout.write('---Return to continue, q to quit--- ') ans = msvcrt.getch() if ans in ("q", "Q"): result = False else: result = True - Term.cout.write("\b"*37 + " "*37 + "\b"*37) + IPython.utils.io.Term.cout.write("\b"*37 + " "*37 + "\b"*37) return result else: def page_more(): diff --git a/IPython/core/prefilter.py b/IPython/core/prefilter.py index ca9c295..a7bd9c6 100755 --- a/IPython/core/prefilter.py +++ b/IPython/core/prefilter.py @@ -36,7 +36,7 @@ from IPython.core.splitinput import split_user_input from IPython.core.page import page from IPython.utils.traitlets import List, Int, Any, Str, CBool, Bool, Instance -from IPython.utils.io import Term +import IPython.utils.io from IPython.utils.text import make_quoted_expr from IPython.utils.autoattr import auto_attr @@ -922,7 +922,7 @@ class AutoHandler(PrefilterHandler): # plain ascii works better w/ pyreadline, on some machines, so # we use it and only print uncolored rewrite if we have unicode rw = str(rw) - print >>Term.cout, rw + print >>IPython.utils.io.Term.cout, rw except UnicodeEncodeError: print "-------------->" + newcmd diff --git a/IPython/core/prompts.py b/IPython/core/prompts.py index 2220fdb..14231c8 100644 --- a/IPython/core/prompts.py +++ b/IPython/core/prompts.py @@ -25,7 +25,7 @@ from IPython.core.error import TryNext from IPython.utils import coloransi import IPython.utils.generics from IPython.utils.warn import warn -from IPython.utils.io import Term +import IPython.utils.io #**************************************************************************** #Color schemes for Prompts. @@ -537,7 +537,7 @@ class CachedOutput: except KeyError: pass if arg is not None: - cout_write = Term.cout.write # fast lookup + cout_write = IPython.utils.io.Term.cout.write # fast lookup # first handle the cache and counters # do not print output if input ends in ';' @@ -577,7 +577,7 @@ class CachedOutput: if self.logger.log_output: self.logger.log_write(repr(arg),'output') cout_write(self.output_sep2) - Term.cout.flush() + IPython.utils.io.Term.cout.flush() def _display(self,arg): """Default printer method, uses pprint. diff --git a/IPython/core/ultratb.py b/IPython/core/ultratb.py index d5b3e22..40b74e1 100644 --- a/IPython/core/ultratb.py +++ b/IPython/core/ultratb.py @@ -95,7 +95,7 @@ from IPython.core import debugger, ipapi from IPython.core.display_trap import DisplayTrap from IPython.core.excolors import exception_colors from IPython.utils.data import uniq_stable -from IPython.utils.io import Term +import IPython.utils.io from IPython.utils.warn import info, error # Globals @@ -313,14 +313,11 @@ def _format_traceback_lines(lnum, index, lines, Colors, lvals=None,scheme=None): class TBTools: """Basic tools used by all traceback printer classes.""" - #: Default output stream, can be overridden at call time. A special value - #: of 'stdout' *as a string* can be given to force extraction of sys.stdout - #: at runtime. This allows testing exception printing with doctests, that - #: swap sys.stdout just at execution time. - #: Warning: be VERY careful to set this to one of the Term streams, NEVER - #: directly to sys.stdout/err, because under win32 the Term streams come from - #: pyreadline and know how to handle color correctly, whie stdout/err don't. - out_stream = Term.cerr + # This attribute us used in globalipapp.py to have stdout used for + # writting exceptions. This is needed so nose can trap them. This attribute + # should be None (the default, which will use IPython.utils.io.Term) or + # the string 'stdout' which will cause the override to sys.stdout. + out_stream = None def __init__(self,color_scheme = 'NoColor',call_pdb=False): # Whether to call the interactive pdb debugger after printing @@ -384,9 +381,9 @@ class ListTB(TBTools): TBTools.__init__(self,color_scheme = color_scheme,call_pdb=0) def __call__(self, etype, value, elist): - Term.cout.flush() - Term.cerr.write(self.text(etype,value,elist)) - Term.cerr.write('\n') + IPython.utils.io.Term.cout.flush() + IPython.utils.io.Term.cerr.write(self.text(etype,value,elist)) + IPython.utils.io.Term.cerr.write('\n') def text(self, etype, value, elist, context=5): """Return a color formatted string with the traceback info. @@ -535,10 +532,13 @@ class ListTB(TBTools): """ # This method needs to use __call__ from *this* class, not the one from # a subclass whose signature or behavior may be different - Term.cout.flush() - ostream = sys.stdout if self.out_stream == 'stdout' else Term.cerr + if self.out_stream == 'stdout': + ostream = sys.stdout + else: + ostream = IPython.utils.io.Term.cerr + ostream.flush() ostream.write(ListTB.text(self, etype, value, [])) - ostream.flush() + ostream.flush() def _some_str(self, value): # Lifted from traceback.py @@ -659,7 +659,7 @@ class VerboseTB(TBTools): # So far, I haven't been able to find an isolated example to # reproduce the problem. inspect_error() - traceback.print_exc(file=Term.cerr) + traceback.print_exc(file=IPython.utils.io.Term.cerr) info('\nUnfortunately, your original traceback can not be constructed.\n') return '' @@ -696,7 +696,7 @@ class VerboseTB(TBTools): # able to remove this try/except when 2.4 becomes a # requirement. Bug details at http://python.org/sf/1005466 inspect_error() - traceback.print_exc(file=Term.cerr) + traceback.print_exc(file=IPython.utils.io.Term.cerr) info("\nIPython's exception reporting continues...\n") if func == '?': @@ -717,7 +717,7 @@ class VerboseTB(TBTools): # and barfs out. At some point I should dig into this one # and file a bug report about it. inspect_error() - traceback.print_exc(file=Term.cerr) + traceback.print_exc(file=IPython.utils.io.Term.cerr) info("\nIPython's exception reporting continues...\n") call = tpl_call_fail % func @@ -910,9 +910,9 @@ class VerboseTB(TBTools): def handler(self, info=None): (etype, evalue, etb) = info or sys.exc_info() self.tb = etb - Term.cout.flush() - Term.cerr.write(self.text(etype, evalue, etb)) - Term.cerr.write('\n') + IPython.utils.io.Term.cout.flush() + IPython.utils.io.Term.cerr.write(self.text(etype, evalue, etb)) + IPython.utils.io.Term.cerr.write('\n') # Changed so an instance can just be called as VerboseTB_inst() and print # out the right info on its own. @@ -1032,8 +1032,11 @@ class AutoFormattedTB(FormattedTB): given at initialization time. """ if out is None: - out = sys.stdout if self.out_stream=='stdout' else self.out_stream - Term.cout.flush() + if self.out_stream == 'stdout': + out = sys.stdout + else: + out = IPython.utils.io.Term.cerr + out.flush() if tb_offset is not None: tb_offset, self.tb_offset = self.tb_offset, tb_offset out.write(self.text(etype, evalue, etb)) diff --git a/IPython/deathrow/gui/wx/ipshell_nonblocking.py b/IPython/deathrow/gui/wx/ipshell_nonblocking.py index b8d4907..8644ade 100755 --- a/IPython/deathrow/gui/wx/ipshell_nonblocking.py +++ b/IPython/deathrow/gui/wx/ipshell_nonblocking.py @@ -24,7 +24,7 @@ import locale from thread_ex import ThreadEx from IPython.core import iplib -from IPython.utils.io import Term +import IPython.utils.io ############################################################################## class _Helper(object): diff --git a/IPython/deathrow/ipipe.py b/IPython/deathrow/ipipe.py index c440e6e..8c2766d 100644 --- a/IPython/deathrow/ipipe.py +++ b/IPython/deathrow/ipipe.py @@ -133,7 +133,7 @@ from IPython.external import simplegeneric from IPython.external import path try: - from IPython.utils.io import Term + import IPython.utils.io from IPython.utils import generics except ImportError: Term = None diff --git a/IPython/deathrow/oldfrontend/prefilterfrontend.py b/IPython/deathrow/oldfrontend/prefilterfrontend.py index 327ea0a..20726e2 100644 --- a/IPython/deathrow/oldfrontend/prefilterfrontend.py +++ b/IPython/deathrow/oldfrontend/prefilterfrontend.py @@ -31,7 +31,7 @@ from IPython.kernel.core.redirector_output_trap import RedirectorOutputTrap from IPython.kernel.core.sync_traceback_trap import SyncTracebackTrap -from IPython.utils.io import Term +import IPython.utils.io from linefrontendbase import LineFrontEndBase, common_prefix diff --git a/IPython/deathrow/twshell.py b/IPython/deathrow/twshell.py index 3270d65..dd09e7e 100644 --- a/IPython/deathrow/twshell.py +++ b/IPython/deathrow/twshell.py @@ -14,7 +14,7 @@ from IPython.core.iplib import InteractiveShell from IPython.utils.ipstruct import Struct import Queue,thread,threading,signal from signal import signal, SIGINT -from IPython.utils.io import Term, ask_yes_no +import IPython.utils.io, ask_yes_no from IPython.utils.warn import warn, error from IPython.utils.decorators import flag_calls from IPython.core import shellglobals diff --git a/IPython/extensions/pretty.py b/IPython/extensions/pretty.py index 3adf476..17a6e5c 100644 --- a/IPython/extensions/pretty.py +++ b/IPython/extensions/pretty.py @@ -39,7 +39,7 @@ from IPython.core.error import TryNext from IPython.external import pretty from IPython.core.plugin import Plugin from IPython.utils.traitlets import Bool, List, Instance -from IPython.utils.io import Term +import IPython.utils.io from IPython.utils.autoattr import auto_attr from IPython.utils.importstring import import_item @@ -100,8 +100,8 @@ class PrettyResultDisplay(Plugin): # So that multi-line strings line up with the left column of # the screen, instead of having the output prompt mess up # their first line. - Term.cout.write('\n') - print >>Term.cout, out + IPython.utils.io.Term.cout.write('\n') + print >>IPython.utils.io.Term.cout, out else: raise TryNext diff --git a/IPython/kernel/core/prompts.py b/IPython/kernel/core/prompts.py index fc583ea..ab36fa1 100644 --- a/IPython/kernel/core/prompts.py +++ b/IPython/kernel/core/prompts.py @@ -32,7 +32,7 @@ from IPython.external.Itpl import ItplNS from IPython.utils import coloransi from IPython.core import release from IPython.core.error import TryNext -from IPython.utils.io import Term +import IPython.utils.io from IPython.utils.warn import warn import IPython.utils.generics diff --git a/IPython/lib/demo.py b/IPython/lib/demo.py index 398eca3..580588f 100644 --- a/IPython/lib/demo.py +++ b/IPython/lib/demo.py @@ -176,7 +176,8 @@ import shlex import sys from IPython.utils.PyColorize import Parser -from IPython.utils.io import file_read, file_readlines, Term +from IPython.utils.io import file_read, file_readlines +import IPython.utils.io from IPython.utils.text import marquee __all__ = ['Demo','IPythonDemo','LineDemo','IPythonLineDemo','DemoError'] @@ -318,7 +319,7 @@ class Demo(object): if index is None: if self.finished: - print >>Term.cout, 'Demo finished. Use .reset() if you want to rerun it.' + print >>IPython.utils.io.Term.cout, 'Demo finished. Use .reset() if you want to rerun it.' return None index = self.block_index else: @@ -387,9 +388,9 @@ class Demo(object): if index is None: return - print >>Term.cout, self.marquee('<%s> block # %s (%s remaining)' % + print >>IPython.utils.io.Term.cout, self.marquee('<%s> block # %s (%s remaining)' % (self.title,index,self.nblocks-index-1)) - print >>Term.cout,(self.src_blocks_colored[index]) + print >>IPython.utils.io.Term.cout,(self.src_blocks_colored[index]) sys.stdout.flush() def show_all(self): @@ -402,12 +403,12 @@ class Demo(object): marquee = self.marquee for index,block in enumerate(self.src_blocks_colored): if silent[index]: - print >>Term.cout, marquee('<%s> SILENT block # %s (%s remaining)' % + print >>IPython.utils.io.Term.cout, marquee('<%s> SILENT block # %s (%s remaining)' % (title,index,nblocks-index-1)) else: - print >>Term.cout, marquee('<%s> block # %s (%s remaining)' % + print >>IPython.utils.io.Term.cout, marquee('<%s> block # %s (%s remaining)' % (title,index,nblocks-index-1)) - print >>Term.cout, block, + print >>IPython.utils.io.Term.cout, block, sys.stdout.flush() def runlines(self,source): @@ -432,18 +433,18 @@ class Demo(object): next_block = self.src_blocks[index] self.block_index += 1 if self._silent[index]: - print >>Term.cout, marquee('Executing silent block # %s (%s remaining)' % + print >>IPython.utils.io.Term.cout, marquee('Executing silent block # %s (%s remaining)' % (index,self.nblocks-index-1)) else: self.pre_cmd() self.show(index) if self.auto_all or self._auto[index]: - print >>Term.cout, marquee('output:') + print >>IPython.utils.io.Term.cout, marquee('output:') else: - print >>Term.cout, marquee('Press to quit, to execute...'), + print >>IPython.utils.io.Term.cout, marquee('Press to quit, to execute...'), ans = raw_input().strip() if ans: - print >>Term.cout, marquee('Block NOT executed') + print >>IPython.utils.io.Term.cout, marquee('Block NOT executed') return try: save_argv = sys.argv @@ -461,10 +462,10 @@ class Demo(object): if self.block_index == self.nblocks: mq1 = self.marquee('END OF DEMO') if mq1: - # avoid spurious print >>Term.cout,s if empty marquees are used - print >>Term.cout - print >>Term.cout, mq1 - print >>Term.cout, self.marquee('Use .reset() if you want to rerun it.') + # avoid spurious print >>IPython.utils.io.Term.cout,s if empty marquees are used + print >>IPython.utils.io.Term.cout + print >>IPython.utils.io.Term.cout, mq1 + print >>IPython.utils.io.Term.cout, self.marquee('Use .reset() if you want to rerun it.') self.finished = True # These methods are meant to be overridden by subclasses who may wish to diff --git a/IPython/utils/io.py b/IPython/utils/io.py index 30408e2..e38445b 100644 --- a/IPython/utils/io.py +++ b/IPython/utils/io.py @@ -65,21 +65,10 @@ class IOTerm: # In the future, having IPython channel all its I/O operations through # this class will make it easier to embed it into other environments which # are not a normal terminal (such as a GUI-based shell) - def __init__(self,cin=None,cout=None,cerr=None): - self.cin = IOStream(cin,sys.stdin) - self.cout = IOStream(cout,sys.stdout) - self.cerr = IOStream(cerr,sys.stderr) - - -# Global variable to be used for all I/O -Term = IOTerm() - - -import IPython.utils.rlineimpl as readline -# Remake Term to use the readline i/o facilities -if sys.platform == 'win32' and readline.have_readline: - - Term = IOTerm(cout=readline._outputfile,cerr=readline._outputfile) + def __init__(self, cin=None, cout=None, cerr=None): + self.cin = IOStream(cin, sys.stdin) + self.cout = IOStream(cout, sys.stdout) + self.cerr = IOStream(cerr, sys.stderr) class Tee(object): diff --git a/IPython/utils/warn.py b/IPython/utils/warn.py index 772faed..bc9edd3 100644 --- a/IPython/utils/warn.py +++ b/IPython/utils/warn.py @@ -16,7 +16,7 @@ Utilities for warnings. Shoudn't we just use the built in warnings module. import sys -from IPython.utils.io import Term +import IPython.utils.io #----------------------------------------------------------------------------- # Code @@ -25,7 +25,7 @@ from IPython.utils.io import Term def warn(msg,level=2,exit_val=1): """Standard warning printer. Gives formatting consistency. - Output is sent to Term.cerr (sys.stderr by default). + Output is sent to IPython.utils.io.Term.cerr (sys.stderr by default). Options: @@ -41,9 +41,9 @@ def warn(msg,level=2,exit_val=1): if level>0: header = ['','','WARNING: ','ERROR: ','FATAL ERROR: '] - print >> Term.cerr, '%s%s' % (header[level],msg) + print >> IPython.utils.io.Term.cerr, '%s%s' % (header[level],msg) if level == 4: - print >> Term.cerr,'Exiting.\n' + print >> IPython.utils.io.Term.cerr,'Exiting.\n' sys.exit(exit_val) diff --git a/IPython/zmq/ipkernel.py b/IPython/zmq/ipkernel.py index f3d883d..82a048c 100755 --- a/IPython/zmq/ipkernel.py +++ b/IPython/zmq/ipkernel.py @@ -266,9 +266,12 @@ def main(): req_port = bind_port(req_socket, namespace.ip, namespace.req) print >>sys.__stdout__, "REQ Channel on port", req_port - # Redirect input streams and set a display hook. + # Redirect input streams. This needs to be done before the Kernel is done + # because currently the Kernel creates a ZMQInteractiveShell, which + # holds references to sys.stdout and sys.stderr. sys.stdout = OutStream(session, pub_socket, u'stdout') sys.stderr = OutStream(session, pub_socket, u'stderr') + # Set a displayhook. sys.displayhook = DisplayHook(session, pub_socket) # Create the kernel. diff --git a/IPython/zmq/zmqshell.py b/IPython/zmq/zmqshell.py index 6044287..62ba5d0 100644 --- a/IPython/zmq/zmqshell.py +++ b/IPython/zmq/zmqshell.py @@ -19,4 +19,13 @@ class ZMQInteractiveShell(InteractiveShell): print line return p.wait() + def init_io(self): + # This will just use sys.stdout and sys.stderr. If you want to + # override sys.stdout and sys.stderr themselves, you need to do that + # *before* instantiating this class, because Term holds onto + # references to the underlying streams. + import IPython.utils.io + Term = IPython.utils.io.IOTerm() + IPython.utils.io.Term = Term + InteractiveShellABC.register(ZMQInteractiveShell)