diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index a7d7fcc..700bfa1 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -2265,13 +2265,17 @@ class InteractiveShell(Configurable, Magic): The return value can be used to decide whether to use sys.ps1 or sys.ps2 to prompt the next line.""" + # We need to ensure that the source is unicode from here on. + if type(source)==str: + source = source.decode(self.stdin_encoding) + # if the source code has leading blanks, add 'if 1:\n' to it # this allows execution of indented pasted code. It is tempting # to add '\n' at the end of source to run commands like ' a=1' # directly, but this fails for more complicated scenarios - source=source.encode(self.stdin_encoding) + if source[:1] in [' ', '\t']: - source = 'if 1:\n%s' % source + source = u'if 1:\n%s' % source try: code = self.compile(source,filename,symbol) diff --git a/IPython/core/splitinput.py b/IPython/core/splitinput.py old mode 100644 new mode 100755 index 99dc0b5..367d53d --- a/IPython/core/splitinput.py +++ b/IPython/core/splitinput.py @@ -21,6 +21,7 @@ Authors: #----------------------------------------------------------------------------- import re +import sys #----------------------------------------------------------------------------- # Main function @@ -55,7 +56,10 @@ def split_user_input(line, pattern=None): This is currently handles lines with '=' in them in a very inconsistent manner. """ - + # We need to ensure that the rest of this routine deals only with unicode + if type(line)==str: + line = line.decode(sys.stdin.encoding) + if pattern is None: pattern = line_split match = pattern.match(line) @@ -65,15 +69,16 @@ def split_user_input(line, pattern=None): ifun, the_rest = line.split(None,1) except ValueError: # print "split failed for line '%s'" % line - ifun, the_rest = line,'' + ifun, the_rest = line, u'' pre = re.match('^(\s*)(.*)',line).groups()[0] else: pre,ifun,the_rest = match.groups() - # ifun has to be a valid python identifier, so it better be only pure - # ascii, no unicode: + # ifun has to be a valid python identifier, so it better encode into + # ascii. We do still make it a unicode string so that we consistently + # return unicode, but it will be one that is guaranteed to be pure ascii try: - ifun = ifun.encode('ascii') + ifun = unicode(ifun.encode('ascii')) except UnicodeEncodeError: the_rest = ifun + u' ' + the_rest ifun = u'' diff --git a/IPython/zmq/iostream.py b/IPython/zmq/iostream.py index a893f84..437933e 100644 --- a/IPython/zmq/iostream.py +++ b/IPython/zmq/iostream.py @@ -61,6 +61,11 @@ class OutStream(object): if self.pub_socket is None: raise ValueError('I/O operation on closed file') else: + # We can only send raw bytes, not unicode objects, so we encode + # into utf-8 for all frontends if we get unicode inputs. + if type(string) == unicode: + string = string.encode('utf-8') + self._buffer.write(string) current_time = time.time() if self._start <= 0: