diff --git a/IPython/core/splitinput.py b/IPython/core/splitinput.py index 920d415..ed54775 100644 --- a/IPython/core/splitinput.py +++ b/IPython/core/splitinput.py @@ -53,7 +53,8 @@ def split_user_input(line, pattern=None): and the rest. """ # We need to ensure that the rest of this routine deals only with unicode - line = py3compat.cast_unicode(line, sys.stdin.encoding or 'utf-8') + encoding = py3compat.get_stream_enc(sys.stdin, 'utf-8') + line = py3compat.cast_unicode(line, encoding) if pattern is None: pattern = line_split diff --git a/IPython/frontend/terminal/interactiveshell.py b/IPython/frontend/terminal/interactiveshell.py index c29c1d2..42fbcfe 100644 --- a/IPython/frontend/terminal/interactiveshell.py +++ b/IPython/frontend/terminal/interactiveshell.py @@ -319,7 +319,7 @@ class TerminalInteractiveShell(InteractiveShell): for i in range(hlen - hlen_before_cell): self.readline.remove_history_item(hlen - i - 1) - stdin_encoding = sys.stdin.encoding or "utf-8" + stdin_encoding = py3compat.get_stream_enc(sys.stdin, 'utf-8') self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(), stdin_encoding)) return self.readline.get_current_history_length() diff --git a/IPython/utils/io.py b/IPython/utils/io.py index 6df4ab6..33ea0cb 100644 --- a/IPython/utils/io.py +++ b/IPython/utils/io.py @@ -87,9 +87,9 @@ class IOTerm: self.stderr = IOStream(stderr, sys.stderr) # setup stdin/stdout/stderr to sys.stdin/sys.stdout/sys.stderr -stdin = IOStream(sys.stdin) -stdout = IOStream(sys.stdout) -stderr = IOStream(sys.stderr) +stdin = sys.stdin if not sys.stdin else IOStream(sys.stdin) +stdout = sys.stdout if not sys.stdout else IOStream(sys.stdout) +stderr = sys.stderr if not sys.stderr else IOStream(sys.stderr) class Tee(object): diff --git a/IPython/utils/py3compat.py b/IPython/utils/py3compat.py index cc0e220..7909e75 100644 --- a/IPython/utils/py3compat.py +++ b/IPython/utils/py3compat.py @@ -11,14 +11,22 @@ orig_open = open def no_code(x, encoding=None): return x +# to deal with the possibility of sys.std* not being a stream at all +def get_stream_enc(stream, default=None): + if not hasattr(stream, 'encoding') or not stream.encoding: + return default + else: + return stream.encoding + def decode(s, encoding=None): - encoding = encoding or sys.stdin.encoding or sys.getdefaultencoding() + encoding = get_stream_enc(sys.stdin, encoding) or sys.getdefaultencoding() return s.decode(encoding, "replace") def encode(u, encoding=None): - encoding = encoding or sys.stdin.encoding or sys.getdefaultencoding() + encoding = get_stream_enc(sys.stdin, encoding) or sys.getdefaultencoding() return u.encode(encoding, "replace") - + + def cast_unicode(s, encoding=None): if isinstance(s, bytes): return decode(s, encoding) diff --git a/IPython/utils/text.py b/IPython/utils/text.py index df836ce..74b334d 100644 --- a/IPython/utils/text.py +++ b/IPython/utils/text.py @@ -47,7 +47,7 @@ def getdefaultencoding(): and finally to sys.getdefaultencoding() which is the most conservative option, and usually ASCII. """ - enc = sys.stdin.encoding + enc = py3compat.get_stream_enc(sys.stdin) if not enc or enc=='ascii': try: # There are reports of getpreferredencoding raising errors