From 40ec4c33644ee379979328ccedc442426a4e1e65 2012-04-26 16:44:00 From: Brandon Parsons Date: 2012-04-26 16:44:00 Subject: [PATCH] pythonw in py3k sets std{in,out,err} to None The print statement works without error, even though the stdio file objects are instances of None. Since they are instances of None, however, the encoding attribute will not exist, so protect blind attribute access of std{in,out,err} by using a new function, get_stream_enc. --- 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