From f9a281d8fa066976849b0a9845e280dd4e0c5f57 2016-03-30 00:24:45 From: Thomas Kluyver Date: 2016-03-30 00:24:45 Subject: [PATCH] Deprecate io.{stdout,stderr} and shell.{write,write_err} I believe there is no longer any reason to use these --- diff --git a/IPython/core/debugger.py b/IPython/core/debugger.py index 39abf9b..0f0c78a 100644 --- a/IPython/core/debugger.py +++ b/IPython/core/debugger.py @@ -33,7 +33,7 @@ import sys from IPython import get_ipython from IPython.utils import PyColorize, ulinecache -from IPython.utils import coloransi, io, py3compat +from IPython.utils import coloransi, py3compat from IPython.core.excolors import exception_colors from IPython.testing.skipdoctest import skip_doctest @@ -221,7 +221,7 @@ class Pdb(OldPdb): raise ValueError("Context must be a positive integer") if has_pydb and completekey is None: - OldPdb.__init__(self,stdin=stdin,stdout=io.stdout) + OldPdb.__init__(self,stdin=stdin,stdout=sys.stdout) else: OldPdb.__init__(self,completekey,stdin,stdout) @@ -369,7 +369,7 @@ class Pdb(OldPdb): raise ValueError("Context must be a positive integer") except (TypeError, ValueError): raise ValueError("Context must be a positive integer") - print(self.format_stack_entry(frame_lineno, '', context), file=io.stdout) + print(self.format_stack_entry(frame_lineno, '', context)) # vds: >> frame, lineno = frame_lineno @@ -513,7 +513,7 @@ class Pdb(OldPdb): src.append(line) self.lineno = lineno - print(''.join(src), file=io.stdout) + print(''.join(src)) except KeyboardInterrupt: pass diff --git a/IPython/core/display.py b/IPython/core/display.py index 458526a..1db5d8a 100644 --- a/IPython/core/display.py +++ b/IPython/core/display.py @@ -15,6 +15,7 @@ import json import mimetypes import os import struct +import sys import warnings from IPython.utils.py3compat import (string_types, cast_bytes_py2, cast_unicode, @@ -938,11 +939,10 @@ def clear_output(wait=False): if InteractiveShell.initialized(): InteractiveShell.instance().display_pub.clear_output(wait) else: - from IPython.utils import io - print('\033[2K\r', file=io.stdout, end='') - io.stdout.flush() - print('\033[2K\r', file=io.stderr, end='') - io.stderr.flush() + print('\033[2K\r', end='') + sys.stdout.flush() + print('\033[2K\r', end='') + sys.stderr.flush() @skip_doctest diff --git a/IPython/core/displayhook.py b/IPython/core/displayhook.py index 4d17408..269ae18 100644 --- a/IPython/core/displayhook.py +++ b/IPython/core/displayhook.py @@ -14,7 +14,6 @@ import io as _io import tokenize from traitlets.config.configurable import Configurable -from IPython.utils import io from IPython.utils.py3compat import builtin_mod, cast_unicode_py2 from traitlets import Instance, Float from warnings import warn @@ -113,10 +112,10 @@ class DisplayHook(Configurable): ``io.stdout``. """ # Use write, not print which adds an extra space. - io.stdout.write(self.shell.separate_out) + sys.stdout.write(self.shell.separate_out) outprompt = self.shell.prompt_manager.render('out') if self.do_full_cache: - io.stdout.write(outprompt) + sys.stdout.write(outprompt) def compute_format_data(self, result): """Compute format data of the object to be displayed. @@ -185,7 +184,7 @@ class DisplayHook(Configurable): # But avoid extraneous empty lines. result_repr = '\n' + result_repr - print(result_repr, file=io.stdout) + print(result_repr) def update_user_ns(self, result): """Update user_ns with various things like _, __, _1, etc.""" @@ -229,8 +228,8 @@ class DisplayHook(Configurable): def finish_displayhook(self): """Finish up all displayhook activities.""" - io.stdout.write(self.shell.separate_out2) - io.stdout.flush() + sys.stdout.write(self.shell.separate_out2) + sys.stdout.flush() def __call__(self, result=None): """Printing with history cache management. diff --git a/IPython/core/displaypub.py b/IPython/core/displaypub.py index 0fe0398..0269b75 100644 --- a/IPython/core/displaypub.py +++ b/IPython/core/displaypub.py @@ -17,8 +17,9 @@ spec. from __future__ import print_function +import sys + from traitlets.config.configurable import Configurable -from IPython.utils import io from traitlets import List # This used to be defined here - it is imported for backwards compatibility @@ -92,14 +93,14 @@ class DisplayPublisher(Configurable): # The default is to simply write the plain text data using io.stdout. if 'text/plain' in data: - print(data['text/plain'], file=io.stdout) + print(data['text/plain']) def clear_output(self, wait=False): """Clear the output of the cell receiving output.""" - print('\033[2K\r', file=io.stdout, end='') - io.stdout.flush() - print('\033[2K\r', file=io.stderr, end='') - io.stderr.flush() + print('\033[2K\r', end='') + sys.stdout.flush() + print('\033[2K\r', end='') + sys.stderr.flush() class CapturingDisplayPublisher(DisplayPublisher): diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index a78163c..738f1d4 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -1697,11 +1697,11 @@ class InteractiveShell(SingletonConfigurable): except: # clear custom handler immediately self.set_custom_exc((), None) - print("Custom TB Handler failed, unregistering", file=io.stderr) + print("Custom TB Handler failed, unregistering", file=sys.stderr) # show the exception in handler first stb = self.InteractiveTB.structured_traceback(*sys.exc_info()) - print(self.InteractiveTB.stb2text(stb), file=io.stdout) - print("The original exception:", file=io.stdout) + print(self.InteractiveTB.stb2text(stb)) + print("The original exception:") stb = self.InteractiveTB.structured_traceback( (etype,value,tb), tb_offset=tb_offset ) @@ -1799,7 +1799,7 @@ class InteractiveShell(SingletonConfigurable): try: etype, value, tb = self._get_exc_info(exc_tuple) except ValueError: - self.write_err('No traceback available to show.\n') + print('No traceback available to show.', file=sys.stderr) return if issubclass(etype, SyntaxError): @@ -1834,7 +1834,7 @@ class InteractiveShell(SingletonConfigurable): self._showtraceback(etype, value, stb) except KeyboardInterrupt: - self.write_err('\n' + self.get_exception_only()) + print('\n' + self.get_exception_only(), file=sys.stderr) def _showtraceback(self, etype, evalue, stb): """Actually show a traceback. @@ -1842,7 +1842,7 @@ class InteractiveShell(SingletonConfigurable): Subclasses may override this method to put the traceback on a different place, like a side channel. """ - print(self.InteractiveTB.stb2text(stb), file=io.stdout) + print(self.InteractiveTB.stb2text(stb)) def showsyntaxerror(self, filename=None): """Display the syntax error that just occurred. @@ -2228,7 +2228,7 @@ class InteractiveShell(SingletonConfigurable): try: ec = os.system(cmd) except KeyboardInterrupt: - self.write_err('\n' + self.get_exception_only()) + print('\n' + self.get_exception_only(), file=sys.stderr) ec = -2 else: cmd = py3compat.unicode_to_str(cmd) @@ -2247,7 +2247,7 @@ class InteractiveShell(SingletonConfigurable): ec = subprocess.call(cmd, shell=True, executable=executable) except KeyboardInterrupt: # intercept control-C; a long traceback is not useful here - self.write_err('\n' + self.get_exception_only()) + print('\n' + self.get_exception_only(), file=sys.stderr) ec = 130 if ec > 128: ec = -(ec - 128) @@ -2351,7 +2351,7 @@ class InteractiveShell(SingletonConfigurable): # 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(rw, file=io.stdout) + print(rw) except UnicodeEncodeError: print("------> " + cmd) @@ -3056,15 +3056,19 @@ class InteractiveShell(SingletonConfigurable): tmp_file.close() return filename - # TODO: This should be removed when Term is refactored. + @undoc def write(self,data): - """Write a string to the default output""" - io.stdout.write(data) + """DEPRECATED: Write a string to the default output""" + warn('InteractiveShell.write() is deprecated, use sys.stdout instead', + DeprecationWarning, stacklevel=2) + sys.stdout.write(data) - # TODO: This should be removed when Term is refactored. + @undoc def write_err(self,data): - """Write a string to the default error output""" - io.stderr.write(data) + """DEPRECATED: Write a string to the default error output""" + warn('InteractiveShell.write_err() is deprecated, use sys.stderr instead', + DeprecationWarning, stacklevel=2) + sys.stderr.write(data) def ask_yes_no(self, prompt, default=None, interrupt=None): if self.quiet: diff --git a/IPython/core/magics/history.py b/IPython/core/magics/history.py index c21fa2f..5967591 100644 --- a/IPython/core/magics/history.py +++ b/IPython/core/magics/history.py @@ -15,6 +15,7 @@ from __future__ import print_function # Stdlib import os +import sys from io import open as io_open # Our own packages @@ -147,7 +148,7 @@ class HistoryMagics(Magics): # Check if output to specific file was requested. outfname = args.filename if not outfname: - outfile = io.stdout # default + outfile = sys.stdout # default # We don't want to close stdout at the end! close_at_end = False else: diff --git a/IPython/core/oinspect.py b/IPython/core/oinspect.py index 52b701e..d1a122e 100644 --- a/IPython/core/oinspect.py +++ b/IPython/core/oinspect.py @@ -32,7 +32,6 @@ from IPython.core import page from IPython.lib.pretty import pretty from IPython.testing.skipdoctest import skip_doctest_py3 from IPython.utils import PyColorize -from IPython.utils import io from IPython.utils import openpy from IPython.utils import py3compat from IPython.utils.dir2 import safe_hasattr @@ -427,7 +426,7 @@ class Inspector(Colorable): if output is None: self.noinfo('definition header',oname) else: - print(header,self.format(output), end=' ', file=io.stdout) + print(header,self.format(output), end=' ') # In Python 3, all classes are new-style, so they all have __init__. @skip_doctest_py3 diff --git a/IPython/core/page.py b/IPython/core/page.py index 4b29faa..b3f06e6 100644 --- a/IPython/core/page.py +++ b/IPython/core/page.py @@ -26,7 +26,6 @@ from IPython import get_ipython from IPython.core.display import display from IPython.core.error import TryNext from IPython.utils.data import chop -from IPython.utils import io from IPython.utils.process import system from IPython.utils.terminal import get_terminal_size from IPython.utils import py3compat @@ -62,18 +61,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(os.linesep.join(screens[0]), file=io.stdout) + print(os.linesep.join(screens[0])) else: last_escape = "" for scr in screens[0:-1]: hunk = os.linesep.join(scr) - print(last_escape + hunk, file=io.stdout) + print(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(last_escape + os.linesep.join(screens[-1]), file=io.stdout) + print(last_escape + os.linesep.join(screens[-1])) def _detect_screen_size(screen_lines_def): """Attempt to work out the number of lines on the screen. @@ -191,13 +190,13 @@ def pager_page(strng, start=0, screen_lines=0, pager_cmd=None): try: screen_lines += _detect_screen_size(screen_lines_def) except (TypeError, UnsupportedOperation): - print(str_toprint, file=io.stdout) + print(str_toprint) return #print 'numlines',numlines,'screenlines',screen_lines # dbg if numlines <= screen_lines : #print '*** normal print' # dbg - print(str_toprint, file=io.stdout) + print(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 @@ -339,13 +338,13 @@ if os.name == 'nt' and os.environ.get('TERM','dumb') != 'emacs': @return: True if need print more lines, False if quit """ - io.stdout.write('---Return to continue, q to quit--- ') + sys.stdout.write('---Return to continue, q to quit--- ') ans = msvcrt.getwch() if ans in ("q", "Q"): result = False else: result = True - io.stdout.write("\b"*37 + " "*37 + "\b"*37) + sys.stdout.write("\b"*37 + " "*37 + "\b"*37) return result else: def page_more(): diff --git a/IPython/core/tests/test_interactiveshell.py b/IPython/core/tests/test_interactiveshell.py index adc9cf0..11164d4 100644 --- a/IPython/core/tests/test_interactiveshell.py +++ b/IPython/core/tests/test_interactiveshell.py @@ -196,33 +196,19 @@ class InteractiveShellTestCase(unittest.TestCase): def test_bad_custom_tb(self): """Check that InteractiveShell is protected from bad custom exception handlers""" - from IPython.utils import io - save_stderr = io.stderr - try: - # capture stderr - io.stderr = StringIO() - ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0) - self.assertEqual(ip.custom_exceptions, (IOError,)) + ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0) + self.assertEqual(ip.custom_exceptions, (IOError,)) + with tt.AssertPrints("Custom TB Handler failed", channel='stderr'): ip.run_cell(u'raise IOError("foo")') - self.assertEqual(ip.custom_exceptions, ()) - self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue()) - finally: - io.stderr = save_stderr + self.assertEqual(ip.custom_exceptions, ()) def test_bad_custom_tb_return(self): """Check that InteractiveShell is protected from bad return types in custom exception handlers""" - from IPython.utils import io - save_stderr = io.stderr - try: - # capture stderr - io.stderr = StringIO() - ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1) - self.assertEqual(ip.custom_exceptions, (NameError,)) + ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1) + self.assertEqual(ip.custom_exceptions, (NameError,)) + with tt.AssertPrints("Custom TB Handler failed", channel='stderr'): ip.run_cell(u'a=abracadabra') - self.assertEqual(ip.custom_exceptions, ()) - self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue()) - finally: - io.stderr = save_stderr + self.assertEqual(ip.custom_exceptions, ()) def test_drop_by_id(self): myvars = {"a":object(), "b":object(), "c": object()} diff --git a/IPython/core/ultratb.py b/IPython/core/ultratb.py index 8c4a8fc..b41bf4e 100644 --- a/IPython/core/ultratb.py +++ b/IPython/core/ultratb.py @@ -118,7 +118,6 @@ from IPython.core import debugger from IPython.core.display_trap import DisplayTrap from IPython.core.excolors import exception_colors from IPython.utils import PyColorize -from IPython.utils import io from IPython.utils import openpy from IPython.utils import path as util_path from IPython.utils import py3compat @@ -523,7 +522,7 @@ class TBTools(colorable.Colorable): - Any object with 'write' and 'flush' attributes. """ - return io.stdout if self._ostream is None else self._ostream + return sys.stdout if self._ostream is None else self._ostream def _set_ostream(self, val): assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush')) diff --git a/IPython/lib/demo.py b/IPython/lib/demo.py index 435670d..3066722 100644 --- a/IPython/lib/demo.py +++ b/IPython/lib/demo.py @@ -326,7 +326,7 @@ class Demo(object): if index is None: if self.finished: - print('Demo finished. Use .reset() if you want to rerun it.', file=io.stdout) + print('Demo finished. Use .reset() if you want to rerun it.') return None index = self.block_index else: @@ -397,8 +397,8 @@ class Demo(object): return print(self.marquee('<%s> block # %s (%s remaining)' % - (self.title,index,self.nblocks-index-1)), file=io.stdout) - print(self.src_blocks_colored[index], file=io.stdout) + (self.title,index,self.nblocks-index-1))) + print(self.src_blocks_colored[index]) sys.stdout.flush() def show_all(self): @@ -412,11 +412,11 @@ class Demo(object): for index,block in enumerate(self.src_blocks_colored): if silent[index]: print(marquee('<%s> SILENT block # %s (%s remaining)' % - (title,index,nblocks-index-1)), file=io.stdout) + (title,index,nblocks-index-1))) else: print(marquee('<%s> block # %s (%s remaining)' % - (title,index,nblocks-index-1)), file=io.stdout) - print(block, end=' ', file=io.stdout) + (title,index,nblocks-index-1))) + print(block, end=' ') sys.stdout.flush() def run_cell(self,source): @@ -442,17 +442,17 @@ class Demo(object): self.block_index += 1 if self._silent[index]: print(marquee('Executing silent block # %s (%s remaining)' % - (index,self.nblocks-index-1)), file=io.stdout) + (index,self.nblocks-index-1))) else: self.pre_cmd() self.show(index) if self.auto_all or self._auto[index]: - print(marquee('output:'), file=io.stdout) + print(marquee('output:')) else: - print(marquee('Press to quit, to execute...'), end=' ', file=io.stdout) + print(marquee('Press to quit, to execute...'), end=' ') ans = py3compat.input().strip() if ans: - print(marquee('Block NOT executed'), file=io.stdout) + print(marquee('Block NOT executed')) return try: save_argv = sys.argv @@ -471,9 +471,9 @@ class Demo(object): mq1 = self.marquee('END OF DEMO') if mq1: # avoid spurious print >>io.stdout,s if empty marquees are used - print(file=io.stdout) - print(mq1, file=io.stdout) - print(self.marquee('Use .reset() if you want to rerun it.'), file=io.stdout) + print() + print(mq1) + print(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 2ba3fd5..826e3b2 100644 --- a/IPython/utils/io.py +++ b/IPython/utils/io.py @@ -15,10 +15,12 @@ import os import sys import tempfile from warnings import warn + +from IPython.utils.decorators import undoc from .capture import CapturedIO, capture_output from .py3compat import string_types, input, PY3 - +@undoc class IOStream: def __init__(self,stream, fallback=None): @@ -42,6 +44,8 @@ class IOStream: return tpl.format(mod=cls.__module__, cls=cls.__name__, args=self.stream) def write(self,data): + warn('IOStream is deprecated, use sys.{stdin,stdout,stderr} instead', + DeprecationWarning, stacklevel=2) try: self._swrite(data) except: @@ -56,6 +60,8 @@ class IOStream: file=sys.stderr) def writelines(self, lines): + warn('IOStream is deprecated, use sys.{stdin,stdout,stderr} instead', + DeprecationWarning, stacklevel=2) if isinstance(lines, string_types): lines = [lines] for line in lines: diff --git a/IPython/utils/warn.py b/IPython/utils/warn.py index bb610ac..eee175b 100644 --- a/IPython/utils/warn.py +++ b/IPython/utils/warn.py @@ -9,9 +9,6 @@ Utilities for warnings. Shoudn't we just use the built in warnings module. from __future__ import print_function import sys - -from IPython.utils import io - import warnings warnings.warn("The module IPython.utils.warn is deprecated, use the standard warnings module instead", DeprecationWarning) @@ -36,9 +33,9 @@ def warn(msg,level=2,exit_val=1): warnings.warn("The module IPython.utils.warn is deprecated, use the standard warnings module instead", DeprecationWarning) if level>0: header = ['','','WARNING: ','ERROR: ','FATAL ERROR: '] - print(header[level], msg, sep='', file=io.stderr) + print(header[level], msg, sep='', file=sys.stderr) if level == 4: - print('Exiting.\n', file=io.stderr) + print('Exiting.\n', file=sys.stderr) sys.exit(exit_val)