##// END OF EJS Templates
Merge pull request #663 from takluyver/py3compat...
Fernando Perez -
r4778:37dd091e merge
parent child Browse files
Show More
@@ -0,0 +1,11 b''
1 c = get_config()
2
3 # If the master config file uses syntax that's invalid in Python 3, we'll skip
4 # it and just use the factory defaults.
5 try:
6 load_subconfig('ipython_config.py', profile='default')
7 except Exception:
8 pass
9 else:
10 # We reset exec_lines in case they're not compatible with Python 3.
11 c.InteractiveShellApp.exec_lines = []
@@ -0,0 +1,32 b''
1 # coding: utf-8
2 from IPython.core.splitinput import split_user_input
3 from IPython.testing import tools as tt
4 from IPython.utils import py3compat
5
6 tests = [
7 ('x=1', ('', '', 'x', '=1')),
8 ('?', ('', '?', '', '')),
9 ('??', ('', '??', '', '')),
10 (' ?', (' ', '?', '', '')),
11 (' ??', (' ', '??', '', '')),
12 ('??x', ('', '??', 'x', '')),
13 ('?x=1', ('', '?', 'x', '=1')),
14 ('!ls', ('', '!', 'ls', '')),
15 (' !ls', (' ', '!', 'ls', '')),
16 ('!!ls', ('', '!!', 'ls', '')),
17 (' !!ls', (' ', '!!', 'ls', '')),
18 (',ls', ('', ',', 'ls', '')),
19 (';ls', ('', ';', 'ls', '')),
20 (' ;ls', (' ', ';', 'ls', '')),
21 ('f.g(x)', ('', '', 'f.g', '(x)')),
22 ('f.g (x)', ('', '', 'f.g', '(x)')),
23 ('?%hist', ('', '?', '%hist', '')),
24 ('?x*', ('', '?', 'x*', '')),
25 ]
26 if py3compat.PY3:
27 tests.append((u"PΓ©rez Fernando", (u'', u'', u'PΓ©rez', u'Fernando')))
28 else:
29 tests.append((u"PΓ©rez Fernando", (u'', u'', u'P', u'Γ©rez Fernando')))
30
31 def test_split_user_input():
32 return tt.check_pairs(split_user_input, tests)
@@ -0,0 +1,50 b''
1 """Backwards compatibility - we use contextlib.nested to support Python 2.6,
2 but it's removed in Python 3.2."""
3
4 # TODO : Remove this once we drop support for Python 2.6, and use
5 # "with a, b:" instead.
6
7 import sys
8
9 from contextlib import contextmanager
10
11 @contextmanager
12 def nested(*managers):
13 """Combine multiple context managers into a single nested context manager.
14
15 This function has been deprecated in favour of the multiple manager form
16 of the with statement.
17
18 The one advantage of this function over the multiple manager form of the
19 with statement is that argument unpacking allows it to be
20 used with a variable number of context managers as follows:
21
22 with nested(*managers):
23 do_something()
24
25 """
26 exits = []
27 vars = []
28 exc = (None, None, None)
29 try:
30 for mgr in managers:
31 exit = mgr.__exit__
32 enter = mgr.__enter__
33 vars.append(enter())
34 exits.append(exit)
35 yield vars
36 except:
37 exc = sys.exc_info()
38 finally:
39 while exits:
40 exit = exits.pop()
41 try:
42 if exit(*exc):
43 exc = (None, None, None)
44 except:
45 exc = sys.exc_info()
46 if exc != (None, None, None):
47 # Don't rely on sys.exc_info() still containing
48 # the right information. Another exception may
49 # have been raised and caught by an exit method
50 raise exc[0], exc[1], exc[2]
@@ -0,0 +1,95 b''
1 # coding: utf-8
2 """Compatibility tricks for Python 3. Mainly to do with unicode."""
3 import sys
4 import types
5
6 orig_open = open
7
8 def no_code(x, encoding=None):
9 return x
10
11 def decode(s, encoding=None):
12 encoding = encoding or sys.stdin.encoding or sys.getdefaultencoding()
13 return s.decode(encoding, "replace")
14
15 def encode(u, encoding=None):
16 encoding = encoding or sys.stdin.encoding or sys.getdefaultencoding()
17 return u.encode(encoding, "replace")
18
19 def cast_unicode(s, encoding=None):
20 if isinstance(s, bytes):
21 return decode(s, encoding)
22 return s
23
24 def cast_bytes(s, encoding=None):
25 if not isinstance(s, bytes):
26 return encode(s, encoding)
27 return s
28
29 if sys.version_info[0] >= 3:
30 PY3 = True
31
32 input = input
33 builtin_mod_name = "builtins"
34
35 str_to_unicode = no_code
36 unicode_to_str = no_code
37 str_to_bytes = encode
38 bytes_to_str = decode
39 cast_bytes_py2 = no_code
40
41 def isidentifier(s, dotted=False):
42 if dotted:
43 return all(isidentifier(a) for a in s.split("."))
44 return s.isidentifier()
45
46 open = orig_open
47
48 MethodType = types.MethodType
49
50 else:
51 PY3 = False
52
53 input = raw_input
54 builtin_mod_name = "__builtin__"
55
56 str_to_unicode = decode
57 unicode_to_str = encode
58 str_to_bytes = no_code
59 bytes_to_str = no_code
60 cast_bytes_py2 = cast_bytes
61
62 import re
63 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
64 def isidentifier(s, dotted=False):
65 if dotted:
66 return all(isidentifier(a) for a in s.split("."))
67 return bool(_name_re.match(s))
68
69 class open(object):
70 """Wrapper providing key part of Python 3 open() interface."""
71 def __init__(self, fname, mode="r", encoding="utf-8"):
72 self.f = orig_open(fname, mode)
73 self.enc = encoding
74
75 def write(self, s):
76 return self.f.write(s.encode(self.enc))
77
78 def read(self, size=-1):
79 return self.f.read(size).decode(self.enc)
80
81 def close(self):
82 return self.f.close()
83
84 def __enter__(self):
85 return self
86
87 def __exit__(self, etype, value, traceback):
88 self.f.close()
89
90 def MethodType(func, instance):
91 return types.MethodType(func, instance, type(instance))
92
93 def execfile(fname, glob, loc=None):
94 loc = loc if (loc is not None) else glob
95 exec compile(open(fname).read(), fname, 'exec') in glob, loc
@@ -0,0 +1,272 b''
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 """Setup script for IPython.
4
5 Under Posix environments it works like a typical setup.py script.
6 Under Windows, the command sdist is not supported, since IPython
7 requires utilities which are not available under Windows."""
8
9 #-----------------------------------------------------------------------------
10 # Copyright (c) 2008-2011, IPython Development Team.
11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
14 #
15 # Distributed under the terms of the Modified BSD License.
16 #
17 # The full license is in the file COPYING.txt, distributed with this software.
18 #-----------------------------------------------------------------------------
19
20 #-----------------------------------------------------------------------------
21 # Minimal Python version sanity check
22 #-----------------------------------------------------------------------------
23
24 import sys
25
26 # This check is also made in IPython/__init__, don't forget to update both when
27 # changing Python version requirements.
28 if sys.version[0:3] < '2.6':
29 error = """\
30 ERROR: 'IPython requires Python Version 2.6 or above.'
31 Exiting."""
32 print >> sys.stderr, error
33 sys.exit(1)
34
35 # At least we're on the python version we need, move on.
36
37 #-------------------------------------------------------------------------------
38 # Imports
39 #-------------------------------------------------------------------------------
40
41 # Stdlib imports
42 import os
43 import shutil
44
45 from glob import glob
46
47 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
48 # update it when the contents of directories change.
49 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
50
51 from distutils.core import setup
52
53 # Our own imports
54 from IPython.utils.path import target_update
55
56 from setupbase import (
57 setup_args,
58 find_packages,
59 find_package_data,
60 find_scripts,
61 find_data_files,
62 check_for_dependencies,
63 record_commit_info,
64 )
65 from setupext import setupext
66
67 isfile = os.path.isfile
68 pjoin = os.path.join
69
70 #-----------------------------------------------------------------------------
71 # Function definitions
72 #-----------------------------------------------------------------------------
73
74 def cleanup():
75 """Clean up the junk left around by the build process"""
76 if "develop" not in sys.argv:
77 try:
78 shutil.rmtree('ipython.egg-info')
79 except:
80 try:
81 os.unlink('ipython.egg-info')
82 except:
83 pass
84
85 #-------------------------------------------------------------------------------
86 # Handle OS specific things
87 #-------------------------------------------------------------------------------
88
89 if os.name == 'posix':
90 os_name = 'posix'
91 elif os.name in ['nt','dos']:
92 os_name = 'windows'
93 else:
94 print 'Unsupported operating system:',os.name
95 sys.exit(1)
96
97 # Under Windows, 'sdist' has not been supported. Now that the docs build with
98 # Sphinx it might work, but let's not turn it on until someone confirms that it
99 # actually works.
100 if os_name == 'windows' and 'sdist' in sys.argv:
101 print 'The sdist command is not available under Windows. Exiting.'
102 sys.exit(1)
103
104 #-------------------------------------------------------------------------------
105 # Things related to the IPython documentation
106 #-------------------------------------------------------------------------------
107
108 # update the manuals when building a source dist
109 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
110 import textwrap
111
112 # List of things to be updated. Each entry is a triplet of args for
113 # target_update()
114 to_update = [
115 # FIXME - Disabled for now: we need to redo an automatic way
116 # of generating the magic info inside the rst.
117 #('docs/magic.tex',
118 #['IPython/Magic.py'],
119 #"cd doc && ./update_magic.sh" ),
120
121 ('docs/man/ipcluster.1.gz',
122 ['docs/man/ipcluster.1'],
123 'cd docs/man && gzip -9c ipcluster.1 > ipcluster.1.gz'),
124
125 ('docs/man/ipcontroller.1.gz',
126 ['docs/man/ipcontroller.1'],
127 'cd docs/man && gzip -9c ipcontroller.1 > ipcontroller.1.gz'),
128
129 ('docs/man/ipengine.1.gz',
130 ['docs/man/ipengine.1'],
131 'cd docs/man && gzip -9c ipengine.1 > ipengine.1.gz'),
132
133 ('docs/man/iplogger.1.gz',
134 ['docs/man/iplogger.1'],
135 'cd docs/man && gzip -9c iplogger.1 > iplogger.1.gz'),
136
137 ('docs/man/ipython.1.gz',
138 ['docs/man/ipython.1'],
139 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
140
141 ('docs/man/irunner.1.gz',
142 ['docs/man/irunner.1'],
143 'cd docs/man && gzip -9c irunner.1 > irunner.1.gz'),
144
145 ('docs/man/pycolor.1.gz',
146 ['docs/man/pycolor.1'],
147 'cd docs/man && gzip -9c pycolor.1 > pycolor.1.gz'),
148 ]
149
150 # Only build the docs if sphinx is present
151 try:
152 import sphinx
153 except ImportError:
154 pass
155 else:
156 # The Makefile calls the do_sphinx scripts to build html and pdf, so
157 # just one target is enough to cover all manual generation
158
159 # First, compute all the dependencies that can force us to rebuild the
160 # docs. Start with the main release file that contains metadata
161 docdeps = ['IPython/core/release.py']
162 # Inculde all the reST sources
163 pjoin = os.path.join
164 for dirpath,dirnames,filenames in os.walk('docs/source'):
165 if dirpath in ['_static','_templates']:
166 continue
167 docdeps += [ pjoin(dirpath,f) for f in filenames
168 if f.endswith('.txt') ]
169 # and the examples
170 for dirpath,dirnames,filenames in os.walk('docs/example'):
171 docdeps += [ pjoin(dirpath,f) for f in filenames
172 if not f.endswith('~') ]
173 # then, make them all dependencies for the main html docs
174 to_update.append(
175 ('docs/dist/index.html',
176 docdeps,
177 "cd docs && make dist")
178 )
179
180 [ target_update(*t) for t in to_update ]
181
182 #---------------------------------------------------------------------------
183 # Find all the packages, package data, and data_files
184 #---------------------------------------------------------------------------
185
186 packages = find_packages()
187 package_data = find_package_data()
188 data_files = find_data_files()
189
190 #---------------------------------------------------------------------------
191 # Handle scripts, dependencies, and setuptools specific things
192 #---------------------------------------------------------------------------
193
194 # For some commands, use setuptools. Note that we do NOT list install here!
195 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
196 needs_setuptools = set(('develop', 'sdist', 'release', 'bdist_egg', 'bdist_rpm',
197 'bdist', 'bdist_dumb', 'bdist_wininst', 'install_egg_info',
198 'build_sphinx', 'egg_info', 'easy_install', 'upload',
199 ))
200 if sys.platform == 'win32':
201 # Depend on setuptools for install on *Windows only*
202 # If we get script-installation working without setuptools,
203 # then we can back off, but until then use it.
204 # See Issue #369 on GitHub for more
205 needs_setuptools.add('install')
206
207 if len(needs_setuptools.intersection(sys.argv)) > 0:
208 import setuptools
209
210 # This dict is used for passing extra arguments that are setuptools
211 # specific to setup
212 setuptools_extra_args = {}
213
214 if 'setuptools' in sys.modules:
215 setuptools_extra_args['zip_safe'] = False
216 setuptools_extra_args['entry_points'] = find_scripts(True)
217 setup_args['extras_require'] = dict(
218 parallel = 'pyzmq>=2.1.4',
219 zmq = 'pyzmq>=2.1.4',
220 doc = 'Sphinx>=0.3',
221 test = 'nose>=0.10.1',
222 notebook = 'tornado>=2.0'
223 )
224 requires = setup_args.setdefault('install_requires', [])
225 setupext.display_status = False
226 if not setupext.check_for_readline():
227 if sys.platform == 'darwin':
228 requires.append('readline')
229 elif sys.platform.startswith('win') and sys.maxsize < 2**32:
230 # only require pyreadline on 32b Windows, due to 64b bug in pyreadline:
231 # https://bugs.launchpad.net/pyreadline/+bug/787574
232 requires.append('pyreadline')
233 else:
234 pass
235 # do we want to install readline here?
236
237 # Script to be run by the windows binary installer after the default setup
238 # routine, to add shortcuts and similar windows-only things. Windows
239 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
240 # doesn't find them.
241 if 'bdist_wininst' in sys.argv:
242 if len(sys.argv) > 2 and \
243 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
244 print >> sys.stderr, "ERROR: bdist_wininst must be run alone. Exiting."
245 sys.exit(1)
246 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
247 setup_args['options'] = {"bdist_wininst":
248 {"install_script":
249 "ipython_win_post_install.py"}}
250 else:
251 # If we are running without setuptools, call this function which will
252 # check for dependencies an inform the user what is needed. This is
253 # just to make life easy for users.
254 check_for_dependencies()
255 setup_args['scripts'] = find_scripts(False)
256
257 #---------------------------------------------------------------------------
258 # Do the actual setup now
259 #---------------------------------------------------------------------------
260
261 setup_args['cmdclass'] = {'build_py': record_commit_info('IPython')}
262 setup_args['packages'] = packages
263 setup_args['package_data'] = package_data
264 setup_args['data_files'] = data_files
265 setup_args.update(setuptools_extra_args)
266
267 def main():
268 setup(**setup_args)
269 cleanup()
270
271 if __name__ == '__main__':
272 main()
@@ -0,0 +1,13 b''
1 import os.path
2 from setuptools import setup
3
4 from setupbase import (setup_args, find_scripts, find_packages)
5
6 setup_args['entry_points'] = find_scripts(True, suffix='3')
7 setup_args['packages'] = find_packages()
8
9 def main():
10 setup(use_2to3 = True, **setup_args)
11
12 if __name__ == "__main__":
13 main()
@@ -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):
@@ -5,9 +5,9 b' app = c.InteractiveShellApp'
5 5 # and merge it into the current one.
6 6 load_subconfig('ipython_config.py', profile='default')
7 7
8 c.InteractiveShell.prompt_in1 = '\C_LightGreen\u@\h\C_LightBlue[\C_LightCyan\Y1\C_LightBlue]\C_Green|\#> '
9 c.InteractiveShell.prompt_in2 = '\C_Green|\C_LightGreen\D\C_Green> '
10 c.InteractiveShell.prompt_out = '<\#> '
8 c.InteractiveShell.prompt_in1 = r'\C_LightGreen\u@\h\C_LightBlue[\C_LightCyan\Y1\C_LightBlue]\C_Green|\#> '
9 c.InteractiveShell.prompt_in2 = r'\C_Green|\C_LightGreen\D\C_Green> '
10 c.InteractiveShell.prompt_out = r'<\#> '
11 11
12 12 c.InteractiveShell.prompts_pad_left = True
13 13
@@ -27,4 +27,4 b' lines = """'
27 27 if hasattr(app, 'exec_lines'):
28 28 app.exec_lines.append(lines)
29 29 else:
30 app.exec_lines = [lines] No newline at end of file
30 app.exec_lines = [lines]
@@ -48,7 +48,7 b' c = get_config()'
48 48 c.a=10
49 49 c.b=20
50 50 c.Foo.Bar.value=10
51 c.Foo.Bam.value=range(10)
51 c.Foo.Bam.value=list(range(10)) # list() is just so it's the same on Python 3
52 52 c.D.C.value='hi there'
53 53 """
54 54
@@ -38,7 +38,7 b' from IPython.utils.warn import warn, error'
38 38 #-----------------------------------------------------------------------------
39 39
40 40 # This is used as the pattern for calls to split_user_input.
41 shell_line_split = re.compile(r'^(\s*)(\S*\s*)(.*$)')
41 shell_line_split = re.compile(r'^(\s*)()(\S+)(.*$)')
42 42
43 43 def default_aliases():
44 44 """Return list of shell aliases to auto-define.
@@ -222,7 +222,7 b' class AliasManager(Configurable):'
222 222 <16> 'q:/opt/np/notepad++.exe myfile.txt'
223 223 """
224 224
225 pre,fn,rest = split_user_input(line)
225 pre,_,fn,rest = split_user_input(line)
226 226 res = pre + self.expand_aliases(fn, rest)
227 227 return res
228 228
@@ -242,7 +242,7 b' class AliasManager(Configurable):'
242 242
243 243 done = set()
244 244 while 1:
245 pre,fn,rest = split_user_input(line, shell_line_split)
245 pre,_,fn,rest = split_user_input(line, shell_line_split)
246 246 if fn in self.alias_table:
247 247 if fn in done:
248 248 warn("Cyclic alias definition, repeated '%s'" % fn)
@@ -40,6 +40,7 b' from IPython.core import release, crashhandler'
40 40 from IPython.core.profiledir import ProfileDir, ProfileDirError
41 41 from IPython.utils.path import get_ipython_dir, get_ipython_package_dir
42 42 from IPython.utils.traitlets import List, Unicode, Type, Bool, Dict
43 from IPython.utils import py3compat
43 44
44 45 #-----------------------------------------------------------------------------
45 46 # Classes and functions
@@ -102,9 +103,12 b' class BaseIPythonApplication(Application):'
102 103 def _config_file_paths_default(self):
103 104 return [os.getcwdu()]
104 105
105 profile = Unicode(u'default', config=True,
106 profile = Unicode(u'', config=True,
106 107 help="""The IPython profile to use."""
107 108 )
109 def _profile_default(self):
110 return "python3" if py3compat.PY3 else "default"
111
108 112 def _profile_changed(self, name, old, new):
109 113 self.builtin_profile_dir = os.path.join(
110 114 get_ipython_package_dir(), u'config', u'profile', new
@@ -222,7 +226,7 b' class BaseIPythonApplication(Application):'
222 226 p = ProfileDir.find_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
223 227 except ProfileDirError:
224 228 # not found, maybe create it (always create default profile)
225 if self.auto_create or self.profile=='default':
229 if self.auto_create or self.profile==self._profile_default():
226 230 try:
227 231 p = ProfileDir.create_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
228 232 except ProfileDirError:
@@ -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 != '':
@@ -29,6 +29,7 b' from StringIO import StringIO'
29 29 from IPython.config.configurable import Configurable
30 30 from IPython.lib import pretty
31 31 from IPython.utils.traitlets import Bool, Dict, Int, Unicode, CUnicode, ObjectName
32 from IPython.utils.py3compat import unicode_to_str
32 33
33 34
34 35 #-----------------------------------------------------------------------------
@@ -439,7 +440,7 b' class PlainTextFormatter(BaseFormatter):'
439 440 # ensure that stream does not get a mix of unicode and bytestrings,
440 441 # or it will cause trouble.
441 442 printer = pretty.RepresentationPrinter(stream, self.verbose,
442 self.max_width, self.newline.encode(),
443 self.max_width, unicode_to_str(self.newline),
443 444 singleton_pprinters=self.singleton_printers,
444 445 type_pprinters=self.type_printers,
445 446 deferred_pprinters=self.deferred_printers)
@@ -75,8 +75,10 b' class HistoryManager(Configurable):'
75 75
76 76 # History saving in separate thread
77 77 save_thread = Instance('IPython.core.history.HistorySavingThread')
78 # N.B. Event is a function returning an instance of _Event.
79 save_flag = Instance(threading._Event)
78 try: # Event is a function returning an instance of _Event...
79 save_flag = Instance(threading._Event)
80 except AttributeError: # ...until Python 3.3, when it's a class.
81 save_flag = Instance(threading.Event)
80 82
81 83 # Private interface
82 84 # Variables used to store the three last inputs from the user. On each new
@@ -74,7 +74,9 b' import tokenize'
74 74 from StringIO import StringIO
75 75
76 76 # IPython modules
77 from IPython.core.splitinput import split_user_input, LineInfo
77 78 from IPython.utils.text import make_quoted_expr
79 from IPython.utils.py3compat import cast_unicode
78 80
79 81 #-----------------------------------------------------------------------------
80 82 # Globals
@@ -481,132 +483,10 b' class InputSplitter(object):'
481 483 # Functions and classes for IPython-specific syntactic support
482 484 #-----------------------------------------------------------------------------
483 485
484 # RegExp for splitting line contents into pre-char//first word-method//rest.
485 # For clarity, each group in on one line.
486
487 line_split = re.compile("""
488 ^(\s*) # any leading space
489 ([,;/%]|!!?|\?\??) # escape character or characters
490 \s*(%?[\w\.\*]*) # function/method, possibly with leading %
491 # to correctly treat things like '?%magic'
492 (\s+.*$|$) # rest of line
493 """, re.VERBOSE)
494
495
496 def split_user_input(line):
497 """Split user input into early whitespace, esc-char, function part and rest.
498
499 This is currently handles lines with '=' in them in a very inconsistent
500 manner.
501
502 Examples
503 ========
504 >>> split_user_input('x=1')
505 ('', '', 'x=1', '')
506 >>> split_user_input('?')
507 ('', '?', '', '')
508 >>> split_user_input('??')
509 ('', '??', '', '')
510 >>> split_user_input(' ?')
511 (' ', '?', '', '')
512 >>> split_user_input(' ??')
513 (' ', '??', '', '')
514 >>> split_user_input('??x')
515 ('', '??', 'x', '')
516 >>> split_user_input('?x=1')
517 ('', '', '?x=1', '')
518 >>> split_user_input('!ls')
519 ('', '!', 'ls', '')
520 >>> split_user_input(' !ls')
521 (' ', '!', 'ls', '')
522 >>> split_user_input('!!ls')
523 ('', '!!', 'ls', '')
524 >>> split_user_input(' !!ls')
525 (' ', '!!', 'ls', '')
526 >>> split_user_input(',ls')
527 ('', ',', 'ls', '')
528 >>> split_user_input(';ls')
529 ('', ';', 'ls', '')
530 >>> split_user_input(' ;ls')
531 (' ', ';', 'ls', '')
532 >>> split_user_input('f.g(x)')
533 ('', '', 'f.g(x)', '')
534 >>> split_user_input('f.g (x)')
535 ('', '', 'f.g', '(x)')
536 >>> split_user_input('?%hist')
537 ('', '?', '%hist', '')
538 >>> split_user_input('?x*')
539 ('', '?', 'x*', '')
540 """
541 match = line_split.match(line)
542 if match:
543 lspace, esc, fpart, rest = match.groups()
544 else:
545 # print "match failed for line '%s'" % line
546 try:
547 fpart, rest = line.split(None, 1)
548 except ValueError:
549 # print "split failed for line '%s'" % line
550 fpart, rest = line,''
551 lspace = re.match('^(\s*)(.*)', line).groups()[0]
552 esc = ''
553
554 # fpart has to be a valid python identifier, so it better be only pure
555 # ascii, no unicode:
556 try:
557 fpart = fpart.encode('ascii')
558 except UnicodeEncodeError:
559 lspace = unicode(lspace)
560 rest = fpart + u' ' + rest
561 fpart = u''
562
563 #print 'line:<%s>' % line # dbg
564 #print 'esc <%s> fpart <%s> rest <%s>' % (esc,fpart.strip(),rest) # dbg
565 return lspace, esc, fpart.strip(), rest.lstrip()
566
567
568 486 # The escaped translators ALL receive a line where their own escape has been
569 487 # stripped. Only '?' is valid at the end of the line, all others can only be
570 488 # placed at the start.
571 489
572 class LineInfo(object):
573 """A single line of input and associated info.
574
575 This is a utility class that mostly wraps the output of
576 :func:`split_user_input` into a convenient object to be passed around
577 during input transformations.
578
579 Includes the following as properties:
580
581 line
582 The original, raw line
583
584 lspace
585 Any early whitespace before actual text starts.
586
587 esc
588 The initial esc character (or characters, for double-char escapes like
589 '??' or '!!').
590
591 fpart
592 The 'function part', which is basically the maximal initial sequence
593 of valid python identifiers and the '.' character. This is what is
594 checked for alias and magic transformations, used for auto-calling,
595 etc.
596
597 rest
598 Everything else on the line.
599 """
600 def __init__(self, line):
601 self.line = line
602 self.lspace, self.esc, self.fpart, self.rest = \
603 split_user_input(line)
604
605 def __str__(self):
606 return "LineInfo [%s|%s|%s|%s]" % (self.lspace, self.esc,
607 self.fpart, self.rest)
608
609
610 490 # Transformations of the special syntaxes that don't rely on an explicit escape
611 491 # character but instead on patterns on the input line
612 492
@@ -680,19 +560,20 b' def _make_help_call(target, esc, lspace, next_input=None):'
680 560 method = 'pinfo2' if esc == '??' \
681 561 else 'psearch' if '*' in target \
682 562 else 'pinfo'
683
563 arg = make_quoted_expr(" ".join([method, target]))
564
684 565 if next_input:
685 tpl = '%sget_ipython().magic(u"%s %s", next_input=%s)'
686 return tpl % (lspace, method, target, make_quoted_expr(next_input))
566 tpl = '%sget_ipython().magic(%s, next_input=%s)'
567 return tpl % (lspace, arg, make_quoted_expr(next_input))
687 568 else:
688 return '%sget_ipython().magic(u"%s %s")' % (lspace, method, target)
569 return '%sget_ipython().magic(%s)' % (lspace, arg)
689 570
690 571 _initial_space_re = re.compile(r'\s*')
691 572 _help_end_re = re.compile(r"""(%?
692 [a-zA-Z_*][a-zA-Z0-9_*]* # Variable name
693 (\.[a-zA-Z_*][a-zA-Z0-9_*]*)* # .etc.etc
573 [a-zA-Z_*][\w*]* # Variable name
574 (\.[a-zA-Z_*][\w*]*)* # .etc.etc
694 575 )
695 (\?\??)$ # ? or ??""",
576 (\?\??)$ # ? or ??""",
696 577 re.VERBOSE)
697 578 def transform_help_end(line):
698 579 """Translate lines with ?/?? at the end"""
@@ -702,7 +583,6 b' def transform_help_end(line):'
702 583 target = m.group(1)
703 584 esc = m.group(3)
704 585 lspace = _initial_space_re.match(line).group(0)
705 newline = _make_help_call(target, esc, lspace)
706 586
707 587 # If we're mid-command, put it back on the next prompt for the user.
708 588 next_input = line.rstrip('?') if line.strip() != m.group(0) else None
@@ -730,14 +610,14 b' class EscapedTransformer(object):'
730 610 def _tr_system(line_info):
731 611 "Translate lines escaped with: !"
732 612 cmd = line_info.line.lstrip().lstrip(ESC_SHELL)
733 return '%sget_ipython().system(%s)' % (line_info.lspace,
613 return '%sget_ipython().system(%s)' % (line_info.pre,
734 614 make_quoted_expr(cmd))
735 615
736 616 @staticmethod
737 617 def _tr_system2(line_info):
738 618 "Translate lines escaped with: !!"
739 619 cmd = line_info.line.lstrip()[2:]
740 return '%sget_ipython().getoutput(%s)' % (line_info.lspace,
620 return '%sget_ipython().getoutput(%s)' % (line_info.pre,
741 621 make_quoted_expr(cmd))
742 622
743 623 @staticmethod
@@ -747,33 +627,33 b' class EscapedTransformer(object):'
747 627 if not line_info.line[1:]:
748 628 return 'get_ipython().show_usage()'
749 629
750 return _make_help_call(line_info.fpart, line_info.esc, line_info.lspace)
630 return _make_help_call(line_info.ifun, line_info.esc, line_info.pre)
751 631
752 632 @staticmethod
753 633 def _tr_magic(line_info):
754 634 "Translate lines escaped with: %"
755 635 tpl = '%sget_ipython().magic(%s)'
756 cmd = make_quoted_expr(' '.join([line_info.fpart,
757 line_info.rest]).strip())
758 return tpl % (line_info.lspace, cmd)
636 cmd = make_quoted_expr(' '.join([line_info.ifun,
637 line_info.the_rest]).strip())
638 return tpl % (line_info.pre, cmd)
759 639
760 640 @staticmethod
761 641 def _tr_quote(line_info):
762 642 "Translate lines escaped with: ,"
763 return '%s%s("%s")' % (line_info.lspace, line_info.fpart,
764 '", "'.join(line_info.rest.split()) )
643 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
644 '", "'.join(line_info.the_rest.split()) )
765 645
766 646 @staticmethod
767 647 def _tr_quote2(line_info):
768 648 "Translate lines escaped with: ;"
769 return '%s%s("%s")' % (line_info.lspace, line_info.fpart,
770 line_info.rest)
649 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
650 line_info.the_rest)
771 651
772 652 @staticmethod
773 653 def _tr_paren(line_info):
774 654 "Translate lines escaped with: /"
775 return '%s%s(%s)' % (line_info.lspace, line_info.fpart,
776 ", ".join(line_info.rest.split()))
655 return '%s%s(%s)' % (line_info.pre, line_info.ifun,
656 ", ".join(line_info.the_rest.split()))
777 657
778 658 def __call__(self, line):
779 659 """Class to transform lines that are explicitly escaped out.
@@ -837,13 +717,12 b' class IPythonInputSplitter(InputSplitter):'
837 717 return super(IPythonInputSplitter, self).push(lines)
838 718
839 719 # We must ensure all input is pure unicode
840 if type(lines)==str:
841 lines = lines.decode(self.encoding)
720 lines = cast_unicode(lines, self.encoding)
842 721
843 722 lines_list = lines.splitlines()
844 723
845 724 transforms = [transform_ipy_prompt, transform_classic_prompt,
846 transform_escaped, transform_help_end,
725 transform_help_end, transform_escaped,
847 726 transform_assign_system, transform_assign_magic]
848 727
849 728 # Transform logic
@@ -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
@@ -29,7 +29,10 b' import re'
29 29 import sys
30 30 import tempfile
31 31 import types
32 from contextlib import nested
32 try:
33 from contextlib import nested
34 except:
35 from IPython.utils.nested_context import nested
33 36
34 37 from IPython.config.configurable import SingletonConfigurable
35 38 from IPython.core import debugger, oinspect
@@ -61,6 +64,7 b' from IPython.core.profiledir import ProfileDir'
61 64 from IPython.external.Itpl import ItplNS
62 65 from IPython.utils import PyColorize
63 66 from IPython.utils import io
67 from IPython.utils import py3compat
64 68 from IPython.utils.doctestreload import doctest_reload
65 69 from IPython.utils.io import ask_yes_no, rprint
66 70 from IPython.utils.ipstruct import Struct
@@ -410,7 +414,10 b' class InteractiveShell(SingletonConfigurable, Magic):'
410 414 # We save this here in case user code replaces raw_input, but it needs
411 415 # to be after init_readline(), because PyPy's readline works by replacing
412 416 # raw_input.
413 self.raw_input_original = raw_input
417 if py3compat.PY3:
418 self.raw_input_original = input
419 else:
420 self.raw_input_original = raw_input
414 421 # init_completer must come after init_readline, because it needs to
415 422 # know whether readline is present or not system-wide to configure the
416 423 # completers, since the completion machinery can now operate
@@ -925,7 +932,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
925 932 self.ns_table = {'user':user_ns,
926 933 'user_global':user_global_ns,
927 934 'internal':self.internal_ns,
928 'builtin':__builtin__.__dict__
935 'builtin':builtin_mod.__dict__
929 936 }
930 937
931 938 # Similarly, track all namespaces where references can be held and that
@@ -979,13 +986,13 b' class InteractiveShell(SingletonConfigurable, Magic):'
979 986 # Set __name__ to __main__ to better match the behavior of the
980 987 # normal interpreter.
981 988 user_ns = {'__name__' :'__main__',
982 '__builtin__' : __builtin__,
983 '__builtins__' : __builtin__,
989 py3compat.builtin_mod_name: builtin_mod,
990 '__builtins__' : builtin_mod,
984 991 }
985 992 else:
986 993 user_ns.setdefault('__name__','__main__')
987 user_ns.setdefault('__builtin__',__builtin__)
988 user_ns.setdefault('__builtins__',__builtin__)
994 user_ns.setdefault(py3compat.builtin_mod_name,builtin_mod)
995 user_ns.setdefault('__builtins__',builtin_mod)
989 996
990 997 if user_global_ns is None:
991 998 user_global_ns = user_ns
@@ -1049,7 +1056,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1049 1056
1050 1057 # For more details:
1051 1058 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1052 ns = dict(__builtin__ = __builtin__)
1059 ns = dict(__builtin__ = builtin_mod)
1053 1060
1054 1061 # Put 'help' in the user namespace
1055 1062 try:
@@ -1255,13 +1262,9 b' class InteractiveShell(SingletonConfigurable, Magic):'
1255 1262
1256 1263 Has special code to detect magic functions.
1257 1264 """
1258 #oname = oname.strip()
1265 oname = oname.strip()
1259 1266 #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.'
1267 if not py3compat.isidentifier(oname.lstrip(ESC_MAGIC), dotted=True):
1265 1268 return dict(found=False)
1266 1269
1267 1270 alias_ns = None
@@ -1271,7 +1274,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1271 1274 # find things in the same order that Python finds them.
1272 1275 namespaces = [ ('Interactive', self.user_ns),
1273 1276 ('IPython internal', self.internal_ns),
1274 ('Python builtin', __builtin__.__dict__),
1277 ('Python builtin', builtin_mod.__dict__),
1275 1278 ('Alias', self.alias_manager.alias_table),
1276 1279 ]
1277 1280 alias_ns = self.alias_manager.alias_table
@@ -1283,8 +1286,8 b' class InteractiveShell(SingletonConfigurable, Magic):'
1283 1286 # We need to special-case 'print', which as of python2.6 registers as a
1284 1287 # function but should only be treated as one if print_function was
1285 1288 # loaded with a future import. In this case, just bail.
1286 if (oname == 'print' and not (self.compile.compiler_flags &
1287 __future__.CO_FUTURE_PRINT_FUNCTION)):
1289 if (oname == 'print' and not py3compat.PY3 and not \
1290 (self.compile.compiler_flags & __future__.CO_FUTURE_PRINT_FUNCTION)):
1288 1291 return {'found':found, 'obj':obj, 'namespace':ospace,
1289 1292 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1290 1293
@@ -1526,7 +1529,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
1526 1529
1527 1530 if etype is SyntaxError:
1528 1531 # Though this won't be called by syntax errors in the input
1529 # line, there may be SyntaxError cases whith imported code.
1532 # line, there may be SyntaxError cases with imported code.
1530 1533 self.showsyntaxerror(filename)
1531 1534 elif etype is UsageError:
1532 1535 print "UsageError:", value
@@ -1679,7 +1682,9 b' class InteractiveShell(SingletonConfigurable, Magic):'
1679 1682
1680 1683 # Remove some chars from the delimiters list. If we encounter
1681 1684 # unicode chars, discard them.
1682 delims = readline.get_completer_delims().encode("ascii", "ignore")
1685 delims = readline.get_completer_delims()
1686 if not py3compat.PY3:
1687 delims = delims.encode("ascii", "ignore")
1683 1688 for d in self.readline_remove_delims:
1684 1689 delims = delims.replace(d, "")
1685 1690 delims = delims.replace(ESC_MAGIC, '')
@@ -1701,7 +1706,8 b' class InteractiveShell(SingletonConfigurable, Magic):'
1701 1706 include_latest=True):
1702 1707 if cell.strip(): # Ignore blank lines
1703 1708 for line in cell.splitlines():
1704 self.readline.add_history(line.encode(stdin_encoding, 'replace'))
1709 self.readline.add_history(py3compat.unicode_to_str(line,
1710 stdin_encoding))
1705 1711
1706 1712 def set_next_input(self, s):
1707 1713 """ Sets the 'default' input string for the next command line.
@@ -1907,8 +1913,6 b' class InteractiveShell(SingletonConfigurable, Magic):'
1907 1913
1908 1914 self.define_magic('foo',foo_impl)
1909 1915 """
1910
1911 import new
1912 1916 im = types.MethodType(func,self)
1913 1917 old = getattr(self, "magic_" + magicname, None)
1914 1918 setattr(self, "magic_" + magicname, im)
@@ -2175,15 +2179,10 b' class InteractiveShell(SingletonConfigurable, Magic):'
2175 2179 # behavior of running a script from the system command line, where
2176 2180 # Python inserts the script's directory into sys.path
2177 2181 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 2182
2184 2183 with prepended_to_syspath(dname):
2185 2184 try:
2186 execfile(fname,*where)
2185 py3compat.execfile(fname,*where)
2187 2186 except SystemExit, status:
2188 2187 # If the call was made with 0 or None exit status (sys.exit(0)
2189 2188 # or sys.exit() ), don't bother showing a traceback, as both of
@@ -2455,7 +2454,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
2455 2454 # Skip our own frame in searching for locals:
2456 2455 sys._getframe(depth+1).f_locals # locals
2457 2456 )
2458 return str(res).decode(res.codec)
2457 return py3compat.str_to_unicode(str(res), res.codec)
2459 2458
2460 2459 def mktempfile(self, data=None, prefix='ipython_edit_'):
2461 2460 """Make a new tempfile and return its filename.
@@ -10,6 +10,8 b''
10 10 import re
11 11 import sys
12 12
13 from IPython.utils import py3compat
14
13 15 coding_declaration = re.compile(r"#\s*coding[:=]\s*([-\w.]+)")
14 16
15 17 class Macro(object):
@@ -37,8 +39,7 b' class Macro(object):'
37 39 self.value = code + '\n'
38 40
39 41 def __str__(self):
40 enc = sys.stdin.encoding or sys.getdefaultencoding()
41 return self.value.encode(enc, "replace")
42 return py3compat.unicode_to_str(self.value)
42 43
43 44 def __unicode__(self):
44 45 return self.value
@@ -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
@@ -52,6 +52,7 b' from IPython.core import magic_arguments, page'
52 52 from IPython.core.prefilter import ESC_MAGIC
53 53 from IPython.lib.pylabtools import mpl_runner
54 54 from IPython.testing.skipdoctest import skip_doctest
55 from IPython.utils import py3compat
55 56 from IPython.utils.io import file_read, nlprint
56 57 from IPython.utils.path import get_py_filename, unquote_filename
57 58 from IPython.utils.process import arg_split, abbrev_cwd
@@ -60,7 +61,6 b' from IPython.utils.text import LSString, SList, format_screen'
60 61 from IPython.utils.timing import clock, clock2
61 62 from IPython.utils.warn import warn, error
62 63 from IPython.utils.ipstruct import Struct
63 import IPython.utils.generics
64 64
65 65 #-----------------------------------------------------------------------------
66 66 # Utility functions
@@ -676,7 +676,7 b' Currently the magic system has the following functions:\\n"""'
676 676
677 677 %psearch -a _* list objects beginning with a single underscore"""
678 678 try:
679 parameter_s = parameter_s.encode('ascii')
679 parameter_s.encode('ascii')
680 680 except UnicodeEncodeError:
681 681 print 'Python identifiers can only contain ascii characters.'
682 682 return
@@ -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
@@ -2085,11 +2085,9 b' Currently the magic system has the following functions:\\n"""'
2085 2085 except (TypeError, ValueError) as e:
2086 2086 print e.args[0]
2087 2087 return
2088 if isinstance(cmds, unicode):
2089 cmds = cmds.encode("utf-8")
2090 with open(fname,'w') as f:
2091 f.write("# coding: utf-8\n")
2092 f.write(cmds)
2088 with py3compat.open(fname,'w', encoding="utf-8") as f:
2089 f.write(u"# coding: utf-8\n")
2090 f.write(py3compat.cast_unicode(cmds))
2093 2091 print 'The following commands were written to file `%s`:' % fname
2094 2092 print cmds
2095 2093
@@ -24,12 +24,16 b' import os'
24 24 import sys
25 25 import types
26 26 from collections import namedtuple
27 from itertools import izip_longest
27 try:
28 from itertools import izip_longest
29 except ImportError:
30 from itertools import zip_longest as izip_longest
28 31
29 32 # IPython's own
30 33 from IPython.core import page
31 34 from IPython.utils import PyColorize
32 35 from IPython.utils import io
36 from IPython.utils import py3compat
33 37 from IPython.utils.text import indent
34 38 from IPython.utils.wildcard import list_namespace
35 39 from IPython.utils.coloransi import *
@@ -249,7 +253,7 b' class Inspector:'
249 253 try:
250 254 # We need a plain string here, NOT unicode!
251 255 hdef = oname + inspect.formatargspec(*getargspec(obj))
252 return hdef.encode('ascii')
256 return py3compat.unicode_to_str(hdef, 'ascii')
253 257 except:
254 258 return None
255 259
@@ -362,7 +366,7 b' class Inspector:'
362 366 except:
363 367 self.noinfo('source',oname)
364 368 else:
365 page.page(self.format(src))
369 page.page(self.format(py3compat.unicode_to_str(src)))
366 370
367 371 def pfile(self,obj,oname=''):
368 372 """Show the whole file where an object was defined."""
@@ -455,7 +459,7 b' class Inspector:'
455 459 # Source or docstring, depending on detail level and whether
456 460 # source found.
457 461 if detail_level > 0 and info['source'] is not None:
458 displayfields.append(("Source", info['source']))
462 displayfields.append(("Source", self.format(py3compat.unicode_to_str(info['source']))))
459 463 elif info['docstring'] is not None:
460 464 displayfields.append(("Docstring", info["docstring"]))
461 465
@@ -604,12 +608,11 b' class Inspector:'
604 608 source = None
605 609 try:
606 610 try:
607 src = getsource(obj,binary_file)
611 source = getsource(obj,binary_file)
608 612 except TypeError:
609 613 if hasattr(obj,'__class__'):
610 src = getsource(obj.__class__,binary_file)
611 if src is not None:
612 source = self.format(src)
614 source = getsource(obj.__class__,binary_file)
615 if source is not None:
613 616 out['source'] = source.rstrip()
614 617 except Exception:
615 618 pass
@@ -32,7 +32,7 b' from IPython.core.alias import AliasManager'
32 32 from IPython.core.autocall import IPyAutocall
33 33 from IPython.config.configurable import Configurable
34 34 from IPython.core.macro import Macro
35 from IPython.core.splitinput import split_user_input
35 from IPython.core.splitinput import split_user_input, LineInfo
36 36 from IPython.core import page
37 37
38 38 from IPython.utils.traitlets import List, Int, Any, Unicode, CBool, Bool, Instance
@@ -92,78 +92,6 b' def is_shadowed(identifier, ip):'
92 92
93 93
94 94 #-----------------------------------------------------------------------------
95 # The LineInfo class used throughout
96 #-----------------------------------------------------------------------------
97
98
99 class LineInfo(object):
100 """A single line of input and associated info.
101
102 Includes the following as properties:
103
104 line
105 The original, raw line
106
107 continue_prompt
108 Is this line a continuation in a sequence of multiline input?
109
110 pre
111 The initial esc character or whitespace.
112
113 pre_char
114 The escape character(s) in pre or the empty string if there isn't one.
115 Note that '!!' is a possible value for pre_char. Otherwise it will
116 always be a single character.
117
118 pre_whitespace
119 The leading whitespace from pre if it exists. If there is a pre_char,
120 this is just ''.
121
122 ifun
123 The 'function part', which is basically the maximal initial sequence
124 of valid python identifiers and the '.' character. This is what is
125 checked for alias and magic transformations, used for auto-calling,
126 etc.
127
128 the_rest
129 Everything else on the line.
130 """
131 def __init__(self, line, continue_prompt):
132 self.line = line
133 self.continue_prompt = continue_prompt
134 self.pre, self.ifun, self.the_rest = split_user_input(line)
135
136 self.pre_char = self.pre.strip()
137 if self.pre_char:
138 self.pre_whitespace = '' # No whitespace allowd before esc chars
139 else:
140 self.pre_whitespace = self.pre
141
142 self._oinfo = None
143
144 def ofind(self, ip):
145 """Do a full, attribute-walking lookup of the ifun in the various
146 namespaces for the given IPython InteractiveShell instance.
147
148 Return a dict with keys: found,obj,ospace,ismagic
149
150 Note: can cause state changes because of calling getattr, but should
151 only be run if autocall is on and if the line hasn't matched any
152 other, less dangerous handlers.
153
154 Does cache the results of the call, so can be called multiple times
155 without worrying about *further* damaging state.
156 """
157 if not self._oinfo:
158 # ip.shell._ofind is actually on the Magic class!
159 self._oinfo = ip.shell._ofind(self.ifun)
160 return self._oinfo
161
162 def __str__(self):
163 return "Lineinfo [%s|%s|%s]" %(self.pre, self.ifun, self.the_rest)
164
165
166 #-----------------------------------------------------------------------------
167 95 # Main Prefilter manager
168 96 #-----------------------------------------------------------------------------
169 97
@@ -630,7 +558,7 b' class MultiLineMagicChecker(PrefilterChecker):'
630 558 # both ! and !!.
631 559 if line_info.continue_prompt \
632 560 and self.prefilter_manager.multi_line_specials:
633 if line_info.ifun.startswith(ESC_MAGIC):
561 if line_info.esc == ESC_MAGIC:
634 562 return self.prefilter_manager.get_handler_by_name('magic')
635 563 else:
636 564 return None
@@ -644,14 +572,16 b' class EscCharsChecker(PrefilterChecker):'
644 572 """Check for escape character and return either a handler to handle it,
645 573 or None if there is no escape char."""
646 574 if line_info.line[-1] == ESC_HELP \
647 and line_info.pre_char != ESC_SHELL \
648 and line_info.pre_char != ESC_SH_CAP:
575 and line_info.esc != ESC_SHELL \
576 and line_info.esc != ESC_SH_CAP:
649 577 # the ? can be at the end, but *not* for either kind of shell escape,
650 578 # because a ? can be a vaild final char in a shell cmd
651 579 return self.prefilter_manager.get_handler_by_name('help')
652 580 else:
581 if line_info.pre:
582 return None
653 583 # This returns None like it should if no handler exists
654 return self.prefilter_manager.get_handler_by_esc(line_info.pre_char)
584 return self.prefilter_manager.get_handler_by_esc(line_info.esc)
655 585
656 586
657 587 class AssignmentChecker(PrefilterChecker):
@@ -872,6 +802,7 b' class AutoHandler(PrefilterHandler):'
872 802 ifun = line_info.ifun
873 803 the_rest = line_info.the_rest
874 804 pre = line_info.pre
805 esc = line_info.esc
875 806 continue_prompt = line_info.continue_prompt
876 807 obj = line_info.ofind(self)['obj']
877 808 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest) # dbg
@@ -883,13 +814,13 b' class AutoHandler(PrefilterHandler):'
883 814 force_auto = isinstance(obj, IPyAutocall)
884 815 auto_rewrite = getattr(obj, 'rewrite', True)
885 816
886 if pre == ESC_QUOTE:
817 if esc == ESC_QUOTE:
887 818 # Auto-quote splitting on whitespace
888 819 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
889 elif pre == ESC_QUOTE2:
820 elif esc == ESC_QUOTE2:
890 821 # Auto-quote whole string
891 822 newcmd = '%s("%s")' % (ifun,the_rest)
892 elif pre == ESC_PAREN:
823 elif esc == ESC_PAREN:
893 824 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
894 825 else:
895 826 # Auto-paren.
@@ -946,7 +877,7 b' class HelpHandler(PrefilterHandler):'
946 877 line = line[:-1]
947 878 if line:
948 879 #print 'line:<%r>' % line # dbg
949 self.shell.magic_pinfo(line)
880 self.shell.magic_pinfo(line_info.ifun)
950 881 else:
951 882 self.shell.show_usage()
952 883 return '' # Empty string is needed here!
@@ -123,3 +123,18 b" download_url = 'http://archive.ipython.org/release/%s' % version"
123 123 platforms = ['Linux','Mac OSX','Windows XP/2000/NT']
124 124
125 125 keywords = ['Interactive','Interpreter','Shell','Parallel','Distributed']
126
127 classifiers = [
128 'Intended Audience :: Developers',
129 'Intended Audience :: Science/Research'
130 'License :: OSI Approved :: BSD License',
131 'Programming Language :: Python',
132 'Programming Language :: Python :: 2',
133 'Programming Language :: Python :: 2.6',
134 'Programming Language :: Python :: 2.7',
135 'Programming Language :: Python :: 3',
136 'Programming Language :: Python :: 3.1',
137 'Programming Language :: Python :: 3.2',
138 'Topic :: System :: Distributed Computing',
139 'Topic :: System :: Shells'
140 ]
@@ -1,6 +1,7 b''
1 1 # encoding: utf-8
2 2 """
3 Simple utility for splitting user input.
3 Simple utility for splitting user input. This is used by both inputsplitter and
4 prefilter.
4 5
5 6 Authors:
6 7
@@ -22,45 +23,37 b' Authors:'
22 23 import re
23 24 import sys
24 25
26 from IPython.utils import py3compat
27
25 28 #-----------------------------------------------------------------------------
26 29 # Main function
27 30 #-----------------------------------------------------------------------------
28 31
29
30 32 # RegExp for splitting line contents into pre-char//first word-method//rest.
31 33 # For clarity, each group in on one line.
32 34
33 # WARNING: update the regexp if the escapes in interactiveshell are changed, as they
34 # are hardwired in.
35 # WARNING: update the regexp if the escapes in interactiveshell are changed, as
36 # they are hardwired in.
35 37
36 38 # Although it's not solely driven by the regex, note that:
37 39 # ,;/% only trigger if they are the first character on the line
38 40 # ! and !! trigger if they are first char(s) *or* follow an indent
39 41 # ? triggers as first or last char.
40 42
41 # The three parts of the regex are:
42 # 1) pre: pre_char *or* initial whitespace
43 # 2) ifun: first word/method (mix of \w and '.')
44 # 3) the_rest: rest of line (separated from ifun by space if non-empty)
45 line_split = re.compile(r'^([,;/%?]|!!?|\s*)'
46 r'\s*([\w\.]+)'
47 r'(\s+.*$|$)')
48
49 # r'[\w\.]+'
50 # r'\s*=\s*%.*'
43 line_split = re.compile("""
44 ^(\s*) # any leading space
45 ([,;/%]|!!?|\?\??)? # escape character or characters
46 \s*(%?[\w\.\*]*) # function/method, possibly with leading %
47 # to correctly treat things like '?%magic'
48 (.*?$|$) # rest of line
49 """, re.VERBOSE)
51 50
52 51 def split_user_input(line, pattern=None):
53 """Split user input into pre-char/whitespace, function part and rest.
54
55 This is currently handles lines with '=' in them in a very inconsistent
56 manner.
52 """Split user input into initial whitespace, escape character, function part
53 and the rest.
57 54 """
58 55 # 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)
56 line = py3compat.cast_unicode(line, sys.stdin.encoding or 'utf-8')
64 57
65 58 if pattern is None:
66 59 pattern = line_split
@@ -73,18 +66,73 b' def split_user_input(line, pattern=None):'
73 66 # print "split failed for line '%s'" % line
74 67 ifun, the_rest = line, u''
75 68 pre = re.match('^(\s*)(.*)',line).groups()[0]
69 esc = ""
76 70 else:
77 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''
71 pre, esc, ifun, the_rest = match.groups()
87 72
88 73 #print 'line:<%s>' % line # dbg
89 74 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest) # dbg
90 return pre, ifun.strip(), the_rest.lstrip()
75 return pre, esc or '', ifun.strip(), the_rest.lstrip()
76
77 class LineInfo(object):
78 """A single line of input and associated info.
79
80 Includes the following as properties:
81
82 line
83 The original, raw line
84
85 continue_prompt
86 Is this line a continuation in a sequence of multiline input?
87
88 pre
89 Any leading whitespace.
90
91 esc
92 The escape character(s) in pre or the empty string if there isn't one.
93 Note that '!!' and '??' are possible values for esc. Otherwise it will
94 always be a single character.
95
96 ifun
97 The 'function part', which is basically the maximal initial sequence
98 of valid python identifiers and the '.' character. This is what is
99 checked for alias and magic transformations, used for auto-calling,
100 etc. In contrast to Python identifiers, it may start with "%" and contain
101 "*".
102
103 the_rest
104 Everything else on the line.
105 """
106 def __init__(self, line, continue_prompt=False):
107 self.line = line
108 self.continue_prompt = continue_prompt
109 self.pre, self.esc, self.ifun, self.the_rest = split_user_input(line)
110
111 self.pre_char = self.pre.strip()
112 if self.pre_char:
113 self.pre_whitespace = '' # No whitespace allowd before esc chars
114 else:
115 self.pre_whitespace = self.pre
116
117 self._oinfo = None
118
119 def ofind(self, ip):
120 """Do a full, attribute-walking lookup of the ifun in the various
121 namespaces for the given IPython InteractiveShell instance.
122
123 Return a dict with keys: found,obj,ospace,ismagic
124
125 Note: can cause state changes because of calling getattr, but should
126 only be run if autocall is on and if the line hasn't matched any
127 other, less dangerous handlers.
128
129 Does cache the results of the call, so can be called multiple times
130 without worrying about *further* damaging state.
131 """
132 if not self._oinfo:
133 # ip.shell._ofind is actually on the Magic class!
134 self._oinfo = ip.shell._ofind(self.ifun)
135 return self._oinfo
136
137 def __str__(self):
138 return "LineInfo [%s|%s|%s|%s]" %(self.pre, self.esc, self.ifun, self.the_rest)
@@ -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:
@@ -28,5 +31,5 b' else:'
28 31
29 32 # This next print statement is NOT debugging, we're making the check on a
30 33 # completely separate process so we verify by capturing stdout:
31 print 'ARGV 1-:', sys.argv[1:]
34 print('ARGV 1-:', sys.argv[1:])
32 35 sys.stdout.flush()
@@ -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()
@@ -10,6 +10,7 b' import nose.tools as nt'
10 10 # our own packages
11 11 from IPython.core import autocall
12 12 from IPython.testing import decorators as dec
13 from IPython.testing import tools as tt
13 14 from IPython.testing.globalipapp import get_ipython
14 15
15 16 #-----------------------------------------------------------------------------
@@ -40,15 +41,7 b' def run(tests):'
40 41 """Loop through a list of (pre, post) inputs, where pre is the string
41 42 handed to ipython, and post is how that string looks after it's been
42 43 transformed (i.e. ipython's notion of _i)"""
43 for pre, post in tests:
44 global num_tests
45 num_tests += 1
46 actual = ip.prefilter_manager.prefilter_lines(pre)
47 if actual != None:
48 actual = actual.rstrip('\n')
49 if actual != post:
50 failures.append('Expected %r to become %r, found %r' % (
51 pre, post, actual))
44 tt.check_pairs(ip.prefilter_manager.prefilter_lines, tests)
52 45
53 46
54 47 def test_handlers():
@@ -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):
@@ -390,15 +390,6 b' def test_LineInfo():'
390 390 linfo = isp.LineInfo(' %cd /home')
391 391 nt.assert_equals(str(linfo), 'LineInfo [ |%|cd|/home]')
392 392
393
394 def test_split_user_input():
395 """Unicode test - split_user_input already has good doctests"""
396 line = u"PΓ©rez Fernando"
397 parts = isp.split_user_input(line)
398 parts_expected = (u'', u'', u'', line)
399 nt.assert_equal(parts, parts_expected)
400
401
402 393 # Transformer tests
403 394 def transform_checker(tests, func):
404 395 """Utility to loop over test inputs"""
@@ -611,7 +602,8 b' class IPythonInputTestCase(InputSplitterTestCase):'
611 602
612 603 isp.push(raw)
613 604 out, out_raw = isp.source_raw_reset()
614 self.assertEqual(out.rstrip(), out_t)
605 self.assertEqual(out.rstrip(), out_t,
606 tt.pair_fail_msg.format("inputsplitter",raw, out_t, out))
615 607 self.assertEqual(out_raw.rstrip(), raw.rstrip())
616 608
617 609 def test_syntax_multiline(self):
@@ -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
@@ -20,6 +20,7 b' import nose.tools as nt'
20 20
21 21 # Our own imports
22 22 from .. import oinspect
23 from IPython.utils import py3compat
23 24
24 25 #-----------------------------------------------------------------------------
25 26 # Globals and constants
@@ -96,7 +97,8 b' def test_info():'
96 97 "Check that Inspector.info fills out various fields as expected."
97 98 i = inspector.info(Call, oname='Call')
98 99 nt.assert_equal(i['type_name'], 'type')
99 nt.assert_equal(i['base_class'], "<type 'type'>")
100 expted_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
101 nt.assert_equal(i['base_class'], expted_class)
100 102 nt.assert_equal(i['string_form'], "<class 'IPython.core.tests.test_oinspect.Call'>")
101 103 fname = __file__
102 104 if fname.endswith(".pyc"):
@@ -125,9 +127,10 b' def test_info():'
125 127 nt.assert_equal(i['call_docstring'], c.__call__.__doc__)
126 128
127 129 # Test old-style classes, which for example may not have an __init__ method.
128 i = inspector.info(OldStyle)
129 nt.assert_equal(i['type_name'], 'classobj')
130
131 i = inspector.info(OldStyle())
132 nt.assert_equal(i['type_name'], 'instance')
133 nt.assert_equal(i['docstring'], OldStyle.__doc__)
130 if not py3compat.PY3:
131 i = inspector.info(OldStyle)
132 nt.assert_equal(i['type_name'], 'classobj')
133
134 i = inspector.info(OldStyle())
135 nt.assert_equal(i['type_name'], 'instance')
136 nt.assert_equal(i['docstring'], OldStyle.__doc__)
@@ -83,6 +83,11 b' import tokenize'
83 83 import traceback
84 84 import types
85 85
86 try: # Python 2
87 generate_tokens = tokenize.generate_tokens
88 except AttributeError: # Python 3
89 generate_tokens = tokenize.tokenize
90
86 91 # For purposes of monkeypatching inspect to fix a bug in it.
87 92 from inspect import getsourcefile, getfile, getmodule,\
88 93 ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode
@@ -94,6 +99,7 b' from IPython.core.display_trap import DisplayTrap'
94 99 from IPython.core.excolors import exception_colors
95 100 from IPython.utils import PyColorize
96 101 from IPython.utils import io
102 from IPython.utils import py3compat
97 103 from IPython.utils.data import uniq_stable
98 104 from IPython.utils.warn import info, error
99 105
@@ -278,8 +284,7 b' def _format_traceback_lines(lnum, index, lines, Colors, lvals=None,scheme=None):'
278 284 # serious refactoring, so that all of the ultratb and PyColorize code
279 285 # is unicode-safe. So for now this is rather an ugly hack, but
280 286 # necessary to at least have readable tracebacks. Improvements welcome!
281 if type(line)==unicode:
282 line = line.encode('utf-8', 'replace')
287 line = py3compat.cast_bytes_py2(line, 'utf-8')
283 288
284 289 new_line, err = _line_format(line, 'str', scheme)
285 290 if not err: line = new_line
@@ -872,7 +877,8 b' class VerboseTB(TBTools):'
872 877 try:
873 878 # This builds the names list in-place by capturing it from the
874 879 # enclosing scope.
875 tokenize.tokenize(linereader, tokeneater)
880 for token in generate_tokens(linereader):
881 tokeneater(*token)
876 882 except IndexError:
877 883 # signals exit of tokenizer
878 884 pass
@@ -933,7 +939,7 b' class VerboseTB(TBTools):'
933 939 # ... and format it
934 940 exception = ['%s%s%s: %s' % (Colors.excName, etype_str,
935 941 ColorsNormal, evalue_str)]
936 if type(evalue) is types.InstanceType:
942 if (not py3compat.PY3) and type(evalue) is types.InstanceType:
937 943 try:
938 944 names = [w for w in dir(evalue) if isinstance(w, basestring)]
939 945 except:
@@ -1,20 +1,24 b''
1 """This is version 0.7 of Philip J. Eby's simplegeneric module
2 (http://pypi.python.org/pypi/simplegeneric), patched to work with Python 3,
3 which doesn't support old-style classes.
4 """
5
1 6 #Name: simplegeneric
2 #Version: 0.6
7 #Version: 0.7
3 8 #Summary: Simple generic functions (similar to Python's own len(), pickle.dump(), etc.)
4 #Home-page: http://cheeseshop.python.org/pypi/simplegeneric
9 #Home-page: http://pypi.python.org/pypi/simplegeneric
5 10 #Author: Phillip J. Eby
6 11 #Author-email: peak@eby-sarna.com
7 12 #License: PSF or ZPL
8 13
9 # This is version 0.6 of Philip J. Eby's simplegeneric module
10 # (http://cheeseshop.python.org/pypi/simplegeneric) patched to work
11 # with Python 2.3 (which doesn't support assigning to __name__)
12
13 14 __all__ = ["generic"]
14 15
15
16 from types import ClassType, InstanceType
17 classtypes = type, ClassType
16 try:
17 from types import ClassType, InstanceType
18 except ImportError:
19 classtypes = type
20 else:
21 classtypes = type, ClassType
18 22
19 23 def generic(func):
20 24 """Create a simple generic function"""
@@ -30,38 +34,44 b' def generic(func):'
30 34 else:
31 35 return func(*args, **kw)
32 36
33 _by_type = {object: func, InstanceType: _by_class}
37 _by_type = {object: func}
38 try:
39 _by_type[InstanceType] = _by_class
40 except NameError: # Python 3
41 pass
42
34 43 _gbt = _by_type.get
35 44
36 def when_type(t):
37 """Decorator to add a method that will be called for type `t`"""
38 if not isinstance(t, classtypes):
39 raise TypeError(
40 "%r is not a type or class" % (t,)
41 )
42 def decorate(f):
43 if _by_type.setdefault(t,f) is not f:
45 def when_type(*types):
46 """Decorator to add a method that will be called for the given types"""
47 for t in types:
48 if not isinstance(t, classtypes):
44 49 raise TypeError(
45 "%r already has method for type %r" % (func, t)
50 "%r is not a type or class" % (t,)
46 51 )
52 def decorate(f):
53 for t in types:
54 if _by_type.setdefault(t,f) is not f:
55 raise TypeError(
56 "%r already has method for type %r" % (func, t)
57 )
47 58 return f
48 59 return decorate
49 60
50 61
51 62
52 63
53
54
55 64 _by_object = {}
56 65 _gbo = _by_object.get
57 66
58 def when_object(o):
59 """Decorator to add a method that will be called for object `o`"""
67 def when_object(*obs):
68 """Decorator to add a method to be called for the given object(s)"""
60 69 def decorate(f):
61 if _by_object.setdefault(id(o), (o,f))[1] is not f:
62 raise TypeError(
63 "%r already has method for object %r" % (func, o)
64 )
70 for o in obs:
71 if _by_object.setdefault(id(o), (o,f))[1] is not f:
72 raise TypeError(
73 "%r already has method for object %r" % (func, o)
74 )
65 75 return f
66 76 return decorate
67 77
@@ -78,10 +88,7 b' def generic(func):'
78 88 else:
79 89 return f[1](*args, **kw)
80 90
81 try:
82 dispatch.__name__ = func.__name__
83 except TypeError:
84 pass
91 dispatch.__name__ = func.__name__
85 92 dispatch.__dict__ = func.__dict__.copy()
86 93 dispatch.__doc__ = func.__doc__
87 94 dispatch.__module__ = func.__module__
@@ -94,46 +101,9 b' def generic(func):'
94 101 return dispatch
95 102
96 103
97
98
99 104 def test_suite():
100 105 import doctest
101 106 return doctest.DocFileSuite(
102 107 'README.txt',
103 108 optionflags=doctest.ELLIPSIS|doctest.REPORT_ONLY_FIRST_FAILURE,
104 109 )
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
@@ -83,7 +83,7 b' class RichIPythonWidget(IPythonWidget):'
83 83 self._append_html(self._make_out_prompt(prompt_number), True)
84 84 # This helps the output to look nice.
85 85 self._append_plain_text('\n', True)
86 self._append_png(decodestring(data['image/png']), True)
86 self._append_png(decodestring(data['image/png'].encode('ascii')), True)
87 87 self._append_html(self.output_sep2, True)
88 88 else:
89 89 # Default back to the plain text representation.
@@ -104,7 +104,7 b' class RichIPythonWidget(IPythonWidget):'
104 104 elif data.has_key('image/png'):
105 105 # PNG data is base64 encoded as it passes over the network
106 106 # in a JSON structure so we decode it.
107 png = decodestring(data['image/png'])
107 png = decodestring(data['image/png'].encode('ascii'))
108 108 self._append_png(png, True)
109 109 else:
110 110 # Default back to the plain text representation.
@@ -26,7 +26,10 b' from __future__ import with_statement'
26 26 import __main__
27 27
28 28 import sys
29 from contextlib import nested
29 try:
30 from contextlib import nested
31 except:
32 from IPython.utils.nested_context import nested
30 33
31 34 from IPython.core import ultratb
32 35 from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
@@ -16,17 +16,22 b''
16 16
17 17 import __builtin__
18 18 import bdb
19 from contextlib import nested
20 19 import os
21 20 import re
22 21 import sys
23 22
23 try:
24 from contextlib import nested
25 except:
26 from IPython.utils.nested_context import nested
27
24 28 from IPython.core.error import TryNext
25 29 from IPython.core.usage import interactive_usage, default_banner
26 30 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
27 31 from IPython.lib.inputhook import enable_gui
28 32 from IPython.lib.pylabtools import pylab_activate
29 33 from IPython.testing.skipdoctest import skip_doctest
34 from IPython.utils import py3compat
30 35 from IPython.utils.terminal import toggle_set_term_title, set_term_title
31 36 from IPython.utils.process import abbrev_cwd
32 37 from IPython.utils.warn import warn
@@ -332,7 +337,7 b' class TerminalInteractiveShell(InteractiveShell):'
332 337 self.set_readline_completer()
333 338
334 339 try:
335 line = self.raw_input_original(prompt).decode(self.stdin_encoding)
340 line = py3compat.str_to_unicode(self.raw_input_original(prompt))
336 341 except ValueError:
337 342 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
338 343 " or sys.stdout.close()!\nExiting IPython!")
@@ -159,7 +159,10 b' def deep_reload_hook(module):'
159 159 return import_module(name[i+1:], name, parent)
160 160
161 161 # Save the original hooks
162 original_reload = __builtin__.reload
162 try:
163 original_reload = __builtin__.reload
164 except AttributeError:
165 original_reload = imp.reload # Python 3
163 166
164 167 # Replacement for reload()
165 168 def reload(module, exclude=['sys', '__builtin__', '__main__']):
@@ -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)
@@ -454,8 +454,10 b' class GroupQueue(object):'
454 454 except ValueError:
455 455 pass
456 456
457
458 _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
457 try:
458 _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
459 except AttributeError: # Python 3
460 _baseclass_reprs = (object.__repr__,)
459 461
460 462
461 463 def _default_pprint(obj, p, cycle):
@@ -648,23 +650,33 b' _type_pprinters = {'
648 650 tuple: _seq_pprinter_factory('(', ')', tuple),
649 651 list: _seq_pprinter_factory('[', ']', list),
650 652 dict: _dict_pprinter_factory('{', '}', dict),
651 types.DictProxyType: _dict_pprinter_factory('<dictproxy {', '}>'),
653
652 654 set: _seq_pprinter_factory('set([', '])', set),
653 655 frozenset: _seq_pprinter_factory('frozenset([', '])', frozenset),
654 656 super: _super_pprint,
655 657 _re_pattern_type: _re_pattern_pprint,
656 658 type: _type_pprint,
657 types.ClassType: _type_pprint,
658 659 types.FunctionType: _function_pprint,
659 660 types.BuiltinFunctionType: _function_pprint,
660 661 types.SliceType: _repr_pprint,
661 662 types.MethodType: _repr_pprint,
662 xrange: _repr_pprint,
663
663 664 datetime.datetime: _repr_pprint,
664 665 datetime.timedelta: _repr_pprint,
665 666 _exception_base: _exception_pprint
666 667 }
667 668
669 try:
670 _type_pprinters[types.DictProxyType] = _dict_pprinter_factory('<dictproxy {', '}>')
671 _type_pprinters[types.ClassType] = _type_pprint,
672 except AttributeError: # Python 3
673 pass
674
675 try:
676 _type_pprinters[xrange] = _repr_pprint
677 except NameError:
678 _type_pprinters[range] = _repr_pprint
679
668 680 #: printers for types specified by name
669 681 _deferred_type_pprinters = {
670 682 }
@@ -19,7 +19,7 b' Authors'
19 19 # Imports
20 20 #-----------------------------------------------------------------------------
21 21
22 from cStringIO import StringIO
22 from io import BytesIO
23 23
24 24 from IPython.utils.decorators import flag_calls
25 25
@@ -99,11 +99,11 b" def print_figure(fig, fmt='png'):"
99 99 fig.set_facecolor('white')
100 100 fig.set_edgecolor('white')
101 101 try:
102 string_io = StringIO()
102 bytes_io = BytesIO()
103 103 # use 72 dpi to match QTConsole's dpi
104 fig.canvas.print_figure(string_io, format=fmt, dpi=72,
104 fig.canvas.print_figure(bytes_io, format=fmt, dpi=72,
105 105 bbox_inches='tight')
106 data = string_io.getvalue()
106 data = bytes_io.getvalue()
107 107 finally:
108 108 fig.set_facecolor(fc)
109 109 fig.set_edgecolor(ec)
@@ -370,7 +370,7 b' class Client(HasTraits):'
370 370 self.session = Session(**extra_args)
371 371
372 372 self._query_socket = self._context.socket(zmq.DEALER)
373 self._query_socket.setsockopt(zmq.IDENTITY, util.asbytes(self.session.session))
373 self._query_socket.setsockopt(zmq.IDENTITY, self.session.bsession)
374 374 if self._ssh:
375 375 tunnel.tunnel_connection(self._query_socket, url, sshserver, **ssh_kwargs)
376 376 else:
@@ -496,7 +496,7 b' class Client(HasTraits):'
496 496 content = msg.content
497 497 self._config['registration'] = dict(content)
498 498 if content.status == 'ok':
499 ident = util.asbytes(self.session.session)
499 ident = self.session.bsession
500 500 if content.mux:
501 501 self._mux_socket = self._context.socket(zmq.DEALER)
502 502 self._mux_socket.setsockopt(zmq.IDENTITY, ident)
@@ -512,7 +512,7 b' class Client(HasTraits):'
512 512 self._notification_socket.setsockopt(zmq.SUBSCRIBE, b'')
513 513 # if content.query:
514 514 # self._query_socket = self._context.socket(zmq.DEALER)
515 # self._query_socket.setsockopt(zmq.IDENTITY, self.session.session)
515 # self._query_socket.setsockopt(zmq.IDENTITY, self.session.bsession)
516 516 # connect_socket(self._query_socket, content.query)
517 517 if content.control:
518 518 self._control_socket = self._context.socket(zmq.DEALER)
@@ -16,6 +16,7 b' from types import ModuleType'
16 16 from IPython.parallel.client.asyncresult import AsyncResult
17 17 from IPython.parallel.error import UnmetDependency
18 18 from IPython.parallel.util import interactive
19 from IPython.utils import py3compat
19 20
20 21 class depend(object):
21 22 """Dependency decorator, for use with tasks.
@@ -65,9 +66,10 b' class dependent(object):'
65 66 raise UnmetDependency()
66 67 return self.f(*args, **kwargs)
67 68
68 @property
69 def __name__(self):
70 return self.func_name
69 if not py3compat.PY3:
70 @property
71 def __name__(self):
72 return self.func_name
71 73
72 74 @interactive
73 75 def _require(*names):
@@ -288,7 +288,7 b' class HubFactory(RegistrationFactory):'
288 288 # resubmit stream
289 289 r = ZMQStream(ctx.socket(zmq.DEALER), loop)
290 290 url = util.disambiguate_url(self.client_info['task'][-1])
291 r.setsockopt(zmq.IDENTITY, util.asbytes(self.session.session))
291 r.setsockopt(zmq.IDENTITY, self.session.bsession)
292 292 r.connect(url)
293 293
294 294 self.hub = Hub(loop=loop, session=self.session, monitor=sub, heartmonitor=self.heartmonitor,
@@ -177,7 +177,7 b' class TaskScheduler(SessionFactory):'
177 177 ident = CBytes() # ZMQ identity. This should just be self.session.session
178 178 # but ensure Bytes
179 179 def _ident_default(self):
180 return asbytes(self.session.session)
180 return self.session.bsession
181 181
182 182 def start(self):
183 183 self.engine_stream.on_recv(self.dispatch_result, copy=False)
@@ -20,15 +20,15 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 from types import MethodType
27 26
28 27 # our own
29 28 from . import tools
30 29
31 30 from IPython.utils import io
31 from IPython.utils import py3compat
32 32 from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
33 33
34 34 #-----------------------------------------------------------------------------
@@ -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
@@ -204,11 +204,10 b' def start_ipython():'
204 204 # Modify the IPython system call with one that uses getoutput, so that we
205 205 # can capture subcommands and print them to Python's stdout, otherwise the
206 206 # doctest machinery would miss them.
207 shell.system = MethodType(xsys, shell, TerminalInteractiveShell)
207 shell.system = py3compat.MethodType(xsys, shell)
208 208
209 209
210 shell._showtraceback = MethodType(_showtraceback, shell,
211 TerminalInteractiveShell)
210 shell._showtraceback = py3compat.MethodType(_showtraceback, shell)
212 211
213 212 # IPython is ready, now clean up some global state...
214 213
@@ -223,8 +222,8 b' def start_ipython():'
223 222 # now return this without recursively calling here again.
224 223 _ip = shell
225 224 get_ipython = _ip.get_ipython
226 __builtin__._ip = _ip
227 __builtin__.get_ipython = get_ipython
225 builtin_mod._ip = _ip
226 builtin_mod.get_ipython = get_ipython
228 227
229 228 # To avoid extra IPython messages during testing, suppress io.stdout/stderr
230 229 io.stdout = StreamProxy('stdout')
@@ -17,6 +17,7 b' Note: merely importing this module causes the monkeypatch to be applied."""'
17 17 #-----------------------------------------------------------------------------
18 18
19 19 import unittest
20 import sys
20 21 import nose.loader
21 22 from inspect import ismethod, isfunction
22 23
@@ -64,5 +65,7 b' def getTestCaseNames(self, testCaseClass):'
64 65
65 66 ##########################################################################
66 67 # Apply monkeypatch here
67 nose.loader.TestLoader.getTestCaseNames = getTestCaseNames
68 # Python 3 must be running with newer version of Nose, so don't touch anything.
69 if sys.version_info[0] < 3:
70 nose.loader.TestLoader.getTestCaseNames = getTestCaseNames
68 71 ##########################################################################
@@ -295,7 +295,7 b' class TempFileMixin(object):'
295 295 # delete it. I have no clue why
296 296 pass
297 297
298 pair_fail_msg = ("Testing function {0}\n\n"
298 pair_fail_msg = ("Testing {0}\n\n"
299 299 "In:\n"
300 300 " {1!r}\n"
301 301 "Expected:\n"
@@ -318,9 +318,10 b' def check_pairs(func, pairs):'
318 318 None. Raises an AssertionError if any output does not match the expected
319 319 value.
320 320 """
321 name = getattr(func, "func_name", getattr(func, "__name__", "<unknown>"))
321 322 for inp, expected in pairs:
322 323 out = func(inp)
323 assert out == expected, pair_fail_msg.format(func.func_name, inp, expected, out)
324 assert out == expected, pair_fail_msg.format(name, inp, expected, out)
324 325
325 326 @contextmanager
326 327 def mute_warn():
@@ -342,4 +343,3 b' def make_tempfile(name):'
342 343 yield
343 344 finally:
344 345 os.unlink(name)
345
@@ -42,6 +42,13 b' import sys'
42 42 import token
43 43 import tokenize
44 44
45 try:
46 generate_tokens = tokenize.generate_tokens
47 except AttributeError:
48 # Python 3. Note that we use the undocumented _tokenize because it expects
49 # strings, not bytes. See also Python issue #9969.
50 generate_tokens = tokenize._tokenize
51
45 52 from IPython.utils.coloransi import *
46 53
47 54 #############################################################################
@@ -177,10 +184,11 b' class Parser:'
177 184
178 185 error = False
179 186 try:
180 tokenize.tokenize(text.readline, self)
181 except tokenize.TokenError, ex:
182 msg = ex[0]
183 line = ex[1][0]
187 for atoken in generate_tokens(text.readline):
188 self(*atoken)
189 except tokenize.TokenError as ex:
190 msg = ex.args[0]
191 line = ex.args[1][0]
184 192 self.out.write("%s\n\n*** ERROR: %s%s%s\n" %
185 193 (colors[token.ERRORTOKEN],
186 194 msg, self.raw[self.lines[line]:],
@@ -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)
@@ -103,7 +103,7 b' class Tee(object):'
103 103 # Inspired by:
104 104 # http://mail.python.org/pipermail/python-list/2007-May/442737.html
105 105
106 def __init__(self, file_or_name, mode=None, channel='stdout'):
106 def __init__(self, file_or_name, mode="w", channel='stdout'):
107 107 """Construct a new Tee object.
108 108
109 109 Parameters
@@ -119,7 +119,7 b' class Tee(object):'
119 119 if channel not in ['stdout', 'stderr']:
120 120 raise ValueError('Invalid channel spec %s' % channel)
121 121
122 if hasattr(file, 'write') and hasattr(file, 'seek'):
122 if hasattr(file_or_name, 'write') and hasattr(file_or_name, 'seek'):
123 123 self.file = file_or_name
124 124 else:
125 125 self.file = open(file_or_name, mode)
@@ -16,6 +16,9 b' import sys'
16 16 import types
17 17 from datetime import datetime
18 18
19 from IPython.utils import py3compat
20 next_attr_name = '__next__' if py3compat.PY3 else 'next'
21
19 22 #-----------------------------------------------------------------------------
20 23 # Globals and constants
21 24 #-----------------------------------------------------------------------------
@@ -134,7 +137,7 b' def json_clean(obj):'
134 137 return obj.decode(sys.getdefaultencoding(), 'replace')
135 138
136 139 if isinstance(obj, container_to_list) or (
137 hasattr(obj, '__iter__') and hasattr(obj, 'next')):
140 hasattr(obj, '__iter__') and hasattr(obj, next_attr_name)):
138 141 obj = list(obj)
139 142
140 143 if isinstance(obj, list):
@@ -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
@@ -35,8 +35,8 b' License: MIT open source license.'
35 35
36 36 from IPython.external.path import path as Path
37 37 import os,stat,time
38 import collections
38 39 import cPickle as pickle
39 import UserDict
40 40 import glob
41 41
42 42 def gethashfile(key):
@@ -44,7 +44,7 b' def gethashfile(key):'
44 44
45 45 _sentinel = object()
46 46
47 class PickleShareDB(UserDict.DictMixin):
47 class PickleShareDB(collections.MutableMapping):
48 48 """ The main 'connection' object for PickleShare database """
49 49 def __init__(self,root):
50 50 """ Return a db object that will manage the specied directory"""
@@ -187,6 +187,12 b' class PickleShareDB(UserDict.DictMixin):'
187 187 else:
188 188 files = [Path(p) for p in glob.glob(self.root/globpat)]
189 189 return [self._normalized(p) for p in files if p.isfile()]
190
191 def __iter__(self):
192 return iter(keys)
193
194 def __len__(self):
195 return len(keys)
190 196
191 197 def uncache(self,*items):
192 198 """ Removes all, or specified items from cache
@@ -27,6 +27,7 b' else:'
27 27 from ._process_posix import _find_cmd, system, getoutput
28 28
29 29 from ._process_common import getoutputerror
30 from IPython.utils import py3compat
30 31
31 32 #-----------------------------------------------------------------------------
32 33 # Code
@@ -65,7 +66,7 b' def find_cmd(cmd):'
65 66 except OSError:
66 67 raise FindCmdError('command could not be found: %s' % cmd)
67 68 # which returns empty if not found
68 if path == '':
69 if path == b'':
69 70 raise FindCmdError('command could not be found: %s' % cmd)
70 71 return os.path.abspath(path)
71 72
@@ -115,7 +116,7 b' def arg_split(s, posix=False):'
115 116 # At least encoding the input when it's unicode seems to help, but there
116 117 # may be more problems lurking. Apparently this is fixed in python3.
117 118 is_unicode = False
118 if isinstance(s, unicode):
119 if (not py3compat.PY3) and isinstance(s, unicode):
119 120 is_unicode = True
120 121 s = s.encode('utf-8')
121 122 lex = shlex.shlex(s, posix=posix)
@@ -31,17 +31,24 b' from IPython.testing import decorators as dec'
31 31 from IPython.testing.decorators import skip_if_not_win32, skip_win32
32 32 from IPython.testing.tools import make_tempfile
33 33 from IPython.utils import path, io
34 from IPython.utils import py3compat
34 35
35 36 # Platform-dependent imports
36 37 try:
37 38 import _winreg as wreg
38 39 except ImportError:
39 40 #Fake _winreg module on none windows platforms
40 import new
41 sys.modules["_winreg"] = new.module("_winreg")
41 import types
42 wr_name = "winreg" if py3compat.PY3 else "_winreg"
43 sys.modules[wr_name] = types.ModuleType(wr_name)
42 44 import _winreg as wreg
43 45 #Add entries that needs to be stubbed by the testing code
44 46 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
47
48 try:
49 reload
50 except NameError: # Python 3
51 from imp import reload
45 52
46 53 #-----------------------------------------------------------------------------
47 54 # Globals
@@ -37,7 +37,7 b' def test_find_cmd_python():'
37 37 def test_find_cmd_ls():
38 38 """Make sure we can find the full path to ls."""
39 39 path = find_cmd('ls')
40 nt.assert_true(path.endswith('ls'))
40 nt.assert_true(path.endswith(b'ls'))
41 41
42 42
43 43 def has_pywin32():
@@ -23,7 +23,7 b' import textwrap'
23 23 from string import Formatter
24 24
25 25 from IPython.external.path import path
26
26 from IPython.utils import py3compat
27 27 from IPython.utils.io import nlprint
28 28 from IPython.utils.data import flatten
29 29
@@ -284,7 +284,7 b' def make_quoted_expr(s):'
284 284 tail = ''
285 285 tailpadding = ''
286 286 raw = ''
287 ucode = 'u'
287 ucode = '' if py3compat.PY3 else 'u'
288 288 if "\\" in s:
289 289 raw = 'r'
290 290 if s.endswith('\\'):
@@ -494,7 +494,7 b" def marquee(txt='',width=78,mark='*'):"
494 494 """
495 495 if not txt:
496 496 return (mark*width)[:width]
497 nmark = (width-len(txt)-2)/len(mark)/2
497 nmark = (width-len(txt)-2)//len(mark)//2
498 498 if nmark < 0: nmark =0
499 499 marks = mark*nmark
500 500 return '%s %s %s' % (marks,txt,marks)
@@ -587,10 +587,10 b' class EvalFormatter(Formatter):'
587 587 --------
588 588
589 589 In [1]: f = EvalFormatter()
590 In [2]: f.format('{n/4}', n=8)
590 In [2]: f.format('{n//4}', n=8)
591 591 Out[2]: '2'
592 592
593 In [3]: f.format('{range(3)}')
593 In [3]: f.format('{list(range(3))}')
594 594 Out[3]: '[0, 1, 2]'
595 595
596 596 In [4]: f.format('{3*2}')
@@ -52,15 +52,17 b' import inspect'
52 52 import re
53 53 import sys
54 54 import types
55 from types import (
56 InstanceType, ClassType, FunctionType,
57 ListType, TupleType
58 )
55 from types import FunctionType
56 try:
57 from types import ClassType, InstanceType
58 ClassTypes = (ClassType, type)
59 except:
60 ClassTypes = (type,)
61
59 62 from .importstring import import_item
63 from IPython.utils import py3compat
60 64
61 ClassTypes = (ClassType, type)
62
63 SequenceTypes = (ListType, TupleType, set, frozenset)
65 SequenceTypes = (list, tuple, set, frozenset)
64 66
65 67 #-----------------------------------------------------------------------------
66 68 # Basic classes
@@ -108,7 +110,7 b' def repr_type(obj):'
108 110 error messages.
109 111 """
110 112 the_type = type(obj)
111 if the_type is InstanceType:
113 if (not py3compat.PY3) and the_type is InstanceType:
112 114 # Old-style class.
113 115 the_type = obj.__class__
114 116 msg = '%r %r' % (obj, the_type)
@@ -616,7 +618,7 b' class ClassBasedTraitType(TraitType):'
616 618
617 619 def error(self, obj, value):
618 620 kind = type(value)
619 if kind is InstanceType:
621 if (not py3compat.PY3) and kind is InstanceType:
620 622 msg = 'class %s' % value.__class__.__name__
621 623 else:
622 624 msg = '%s (i.e. %s)' % ( str( kind )[1:-1], repr( value ) )
@@ -880,29 +882,31 b' class CInt(Int):'
880 882 except:
881 883 self.error(obj, value)
882 884
885 if py3compat.PY3:
886 Long, CLong = Int, CInt
887 else:
888 class Long(TraitType):
889 """A long integer trait."""
883 890
884 class Long(TraitType):
885 """A long integer trait."""
886
887 default_value = 0L
888 info_text = 'a long'
891 default_value = 0L
892 info_text = 'a long'
889 893
890 def validate(self, obj, value):
891 if isinstance(value, long):
892 return value
893 if isinstance(value, int):
894 return long(value)
895 self.error(obj, value)
894 def validate(self, obj, value):
895 if isinstance(value, long):
896 return value
897 if isinstance(value, int):
898 return long(value)
899 self.error(obj, value)
896 900
897 901
898 class CLong(Long):
899 """A casting version of the long integer trait."""
902 class CLong(Long):
903 """A casting version of the long integer trait."""
900 904
901 def validate(self, obj, value):
902 try:
903 return long(value)
904 except:
905 self.error(obj, value)
905 def validate(self, obj, value):
906 try:
907 return long(value)
908 except:
909 self.error(obj, value)
906 910
907 911
908 912 class Float(TraitType):
@@ -955,7 +959,7 b' class CComplex(Complex):'
955 959 # for Python 3 conversion and for reliable unicode behaviour on Python 2. So
956 960 # we don't have a Str type.
957 961 class Bytes(TraitType):
958 """A trait for strings."""
962 """A trait for byte strings."""
959 963
960 964 default_value = ''
961 965 info_text = 'a string'
@@ -967,7 +971,7 b' class Bytes(TraitType):'
967 971
968 972
969 973 class CBytes(Bytes):
970 """A casting version of the string trait."""
974 """A casting version of the byte string trait."""
971 975
972 976 def validate(self, obj, value):
973 977 try:
@@ -1006,12 +1010,12 b' class ObjectName(TraitType):'
1006 1010 This does not check that the name exists in any scope."""
1007 1011 info_text = "a valid object identifier in Python"
1008 1012
1009 if sys.version_info[0] < 3:
1013 if py3compat.PY3:
1014 # Python 3:
1015 coerce_str = staticmethod(lambda _,s: s)
1016
1017 else:
1010 1018 # Python 2:
1011 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
1012 def isidentifier(self, s):
1013 return bool(self._name_re.match(s))
1014
1015 1019 def coerce_str(self, obj, value):
1016 1020 "In Python 2, coerce ascii-only unicode to str"
1017 1021 if isinstance(value, unicode):
@@ -1021,15 +1025,10 b' class ObjectName(TraitType):'
1021 1025 self.error(obj, value)
1022 1026 return value
1023 1027
1024 else:
1025 # Python 3:
1026 isidentifier = staticmethod(lambda s: s.isidentifier())
1027 coerce_str = staticmethod(lambda _,s: s)
1028
1029 1028 def validate(self, obj, value):
1030 1029 value = self.coerce_str(obj, value)
1031 1030
1032 if isinstance(value, str) and self.isidentifier(value):
1031 if isinstance(value, str) and py3compat.isidentifier(value):
1033 1032 return value
1034 1033 self.error(obj, value)
1035 1034
@@ -1038,8 +1037,7 b' class DottedObjectName(ObjectName):'
1038 1037 def validate(self, obj, value):
1039 1038 value = self.coerce_str(obj, value)
1040 1039
1041 if isinstance(value, str) and all(self.isidentifier(x) \
1042 for x in value.split('.')):
1040 if isinstance(value, str) and py3compat.isidentifier(value, dotted=True):
1043 1041 return value
1044 1042 self.error(obj, value)
1045 1043
@@ -30,10 +30,10 b' class ZMQDisplayHook(object):'
30 30 def _encode_binary(format_dict):
31 31 pngdata = format_dict.get('image/png')
32 32 if pngdata is not None:
33 format_dict['image/png'] = encodestring(pngdata)
33 format_dict['image/png'] = encodestring(pngdata).decode('ascii')
34 34 jpegdata = format_dict.get('image/jpeg')
35 35 if jpegdata is not None:
36 format_dict['image/jpeg'] = encodestring(jpegdata)
36 format_dict['image/jpeg'] = encodestring(jpegdata).decode('ascii')
37 37
38 38
39 39 class ZMQShellDisplayHook(DisplayHook):
@@ -33,6 +33,7 b' from IPython.core.shellapp import ('
33 33 InteractiveShellApp, shell_flags, shell_aliases
34 34 )
35 35 from IPython.utils import io
36 from IPython.utils import py3compat
36 37 from IPython.utils.jsonutil import json_clean
37 38 from IPython.lib import pylabtools
38 39 from IPython.utils.traitlets import (
@@ -219,7 +220,10 b' class Kernel(Configurable):'
219 220 # Replace raw_input. Note that is not sufficient to replace
220 221 # raw_input in the user namespace.
221 222 raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
222 __builtin__.raw_input = raw_input
223 if py3compat.PY3:
224 __builtin__.input = raw_input
225 else:
226 __builtin__.raw_input = raw_input
223 227
224 228 # Set the parent message of the display hook and out streams.
225 229 shell.displayhook.set_parent(parent)
@@ -188,7 +188,7 b' class ShellSocketChannel(ZMQSocketChannel):'
188 188 def run(self):
189 189 """The thread's main activity. Call start() instead."""
190 190 self.socket = self.context.socket(zmq.DEALER)
191 self.socket.setsockopt(zmq.IDENTITY, self.session.session)
191 self.socket.setsockopt(zmq.IDENTITY, self.session.bsession)
192 192 self.socket.connect('tcp://%s:%i' % self.address)
193 193 self.iostate = POLLERR|POLLIN
194 194 self.ioloop.add_handler(self.socket, self._handle_events,
@@ -394,8 +394,8 b' class SubSocketChannel(ZMQSocketChannel):'
394 394 def run(self):
395 395 """The thread's main activity. Call start() instead."""
396 396 self.socket = self.context.socket(zmq.SUB)
397 self.socket.setsockopt(zmq.SUBSCRIBE,'')
398 self.socket.setsockopt(zmq.IDENTITY, self.session.session)
397 self.socket.setsockopt(zmq.SUBSCRIBE,b'')
398 self.socket.setsockopt(zmq.IDENTITY, self.session.bsession)
399 399 self.socket.connect('tcp://%s:%i' % self.address)
400 400 self.iostate = POLLIN|POLLERR
401 401 self.ioloop.add_handler(self.socket, self._handle_events,
@@ -483,7 +483,7 b' class StdInSocketChannel(ZMQSocketChannel):'
483 483 def run(self):
484 484 """The thread's main activity. Call start() instead."""
485 485 self.socket = self.context.socket(zmq.DEALER)
486 self.socket.setsockopt(zmq.IDENTITY, self.session.session)
486 self.socket.setsockopt(zmq.IDENTITY, self.session.bsession)
487 487 self.socket.connect('tcp://%s:%i' % self.address)
488 488 self.iostate = POLLERR|POLLIN
489 489 self.ioloop.add_handler(self.socket, self._handle_events,
@@ -562,7 +562,7 b' class HBSocketChannel(ZMQSocketChannel):'
562 562
563 563 def _create_socket(self):
564 564 self.socket = self.context.socket(zmq.REQ)
565 self.socket.setsockopt(zmq.IDENTITY, self.session.session)
565 self.socket.setsockopt(zmq.IDENTITY, self.session.bsession)
566 566 self.socket.connect('tcp://%s:%i' % self.address)
567 567 self.poller = zmq.Poller()
568 568 self.poller.register(self.socket, zmq.POLLIN)
@@ -25,6 +25,7 b' import traceback'
25 25 import zmq
26 26
27 27 # Local imports.
28 from IPython.utils import py3compat
28 29 from IPython.utils.traitlets import HasTraits, Instance, Dict, Float
29 30 from completer import KernelCompleter
30 31 from entry_point import base_launch_kernel
@@ -116,7 +117,10 b' class Kernel(HasTraits):'
116 117 # Replace raw_input. Note that is not sufficient to replace
117 118 # raw_input in the user namespace.
118 119 raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
119 __builtin__.raw_input = raw_input
120 if py3compat.PY3:
121 __builtin__.input = raw_input
122 else:
123 __builtin__.raw_input = raw_input
120 124
121 125 # Set the parent message of the display hook and out streams.
122 126 sys.displayhook.set_parent(parent)
@@ -46,8 +46,9 b' from zmq.eventloop.zmqstream import ZMQStream'
46 46 from IPython.config.configurable import Configurable, LoggingConfigurable
47 47 from IPython.utils.importstring import import_item
48 48 from IPython.utils.jsonutil import extract_dates, squash_dates, date_default
49 from IPython.utils.py3compat import str_to_bytes
49 50 from IPython.utils.traitlets import (CBytes, Unicode, Bool, Any, Instance, Set,
50 DottedObjectName)
51 DottedObjectName, CUnicode)
51 52
52 53 #-----------------------------------------------------------------------------
53 54 # utility functions
@@ -238,10 +239,18 b' class Session(Configurable):'
238 239 else:
239 240 self.unpack = import_item(str(new))
240 241
241 session = CBytes(b'', config=True,
242 session = CUnicode(u'', config=True,
242 243 help="""The UUID identifying this session.""")
243 244 def _session_default(self):
244 return bytes(uuid.uuid4())
245 u = unicode(uuid.uuid4())
246 self.bsession = u.encode('ascii')
247 return u
248
249 def _session_changed(self, name, old, new):
250 self.bsession = self.session.encode('ascii')
251
252 # bsession is the session as bytes
253 bsession = CBytes(b'')
245 254
246 255 username = Unicode(os.environ.get('USER',u'username'), config=True,
247 256 help="""Username for the Session. Default is your system username.""")
@@ -295,9 +304,11 b' class Session(Configurable):'
295 304 pack/unpack : callables
296 305 You can also set the pack/unpack callables for serialization
297 306 directly.
298 session : bytes
307 session : unicode (must be ascii)
299 308 the ID of this Session object. The default is to generate a new
300 309 UUID.
310 bsession : bytes
311 The session as bytes
301 312 username : unicode
302 313 username added to message headers. The default is to ask the OS.
303 314 key : bytes
@@ -310,6 +321,8 b' class Session(Configurable):'
310 321 super(Session, self).__init__(**kwargs)
311 322 self._check_packers()
312 323 self.none = self.pack({})
324 # ensure self._session_default() if necessary, so bsession is defined:
325 self.session
313 326
314 327 @property
315 328 def msg_id(self):
@@ -380,7 +393,7 b' class Session(Configurable):'
380 393 h = self.auth.copy()
381 394 for m in msg_list:
382 395 h.update(m)
383 return h.hexdigest()
396 return str_to_bytes(h.hexdigest())
384 397
385 398 def serialize(self, msg, ident=None):
386 399 """Serialize the message components to bytes.
@@ -401,7 +414,7 b' class Session(Configurable):'
401 414 [ident1,ident2,...,DELIM,HMAC,p_header,p_parent,p_content,
402 415 buffer1,buffer2,...]. In this list, the p_* entities are
403 416 the packed or serialized versions, so if JSON is used, these
404 are uft8 encoded JSON strings.
417 are utf8 encoded JSON strings.
405 418 """
406 419 content = msg.get('content', {})
407 420 if content is None:
@@ -185,4 +185,26 b' class TestSession(SessionTestCase):'
185 185 content = dict(code='whoda',stuff=object())
186 186 themsg = self.session.msg('execute',content=content)
187 187 pmsg = theids
188
189 def test_session_id(self):
190 session = ss.Session()
191 # get bs before us
192 bs = session.bsession
193 us = session.session
194 self.assertEquals(us.encode('ascii'), bs)
195 session = ss.Session()
196 # get us before bs
197 us = session.session
198 bs = session.bsession
199 self.assertEquals(us.encode('ascii'), bs)
200 # change propagates:
201 session.session = 'something else'
202 bs = session.bsession
203 us = session.session
204 self.assertEquals(us.encode('ascii'), bs)
205 session = ss.Session(session='stuff')
206 # get us before bs
207 self.assertEquals(session.bsession, session.session.encode('ascii'))
208 self.assertEquals(b'stuff', session.bsession)
209
188 210
@@ -1,270 +1,10 b''
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 """Setup script for IPython.
4
5 Under Posix environments it works like a typical setup.py script.
6 Under Windows, the command sdist is not supported, since IPython
7 requires utilities which are not available under Windows."""
8
9 #-----------------------------------------------------------------------------
10 # Copyright (c) 2008-2011, IPython Development Team.
11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
14 #
15 # Distributed under the terms of the Modified BSD License.
16 #
17 # The full license is in the file COPYING.txt, distributed with this software.
18 #-----------------------------------------------------------------------------
19
20 #-----------------------------------------------------------------------------
21 # Minimal Python version sanity check
22 #-----------------------------------------------------------------------------
1 """This calls the setup routine for Python 2 or 3 as required."""
23 2
24 3 import sys
25 4
26 # This check is also made in IPython/__init__, don't forget to update both when
27 # changing Python version requirements.
28 if sys.version[0:3] < '2.6':
29 error = """\
30 ERROR: 'IPython requires Python Version 2.6 or above.'
31 Exiting."""
32 print >> sys.stderr, error
33 sys.exit(1)
34
35 # At least we're on the python version we need, move on.
36
37 #-------------------------------------------------------------------------------
38 # Imports
39 #-------------------------------------------------------------------------------
40
41 # Stdlib imports
42 import os
43 import shutil
44
45 from glob import glob
46
47 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
48 # update it when the contents of directories change.
49 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
50
51 from distutils.core import setup
52
53 # Our own imports
54 from IPython.utils.path import target_update
55
56 from setupbase import (
57 setup_args,
58 find_packages,
59 find_package_data,
60 find_scripts,
61 find_data_files,
62 check_for_dependencies,
63 record_commit_info,
64 )
65 from setupext import setupext
66
67 isfile = os.path.isfile
68 pjoin = os.path.join
69
70 #-----------------------------------------------------------------------------
71 # Function definitions
72 #-----------------------------------------------------------------------------
73
74 def cleanup():
75 """Clean up the junk left around by the build process"""
76 if "develop" not in sys.argv:
77 try:
78 shutil.rmtree('ipython.egg-info')
79 except:
80 try:
81 os.unlink('ipython.egg-info')
82 except:
83 pass
84
85 #-------------------------------------------------------------------------------
86 # Handle OS specific things
87 #-------------------------------------------------------------------------------
88
89 if os.name == 'posix':
90 os_name = 'posix'
91 elif os.name in ['nt','dos']:
92 os_name = 'windows'
5 if sys.version_info[0] >= 3:
6 from setup3 import main
93 7 else:
94 print 'Unsupported operating system:',os.name
95 sys.exit(1)
96
97 # Under Windows, 'sdist' has not been supported. Now that the docs build with
98 # Sphinx it might work, but let's not turn it on until someone confirms that it
99 # actually works.
100 if os_name == 'windows' and 'sdist' in sys.argv:
101 print 'The sdist command is not available under Windows. Exiting.'
102 sys.exit(1)
103
104 #-------------------------------------------------------------------------------
105 # Things related to the IPython documentation
106 #-------------------------------------------------------------------------------
107
108 # update the manuals when building a source dist
109 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
110 import textwrap
111
112 # List of things to be updated. Each entry is a triplet of args for
113 # target_update()
114 to_update = [
115 # FIXME - Disabled for now: we need to redo an automatic way
116 # of generating the magic info inside the rst.
117 #('docs/magic.tex',
118 #['IPython/Magic.py'],
119 #"cd doc && ./update_magic.sh" ),
120
121 ('docs/man/ipcluster.1.gz',
122 ['docs/man/ipcluster.1'],
123 'cd docs/man && gzip -9c ipcluster.1 > ipcluster.1.gz'),
124
125 ('docs/man/ipcontroller.1.gz',
126 ['docs/man/ipcontroller.1'],
127 'cd docs/man && gzip -9c ipcontroller.1 > ipcontroller.1.gz'),
128
129 ('docs/man/ipengine.1.gz',
130 ['docs/man/ipengine.1'],
131 'cd docs/man && gzip -9c ipengine.1 > ipengine.1.gz'),
132
133 ('docs/man/iplogger.1.gz',
134 ['docs/man/iplogger.1'],
135 'cd docs/man && gzip -9c iplogger.1 > iplogger.1.gz'),
136
137 ('docs/man/ipython.1.gz',
138 ['docs/man/ipython.1'],
139 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
140
141 ('docs/man/irunner.1.gz',
142 ['docs/man/irunner.1'],
143 'cd docs/man && gzip -9c irunner.1 > irunner.1.gz'),
144
145 ('docs/man/pycolor.1.gz',
146 ['docs/man/pycolor.1'],
147 'cd docs/man && gzip -9c pycolor.1 > pycolor.1.gz'),
148 ]
149
150 # Only build the docs if sphinx is present
151 try:
152 import sphinx
153 except ImportError:
154 pass
155 else:
156 # The Makefile calls the do_sphinx scripts to build html and pdf, so
157 # just one target is enough to cover all manual generation
158
159 # First, compute all the dependencies that can force us to rebuild the
160 # docs. Start with the main release file that contains metadata
161 docdeps = ['IPython/core/release.py']
162 # Inculde all the reST sources
163 pjoin = os.path.join
164 for dirpath,dirnames,filenames in os.walk('docs/source'):
165 if dirpath in ['_static','_templates']:
166 continue
167 docdeps += [ pjoin(dirpath,f) for f in filenames
168 if f.endswith('.txt') ]
169 # and the examples
170 for dirpath,dirnames,filenames in os.walk('docs/example'):
171 docdeps += [ pjoin(dirpath,f) for f in filenames
172 if not f.endswith('~') ]
173 # then, make them all dependencies for the main html docs
174 to_update.append(
175 ('docs/dist/index.html',
176 docdeps,
177 "cd docs && make dist")
178 )
179
180 [ target_update(*t) for t in to_update ]
181
182 #---------------------------------------------------------------------------
183 # Find all the packages, package data, and data_files
184 #---------------------------------------------------------------------------
185
186 packages = find_packages()
187 package_data = find_package_data()
188 data_files = find_data_files()
189
190 #---------------------------------------------------------------------------
191 # Handle scripts, dependencies, and setuptools specific things
192 #---------------------------------------------------------------------------
193
194 # For some commands, use setuptools. Note that we do NOT list install here!
195 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
196 needs_setuptools = set(('develop', 'sdist', 'release', 'bdist_egg', 'bdist_rpm',
197 'bdist', 'bdist_dumb', 'bdist_wininst', 'install_egg_info',
198 'build_sphinx', 'egg_info', 'easy_install', 'upload',
199 ))
200 if sys.platform == 'win32':
201 # Depend on setuptools for install on *Windows only*
202 # If we get script-installation working without setuptools,
203 # then we can back off, but until then use it.
204 # See Issue #369 on GitHub for more
205 needs_setuptools.add('install')
206
207 if len(needs_setuptools.intersection(sys.argv)) > 0:
208 import setuptools
209
210 # This dict is used for passing extra arguments that are setuptools
211 # specific to setup
212 setuptools_extra_args = {}
213
214 if 'setuptools' in sys.modules:
215 setuptools_extra_args['zip_safe'] = False
216 setuptools_extra_args['entry_points'] = find_scripts(True)
217 setup_args['extras_require'] = dict(
218 parallel = 'pyzmq>=2.1.4',
219 zmq = 'pyzmq>=2.1.4',
220 doc = 'Sphinx>=0.3',
221 test = 'nose>=0.10.1',
222 notebook = 'tornado>=2.0'
223 )
224 requires = setup_args.setdefault('install_requires', [])
225 setupext.display_status = False
226 if not setupext.check_for_readline():
227 if sys.platform == 'darwin':
228 requires.append('readline')
229 elif sys.platform.startswith('win') and sys.maxsize < 2**32:
230 # only require pyreadline on 32b Windows, due to 64b bug in pyreadline:
231 # https://bugs.launchpad.net/pyreadline/+bug/787574
232 requires.append('pyreadline')
233 else:
234 pass
235 # do we want to install readline here?
236
237 # Script to be run by the windows binary installer after the default setup
238 # routine, to add shortcuts and similar windows-only things. Windows
239 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
240 # doesn't find them.
241 if 'bdist_wininst' in sys.argv:
242 if len(sys.argv) > 2 and \
243 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
244 print >> sys.stderr, "ERROR: bdist_wininst must be run alone. Exiting."
245 sys.exit(1)
246 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
247 setup_args['options'] = {"bdist_wininst":
248 {"install_script":
249 "ipython_win_post_install.py"}}
250 else:
251 # If we are running without setuptools, call this function which will
252 # check for dependencies an inform the user what is needed. This is
253 # just to make life easy for users.
254 check_for_dependencies()
255 setup_args['scripts'] = find_scripts(False)
256
257 #---------------------------------------------------------------------------
258 # Do the actual setup now
259 #---------------------------------------------------------------------------
260
261 setup_args['cmdclass'] = {'build_py': record_commit_info('IPython')}
262 setup_args['packages'] = packages
263 setup_args['package_data'] = package_data
264 setup_args['data_files'] = data_files
265 setup_args.update(setuptools_extra_args)
266
8 from setup2 import main
267 9
268 if __name__ == '__main__':
269 setup(**setup_args)
270 cleanup()
10 main()
@@ -23,7 +23,10 b' from __future__ import print_function'
23 23 import os
24 24 import sys
25 25
26 from ConfigParser import ConfigParser
26 try:
27 from configparser import ConfigParser
28 except:
29 from ConfigParser import ConfigParser
27 30 from distutils.command.build_py import build_py
28 31 from glob import glob
29 32
@@ -40,6 +43,13 b' pjoin = os.path.join'
40 43 def oscmd(s):
41 44 print(">", s)
42 45 os.system(s)
46
47 try:
48 execfile
49 except NameError:
50 def execfile(fname, globs, locs=None):
51 locs = locs or globs
52 exec(compile(open(fname).read(), fname, "exec"), globs, locs)
43 53
44 54 # A little utility we'll need below, since glob() does NOT allow you to do
45 55 # exclusion on multiple endings!
@@ -58,7 +68,7 b' def file_doesnt_endwith(test,endings):'
58 68 #---------------------------------------------------------------------------
59 69
60 70 # release.py contains version, authors, license, url, keywords, etc.
61 execfile(pjoin('IPython','core','release.py'))
71 execfile(pjoin('IPython','core','release.py'), globals())
62 72
63 73 # Create a dict with the basic information
64 74 # This dict is eventually passed to setup after additional keys are added.
@@ -74,6 +84,7 b' setup_args = dict('
74 84 license = license,
75 85 platforms = platforms,
76 86 keywords = keywords,
87 classifiers = classifiers,
77 88 cmdclass = {'install_data': install_data_ext},
78 89 )
79 90
@@ -235,28 +246,31 b' def make_man_update_target(manpage):'
235 246 # Find scripts
236 247 #---------------------------------------------------------------------------
237 248
238 def find_scripts(entry_points=False):
249 def find_scripts(entry_points=False, suffix=''):
239 250 """Find IPython's scripts.
240 251
241 252 if entry_points is True:
242 253 return setuptools entry_point-style definitions
243 254 else:
244 255 return file paths of plain scripts [default]
256
257 suffix is appended to script names if entry_points is True, so that the
258 Python 3 scripts get named "ipython3" etc.
245 259 """
246 260 if entry_points:
247 console_scripts = [
248 'ipython = IPython.frontend.terminal.ipapp:launch_new_instance',
249 'pycolor = IPython.utils.PyColorize:main',
250 'ipcontroller = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
251 'ipengine = IPython.parallel.apps.ipengineapp:launch_new_instance',
252 'iplogger = IPython.parallel.apps.iploggerapp:launch_new_instance',
253 'ipcluster = IPython.parallel.apps.ipclusterapp:launch_new_instance',
254 'iptest = IPython.testing.iptest:main',
255 'irunner = IPython.lib.irunner:main'
256 ]
257 gui_scripts = [
258 'ipython-qtconsole = IPython.frontend.qt.console.qtconsoleapp:main',
259 ]
261 console_scripts = [s % suffix for s in [
262 'ipython%s = IPython.frontend.terminal.ipapp:launch_new_instance',
263 'pycolor%s = IPython.utils.PyColorize:main',
264 'ipcontroller%s = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
265 'ipengine%s = IPython.parallel.apps.ipengineapp:launch_new_instance',
266 'iplogger%s = IPython.parallel.apps.iploggerapp:launch_new_instance',
267 'ipcluster%s = IPython.parallel.apps.ipclusterapp:launch_new_instance',
268 'iptest%s = IPython.testing.iptest:main',
269 'irunner%s = IPython.lib.irunner:main'
270 ]]
271 gui_scripts = [s % suffix for s in [
272 'ipython%s-qtconsole = IPython.frontend.qt.console.qtconsoleapp:main',
273 ]]
260 274 scripts = dict(console_scripts=console_scripts, gui_scripts=gui_scripts)
261 275 else:
262 276 parallel_scripts = pjoin('IPython','parallel','scripts')
@@ -1,3 +1,3 b''
1 1 # load extended setup modules for distuils
2 2
3 from install_data_ext import install_data_ext
3 from .install_data_ext import install_data_ext
General Comments 0
You need to be logged in to leave comments. Login now