##// END OF EJS Templates
Start using py3compat module.
Thomas Kluyver -
Show More
@@ -18,13 +18,13 b' Authors'
18 18 # Imports
19 19 #-----------------------------------------------------------------------------
20 20
21 import __builtin__
21 import __builtin__ as builtin_mod
22 22 import re
23 23 import sys
24 24
25 25 from IPython.external import argparse
26 26 from IPython.utils.path import filefind, get_ipython_dir
27 from IPython.utils import warn
27 from IPython.utils import py3compat, warn
28 28
29 29 #-----------------------------------------------------------------------------
30 30 # Exceptions
@@ -131,7 +131,7 b' class Config(dict):'
131 131 # that you can't have section or attribute names that are
132 132 # builtins.
133 133 try:
134 return getattr(__builtin__, key)
134 return getattr(builtin_mod, key)
135 135 except AttributeError:
136 136 pass
137 137 if is_section_key(key):
@@ -146,7 +146,7 b' class Config(dict):'
146 146
147 147 def __setitem__(self, key, value):
148 148 # Don't allow names in __builtin__ to be modified.
149 if hasattr(__builtin__, key):
149 if hasattr(builtin_mod, key):
150 150 raise ConfigError('Config variable names cannot have the same name '
151 151 'as a Python builtin: %s' % key)
152 152 if self._is_section_key(key):
@@ -312,7 +312,7 b' class PyFileConfigLoader(FileConfigLoader):'
312 312 namespace = dict(load_subconfig=load_subconfig, get_config=get_config)
313 313 fs_encoding = sys.getfilesystemencoding() or 'ascii'
314 314 conf_filename = self.full_filename.encode(fs_encoding)
315 execfile(conf_filename, namespace)
315 py3compat.execfile(conf_filename, namespace)
316 316
317 317 def _convert_to_config(self):
318 318 if self.data is None:
@@ -586,13 +586,7 b' class ArgParseConfigLoader(CommandLineConfigLoader):'
586 586 def _parse_args(self, args):
587 587 """self.parser->self.parsed_data"""
588 588 # decode sys.argv to support unicode command-line options
589 uargs = []
590 for a in args:
591 if isinstance(a, str):
592 # don't decode if we already got unicode
593 a = a.decode(sys.stdin.encoding or
594 sys.getdefaultencoding())
595 uargs.append(a)
589 uargs = [py3compat.cast_unicode(a) for a in args]
596 590 self.parsed_data, self.extra_args = self.parser.parse_known_args(uargs)
597 591
598 592 def _convert_to_config(self):
@@ -30,6 +30,7 b' from zipimport import zipimporter'
30 30 # Our own imports
31 31 from IPython.core.completer import expand_user, compress_user
32 32 from IPython.core.error import TryNext
33 from IPython.utils import py3compat
33 34
34 35 # FIXME: this should be pulled in with the right call via the component system
35 36 from IPython.core.ipapi import get as get_ipython
@@ -66,10 +67,9 b' def shlex_split(x):'
66 67 # Example:
67 68 # %run "c:/python -> ['%run','"c:/python']
68 69
69 # shlex.split has unicode bugs, so encode first to str
70 if isinstance(x, unicode):
71 # don't raise errors on encoding:
72 x = x.encode(sys.stdin.encoding or sys.getdefaultencoding(), 'replace')
70 # shlex.split has unicode bugs in Python 2, so encode first to str
71 if not py3compat.PY3:
72 x = py3compat.cast_bytes(x)
73 73
74 74 endofline = []
75 75 while x != '':
@@ -17,7 +17,7 b''
17 17 from __future__ import with_statement
18 18 from __future__ import absolute_import
19 19
20 import __builtin__
20 import __builtin__ as builtin_mod
21 21 import __future__
22 22 import abc
23 23 import ast
@@ -61,6 +61,7 b' from IPython.core.profiledir import ProfileDir'
61 61 from IPython.external.Itpl import ItplNS
62 62 from IPython.utils import PyColorize
63 63 from IPython.utils import io
64 from IPython.utils import py3compat
64 65 from IPython.utils.doctestreload import doctest_reload
65 66 from IPython.utils.io import ask_yes_no, rprint
66 67 from IPython.utils.ipstruct import Struct
@@ -979,13 +980,13 b' class InteractiveShell(SingletonConfigurable, Magic):'
979 980 # Set __name__ to __main__ to better match the behavior of the
980 981 # normal interpreter.
981 982 user_ns = {'__name__' :'__main__',
982 '__builtin__' : __builtin__,
983 '__builtins__' : __builtin__,
983 py3compat.builtin_mod_name: builtin_mod,
984 '__builtins__' : builtin_mod,
984 985 }
985 986 else:
986 987 user_ns.setdefault('__name__','__main__')
987 user_ns.setdefault('__builtin__',__builtin__)
988 user_ns.setdefault('__builtins__',__builtin__)
988 user_ns.setdefault(py3compat.builtin_mod_name,builtin_mod)
989 user_ns.setdefault('__builtins__',builtin_mod)
989 990
990 991 if user_global_ns is None:
991 992 user_global_ns = user_ns
@@ -1255,14 +1256,15 b' class InteractiveShell(SingletonConfigurable, Magic):'
1255 1256
1256 1257 Has special code to detect magic functions.
1257 1258 """
1258 #oname = oname.strip()
1259 oname = oname.strip()
1259 1260 #print '1- oname: <%r>' % oname # dbg
1260 try:
1261 oname = oname.strip().encode('ascii')
1262 #print '2- oname: <%r>' % oname # dbg
1263 except UnicodeEncodeError:
1264 print 'Python identifiers can only contain ascii characters.'
1265 return dict(found=False)
1261 if not py3compat.PY3:
1262 try:
1263 oname = oname.encode('ascii')
1264 #print '2- oname: <%r>' % oname # dbg
1265 except UnicodeError:
1266 print 'Python identifiers can only contain ascii characters.'
1267 return dict(found=False)
1266 1268
1267 1269 alias_ns = None
1268 1270 if namespaces is None:
@@ -1701,7 +1703,8 b' class InteractiveShell(SingletonConfigurable, Magic):'
1701 1703 include_latest=True):
1702 1704 if cell.strip(): # Ignore blank lines
1703 1705 for line in cell.splitlines():
1704 self.readline.add_history(line.encode(stdin_encoding, 'replace'))
1706 self.readline.add_history(py3compat.unicode_to_str(line,
1707 stdin_encoding))
1705 1708
1706 1709 def set_next_input(self, s):
1707 1710 """ Sets the 'default' input string for the next command line.
@@ -1907,8 +1910,6 b' class InteractiveShell(SingletonConfigurable, Magic):'
1907 1910
1908 1911 self.define_magic('foo',foo_impl)
1909 1912 """
1910
1911 import new
1912 1913 im = types.MethodType(func,self)
1913 1914 old = getattr(self, "magic_" + magicname, None)
1914 1915 setattr(self, "magic_" + magicname, im)
@@ -2175,15 +2176,10 b' class InteractiveShell(SingletonConfigurable, Magic):'
2175 2176 # behavior of running a script from the system command line, where
2176 2177 # Python inserts the script's directory into sys.path
2177 2178 dname = os.path.dirname(fname)
2178
2179 if isinstance(fname, unicode):
2180 # execfile uses default encoding instead of filesystem encoding
2181 # so unicode filenames will fail
2182 fname = fname.encode(sys.getfilesystemencoding() or sys.getdefaultencoding())
2183 2179
2184 2180 with prepended_to_syspath(dname):
2185 2181 try:
2186 execfile(fname,*where)
2182 py3compat.execfile(fname,*where)
2187 2183 except SystemExit, status:
2188 2184 # If the call was made with 0 or None exit status (sys.exit(0)
2189 2185 # or sys.exit() ), don't bother showing a traceback, as both of
@@ -15,7 +15,7 b''
15 15 # Imports
16 16 #-----------------------------------------------------------------------------
17 17
18 import __builtin__
18 import __builtin__ as builtin_mod
19 19 import __future__
20 20 import bdb
21 21 import inspect
@@ -1729,7 +1729,7 b' Currently the magic system has the following functions:\\n"""'
1729 1729 # Since this seems to be done by the interpreter itself, the best
1730 1730 # we can do is to at least restore __builtins__ for the user on
1731 1731 # exit.
1732 self.shell.user_ns['__builtins__'] = __builtin__
1732 self.shell.user_ns['__builtins__'] = builtin_mod
1733 1733
1734 1734 # Ensure key global structures are restored
1735 1735 sys.argv = save_argv
@@ -22,6 +22,8 b' Authors:'
22 22 import re
23 23 import sys
24 24
25 from IPython.utils import py3compat
26
25 27 #-----------------------------------------------------------------------------
26 28 # Main function
27 29 #-----------------------------------------------------------------------------
@@ -56,11 +58,7 b' def split_user_input(line, pattern=None):'
56 58 manner.
57 59 """
58 60 # We need to ensure that the rest of this routine deals only with unicode
59 if type(line)==str:
60 codec = sys.stdin.encoding
61 if codec is None:
62 codec = 'utf-8'
63 line = line.decode(codec)
61 line = py3compat.cast_unicode(line, sys.stdin.encoding or 'utf-8')
64 62
65 63 if pattern is None:
66 64 pattern = line_split
@@ -75,15 +73,16 b' def split_user_input(line, pattern=None):'
75 73 pre = re.match('^(\s*)(.*)',line).groups()[0]
76 74 else:
77 75 pre,ifun,the_rest = match.groups()
78
79 # ifun has to be a valid python identifier, so it better encode into
80 # ascii. We do still make it a unicode string so that we consistently
81 # return unicode, but it will be one that is guaranteed to be pure ascii
82 try:
83 ifun = unicode(ifun.encode('ascii'))
84 except UnicodeEncodeError:
85 the_rest = ifun + u' ' + the_rest
86 ifun = u''
76
77 if not py3compat.PY3:
78 # ifun has to be a valid python identifier, so it better encode into
79 # ascii. We do still make it a unicode string so that we consistently
80 # return unicode, but it will be one that is guaranteed to be pure ascii
81 try:
82 ifun = unicode(ifun.encode('ascii'))
83 except UnicodeEncodeError:
84 the_rest = ifun + u' ' + the_rest
85 ifun = u''
87 86
88 87 #print 'line:<%s>' % line # dbg
89 88 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest) # dbg
@@ -2,6 +2,8 b''
2 2
3 3 See test_run for details."""
4 4
5 from __future__ import print_function
6
5 7 import sys
6 8
7 9 # We want to ensure that while objects remain available for immediate access,
@@ -10,10 +12,11 b' import sys'
10 12 class C(object):
11 13 def __init__(self,name):
12 14 self.name = name
15 self.p = print
13 16 self.flush_stdout = sys.stdout.flush
14 17
15 18 def __del__(self):
16 print 'tclass.py: deleting object:',self.name
19 self.p('tclass.py: deleting object:',self.name)
17 20 self.flush_stdout()
18 21
19 22 try:
@@ -6,6 +6,7 b' import tempfile'
6 6
7 7 from IPython.core.application import BaseIPythonApplication
8 8 from IPython.testing import decorators as testdec
9 from IPython.utils import py3compat
9 10
10 11 @testdec.onlyif_unicode_paths
11 12 def test_unicode_cwd():
@@ -35,7 +36,7 b' def test_unicode_ipdir():'
35 36
36 37 old_ipdir1 = os.environ.pop("IPYTHONDIR", None)
37 38 old_ipdir2 = os.environ.pop("IPYTHON_DIR", None)
38 os.environ["IPYTHONDIR"] = ipdir.encode("utf-8")
39 os.environ["IPYTHONDIR"] = py3compat.unicode_to_str(ipdir, "utf-8")
39 40 try:
40 41 app = BaseIPythonApplication()
41 42 # The lines below are copied from Application.initialize()
@@ -23,6 +23,7 b' import nose.tools as nt'
23 23
24 24 # Our own imports
25 25 from IPython.core import compilerop
26 from IPython.utils import py3compat
26 27
27 28 #-----------------------------------------------------------------------------
28 29 # Test functions
@@ -51,7 +52,7 b' def test_cache():'
51 52 def setUp():
52 53 # Check we're in a proper Python 2 environment (some imports, such
53 54 # as GTK, can change the default encoding, which can hide bugs.)
54 nt.assert_equal(sys.getdefaultencoding(), "ascii")
55 nt.assert_equal(sys.getdefaultencoding(), "utf-8" if py3compat.PY3 else "ascii")
55 56
56 57 def test_cache_unicode():
57 58 cp = compilerop.CachingCompiler()
@@ -16,9 +16,10 b' import nose.tools as nt'
16 16 # our own packages
17 17 from IPython.utils.tempdir import TemporaryDirectory
18 18 from IPython.core.history import HistoryManager, extract_hist_ranges
19 from IPython.utils import py3compat
19 20
20 21 def setUp():
21 nt.assert_equal(sys.getdefaultencoding(), "ascii")
22 nt.assert_equal(sys.getdefaultencoding(), "utf-8" if py3compat.PY3 else "ascii")
22 23
23 24 def test_history():
24 25 ip = get_ipython()
@@ -125,7 +125,7 b' def test_get_input_encoding():'
125 125 nt.assert_true(isinstance(encoding, basestring))
126 126 # simple-minded check that at least encoding a simple string works with the
127 127 # encoding we got.
128 nt.assert_equal('test'.encode(encoding), 'test')
128 nt.assert_equal(u'test'.encode(encoding), b'test')
129 129
130 130
131 131 class NoInputEncodingTestCase(unittest.TestCase):
@@ -75,7 +75,7 b' Traceback (most recent call last):'
75 75 div0()
76 76 ...line 8, in div0
77 77 x/y
78 ZeroDivisionError: integer division or modulo by zero
78 ZeroDivisionError: ...
79 79 """
80 80
81 81
@@ -107,7 +107,7 b' ZeroDivisionError Traceback (most recent call last)'
107 107 9
108 108 10 def sysexit(stat, mode):
109 109 <BLANKLINE>
110 ZeroDivisionError: integer division or modulo by zero
110 ZeroDivisionError: ...
111 111 """
112 112
113 113
@@ -144,7 +144,7 b' ZeroDivisionError Traceback (most recent call last)'
144 144 9
145 145 10 def sysexit(stat, mode):
146 146 <BLANKLINE>
147 ZeroDivisionError: integer division or modulo by zero
147 ZeroDivisionError: ...
148 148 """
149 149
150 150
@@ -332,7 +332,7 b' class TerminalInteractiveShell(InteractiveShell):'
332 332 self.set_readline_completer()
333 333
334 334 try:
335 line = self.raw_input_original(prompt).decode(self.stdin_encoding)
335 line = py3compat.str_to_unicode(self.raw_input_original(prompt))
336 336 except ValueError:
337 337 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
338 338 " or sys.stdout.close()!\nExiting IPython!")
@@ -169,7 +169,6 b" print 'bye!'"
169 169 #
170 170 #*****************************************************************************
171 171
172 import exceptions
173 172 import os
174 173 import re
175 174 import shlex
@@ -182,7 +181,7 b' from IPython.utils.text import marquee'
182 181
183 182 __all__ = ['Demo','IPythonDemo','LineDemo','IPythonLineDemo','DemoError']
184 183
185 class DemoError(exceptions.Exception): pass
184 class DemoError(Exception): pass
186 185
187 186 def re_mark(mark):
188 187 return re.compile(r'^\s*#\s+<demo>\s+%s\s*$' % mark,re.MULTILINE)
@@ -20,7 +20,7 b' from __future__ import print_function'
20 20 #-----------------------------------------------------------------------------
21 21
22 22 # stdlib
23 import __builtin__
23 import __builtin__ as builtin_mod
24 24 import os
25 25 import sys
26 26 from types import MethodType
@@ -131,7 +131,7 b' class ipnsdict(dict):'
131 131 # aggressive low-level cleaning of the execution namespace, we need to
132 132 # correct for that ourselves, to ensure consitency with the 'real'
133 133 # ipython.
134 self['__builtins__'] = __builtin__
134 self['__builtins__'] = builtin_mod
135 135
136 136 def __delitem__(self, key):
137 137 """Part of the test suite checks that we can release all
@@ -17,6 +17,8 b' of subprocess utilities, and it contains tools that are common to all of them.'
17 17 import subprocess
18 18 import sys
19 19
20 from IPython.utils import py3compat
21
20 22 #-----------------------------------------------------------------------------
21 23 # Function definitions
22 24 #-----------------------------------------------------------------------------
@@ -116,8 +118,8 b' def getoutput(cmd):'
116 118
117 119 out = process_handler(cmd, lambda p: p.communicate()[0], subprocess.STDOUT)
118 120 if out is None:
119 out = ''
120 return out
121 return ''
122 return py3compat.bytes_to_str(out)
121 123
122 124
123 125 def getoutputerror(cmd):
@@ -138,5 +140,6 b' def getoutputerror(cmd):'
138 140
139 141 out_err = process_handler(cmd, lambda p: p.communicate())
140 142 if out_err is None:
141 out_err = '', ''
142 return out_err
143 return '', ''
144 out, err = out_err
145 return py3compat.bytes_to_str(out), py3compat.bytes_to_str(err)
@@ -23,6 +23,7 b' import IPython'
23 23 from IPython.utils import warn
24 24 from IPython.utils.process import system
25 25 from IPython.utils.importstring import import_item
26 from IPython.utils import py3compat
26 27
27 28 #-----------------------------------------------------------------------------
28 29 # Code
@@ -30,14 +31,6 b' from IPython.utils.importstring import import_item'
30 31
31 32 fs_encoding = sys.getfilesystemencoding()
32 33
33 def _cast_unicode(s, enc=None):
34 """Turn 8-bit strings into unicode."""
35 if isinstance(s, bytes):
36 enc = enc or sys.getdefaultencoding()
37 return s.decode(enc)
38 return s
39
40
41 34 def _get_long_path_name(path):
42 35 """Dummy no-op."""
43 36 return path
@@ -203,7 +196,7 b' def get_home_dir():'
203 196 root=os.path.abspath(root).rstrip('\\')
204 197 if _writable_dir(os.path.join(root, '_ipython')):
205 198 os.environ["IPYKITROOT"] = root
206 return _cast_unicode(root, fs_encoding)
199 return py3compat.cast_unicode(root, fs_encoding)
207 200
208 201 if os.name == 'posix':
209 202 # Linux, Unix, AIX, OS X
@@ -218,11 +211,11 b' def get_home_dir():'
218 211 homedir = Popen('echo $HOME', shell=True,
219 212 stdout=PIPE).communicate()[0].strip()
220 213 if homedir:
221 return _cast_unicode(homedir, fs_encoding)
214 return py3compat.cast_unicode(homedir, fs_encoding)
222 215 else:
223 216 raise HomeDirError('Undefined $HOME, IPython cannot proceed.')
224 217 else:
225 return _cast_unicode(homedir, fs_encoding)
218 return py3compat.cast_unicode(homedir, fs_encoding)
226 219 elif os.name == 'nt':
227 220 # Now for win9x, XP, Vista, 7?
228 221 # For some strange reason all of these return 'nt' for os.name.
@@ -236,7 +229,7 b' def get_home_dir():'
236 229 pass
237 230 else:
238 231 if _writable_dir(homedir):
239 return _cast_unicode(homedir, fs_encoding)
232 return py3compat.cast_unicode(homedir, fs_encoding)
240 233
241 234 # Now look for a local home directory
242 235 try:
@@ -245,7 +238,7 b' def get_home_dir():'
245 238 pass
246 239 else:
247 240 if _writable_dir(homedir):
248 return _cast_unicode(homedir, fs_encoding)
241 return py3compat.cast_unicode(homedir, fs_encoding)
249 242
250 243 # Now the users profile directory
251 244 try:
@@ -254,7 +247,7 b' def get_home_dir():'
254 247 pass
255 248 else:
256 249 if _writable_dir(homedir):
257 return _cast_unicode(homedir, fs_encoding)
250 return py3compat.cast_unicode(homedir, fs_encoding)
258 251
259 252 # Use the registry to get the 'My Documents' folder.
260 253 try:
@@ -269,7 +262,7 b' def get_home_dir():'
269 262 pass
270 263 else:
271 264 if _writable_dir(homedir):
272 return _cast_unicode(homedir, fs_encoding)
265 return py3compat.cast_unicode(homedir, fs_encoding)
273 266
274 267 # A user with a lot of unix tools in win32 may have defined $HOME.
275 268 # Try this as a last ditch option.
@@ -279,7 +272,7 b' def get_home_dir():'
279 272 pass
280 273 else:
281 274 if _writable_dir(homedir):
282 return _cast_unicode(homedir, fs_encoding)
275 return py3compat.cast_unicode(homedir, fs_encoding)
283 276
284 277 # If all else fails, raise HomeDirError
285 278 raise HomeDirError('No valid home directory could be found')
@@ -302,7 +295,7 b' def get_xdg_dir():'
302 295 # use ~/.config if not set OR empty
303 296 xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config')
304 297 if xdg and _writable_dir(xdg):
305 return _cast_unicode(xdg, fs_encoding)
298 return py3compat.cast_unicode(xdg, fs_encoding)
306 299
307 300 return None
308 301
@@ -311,7 +304,7 b' def get_ipython_dir():'
311 304 """Get the IPython directory for this platform and user.
312 305
313 306 This uses the logic in `get_home_dir` to find the home directory
314 and the adds .ipython to the end of the path.
307 and then adds .ipython to the end of the path.
315 308 """
316 309
317 310 env = os.environ
@@ -356,13 +349,13 b' def get_ipython_dir():'
356 349 " using a temp directory."%parent)
357 350 ipdir = tempfile.mkdtemp()
358 351
359 return _cast_unicode(ipdir, fs_encoding)
352 return py3compat.cast_unicode(ipdir, fs_encoding)
360 353
361 354
362 355 def get_ipython_package_dir():
363 356 """Get the base directory where IPython itself is installed."""
364 357 ipdir = os.path.dirname(IPython.__file__)
365 return _cast_unicode(ipdir, fs_encoding)
358 return py3compat.cast_unicode(ipdir, fs_encoding)
366 359
367 360
368 361 def get_ipython_module_path(module_str):
@@ -377,7 +370,7 b' def get_ipython_module_path(module_str):'
377 370 mod = import_item(module_str)
378 371 the_path = mod.__file__.replace('.pyc', '.py')
379 372 the_path = the_path.replace('.pyo', '.py')
380 return _cast_unicode(the_path, fs_encoding)
373 return py3compat.cast_unicode(the_path, fs_encoding)
381 374
382 375
383 376 def expand_path(s):
@@ -442,7 +435,7 b' def filehash(path):'
442 435 """Make an MD5 hash of a file, ignoring any differences in line
443 436 ending characters."""
444 437 with open(path, "rU") as f:
445 return md5(f.read()).hexdigest()
438 return md5(py3compat.str_to_bytes(f.read())).hexdigest()
446 439
447 440 # If the config is unmodified from the default, we'll just delete it.
448 441 # These are consistent for 0.10.x, thankfully. We're not going to worry about
@@ -10,6 +10,16 b' def decode(s, encoding=None):'
10 10 def encode(u, encoding=None):
11 11 encoding = encoding or sys.stdin.encoding or sys.getdefaultencoding()
12 12 return u.encode(encoding, "replace")
13
14 def cast_unicode(s, encoding=None):
15 if isinstance(s, bytes):
16 return decode(s, encoding)
17 return s
18
19 def cast_bytes(s, encoding=None):
20 if not isinstance(s, bytes):
21 return encode(s, encoding)
22 return s
13 23
14 24 if sys.version_info[0] >= 3:
15 25 PY3 = True
@@ -33,5 +43,6 b' else:'
33 43 str_to_bytes = no_code
34 44 bytes_to_str = no_code
35 45
36 def execfile(fname, glob, loc):
46 def execfile(fname, glob, loc=None):
47 loc = loc if (loc is not None) else glob
37 48 exec compile(open(fname).read(), fname, 'exec') in glob, loc
General Comments 0
You need to be logged in to leave comments. Login now