diff --git a/IPython/config/loader.py b/IPython/config/loader.py index cfbd92b..d6212cd 100644 --- a/IPython/config/loader.py +++ b/IPython/config/loader.py @@ -439,7 +439,7 @@ class KeyValueConfigLoader(CommandLineConfigLoader): """decode argv if bytes, using stin.encoding, falling back on default enc""" uargv = [] if enc is None: - enc = text.getdefaultencoding() + enc = py3compat.getdefaultencoding() for arg in argv: if not isinstance(arg, unicode): # only decode if not already decoded @@ -603,7 +603,7 @@ class ArgParseConfigLoader(CommandLineConfigLoader): def _parse_args(self, args): """self.parser->self.parsed_data""" # decode sys.argv to support unicode command-line options - enc = text.getdefaultencoding() + enc = py3compat.getdefaultencoding() uargs = [py3compat.cast_unicode(a, enc) for a in args] self.parsed_data, self.extra_args = self.parser.parse_known_args(uargs) diff --git a/IPython/core/macro.py b/IPython/core/macro.py index 86031eb..d8b878d 100644 --- a/IPython/core/macro.py +++ b/IPython/core/macro.py @@ -35,7 +35,7 @@ class Macro(object): lines.append(line) code = "\n".join(lines) if isinstance(code, bytes): - code = code.decode(enc or sys.getdefaultencoding()) + code = code.decode(enc or py3compat.getdefaultencoding()) self.value = code + '\n' def __str__(self): diff --git a/IPython/core/magic.py b/IPython/core/magic.py index b294a0f..4d3d059 100644 --- a/IPython/core/magic.py +++ b/IPython/core/magic.py @@ -949,7 +949,7 @@ Currently the magic system has the following functions:\n""" try: vstr = str(var) except UnicodeEncodeError: - vstr = unicode(var).encode(sys.getdefaultencoding(), + vstr = unicode(var).encode(py3compat.getdefaultencoding(), 'backslashreplace') vstr = vstr.replace('\n','\\n') if len(vstr) < 50: diff --git a/IPython/core/tests/test_compilerop.py b/IPython/core/tests/test_compilerop.py index f586c33..1ffaaa2 100644 --- a/IPython/core/tests/test_compilerop.py +++ b/IPython/core/tests/test_compilerop.py @@ -52,7 +52,7 @@ def test_cache(): def setUp(): # Check we're in a proper Python 2 environment (some imports, such # as GTK, can change the default encoding, which can hide bugs.) - nt.assert_equal(sys.getdefaultencoding(), "utf-8" if py3compat.PY3 else "ascii") + nt.assert_equal(py3compat.getdefaultencoding(), "utf-8" if py3compat.PY3 else "ascii") def test_cache_unicode(): cp = compilerop.CachingCompiler() diff --git a/IPython/core/tests/test_history.py b/IPython/core/tests/test_history.py index b55a8aa..3d499cd 100644 --- a/IPython/core/tests/test_history.py +++ b/IPython/core/tests/test_history.py @@ -23,7 +23,7 @@ from IPython.core.history import HistoryManager, extract_hist_ranges from IPython.utils import py3compat def setUp(): - nt.assert_equal(sys.getdefaultencoding(), "utf-8" if py3compat.PY3 else "ascii") + nt.assert_equal(py3compat.getdefaultencoding(), "utf-8" if py3compat.PY3 else "ascii") def test_history(): ip = get_ipython() diff --git a/IPython/external/pyparsing/_pyparsing.py b/IPython/external/pyparsing/_pyparsing.py index a4f0c3b..0218a99 100644 --- a/IPython/external/pyparsing/_pyparsing.py +++ b/IPython/external/pyparsing/_pyparsing.py @@ -128,9 +128,9 @@ if not _PY3K: return unicode(obj) # Else encode it... but how? There are many choices... :) # Replace unprintables with escape codes? - #return unicode(obj).encode(sys.getdefaultencoding(), 'backslashreplace_errors') + #return unicode(obj).encode(py3compat.getdefaultencoding(), 'backslashreplace_errors') # Replace unprintables with question marks? - #return unicode(obj).encode(sys.getdefaultencoding(), 'replace') + #return unicode(obj).encode(py3compat.getdefaultencoding(), 'replace') # ... else: _ustr = str diff --git a/IPython/testing/tools.py b/IPython/testing/tools.py index a8038b3..ef07f78 100644 --- a/IPython/testing/tools.py +++ b/IPython/testing/tools.py @@ -42,7 +42,7 @@ except ImportError: from IPython.config.loader import Config from IPython.utils.process import find_cmd, getoutputerror -from IPython.utils.text import list_strings, getdefaultencoding +from IPython.utils.text import list_strings from IPython.utils.io import temp_pyfile, Tee from IPython.utils import py3compat @@ -322,7 +322,7 @@ else: # so we need a class that can handle both. class MyStringIO(StringIO): def write(self, s): - s = py3compat.cast_unicode(s, encoding=getdefaultencoding()) + s = py3compat.cast_unicode(s, encoding=py3compat.getdefaultencoding()) super(MyStringIO, self).write(s) notprinted_msg = """Did not find {0!r} in printed output (on {1}): diff --git a/IPython/utils/_process_posix.py b/IPython/utils/_process_posix.py index 6227f35..d774fda 100644 --- a/IPython/utils/_process_posix.py +++ b/IPython/utils/_process_posix.py @@ -128,7 +128,7 @@ class ProcessHandler(object): int : child's exitstatus """ # Get likely encoding for the output. - enc = text.getdefaultencoding() + enc = py3compat.getdefaultencoding() # Patterns to match on the output, for pexpect. We read input and # allow either a short timeout or EOF diff --git a/IPython/utils/_process_win32.py b/IPython/utils/_process_win32.py index 7ee9b62..31ec63a 100644 --- a/IPython/utils/_process_win32.py +++ b/IPython/utils/_process_win32.py @@ -94,7 +94,7 @@ def _find_cmd(cmd): def _system_body(p): """Callback for _system.""" - enc = text.getdefaultencoding() + enc = py3compat.getdefaultencoding() for line in read_no_interrupt(p.stdout).splitlines(): line = line.decode(enc, 'replace') print(line, file=sys.stdout) diff --git a/IPython/utils/io.py b/IPython/utils/io.py index 199c023..3869635 100644 --- a/IPython/utils/io.py +++ b/IPython/utils/io.py @@ -14,6 +14,7 @@ from __future__ import print_function #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- +import os import sys import tempfile diff --git a/IPython/utils/jsonutil.py b/IPython/utils/jsonutil.py index b2332ad..b4bdd95 100644 --- a/IPython/utils/jsonutil.py +++ b/IPython/utils/jsonutil.py @@ -135,7 +135,7 @@ def json_clean(obj): return obj if isinstance(obj, bytes): - return obj.decode(text.getdefaultencoding(), 'replace') + return obj.decode(py3compat.getdefaultencoding(), 'replace') if isinstance(obj, container_to_list) or ( hasattr(obj, '__iter__') and hasattr(obj, next_attr_name)): diff --git a/IPython/utils/py3compat.py b/IPython/utils/py3compat.py index 7909e75..936c5df 100644 --- a/IPython/utils/py3compat.py +++ b/IPython/utils/py3compat.py @@ -5,6 +5,7 @@ import functools import sys import re import types +import locale orig_open = open @@ -18,12 +19,35 @@ def get_stream_enc(stream, default=None): else: return stream.encoding +# Less conservative replacement for sys.getdefaultencoding, that will try +# to match the environment. +# Defined here as central function, so if we find better choices, we +# won't need to make changes all over IPython. +def getdefaultencoding(): + """Return IPython's guess for the default encoding for bytes as text. + + Asks for stdin.encoding first, to match the calling Terminal, but that + is often None for subprocesses. Fall back on locale.getpreferredencoding() + which should be a sensible platform default (that respects LANG environment), + and finally to sys.getdefaultencoding() which is the most conservative option, + and usually ASCII. + """ + enc = get_stream_enc(sys.stdin) + if not enc or enc=='ascii': + try: + # There are reports of getpreferredencoding raising errors + # in some cases, which may well be fixed, but let's be conservative here. + enc = locale.getpreferredencoding() + except Exception: + pass + return enc or sys.getdefaultencoding() + def decode(s, encoding=None): - encoding = get_stream_enc(sys.stdin, encoding) or sys.getdefaultencoding() + encoding = get_stream_enc(sys.stdin, encoding) or getdefaultencoding() return s.decode(encoding, "replace") def encode(u, encoding=None): - encoding = get_stream_enc(sys.stdin, encoding) or sys.getdefaultencoding() + encoding = get_stream_enc(sys.stdin, encoding) or getdefaultencoding() return u.encode(encoding, "replace") diff --git a/IPython/utils/text.py b/IPython/utils/text.py index 74b334d..aa07f39 100644 --- a/IPython/utils/text.py +++ b/IPython/utils/text.py @@ -16,7 +16,6 @@ Utilities for working with strings and text. import __main__ -import locale import os import re import shutil @@ -34,29 +33,6 @@ from IPython.utils.data import flatten # Code #----------------------------------------------------------------------------- -# Less conservative replacement for sys.getdefaultencoding, that will try -# to match the environment. -# Defined here as central function, so if we find better choices, we -# won't need to make changes all over IPython. -def getdefaultencoding(): - """Return IPython's guess for the default encoding for bytes as text. - - Asks for stdin.encoding first, to match the calling Terminal, but that - is often None for subprocesses. Fall back on locale.getpreferredencoding() - which should be a sensible platform default (that respects LANG environment), - and finally to sys.getdefaultencoding() which is the most conservative option, - and usually ASCII. - """ - enc = py3compat.get_stream_enc(sys.stdin) - if not enc or enc=='ascii': - try: - # There are reports of getpreferredencoding raising errors - # in some cases, which may well be fixed, but let's be conservative here. - enc = locale.getpreferredencoding() - except Exception: - pass - return enc or sys.getdefaultencoding() - def unquote_ends(istr): """Remove a single pair of quotes from the endpoints of a string.""" diff --git a/IPython/zmq/iostream.py b/IPython/zmq/iostream.py index 8579398..6b43225 100644 --- a/IPython/zmq/iostream.py +++ b/IPython/zmq/iostream.py @@ -4,7 +4,7 @@ from io import StringIO from session import extract_header, Message -from IPython.utils import io, text +from IPython.utils import io, text, py3compat #----------------------------------------------------------------------------- # Globals @@ -69,7 +69,7 @@ class OutStream(object): else: # Make sure that we're handling unicode if not isinstance(string, unicode): - enc = text.getdefaultencoding() + enc = py3compat.getdefaultencoding() string = string.decode(enc, 'replace') self._buffer.write(string)