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 | # Imports |
|
18 | # Imports | |
19 | #----------------------------------------------------------------------------- |
|
19 | #----------------------------------------------------------------------------- | |
20 |
|
20 | |||
21 | import __builtin__ |
|
21 | import __builtin__ as builtin_mod | |
22 | import re |
|
22 | import re | |
23 | import sys |
|
23 | import sys | |
24 |
|
24 | |||
25 | from IPython.external import argparse |
|
25 | from IPython.external import argparse | |
26 | from IPython.utils.path import filefind, get_ipython_dir |
|
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 | # Exceptions |
|
30 | # Exceptions | |
@@ -131,7 +131,7 b' class Config(dict):' | |||||
131 | # that you can't have section or attribute names that are |
|
131 | # that you can't have section or attribute names that are | |
132 | # builtins. |
|
132 | # builtins. | |
133 | try: |
|
133 | try: | |
134 |
return getattr( |
|
134 | return getattr(builtin_mod, key) | |
135 | except AttributeError: |
|
135 | except AttributeError: | |
136 | pass |
|
136 | pass | |
137 | if is_section_key(key): |
|
137 | if is_section_key(key): | |
@@ -146,7 +146,7 b' class Config(dict):' | |||||
146 |
|
146 | |||
147 | def __setitem__(self, key, value): |
|
147 | def __setitem__(self, key, value): | |
148 | # Don't allow names in __builtin__ to be modified. |
|
148 | # Don't allow names in __builtin__ to be modified. | |
149 |
if hasattr( |
|
149 | if hasattr(builtin_mod, key): | |
150 | raise ConfigError('Config variable names cannot have the same name ' |
|
150 | raise ConfigError('Config variable names cannot have the same name ' | |
151 | 'as a Python builtin: %s' % key) |
|
151 | 'as a Python builtin: %s' % key) | |
152 | if self._is_section_key(key): |
|
152 | if self._is_section_key(key): | |
@@ -312,7 +312,7 b' class PyFileConfigLoader(FileConfigLoader):' | |||||
312 | namespace = dict(load_subconfig=load_subconfig, get_config=get_config) |
|
312 | namespace = dict(load_subconfig=load_subconfig, get_config=get_config) | |
313 | fs_encoding = sys.getfilesystemencoding() or 'ascii' |
|
313 | fs_encoding = sys.getfilesystemencoding() or 'ascii' | |
314 | conf_filename = self.full_filename.encode(fs_encoding) |
|
314 | conf_filename = self.full_filename.encode(fs_encoding) | |
315 | execfile(conf_filename, namespace) |
|
315 | py3compat.execfile(conf_filename, namespace) | |
316 |
|
316 | |||
317 | def _convert_to_config(self): |
|
317 | def _convert_to_config(self): | |
318 | if self.data is None: |
|
318 | if self.data is None: | |
@@ -586,13 +586,7 b' class ArgParseConfigLoader(CommandLineConfigLoader):' | |||||
586 | def _parse_args(self, args): |
|
586 | def _parse_args(self, args): | |
587 | """self.parser->self.parsed_data""" |
|
587 | """self.parser->self.parsed_data""" | |
588 | # decode sys.argv to support unicode command-line options |
|
588 | # decode sys.argv to support unicode command-line options | |
589 | uargs = [] |
|
589 | uargs = [py3compat.cast_unicode(a) for a in args] | |
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) |
|
|||
596 | self.parsed_data, self.extra_args = self.parser.parse_known_args(uargs) |
|
590 | self.parsed_data, self.extra_args = self.parser.parse_known_args(uargs) | |
597 |
|
591 | |||
598 | def _convert_to_config(self): |
|
592 | def _convert_to_config(self): |
@@ -5,9 +5,9 b' app = c.InteractiveShellApp' | |||||
5 | # and merge it into the current one. |
|
5 | # and merge it into the current one. | |
6 | load_subconfig('ipython_config.py', profile='default') |
|
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|\#> ' |
|
8 | c.InteractiveShell.prompt_in1 = r'\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> ' |
|
9 | c.InteractiveShell.prompt_in2 = r'\C_Green|\C_LightGreen\D\C_Green> ' | |
10 | c.InteractiveShell.prompt_out = '<\#> ' |
|
10 | c.InteractiveShell.prompt_out = r'<\#> ' | |
11 |
|
11 | |||
12 | c.InteractiveShell.prompts_pad_left = True |
|
12 | c.InteractiveShell.prompts_pad_left = True | |
13 |
|
13 | |||
@@ -27,4 +27,4 b' lines = """' | |||||
27 | if hasattr(app, 'exec_lines'): |
|
27 | if hasattr(app, 'exec_lines'): | |
28 | app.exec_lines.append(lines) |
|
28 | app.exec_lines.append(lines) | |
29 | else: |
|
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 | c.a=10 |
|
48 | c.a=10 | |
49 | c.b=20 |
|
49 | c.b=20 | |
50 | c.Foo.Bar.value=10 |
|
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 | c.D.C.value='hi there' |
|
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 | # This is used as the pattern for calls to split_user_input. |
|
40 | # This is used as the pattern for calls to split_user_input. | |
41 |
shell_line_split = re.compile(r'^(\s*)(\S |
|
41 | shell_line_split = re.compile(r'^(\s*)()(\S+)(.*$)') | |
42 |
|
42 | |||
43 | def default_aliases(): |
|
43 | def default_aliases(): | |
44 | """Return list of shell aliases to auto-define. |
|
44 | """Return list of shell aliases to auto-define. | |
@@ -222,7 +222,7 b' class AliasManager(Configurable):' | |||||
222 | <16> 'q:/opt/np/notepad++.exe myfile.txt' |
|
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 | res = pre + self.expand_aliases(fn, rest) |
|
226 | res = pre + self.expand_aliases(fn, rest) | |
227 | return res |
|
227 | return res | |
228 |
|
228 | |||
@@ -242,7 +242,7 b' class AliasManager(Configurable):' | |||||
242 |
|
242 | |||
243 | done = set() |
|
243 | done = set() | |
244 | while 1: |
|
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 | if fn in self.alias_table: |
|
246 | if fn in self.alias_table: | |
247 | if fn in done: |
|
247 | if fn in done: | |
248 | warn("Cyclic alias definition, repeated '%s'" % fn) |
|
248 | warn("Cyclic alias definition, repeated '%s'" % fn) |
@@ -40,6 +40,7 b' from IPython.core import release, crashhandler' | |||||
40 | from IPython.core.profiledir import ProfileDir, ProfileDirError |
|
40 | from IPython.core.profiledir import ProfileDir, ProfileDirError | |
41 | from IPython.utils.path import get_ipython_dir, get_ipython_package_dir |
|
41 | from IPython.utils.path import get_ipython_dir, get_ipython_package_dir | |
42 | from IPython.utils.traitlets import List, Unicode, Type, Bool, Dict |
|
42 | from IPython.utils.traitlets import List, Unicode, Type, Bool, Dict | |
|
43 | from IPython.utils import py3compat | |||
43 |
|
44 | |||
44 | #----------------------------------------------------------------------------- |
|
45 | #----------------------------------------------------------------------------- | |
45 | # Classes and functions |
|
46 | # Classes and functions | |
@@ -102,9 +103,12 b' class BaseIPythonApplication(Application):' | |||||
102 | def _config_file_paths_default(self): |
|
103 | def _config_file_paths_default(self): | |
103 | return [os.getcwdu()] |
|
104 | return [os.getcwdu()] | |
104 |
|
105 | |||
105 |
profile = Unicode(u' |
|
106 | profile = Unicode(u'', config=True, | |
106 | help="""The IPython profile to use.""" |
|
107 | help="""The IPython profile to use.""" | |
107 | ) |
|
108 | ) | |
|
109 | def _profile_default(self): | |||
|
110 | return "python3" if py3compat.PY3 else "default" | |||
|
111 | ||||
108 | def _profile_changed(self, name, old, new): |
|
112 | def _profile_changed(self, name, old, new): | |
109 | self.builtin_profile_dir = os.path.join( |
|
113 | self.builtin_profile_dir = os.path.join( | |
110 | get_ipython_package_dir(), u'config', u'profile', new |
|
114 | get_ipython_package_dir(), u'config', u'profile', new | |
@@ -222,7 +226,7 b' class BaseIPythonApplication(Application):' | |||||
222 | p = ProfileDir.find_profile_dir_by_name(self.ipython_dir, self.profile, self.config) |
|
226 | p = ProfileDir.find_profile_dir_by_name(self.ipython_dir, self.profile, self.config) | |
223 | except ProfileDirError: |
|
227 | except ProfileDirError: | |
224 | # not found, maybe create it (always create default profile) |
|
228 | # not found, maybe create it (always create default profile) | |
225 |
if self.auto_create or self.profile== |
|
229 | if self.auto_create or self.profile==self._profile_default(): | |
226 | try: |
|
230 | try: | |
227 | p = ProfileDir.create_profile_dir_by_name(self.ipython_dir, self.profile, self.config) |
|
231 | p = ProfileDir.create_profile_dir_by_name(self.ipython_dir, self.profile, self.config) | |
228 | except ProfileDirError: |
|
232 | except ProfileDirError: |
@@ -30,6 +30,7 b' from zipimport import zipimporter' | |||||
30 | # Our own imports |
|
30 | # Our own imports | |
31 | from IPython.core.completer import expand_user, compress_user |
|
31 | from IPython.core.completer import expand_user, compress_user | |
32 | from IPython.core.error import TryNext |
|
32 | from IPython.core.error import TryNext | |
|
33 | from IPython.utils import py3compat | |||
33 |
|
34 | |||
34 | # FIXME: this should be pulled in with the right call via the component system |
|
35 | # FIXME: this should be pulled in with the right call via the component system | |
35 | from IPython.core.ipapi import get as get_ipython |
|
36 | from IPython.core.ipapi import get as get_ipython | |
@@ -66,10 +67,9 b' def shlex_split(x):' | |||||
66 | # Example: |
|
67 | # Example: | |
67 | # %run "c:/python -> ['%run','"c:/python'] |
|
68 | # %run "c:/python -> ['%run','"c:/python'] | |
68 |
|
69 | |||
69 | # shlex.split has unicode bugs, so encode first to str |
|
70 | # shlex.split has unicode bugs in Python 2, so encode first to str | |
70 | if isinstance(x, unicode): |
|
71 | if not py3compat.PY3: | |
71 | # don't raise errors on encoding: |
|
72 | x = py3compat.cast_bytes(x) | |
72 | x = x.encode(sys.stdin.encoding or sys.getdefaultencoding(), 'replace') |
|
|||
73 |
|
73 | |||
74 | endofline = [] |
|
74 | endofline = [] | |
75 | while x != '': |
|
75 | while x != '': |
@@ -29,6 +29,7 b' from StringIO import StringIO' | |||||
29 | from IPython.config.configurable import Configurable |
|
29 | from IPython.config.configurable import Configurable | |
30 | from IPython.lib import pretty |
|
30 | from IPython.lib import pretty | |
31 | from IPython.utils.traitlets import Bool, Dict, Int, Unicode, CUnicode, ObjectName |
|
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 | # ensure that stream does not get a mix of unicode and bytestrings, |
|
440 | # ensure that stream does not get a mix of unicode and bytestrings, | |
440 | # or it will cause trouble. |
|
441 | # or it will cause trouble. | |
441 | printer = pretty.RepresentationPrinter(stream, self.verbose, |
|
442 | printer = pretty.RepresentationPrinter(stream, self.verbose, | |
442 |
self.max_width, self.newline |
|
443 | self.max_width, unicode_to_str(self.newline), | |
443 | singleton_pprinters=self.singleton_printers, |
|
444 | singleton_pprinters=self.singleton_printers, | |
444 | type_pprinters=self.type_printers, |
|
445 | type_pprinters=self.type_printers, | |
445 | deferred_pprinters=self.deferred_printers) |
|
446 | deferred_pprinters=self.deferred_printers) |
@@ -75,8 +75,10 b' class HistoryManager(Configurable):' | |||||
75 |
|
75 | |||
76 | # History saving in separate thread |
|
76 | # History saving in separate thread | |
77 | save_thread = Instance('IPython.core.history.HistorySavingThread') |
|
77 | save_thread = Instance('IPython.core.history.HistorySavingThread') | |
78 |
|
|
78 | try: # Event is a function returning an instance of _Event... | |
79 | save_flag = Instance(threading._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 | # Private interface |
|
83 | # Private interface | |
82 | # Variables used to store the three last inputs from the user. On each new |
|
84 | # Variables used to store the three last inputs from the user. On each new |
@@ -74,7 +74,9 b' import tokenize' | |||||
74 | from StringIO import StringIO |
|
74 | from StringIO import StringIO | |
75 |
|
75 | |||
76 | # IPython modules |
|
76 | # IPython modules | |
|
77 | from IPython.core.splitinput import split_user_input, LineInfo | |||
77 | from IPython.utils.text import make_quoted_expr |
|
78 | from IPython.utils.text import make_quoted_expr | |
|
79 | from IPython.utils.py3compat import cast_unicode | |||
78 |
|
80 | |||
79 | #----------------------------------------------------------------------------- |
|
81 | #----------------------------------------------------------------------------- | |
80 | # Globals |
|
82 | # Globals | |
@@ -481,132 +483,10 b' class InputSplitter(object):' | |||||
481 | # Functions and classes for IPython-specific syntactic support |
|
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 | # The escaped translators ALL receive a line where their own escape has been |
|
486 | # The escaped translators ALL receive a line where their own escape has been | |
569 | # stripped. Only '?' is valid at the end of the line, all others can only be |
|
487 | # stripped. Only '?' is valid at the end of the line, all others can only be | |
570 | # placed at the start. |
|
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 | # Transformations of the special syntaxes that don't rely on an explicit escape |
|
490 | # Transformations of the special syntaxes that don't rely on an explicit escape | |
611 | # character but instead on patterns on the input line |
|
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 | method = 'pinfo2' if esc == '??' \ |
|
560 | method = 'pinfo2' if esc == '??' \ | |
681 | else 'psearch' if '*' in target \ |
|
561 | else 'psearch' if '*' in target \ | |
682 | else 'pinfo' |
|
562 | else 'pinfo' | |
683 |
|
563 | arg = make_quoted_expr(" ".join([method, target])) | ||
|
564 | ||||
684 | if next_input: |
|
565 | if next_input: | |
685 |
tpl = '%sget_ipython().magic( |
|
566 | tpl = '%sget_ipython().magic(%s, next_input=%s)' | |
686 |
return tpl % (lspace, |
|
567 | return tpl % (lspace, arg, make_quoted_expr(next_input)) | |
687 | else: |
|
568 | else: | |
688 |
return '%sget_ipython().magic( |
|
569 | return '%sget_ipython().magic(%s)' % (lspace, arg) | |
689 |
|
570 | |||
690 | _initial_space_re = re.compile(r'\s*') |
|
571 | _initial_space_re = re.compile(r'\s*') | |
691 | _help_end_re = re.compile(r"""(%? |
|
572 | _help_end_re = re.compile(r"""(%? | |
692 |
[a-zA-Z_*][ |
|
573 | [a-zA-Z_*][\w*]* # Variable name | |
693 |
(\.[a-zA-Z_*][ |
|
574 | (\.[a-zA-Z_*][\w*]*)* # .etc.etc | |
694 | ) |
|
575 | ) | |
695 |
(\?\??)$ |
|
576 | (\?\??)$ # ? or ??""", | |
696 | re.VERBOSE) |
|
577 | re.VERBOSE) | |
697 | def transform_help_end(line): |
|
578 | def transform_help_end(line): | |
698 | """Translate lines with ?/?? at the end""" |
|
579 | """Translate lines with ?/?? at the end""" | |
@@ -702,7 +583,6 b' def transform_help_end(line):' | |||||
702 | target = m.group(1) |
|
583 | target = m.group(1) | |
703 | esc = m.group(3) |
|
584 | esc = m.group(3) | |
704 | lspace = _initial_space_re.match(line).group(0) |
|
585 | lspace = _initial_space_re.match(line).group(0) | |
705 | newline = _make_help_call(target, esc, lspace) |
|
|||
706 |
|
586 | |||
707 | # If we're mid-command, put it back on the next prompt for the user. |
|
587 | # If we're mid-command, put it back on the next prompt for the user. | |
708 | next_input = line.rstrip('?') if line.strip() != m.group(0) else None |
|
588 | next_input = line.rstrip('?') if line.strip() != m.group(0) else None | |
@@ -730,14 +610,14 b' class EscapedTransformer(object):' | |||||
730 | def _tr_system(line_info): |
|
610 | def _tr_system(line_info): | |
731 | "Translate lines escaped with: !" |
|
611 | "Translate lines escaped with: !" | |
732 | cmd = line_info.line.lstrip().lstrip(ESC_SHELL) |
|
612 | cmd = line_info.line.lstrip().lstrip(ESC_SHELL) | |
733 |
return '%sget_ipython().system(%s)' % (line_info. |
|
613 | return '%sget_ipython().system(%s)' % (line_info.pre, | |
734 | make_quoted_expr(cmd)) |
|
614 | make_quoted_expr(cmd)) | |
735 |
|
615 | |||
736 | @staticmethod |
|
616 | @staticmethod | |
737 | def _tr_system2(line_info): |
|
617 | def _tr_system2(line_info): | |
738 | "Translate lines escaped with: !!" |
|
618 | "Translate lines escaped with: !!" | |
739 | cmd = line_info.line.lstrip()[2:] |
|
619 | cmd = line_info.line.lstrip()[2:] | |
740 |
return '%sget_ipython().getoutput(%s)' % (line_info. |
|
620 | return '%sget_ipython().getoutput(%s)' % (line_info.pre, | |
741 | make_quoted_expr(cmd)) |
|
621 | make_quoted_expr(cmd)) | |
742 |
|
622 | |||
743 | @staticmethod |
|
623 | @staticmethod | |
@@ -747,33 +627,33 b' class EscapedTransformer(object):' | |||||
747 | if not line_info.line[1:]: |
|
627 | if not line_info.line[1:]: | |
748 | return 'get_ipython().show_usage()' |
|
628 | return 'get_ipython().show_usage()' | |
749 |
|
629 | |||
750 |
return _make_help_call(line_info. |
|
630 | return _make_help_call(line_info.ifun, line_info.esc, line_info.pre) | |
751 |
|
631 | |||
752 | @staticmethod |
|
632 | @staticmethod | |
753 | def _tr_magic(line_info): |
|
633 | def _tr_magic(line_info): | |
754 | "Translate lines escaped with: %" |
|
634 | "Translate lines escaped with: %" | |
755 | tpl = '%sget_ipython().magic(%s)' |
|
635 | tpl = '%sget_ipython().magic(%s)' | |
756 |
cmd = make_quoted_expr(' '.join([line_info. |
|
636 | cmd = make_quoted_expr(' '.join([line_info.ifun, | |
757 |
|
|
637 | line_info.the_rest]).strip()) | |
758 |
return tpl % (line_info. |
|
638 | return tpl % (line_info.pre, cmd) | |
759 |
|
639 | |||
760 | @staticmethod |
|
640 | @staticmethod | |
761 | def _tr_quote(line_info): |
|
641 | def _tr_quote(line_info): | |
762 | "Translate lines escaped with: ," |
|
642 | "Translate lines escaped with: ," | |
763 |
return '%s%s("%s")' % (line_info. |
|
643 | return '%s%s("%s")' % (line_info.pre, line_info.ifun, | |
764 | '", "'.join(line_info.rest.split()) ) |
|
644 | '", "'.join(line_info.the_rest.split()) ) | |
765 |
|
645 | |||
766 | @staticmethod |
|
646 | @staticmethod | |
767 | def _tr_quote2(line_info): |
|
647 | def _tr_quote2(line_info): | |
768 | "Translate lines escaped with: ;" |
|
648 | "Translate lines escaped with: ;" | |
769 |
return '%s%s("%s")' % (line_info. |
|
649 | return '%s%s("%s")' % (line_info.pre, line_info.ifun, | |
770 | line_info.rest) |
|
650 | line_info.the_rest) | |
771 |
|
651 | |||
772 | @staticmethod |
|
652 | @staticmethod | |
773 | def _tr_paren(line_info): |
|
653 | def _tr_paren(line_info): | |
774 | "Translate lines escaped with: /" |
|
654 | "Translate lines escaped with: /" | |
775 |
return '%s%s(%s)' % (line_info. |
|
655 | return '%s%s(%s)' % (line_info.pre, line_info.ifun, | |
776 | ", ".join(line_info.rest.split())) |
|
656 | ", ".join(line_info.the_rest.split())) | |
777 |
|
657 | |||
778 | def __call__(self, line): |
|
658 | def __call__(self, line): | |
779 | """Class to transform lines that are explicitly escaped out. |
|
659 | """Class to transform lines that are explicitly escaped out. | |
@@ -837,13 +717,12 b' class IPythonInputSplitter(InputSplitter):' | |||||
837 | return super(IPythonInputSplitter, self).push(lines) |
|
717 | return super(IPythonInputSplitter, self).push(lines) | |
838 |
|
718 | |||
839 | # We must ensure all input is pure unicode |
|
719 | # We must ensure all input is pure unicode | |
840 | if type(lines)==str: |
|
720 | lines = cast_unicode(lines, self.encoding) | |
841 | lines = lines.decode(self.encoding) |
|
|||
842 |
|
721 | |||
843 | lines_list = lines.splitlines() |
|
722 | lines_list = lines.splitlines() | |
844 |
|
723 | |||
845 | transforms = [transform_ipy_prompt, transform_classic_prompt, |
|
724 | transforms = [transform_ipy_prompt, transform_classic_prompt, | |
846 |
transform_escaped, |
|
725 | transform_help_end, transform_escaped, | |
847 | transform_assign_system, transform_assign_magic] |
|
726 | transform_assign_system, transform_assign_magic] | |
848 |
|
727 | |||
849 | # Transform logic |
|
728 | # Transform logic |
@@ -17,7 +17,7 b'' | |||||
17 | from __future__ import with_statement |
|
17 | from __future__ import with_statement | |
18 | from __future__ import absolute_import |
|
18 | from __future__ import absolute_import | |
19 |
|
19 | |||
20 | import __builtin__ |
|
20 | import __builtin__ as builtin_mod | |
21 | import __future__ |
|
21 | import __future__ | |
22 | import abc |
|
22 | import abc | |
23 | import ast |
|
23 | import ast | |
@@ -29,7 +29,10 b' import re' | |||||
29 | import sys |
|
29 | import sys | |
30 | import tempfile |
|
30 | import tempfile | |
31 | import types |
|
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 | from IPython.config.configurable import SingletonConfigurable |
|
37 | from IPython.config.configurable import SingletonConfigurable | |
35 | from IPython.core import debugger, oinspect |
|
38 | from IPython.core import debugger, oinspect | |
@@ -61,6 +64,7 b' from IPython.core.profiledir import ProfileDir' | |||||
61 | from IPython.external.Itpl import ItplNS |
|
64 | from IPython.external.Itpl import ItplNS | |
62 | from IPython.utils import PyColorize |
|
65 | from IPython.utils import PyColorize | |
63 | from IPython.utils import io |
|
66 | from IPython.utils import io | |
|
67 | from IPython.utils import py3compat | |||
64 | from IPython.utils.doctestreload import doctest_reload |
|
68 | from IPython.utils.doctestreload import doctest_reload | |
65 | from IPython.utils.io import ask_yes_no, rprint |
|
69 | from IPython.utils.io import ask_yes_no, rprint | |
66 | from IPython.utils.ipstruct import Struct |
|
70 | from IPython.utils.ipstruct import Struct | |
@@ -410,7 +414,10 b' class InteractiveShell(SingletonConfigurable, Magic):' | |||||
410 | # We save this here in case user code replaces raw_input, but it needs |
|
414 | # We save this here in case user code replaces raw_input, but it needs | |
411 | # to be after init_readline(), because PyPy's readline works by replacing |
|
415 | # to be after init_readline(), because PyPy's readline works by replacing | |
412 | # raw_input. |
|
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 | # init_completer must come after init_readline, because it needs to |
|
421 | # init_completer must come after init_readline, because it needs to | |
415 | # know whether readline is present or not system-wide to configure the |
|
422 | # know whether readline is present or not system-wide to configure the | |
416 | # completers, since the completion machinery can now operate |
|
423 | # completers, since the completion machinery can now operate | |
@@ -925,7 +932,7 b' class InteractiveShell(SingletonConfigurable, Magic):' | |||||
925 | self.ns_table = {'user':user_ns, |
|
932 | self.ns_table = {'user':user_ns, | |
926 | 'user_global':user_global_ns, |
|
933 | 'user_global':user_global_ns, | |
927 | 'internal':self.internal_ns, |
|
934 | 'internal':self.internal_ns, | |
928 |
'builtin': |
|
935 | 'builtin':builtin_mod.__dict__ | |
929 | } |
|
936 | } | |
930 |
|
937 | |||
931 | # Similarly, track all namespaces where references can be held and that |
|
938 | # Similarly, track all namespaces where references can be held and that | |
@@ -979,13 +986,13 b' class InteractiveShell(SingletonConfigurable, Magic):' | |||||
979 | # Set __name__ to __main__ to better match the behavior of the |
|
986 | # Set __name__ to __main__ to better match the behavior of the | |
980 | # normal interpreter. |
|
987 | # normal interpreter. | |
981 | user_ns = {'__name__' :'__main__', |
|
988 | user_ns = {'__name__' :'__main__', | |
982 |
|
|
989 | py3compat.builtin_mod_name: builtin_mod, | |
983 |
'__builtins__' : |
|
990 | '__builtins__' : builtin_mod, | |
984 | } |
|
991 | } | |
985 | else: |
|
992 | else: | |
986 | user_ns.setdefault('__name__','__main__') |
|
993 | user_ns.setdefault('__name__','__main__') | |
987 |
user_ns.setdefault( |
|
994 | user_ns.setdefault(py3compat.builtin_mod_name,builtin_mod) | |
988 |
user_ns.setdefault('__builtins__', |
|
995 | user_ns.setdefault('__builtins__',builtin_mod) | |
989 |
|
996 | |||
990 | if user_global_ns is None: |
|
997 | if user_global_ns is None: | |
991 | user_global_ns = user_ns |
|
998 | user_global_ns = user_ns | |
@@ -1049,7 +1056,7 b' class InteractiveShell(SingletonConfigurable, Magic):' | |||||
1049 |
|
1056 | |||
1050 | # For more details: |
|
1057 | # For more details: | |
1051 | # http://mail.python.org/pipermail/python-dev/2001-April/014068.html |
|
1058 | # http://mail.python.org/pipermail/python-dev/2001-April/014068.html | |
1052 |
ns = dict(__builtin__ = |
|
1059 | ns = dict(__builtin__ = builtin_mod) | |
1053 |
|
1060 | |||
1054 | # Put 'help' in the user namespace |
|
1061 | # Put 'help' in the user namespace | |
1055 | try: |
|
1062 | try: | |
@@ -1255,13 +1262,9 b' class InteractiveShell(SingletonConfigurable, Magic):' | |||||
1255 |
|
1262 | |||
1256 | Has special code to detect magic functions. |
|
1263 | Has special code to detect magic functions. | |
1257 | """ |
|
1264 | """ | |
1258 |
|
|
1265 | oname = oname.strip() | |
1259 | #print '1- oname: <%r>' % oname # dbg |
|
1266 | #print '1- oname: <%r>' % oname # dbg | |
1260 | try: |
|
1267 | if not py3compat.isidentifier(oname.lstrip(ESC_MAGIC), dotted=True): | |
1261 | oname = oname.strip().encode('ascii') |
|
|||
1262 | #print '2- oname: <%r>' % oname # dbg |
|
|||
1263 | except UnicodeEncodeError: |
|
|||
1264 | print 'Python identifiers can only contain ascii characters.' |
|
|||
1265 | return dict(found=False) |
|
1268 | return dict(found=False) | |
1266 |
|
1269 | |||
1267 | alias_ns = None |
|
1270 | alias_ns = None | |
@@ -1271,7 +1274,7 b' class InteractiveShell(SingletonConfigurable, Magic):' | |||||
1271 | # find things in the same order that Python finds them. |
|
1274 | # find things in the same order that Python finds them. | |
1272 | namespaces = [ ('Interactive', self.user_ns), |
|
1275 | namespaces = [ ('Interactive', self.user_ns), | |
1273 | ('IPython internal', self.internal_ns), |
|
1276 | ('IPython internal', self.internal_ns), | |
1274 |
('Python builtin', |
|
1277 | ('Python builtin', builtin_mod.__dict__), | |
1275 | ('Alias', self.alias_manager.alias_table), |
|
1278 | ('Alias', self.alias_manager.alias_table), | |
1276 | ] |
|
1279 | ] | |
1277 | alias_ns = self.alias_manager.alias_table |
|
1280 | alias_ns = self.alias_manager.alias_table | |
@@ -1283,8 +1286,8 b' class InteractiveShell(SingletonConfigurable, Magic):' | |||||
1283 | # We need to special-case 'print', which as of python2.6 registers as a |
|
1286 | # We need to special-case 'print', which as of python2.6 registers as a | |
1284 | # function but should only be treated as one if print_function was |
|
1287 | # function but should only be treated as one if print_function was | |
1285 | # loaded with a future import. In this case, just bail. |
|
1288 | # loaded with a future import. In this case, just bail. | |
1286 |
if (oname == 'print' and not |
|
1289 | if (oname == 'print' and not py3compat.PY3 and not \ | |
1287 |
|
|
1290 | (self.compile.compiler_flags & __future__.CO_FUTURE_PRINT_FUNCTION)): | |
1288 | return {'found':found, 'obj':obj, 'namespace':ospace, |
|
1291 | return {'found':found, 'obj':obj, 'namespace':ospace, | |
1289 | 'ismagic':ismagic, 'isalias':isalias, 'parent':parent} |
|
1292 | 'ismagic':ismagic, 'isalias':isalias, 'parent':parent} | |
1290 |
|
1293 | |||
@@ -1526,7 +1529,7 b' class InteractiveShell(SingletonConfigurable, Magic):' | |||||
1526 |
|
1529 | |||
1527 | if etype is SyntaxError: |
|
1530 | if etype is SyntaxError: | |
1528 | # Though this won't be called by syntax errors in the input |
|
1531 | # Though this won't be called by syntax errors in the input | |
1529 |
# line, there may be SyntaxError cases w |
|
1532 | # line, there may be SyntaxError cases with imported code. | |
1530 | self.showsyntaxerror(filename) |
|
1533 | self.showsyntaxerror(filename) | |
1531 | elif etype is UsageError: |
|
1534 | elif etype is UsageError: | |
1532 | print "UsageError:", value |
|
1535 | print "UsageError:", value | |
@@ -1679,7 +1682,9 b' class InteractiveShell(SingletonConfigurable, Magic):' | |||||
1679 |
|
1682 | |||
1680 | # Remove some chars from the delimiters list. If we encounter |
|
1683 | # Remove some chars from the delimiters list. If we encounter | |
1681 | # unicode chars, discard them. |
|
1684 | # unicode chars, discard them. | |
1682 |
delims = readline.get_completer_delims() |
|
1685 | delims = readline.get_completer_delims() | |
|
1686 | if not py3compat.PY3: | |||
|
1687 | delims = delims.encode("ascii", "ignore") | |||
1683 | for d in self.readline_remove_delims: |
|
1688 | for d in self.readline_remove_delims: | |
1684 | delims = delims.replace(d, "") |
|
1689 | delims = delims.replace(d, "") | |
1685 | delims = delims.replace(ESC_MAGIC, '') |
|
1690 | delims = delims.replace(ESC_MAGIC, '') | |
@@ -1701,7 +1706,8 b' class InteractiveShell(SingletonConfigurable, Magic):' | |||||
1701 | include_latest=True): |
|
1706 | include_latest=True): | |
1702 | if cell.strip(): # Ignore blank lines |
|
1707 | if cell.strip(): # Ignore blank lines | |
1703 | for line in cell.splitlines(): |
|
1708 | for line in cell.splitlines(): | |
1704 |
self.readline.add_history(line |
|
1709 | self.readline.add_history(py3compat.unicode_to_str(line, | |
|
1710 | stdin_encoding)) | |||
1705 |
|
1711 | |||
1706 | def set_next_input(self, s): |
|
1712 | def set_next_input(self, s): | |
1707 | """ Sets the 'default' input string for the next command line. |
|
1713 | """ Sets the 'default' input string for the next command line. | |
@@ -1907,8 +1913,6 b' class InteractiveShell(SingletonConfigurable, Magic):' | |||||
1907 |
|
1913 | |||
1908 | self.define_magic('foo',foo_impl) |
|
1914 | self.define_magic('foo',foo_impl) | |
1909 | """ |
|
1915 | """ | |
1910 |
|
||||
1911 | import new |
|
|||
1912 | im = types.MethodType(func,self) |
|
1916 | im = types.MethodType(func,self) | |
1913 | old = getattr(self, "magic_" + magicname, None) |
|
1917 | old = getattr(self, "magic_" + magicname, None) | |
1914 | setattr(self, "magic_" + magicname, im) |
|
1918 | setattr(self, "magic_" + magicname, im) | |
@@ -2175,15 +2179,10 b' class InteractiveShell(SingletonConfigurable, Magic):' | |||||
2175 | # behavior of running a script from the system command line, where |
|
2179 | # behavior of running a script from the system command line, where | |
2176 | # Python inserts the script's directory into sys.path |
|
2180 | # Python inserts the script's directory into sys.path | |
2177 | dname = os.path.dirname(fname) |
|
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 | with prepended_to_syspath(dname): |
|
2183 | with prepended_to_syspath(dname): | |
2185 | try: |
|
2184 | try: | |
2186 | execfile(fname,*where) |
|
2185 | py3compat.execfile(fname,*where) | |
2187 | except SystemExit, status: |
|
2186 | except SystemExit, status: | |
2188 | # If the call was made with 0 or None exit status (sys.exit(0) |
|
2187 | # If the call was made with 0 or None exit status (sys.exit(0) | |
2189 | # or sys.exit() ), don't bother showing a traceback, as both of |
|
2188 | # or sys.exit() ), don't bother showing a traceback, as both of | |
@@ -2455,7 +2454,7 b' class InteractiveShell(SingletonConfigurable, Magic):' | |||||
2455 | # Skip our own frame in searching for locals: |
|
2454 | # Skip our own frame in searching for locals: | |
2456 | sys._getframe(depth+1).f_locals # locals |
|
2455 | sys._getframe(depth+1).f_locals # locals | |
2457 | ) |
|
2456 | ) | |
2458 |
return str(res) |
|
2457 | return py3compat.str_to_unicode(str(res), res.codec) | |
2459 |
|
2458 | |||
2460 | def mktempfile(self, data=None, prefix='ipython_edit_'): |
|
2459 | def mktempfile(self, data=None, prefix='ipython_edit_'): | |
2461 | """Make a new tempfile and return its filename. |
|
2460 | """Make a new tempfile and return its filename. |
@@ -10,6 +10,8 b'' | |||||
10 | import re |
|
10 | import re | |
11 | import sys |
|
11 | import sys | |
12 |
|
12 | |||
|
13 | from IPython.utils import py3compat | |||
|
14 | ||||
13 | coding_declaration = re.compile(r"#\s*coding[:=]\s*([-\w.]+)") |
|
15 | coding_declaration = re.compile(r"#\s*coding[:=]\s*([-\w.]+)") | |
14 |
|
16 | |||
15 | class Macro(object): |
|
17 | class Macro(object): | |
@@ -37,8 +39,7 b' class Macro(object):' | |||||
37 | self.value = code + '\n' |
|
39 | self.value = code + '\n' | |
38 |
|
40 | |||
39 | def __str__(self): |
|
41 | def __str__(self): | |
40 | enc = sys.stdin.encoding or sys.getdefaultencoding() |
|
42 | return py3compat.unicode_to_str(self.value) | |
41 | return self.value.encode(enc, "replace") |
|
|||
42 |
|
43 | |||
43 | def __unicode__(self): |
|
44 | def __unicode__(self): | |
44 | return self.value |
|
45 | return self.value |
@@ -15,7 +15,7 b'' | |||||
15 | # Imports |
|
15 | # Imports | |
16 | #----------------------------------------------------------------------------- |
|
16 | #----------------------------------------------------------------------------- | |
17 |
|
17 | |||
18 | import __builtin__ |
|
18 | import __builtin__ as builtin_mod | |
19 | import __future__ |
|
19 | import __future__ | |
20 | import bdb |
|
20 | import bdb | |
21 | import inspect |
|
21 | import inspect | |
@@ -52,6 +52,7 b' from IPython.core import magic_arguments, page' | |||||
52 | from IPython.core.prefilter import ESC_MAGIC |
|
52 | from IPython.core.prefilter import ESC_MAGIC | |
53 | from IPython.lib.pylabtools import mpl_runner |
|
53 | from IPython.lib.pylabtools import mpl_runner | |
54 | from IPython.testing.skipdoctest import skip_doctest |
|
54 | from IPython.testing.skipdoctest import skip_doctest | |
|
55 | from IPython.utils import py3compat | |||
55 | from IPython.utils.io import file_read, nlprint |
|
56 | from IPython.utils.io import file_read, nlprint | |
56 | from IPython.utils.path import get_py_filename, unquote_filename |
|
57 | from IPython.utils.path import get_py_filename, unquote_filename | |
57 | from IPython.utils.process import arg_split, abbrev_cwd |
|
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 | from IPython.utils.timing import clock, clock2 |
|
61 | from IPython.utils.timing import clock, clock2 | |
61 | from IPython.utils.warn import warn, error |
|
62 | from IPython.utils.warn import warn, error | |
62 | from IPython.utils.ipstruct import Struct |
|
63 | from IPython.utils.ipstruct import Struct | |
63 | import IPython.utils.generics |
|
|||
64 |
|
64 | |||
65 | #----------------------------------------------------------------------------- |
|
65 | #----------------------------------------------------------------------------- | |
66 | # Utility functions |
|
66 | # Utility functions | |
@@ -676,7 +676,7 b' Currently the magic system has the following functions:\\n"""' | |||||
676 |
|
676 | |||
677 | %psearch -a _* list objects beginning with a single underscore""" |
|
677 | %psearch -a _* list objects beginning with a single underscore""" | |
678 | try: |
|
678 | try: | |
679 |
|
|
679 | parameter_s.encode('ascii') | |
680 | except UnicodeEncodeError: |
|
680 | except UnicodeEncodeError: | |
681 | print 'Python identifiers can only contain ascii characters.' |
|
681 | print 'Python identifiers can only contain ascii characters.' | |
682 | return |
|
682 | return | |
@@ -1729,7 +1729,7 b' Currently the magic system has the following functions:\\n"""' | |||||
1729 | # Since this seems to be done by the interpreter itself, the best |
|
1729 | # Since this seems to be done by the interpreter itself, the best | |
1730 | # we can do is to at least restore __builtins__ for the user on |
|
1730 | # we can do is to at least restore __builtins__ for the user on | |
1731 | # exit. |
|
1731 | # exit. | |
1732 |
self.shell.user_ns['__builtins__'] = |
|
1732 | self.shell.user_ns['__builtins__'] = builtin_mod | |
1733 |
|
1733 | |||
1734 | # Ensure key global structures are restored |
|
1734 | # Ensure key global structures are restored | |
1735 | sys.argv = save_argv |
|
1735 | sys.argv = save_argv | |
@@ -2085,11 +2085,9 b' Currently the magic system has the following functions:\\n"""' | |||||
2085 | except (TypeError, ValueError) as e: |
|
2085 | except (TypeError, ValueError) as e: | |
2086 | print e.args[0] |
|
2086 | print e.args[0] | |
2087 | return |
|
2087 | return | |
2088 | if isinstance(cmds, unicode): |
|
2088 | with py3compat.open(fname,'w', encoding="utf-8") as f: | |
2089 | cmds = cmds.encode("utf-8") |
|
2089 | f.write(u"# coding: utf-8\n") | |
2090 | with open(fname,'w') as f: |
|
2090 | f.write(py3compat.cast_unicode(cmds)) | |
2091 | f.write("# coding: utf-8\n") |
|
|||
2092 | f.write(cmds) |
|
|||
2093 | print 'The following commands were written to file `%s`:' % fname |
|
2091 | print 'The following commands were written to file `%s`:' % fname | |
2094 | print cmds |
|
2092 | print cmds | |
2095 |
|
2093 |
@@ -24,12 +24,16 b' import os' | |||||
24 | import sys |
|
24 | import sys | |
25 | import types |
|
25 | import types | |
26 | from collections import namedtuple |
|
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 | # IPython's own |
|
32 | # IPython's own | |
30 | from IPython.core import page |
|
33 | from IPython.core import page | |
31 | from IPython.utils import PyColorize |
|
34 | from IPython.utils import PyColorize | |
32 | from IPython.utils import io |
|
35 | from IPython.utils import io | |
|
36 | from IPython.utils import py3compat | |||
33 | from IPython.utils.text import indent |
|
37 | from IPython.utils.text import indent | |
34 | from IPython.utils.wildcard import list_namespace |
|
38 | from IPython.utils.wildcard import list_namespace | |
35 | from IPython.utils.coloransi import * |
|
39 | from IPython.utils.coloransi import * | |
@@ -249,7 +253,7 b' class Inspector:' | |||||
249 | try: |
|
253 | try: | |
250 | # We need a plain string here, NOT unicode! |
|
254 | # We need a plain string here, NOT unicode! | |
251 | hdef = oname + inspect.formatargspec(*getargspec(obj)) |
|
255 | hdef = oname + inspect.formatargspec(*getargspec(obj)) | |
252 |
return hdef |
|
256 | return py3compat.unicode_to_str(hdef, 'ascii') | |
253 | except: |
|
257 | except: | |
254 | return None |
|
258 | return None | |
255 |
|
259 | |||
@@ -362,7 +366,7 b' class Inspector:' | |||||
362 | except: |
|
366 | except: | |
363 | self.noinfo('source',oname) |
|
367 | self.noinfo('source',oname) | |
364 | else: |
|
368 | else: | |
365 | page.page(self.format(src)) |
|
369 | page.page(self.format(py3compat.unicode_to_str(src))) | |
366 |
|
370 | |||
367 | def pfile(self,obj,oname=''): |
|
371 | def pfile(self,obj,oname=''): | |
368 | """Show the whole file where an object was defined.""" |
|
372 | """Show the whole file where an object was defined.""" | |
@@ -455,7 +459,7 b' class Inspector:' | |||||
455 | # Source or docstring, depending on detail level and whether |
|
459 | # Source or docstring, depending on detail level and whether | |
456 | # source found. |
|
460 | # source found. | |
457 | if detail_level > 0 and info['source'] is not None: |
|
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 | elif info['docstring'] is not None: |
|
463 | elif info['docstring'] is not None: | |
460 | displayfields.append(("Docstring", info["docstring"])) |
|
464 | displayfields.append(("Docstring", info["docstring"])) | |
461 |
|
465 | |||
@@ -604,12 +608,11 b' class Inspector:' | |||||
604 | source = None |
|
608 | source = None | |
605 | try: |
|
609 | try: | |
606 | try: |
|
610 | try: | |
607 | src = getsource(obj,binary_file) |
|
611 | source = getsource(obj,binary_file) | |
608 | except TypeError: |
|
612 | except TypeError: | |
609 | if hasattr(obj,'__class__'): |
|
613 | if hasattr(obj,'__class__'): | |
610 | src = getsource(obj.__class__,binary_file) |
|
614 | source = getsource(obj.__class__,binary_file) | |
611 | if src is not None: |
|
615 | if source is not None: | |
612 | source = self.format(src) |
|
|||
613 | out['source'] = source.rstrip() |
|
616 | out['source'] = source.rstrip() | |
614 | except Exception: |
|
617 | except Exception: | |
615 | pass |
|
618 | pass |
@@ -32,7 +32,7 b' from IPython.core.alias import AliasManager' | |||||
32 | from IPython.core.autocall import IPyAutocall |
|
32 | from IPython.core.autocall import IPyAutocall | |
33 | from IPython.config.configurable import Configurable |
|
33 | from IPython.config.configurable import Configurable | |
34 | from IPython.core.macro import Macro |
|
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 | from IPython.core import page |
|
36 | from IPython.core import page | |
37 |
|
37 | |||
38 | from IPython.utils.traitlets import List, Int, Any, Unicode, CBool, Bool, Instance |
|
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 | # Main Prefilter manager |
|
95 | # Main Prefilter manager | |
168 | #----------------------------------------------------------------------------- |
|
96 | #----------------------------------------------------------------------------- | |
169 |
|
97 | |||
@@ -630,7 +558,7 b' class MultiLineMagicChecker(PrefilterChecker):' | |||||
630 | # both ! and !!. |
|
558 | # both ! and !!. | |
631 | if line_info.continue_prompt \ |
|
559 | if line_info.continue_prompt \ | |
632 | and self.prefilter_manager.multi_line_specials: |
|
560 | and self.prefilter_manager.multi_line_specials: | |
633 |
if line_info. |
|
561 | if line_info.esc == ESC_MAGIC: | |
634 | return self.prefilter_manager.get_handler_by_name('magic') |
|
562 | return self.prefilter_manager.get_handler_by_name('magic') | |
635 | else: |
|
563 | else: | |
636 | return None |
|
564 | return None | |
@@ -644,14 +572,16 b' class EscCharsChecker(PrefilterChecker):' | |||||
644 | """Check for escape character and return either a handler to handle it, |
|
572 | """Check for escape character and return either a handler to handle it, | |
645 | or None if there is no escape char.""" |
|
573 | or None if there is no escape char.""" | |
646 | if line_info.line[-1] == ESC_HELP \ |
|
574 | if line_info.line[-1] == ESC_HELP \ | |
647 |
and line_info. |
|
575 | and line_info.esc != ESC_SHELL \ | |
648 |
and line_info. |
|
576 | and line_info.esc != ESC_SH_CAP: | |
649 | # the ? can be at the end, but *not* for either kind of shell escape, |
|
577 | # the ? can be at the end, but *not* for either kind of shell escape, | |
650 | # because a ? can be a vaild final char in a shell cmd |
|
578 | # because a ? can be a vaild final char in a shell cmd | |
651 | return self.prefilter_manager.get_handler_by_name('help') |
|
579 | return self.prefilter_manager.get_handler_by_name('help') | |
652 | else: |
|
580 | else: | |
|
581 | if line_info.pre: | |||
|
582 | return None | |||
653 | # This returns None like it should if no handler exists |
|
583 | # This returns None like it should if no handler exists | |
654 |
return self.prefilter_manager.get_handler_by_esc(line_info. |
|
584 | return self.prefilter_manager.get_handler_by_esc(line_info.esc) | |
655 |
|
585 | |||
656 |
|
586 | |||
657 | class AssignmentChecker(PrefilterChecker): |
|
587 | class AssignmentChecker(PrefilterChecker): | |
@@ -872,6 +802,7 b' class AutoHandler(PrefilterHandler):' | |||||
872 | ifun = line_info.ifun |
|
802 | ifun = line_info.ifun | |
873 | the_rest = line_info.the_rest |
|
803 | the_rest = line_info.the_rest | |
874 | pre = line_info.pre |
|
804 | pre = line_info.pre | |
|
805 | esc = line_info.esc | |||
875 | continue_prompt = line_info.continue_prompt |
|
806 | continue_prompt = line_info.continue_prompt | |
876 | obj = line_info.ofind(self)['obj'] |
|
807 | obj = line_info.ofind(self)['obj'] | |
877 | #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest) # dbg |
|
808 | #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest) # dbg | |
@@ -883,13 +814,13 b' class AutoHandler(PrefilterHandler):' | |||||
883 | force_auto = isinstance(obj, IPyAutocall) |
|
814 | force_auto = isinstance(obj, IPyAutocall) | |
884 | auto_rewrite = getattr(obj, 'rewrite', True) |
|
815 | auto_rewrite = getattr(obj, 'rewrite', True) | |
885 |
|
816 | |||
886 |
if |
|
817 | if esc == ESC_QUOTE: | |
887 | # Auto-quote splitting on whitespace |
|
818 | # Auto-quote splitting on whitespace | |
888 | newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) ) |
|
819 | newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) ) | |
889 |
elif |
|
820 | elif esc == ESC_QUOTE2: | |
890 | # Auto-quote whole string |
|
821 | # Auto-quote whole string | |
891 | newcmd = '%s("%s")' % (ifun,the_rest) |
|
822 | newcmd = '%s("%s")' % (ifun,the_rest) | |
892 |
elif |
|
823 | elif esc == ESC_PAREN: | |
893 | newcmd = '%s(%s)' % (ifun,",".join(the_rest.split())) |
|
824 | newcmd = '%s(%s)' % (ifun,",".join(the_rest.split())) | |
894 | else: |
|
825 | else: | |
895 | # Auto-paren. |
|
826 | # Auto-paren. | |
@@ -946,7 +877,7 b' class HelpHandler(PrefilterHandler):' | |||||
946 | line = line[:-1] |
|
877 | line = line[:-1] | |
947 | if line: |
|
878 | if line: | |
948 | #print 'line:<%r>' % line # dbg |
|
879 | #print 'line:<%r>' % line # dbg | |
949 | self.shell.magic_pinfo(line) |
|
880 | self.shell.magic_pinfo(line_info.ifun) | |
950 | else: |
|
881 | else: | |
951 | self.shell.show_usage() |
|
882 | self.shell.show_usage() | |
952 | return '' # Empty string is needed here! |
|
883 | return '' # Empty string is needed here! |
@@ -123,3 +123,18 b" download_url = 'http://archive.ipython.org/release/%s' % version" | |||||
123 | platforms = ['Linux','Mac OSX','Windows XP/2000/NT'] |
|
123 | platforms = ['Linux','Mac OSX','Windows XP/2000/NT'] | |
124 |
|
124 | |||
125 | keywords = ['Interactive','Interpreter','Shell','Parallel','Distributed'] |
|
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 | # encoding: utf-8 |
|
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 | Authors: |
|
6 | Authors: | |
6 |
|
7 | |||
@@ -22,45 +23,37 b' Authors:' | |||||
22 | import re |
|
23 | import re | |
23 | import sys |
|
24 | import sys | |
24 |
|
25 | |||
|
26 | from IPython.utils import py3compat | |||
|
27 | ||||
25 | #----------------------------------------------------------------------------- |
|
28 | #----------------------------------------------------------------------------- | |
26 | # Main function |
|
29 | # Main function | |
27 | #----------------------------------------------------------------------------- |
|
30 | #----------------------------------------------------------------------------- | |
28 |
|
31 | |||
29 |
|
||||
30 | # RegExp for splitting line contents into pre-char//first word-method//rest. |
|
32 | # RegExp for splitting line contents into pre-char//first word-method//rest. | |
31 | # For clarity, each group in on one line. |
|
33 | # For clarity, each group in on one line. | |
32 |
|
34 | |||
33 |
# WARNING: update the regexp if the escapes in interactiveshell are changed, as |
|
35 | # WARNING: update the regexp if the escapes in interactiveshell are changed, as | |
34 | # are hardwired in. |
|
36 | # they are hardwired in. | |
35 |
|
37 | |||
36 | # Although it's not solely driven by the regex, note that: |
|
38 | # Although it's not solely driven by the regex, note that: | |
37 | # ,;/% only trigger if they are the first character on the line |
|
39 | # ,;/% only trigger if they are the first character on the line | |
38 | # ! and !! trigger if they are first char(s) *or* follow an indent |
|
40 | # ! and !! trigger if they are first char(s) *or* follow an indent | |
39 | # ? triggers as first or last char. |
|
41 | # ? triggers as first or last char. | |
40 |
|
42 | |||
41 | # The three parts of the regex are: |
|
43 | line_split = re.compile(""" | |
42 | # 1) pre: pre_char *or* initial whitespace |
|
44 | ^(\s*) # any leading space | |
43 | # 2) ifun: first word/method (mix of \w and '.') |
|
45 | ([,;/%]|!!?|\?\??)? # escape character or characters | |
44 | # 3) the_rest: rest of line (separated from ifun by space if non-empty) |
|
46 | \s*(%?[\w\.\*]*) # function/method, possibly with leading % | |
45 | line_split = re.compile(r'^([,;/%?]|!!?|\s*)' |
|
47 | # to correctly treat things like '?%magic' | |
46 | r'\s*([\w\.]+)' |
|
48 | (.*?$|$) # rest of line | |
47 | r'(\s+.*$|$)') |
|
49 | """, re.VERBOSE) | |
48 |
|
||||
49 | # r'[\w\.]+' |
|
|||
50 | # r'\s*=\s*%.*' |
|
|||
51 |
|
50 | |||
52 | def split_user_input(line, pattern=None): |
|
51 | def split_user_input(line, pattern=None): | |
53 |
"""Split user input into |
|
52 | """Split user input into initial whitespace, escape character, function part | |
54 |
|
53 | and the rest. | ||
55 | This is currently handles lines with '=' in them in a very inconsistent |
|
|||
56 | manner. |
|
|||
57 | """ |
|
54 | """ | |
58 | # We need to ensure that the rest of this routine deals only with unicode |
|
55 | # We need to ensure that the rest of this routine deals only with unicode | |
59 | if type(line)==str: |
|
56 | line = py3compat.cast_unicode(line, sys.stdin.encoding or 'utf-8') | |
60 | codec = sys.stdin.encoding |
|
|||
61 | if codec is None: |
|
|||
62 | codec = 'utf-8' |
|
|||
63 | line = line.decode(codec) |
|
|||
64 |
|
57 | |||
65 | if pattern is None: |
|
58 | if pattern is None: | |
66 | pattern = line_split |
|
59 | pattern = line_split | |
@@ -73,18 +66,73 b' def split_user_input(line, pattern=None):' | |||||
73 | # print "split failed for line '%s'" % line |
|
66 | # print "split failed for line '%s'" % line | |
74 | ifun, the_rest = line, u'' |
|
67 | ifun, the_rest = line, u'' | |
75 | pre = re.match('^(\s*)(.*)',line).groups()[0] |
|
68 | pre = re.match('^(\s*)(.*)',line).groups()[0] | |
|
69 | esc = "" | |||
76 | else: |
|
70 | else: | |
77 | pre,ifun,the_rest = match.groups() |
|
71 | pre, esc, 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'' |
|
|||
87 |
|
72 | |||
88 | #print 'line:<%s>' % line # dbg |
|
73 | #print 'line:<%s>' % line # dbg | |
89 | #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest) # dbg |
|
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 | See test_run for details.""" |
|
3 | See test_run for details.""" | |
4 |
|
4 | |||
|
5 | from __future__ import print_function | |||
|
6 | ||||
5 | import sys |
|
7 | import sys | |
6 |
|
8 | |||
7 | # We want to ensure that while objects remain available for immediate access, |
|
9 | # We want to ensure that while objects remain available for immediate access, | |
@@ -10,10 +12,11 b' import sys' | |||||
10 | class C(object): |
|
12 | class C(object): | |
11 | def __init__(self,name): |
|
13 | def __init__(self,name): | |
12 | self.name = name |
|
14 | self.name = name | |
|
15 | self.p = print | |||
13 | self.flush_stdout = sys.stdout.flush |
|
16 | self.flush_stdout = sys.stdout.flush | |
14 |
|
17 | |||
15 | def __del__(self): |
|
18 | def __del__(self): | |
16 |
|
|
19 | self.p('tclass.py: deleting object:',self.name) | |
17 | self.flush_stdout() |
|
20 | self.flush_stdout() | |
18 |
|
21 | |||
19 | try: |
|
22 | try: | |
@@ -28,5 +31,5 b' else:' | |||||
28 |
|
31 | |||
29 | # This next print statement is NOT debugging, we're making the check on a |
|
32 | # This next print statement is NOT debugging, we're making the check on a | |
30 | # completely separate process so we verify by capturing stdout: |
|
33 | # completely separate process so we verify by capturing stdout: | |
31 |
print |
|
34 | print('ARGV 1-:', sys.argv[1:]) | |
32 | sys.stdout.flush() |
|
35 | sys.stdout.flush() |
@@ -6,6 +6,7 b' import tempfile' | |||||
6 |
|
6 | |||
7 | from IPython.core.application import BaseIPythonApplication |
|
7 | from IPython.core.application import BaseIPythonApplication | |
8 | from IPython.testing import decorators as testdec |
|
8 | from IPython.testing import decorators as testdec | |
|
9 | from IPython.utils import py3compat | |||
9 |
|
10 | |||
10 | @testdec.onlyif_unicode_paths |
|
11 | @testdec.onlyif_unicode_paths | |
11 | def test_unicode_cwd(): |
|
12 | def test_unicode_cwd(): | |
@@ -35,7 +36,7 b' def test_unicode_ipdir():' | |||||
35 |
|
36 | |||
36 | old_ipdir1 = os.environ.pop("IPYTHONDIR", None) |
|
37 | old_ipdir1 = os.environ.pop("IPYTHONDIR", None) | |
37 | old_ipdir2 = os.environ.pop("IPYTHON_DIR", None) |
|
38 | old_ipdir2 = os.environ.pop("IPYTHON_DIR", None) | |
38 |
os.environ["IPYTHONDIR"] = ipdir |
|
39 | os.environ["IPYTHONDIR"] = py3compat.unicode_to_str(ipdir, "utf-8") | |
39 | try: |
|
40 | try: | |
40 | app = BaseIPythonApplication() |
|
41 | app = BaseIPythonApplication() | |
41 | # The lines below are copied from Application.initialize() |
|
42 | # The lines below are copied from Application.initialize() |
@@ -23,6 +23,7 b' import nose.tools as nt' | |||||
23 |
|
23 | |||
24 | # Our own imports |
|
24 | # Our own imports | |
25 | from IPython.core import compilerop |
|
25 | from IPython.core import compilerop | |
|
26 | from IPython.utils import py3compat | |||
26 |
|
27 | |||
27 | #----------------------------------------------------------------------------- |
|
28 | #----------------------------------------------------------------------------- | |
28 | # Test functions |
|
29 | # Test functions | |
@@ -51,7 +52,7 b' def test_cache():' | |||||
51 | def setUp(): |
|
52 | def setUp(): | |
52 | # Check we're in a proper Python 2 environment (some imports, such |
|
53 | # Check we're in a proper Python 2 environment (some imports, such | |
53 | # as GTK, can change the default encoding, which can hide bugs.) |
|
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 | def test_cache_unicode(): |
|
57 | def test_cache_unicode(): | |
57 | cp = compilerop.CachingCompiler() |
|
58 | cp = compilerop.CachingCompiler() |
@@ -10,6 +10,7 b' import nose.tools as nt' | |||||
10 | # our own packages |
|
10 | # our own packages | |
11 | from IPython.core import autocall |
|
11 | from IPython.core import autocall | |
12 | from IPython.testing import decorators as dec |
|
12 | from IPython.testing import decorators as dec | |
|
13 | from IPython.testing import tools as tt | |||
13 | from IPython.testing.globalipapp import get_ipython |
|
14 | from IPython.testing.globalipapp import get_ipython | |
14 |
|
15 | |||
15 | #----------------------------------------------------------------------------- |
|
16 | #----------------------------------------------------------------------------- | |
@@ -40,15 +41,7 b' def run(tests):' | |||||
40 | """Loop through a list of (pre, post) inputs, where pre is the string |
|
41 | """Loop through a list of (pre, post) inputs, where pre is the string | |
41 | handed to ipython, and post is how that string looks after it's been |
|
42 | handed to ipython, and post is how that string looks after it's been | |
42 | transformed (i.e. ipython's notion of _i)""" |
|
43 | transformed (i.e. ipython's notion of _i)""" | |
43 | for pre, post in tests: |
|
44 | tt.check_pairs(ip.prefilter_manager.prefilter_lines, 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)) |
|
|||
52 |
|
45 | |||
53 |
|
46 | |||
54 | def test_handlers(): |
|
47 | def test_handlers(): |
@@ -16,9 +16,10 b' import nose.tools as nt' | |||||
16 | # our own packages |
|
16 | # our own packages | |
17 | from IPython.utils.tempdir import TemporaryDirectory |
|
17 | from IPython.utils.tempdir import TemporaryDirectory | |
18 | from IPython.core.history import HistoryManager, extract_hist_ranges |
|
18 | from IPython.core.history import HistoryManager, extract_hist_ranges | |
|
19 | from IPython.utils import py3compat | |||
19 |
|
20 | |||
20 | def setUp(): |
|
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 | def test_history(): |
|
24 | def test_history(): | |
24 | ip = get_ipython() |
|
25 | ip = get_ipython() |
@@ -125,7 +125,7 b' def test_get_input_encoding():' | |||||
125 | nt.assert_true(isinstance(encoding, basestring)) |
|
125 | nt.assert_true(isinstance(encoding, basestring)) | |
126 | # simple-minded check that at least encoding a simple string works with the |
|
126 | # simple-minded check that at least encoding a simple string works with the | |
127 | # encoding we got. |
|
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 | class NoInputEncodingTestCase(unittest.TestCase): |
|
131 | class NoInputEncodingTestCase(unittest.TestCase): | |
@@ -390,15 +390,6 b' def test_LineInfo():' | |||||
390 | linfo = isp.LineInfo(' %cd /home') |
|
390 | linfo = isp.LineInfo(' %cd /home') | |
391 | nt.assert_equals(str(linfo), 'LineInfo [ |%|cd|/home]') |
|
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 | # Transformer tests |
|
393 | # Transformer tests | |
403 | def transform_checker(tests, func): |
|
394 | def transform_checker(tests, func): | |
404 | """Utility to loop over test inputs""" |
|
395 | """Utility to loop over test inputs""" | |
@@ -611,7 +602,8 b' class IPythonInputTestCase(InputSplitterTestCase):' | |||||
611 |
|
602 | |||
612 | isp.push(raw) |
|
603 | isp.push(raw) | |
613 | out, out_raw = isp.source_raw_reset() |
|
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 | self.assertEqual(out_raw.rstrip(), raw.rstrip()) |
|
607 | self.assertEqual(out_raw.rstrip(), raw.rstrip()) | |
616 |
|
608 | |||
617 | def test_syntax_multiline(self): |
|
609 | def test_syntax_multiline(self): |
@@ -75,7 +75,7 b' Traceback (most recent call last):' | |||||
75 | div0() |
|
75 | div0() | |
76 | ...line 8, in div0 |
|
76 | ...line 8, in div0 | |
77 | x/y |
|
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 | 9 |
|
107 | 9 | |
108 | 10 def sysexit(stat, mode): |
|
108 | 10 def sysexit(stat, mode): | |
109 | <BLANKLINE> |
|
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 | 9 |
|
144 | 9 | |
145 | 10 def sysexit(stat, mode): |
|
145 | 10 def sysexit(stat, mode): | |
146 | <BLANKLINE> |
|
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 | # Our own imports |
|
21 | # Our own imports | |
22 | from .. import oinspect |
|
22 | from .. import oinspect | |
|
23 | from IPython.utils import py3compat | |||
23 |
|
24 | |||
24 | #----------------------------------------------------------------------------- |
|
25 | #----------------------------------------------------------------------------- | |
25 | # Globals and constants |
|
26 | # Globals and constants | |
@@ -96,7 +97,8 b' def test_info():' | |||||
96 | "Check that Inspector.info fills out various fields as expected." |
|
97 | "Check that Inspector.info fills out various fields as expected." | |
97 | i = inspector.info(Call, oname='Call') |
|
98 | i = inspector.info(Call, oname='Call') | |
98 | nt.assert_equal(i['type_name'], 'type') |
|
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 | nt.assert_equal(i['string_form'], "<class 'IPython.core.tests.test_oinspect.Call'>") |
|
102 | nt.assert_equal(i['string_form'], "<class 'IPython.core.tests.test_oinspect.Call'>") | |
101 | fname = __file__ |
|
103 | fname = __file__ | |
102 | if fname.endswith(".pyc"): |
|
104 | if fname.endswith(".pyc"): | |
@@ -125,9 +127,10 b' def test_info():' | |||||
125 | nt.assert_equal(i['call_docstring'], c.__call__.__doc__) |
|
127 | nt.assert_equal(i['call_docstring'], c.__call__.__doc__) | |
126 |
|
128 | |||
127 | # Test old-style classes, which for example may not have an __init__ method. |
|
129 | # Test old-style classes, which for example may not have an __init__ method. | |
128 | i = inspector.info(OldStyle) |
|
130 | if not py3compat.PY3: | |
129 | nt.assert_equal(i['type_name'], 'classobj') |
|
131 | i = inspector.info(OldStyle) | |
130 |
|
132 | nt.assert_equal(i['type_name'], 'classobj') | ||
131 | i = inspector.info(OldStyle()) |
|
133 | ||
132 | nt.assert_equal(i['type_name'], 'instance') |
|
134 | i = inspector.info(OldStyle()) | |
133 |
nt.assert_equal(i[' |
|
135 | nt.assert_equal(i['type_name'], 'instance') | |
|
136 | nt.assert_equal(i['docstring'], OldStyle.__doc__) |
@@ -83,6 +83,11 b' import tokenize' | |||||
83 | import traceback |
|
83 | import traceback | |
84 | import types |
|
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 | # For purposes of monkeypatching inspect to fix a bug in it. |
|
91 | # For purposes of monkeypatching inspect to fix a bug in it. | |
87 | from inspect import getsourcefile, getfile, getmodule,\ |
|
92 | from inspect import getsourcefile, getfile, getmodule,\ | |
88 | ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode |
|
93 | ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode | |
@@ -94,6 +99,7 b' from IPython.core.display_trap import DisplayTrap' | |||||
94 | from IPython.core.excolors import exception_colors |
|
99 | from IPython.core.excolors import exception_colors | |
95 | from IPython.utils import PyColorize |
|
100 | from IPython.utils import PyColorize | |
96 | from IPython.utils import io |
|
101 | from IPython.utils import io | |
|
102 | from IPython.utils import py3compat | |||
97 | from IPython.utils.data import uniq_stable |
|
103 | from IPython.utils.data import uniq_stable | |
98 | from IPython.utils.warn import info, error |
|
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 | # serious refactoring, so that all of the ultratb and PyColorize code |
|
284 | # serious refactoring, so that all of the ultratb and PyColorize code | |
279 | # is unicode-safe. So for now this is rather an ugly hack, but |
|
285 | # is unicode-safe. So for now this is rather an ugly hack, but | |
280 | # necessary to at least have readable tracebacks. Improvements welcome! |
|
286 | # necessary to at least have readable tracebacks. Improvements welcome! | |
281 | if type(line)==unicode: |
|
287 | line = py3compat.cast_bytes_py2(line, 'utf-8') | |
282 | line = line.encode('utf-8', 'replace') |
|
|||
283 |
|
288 | |||
284 | new_line, err = _line_format(line, 'str', scheme) |
|
289 | new_line, err = _line_format(line, 'str', scheme) | |
285 | if not err: line = new_line |
|
290 | if not err: line = new_line | |
@@ -872,7 +877,8 b' class VerboseTB(TBTools):' | |||||
872 | try: |
|
877 | try: | |
873 | # This builds the names list in-place by capturing it from the |
|
878 | # This builds the names list in-place by capturing it from the | |
874 | # enclosing scope. |
|
879 | # enclosing scope. | |
875 |
|
|
880 | for token in generate_tokens(linereader): | |
|
881 | tokeneater(*token) | |||
876 | except IndexError: |
|
882 | except IndexError: | |
877 | # signals exit of tokenizer |
|
883 | # signals exit of tokenizer | |
878 | pass |
|
884 | pass | |
@@ -933,7 +939,7 b' class VerboseTB(TBTools):' | |||||
933 | # ... and format it |
|
939 | # ... and format it | |
934 | exception = ['%s%s%s: %s' % (Colors.excName, etype_str, |
|
940 | exception = ['%s%s%s: %s' % (Colors.excName, etype_str, | |
935 | ColorsNormal, evalue_str)] |
|
941 | ColorsNormal, evalue_str)] | |
936 | if type(evalue) is types.InstanceType: |
|
942 | if (not py3compat.PY3) and type(evalue) is types.InstanceType: | |
937 | try: |
|
943 | try: | |
938 | names = [w for w in dir(evalue) if isinstance(w, basestring)] |
|
944 | names = [w for w in dir(evalue) if isinstance(w, basestring)] | |
939 | except: |
|
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 | #Name: simplegeneric |
|
6 | #Name: simplegeneric | |
2 |
#Version: 0. |
|
7 | #Version: 0.7 | |
3 | #Summary: Simple generic functions (similar to Python's own len(), pickle.dump(), etc.) |
|
8 | #Summary: Simple generic functions (similar to Python's own len(), pickle.dump(), etc.) | |
4 |
#Home-page: http:// |
|
9 | #Home-page: http://pypi.python.org/pypi/simplegeneric | |
5 | #Author: Phillip J. Eby |
|
10 | #Author: Phillip J. Eby | |
6 | #Author-email: peak@eby-sarna.com |
|
11 | #Author-email: peak@eby-sarna.com | |
7 | #License: PSF or ZPL |
|
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 | __all__ = ["generic"] |
|
14 | __all__ = ["generic"] | |
14 |
|
15 | |||
15 |
|
16 | try: | ||
16 | from types import ClassType, InstanceType |
|
17 | from types import ClassType, InstanceType | |
17 | classtypes = type, ClassType |
|
18 | except ImportError: | |
|
19 | classtypes = type | |||
|
20 | else: | |||
|
21 | classtypes = type, ClassType | |||
18 |
|
22 | |||
19 | def generic(func): |
|
23 | def generic(func): | |
20 | """Create a simple generic function""" |
|
24 | """Create a simple generic function""" | |
@@ -30,38 +34,44 b' def generic(func):' | |||||
30 | else: |
|
34 | else: | |
31 | return func(*args, **kw) |
|
35 | return func(*args, **kw) | |
32 |
|
36 | |||
33 |
_by_type = {object: func |
|
37 | _by_type = {object: func} | |
|
38 | try: | |||
|
39 | _by_type[InstanceType] = _by_class | |||
|
40 | except NameError: # Python 3 | |||
|
41 | pass | |||
|
42 | ||||
34 | _gbt = _by_type.get |
|
43 | _gbt = _by_type.get | |
35 |
|
44 | |||
36 | def when_type(t): |
|
45 | def when_type(*types): | |
37 |
"""Decorator to add a method that will be called for t |
|
46 | """Decorator to add a method that will be called for the given types""" | |
38 |
|
|
47 | for t in types: | |
39 | raise TypeError( |
|
48 | if not isinstance(t, classtypes): | |
40 | "%r is not a type or class" % (t,) |
|
|||
41 | ) |
|
|||
42 | def decorate(f): |
|
|||
43 | if _by_type.setdefault(t,f) is not f: |
|
|||
44 | raise TypeError( |
|
49 | raise TypeError( | |
45 |
"%r |
|
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 | return f |
|
58 | return f | |
48 | return decorate |
|
59 | return decorate | |
49 |
|
60 | |||
50 |
|
61 | |||
51 |
|
62 | |||
52 |
|
63 | |||
53 |
|
||||
54 |
|
||||
55 | _by_object = {} |
|
64 | _by_object = {} | |
56 | _gbo = _by_object.get |
|
65 | _gbo = _by_object.get | |
57 |
|
66 | |||
58 | def when_object(o): |
|
67 | def when_object(*obs): | |
59 |
"""Decorator to add a method t |
|
68 | """Decorator to add a method to be called for the given object(s)""" | |
60 | def decorate(f): |
|
69 | def decorate(f): | |
61 | if _by_object.setdefault(id(o), (o,f))[1] is not f: |
|
70 | for o in obs: | |
62 | raise TypeError( |
|
71 | if _by_object.setdefault(id(o), (o,f))[1] is not f: | |
63 | "%r already has method for object %r" % (func, o) |
|
72 | raise TypeError( | |
64 | ) |
|
73 | "%r already has method for object %r" % (func, o) | |
|
74 | ) | |||
65 | return f |
|
75 | return f | |
66 | return decorate |
|
76 | return decorate | |
67 |
|
77 | |||
@@ -78,10 +88,7 b' def generic(func):' | |||||
78 | else: |
|
88 | else: | |
79 | return f[1](*args, **kw) |
|
89 | return f[1](*args, **kw) | |
80 |
|
90 | |||
81 | try: |
|
91 | dispatch.__name__ = func.__name__ | |
82 | dispatch.__name__ = func.__name__ |
|
|||
83 | except TypeError: |
|
|||
84 | pass |
|
|||
85 | dispatch.__dict__ = func.__dict__.copy() |
|
92 | dispatch.__dict__ = func.__dict__.copy() | |
86 | dispatch.__doc__ = func.__doc__ |
|
93 | dispatch.__doc__ = func.__doc__ | |
87 | dispatch.__module__ = func.__module__ |
|
94 | dispatch.__module__ = func.__module__ | |
@@ -94,46 +101,9 b' def generic(func):' | |||||
94 | return dispatch |
|
101 | return dispatch | |
95 |
|
102 | |||
96 |
|
103 | |||
97 |
|
||||
98 |
|
||||
99 | def test_suite(): |
|
104 | def test_suite(): | |
100 | import doctest |
|
105 | import doctest | |
101 | return doctest.DocFileSuite( |
|
106 | return doctest.DocFileSuite( | |
102 | 'README.txt', |
|
107 | 'README.txt', | |
103 | optionflags=doctest.ELLIPSIS|doctest.REPORT_ONLY_FIRST_FAILURE, |
|
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 | self._append_html(self._make_out_prompt(prompt_number), True) |
|
83 | self._append_html(self._make_out_prompt(prompt_number), True) | |
84 | # This helps the output to look nice. |
|
84 | # This helps the output to look nice. | |
85 | self._append_plain_text('\n', True) |
|
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 | self._append_html(self.output_sep2, True) |
|
87 | self._append_html(self.output_sep2, True) | |
88 | else: |
|
88 | else: | |
89 | # Default back to the plain text representation. |
|
89 | # Default back to the plain text representation. | |
@@ -104,7 +104,7 b' class RichIPythonWidget(IPythonWidget):' | |||||
104 | elif data.has_key('image/png'): |
|
104 | elif data.has_key('image/png'): | |
105 | # PNG data is base64 encoded as it passes over the network |
|
105 | # PNG data is base64 encoded as it passes over the network | |
106 | # in a JSON structure so we decode it. |
|
106 | # in a JSON structure so we decode it. | |
107 | png = decodestring(data['image/png']) |
|
107 | png = decodestring(data['image/png'].encode('ascii')) | |
108 | self._append_png(png, True) |
|
108 | self._append_png(png, True) | |
109 | else: |
|
109 | else: | |
110 | # Default back to the plain text representation. |
|
110 | # Default back to the plain text representation. |
@@ -26,7 +26,10 b' from __future__ import with_statement' | |||||
26 | import __main__ |
|
26 | import __main__ | |
27 |
|
27 | |||
28 | import sys |
|
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 | from IPython.core import ultratb |
|
34 | from IPython.core import ultratb | |
32 | from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell |
|
35 | from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell |
@@ -16,17 +16,22 b'' | |||||
16 |
|
16 | |||
17 | import __builtin__ |
|
17 | import __builtin__ | |
18 | import bdb |
|
18 | import bdb | |
19 | from contextlib import nested |
|
|||
20 | import os |
|
19 | import os | |
21 | import re |
|
20 | import re | |
22 | import sys |
|
21 | import sys | |
23 |
|
22 | |||
|
23 | try: | |||
|
24 | from contextlib import nested | |||
|
25 | except: | |||
|
26 | from IPython.utils.nested_context import nested | |||
|
27 | ||||
24 | from IPython.core.error import TryNext |
|
28 | from IPython.core.error import TryNext | |
25 | from IPython.core.usage import interactive_usage, default_banner |
|
29 | from IPython.core.usage import interactive_usage, default_banner | |
26 | from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC |
|
30 | from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC | |
27 | from IPython.lib.inputhook import enable_gui |
|
31 | from IPython.lib.inputhook import enable_gui | |
28 | from IPython.lib.pylabtools import pylab_activate |
|
32 | from IPython.lib.pylabtools import pylab_activate | |
29 | from IPython.testing.skipdoctest import skip_doctest |
|
33 | from IPython.testing.skipdoctest import skip_doctest | |
|
34 | from IPython.utils import py3compat | |||
30 | from IPython.utils.terminal import toggle_set_term_title, set_term_title |
|
35 | from IPython.utils.terminal import toggle_set_term_title, set_term_title | |
31 | from IPython.utils.process import abbrev_cwd |
|
36 | from IPython.utils.process import abbrev_cwd | |
32 | from IPython.utils.warn import warn |
|
37 | from IPython.utils.warn import warn | |
@@ -332,7 +337,7 b' class TerminalInteractiveShell(InteractiveShell):' | |||||
332 | self.set_readline_completer() |
|
337 | self.set_readline_completer() | |
333 |
|
338 | |||
334 | try: |
|
339 | try: | |
335 |
line = self.raw_input_original(prompt) |
|
340 | line = py3compat.str_to_unicode(self.raw_input_original(prompt)) | |
336 | except ValueError: |
|
341 | except ValueError: | |
337 | warn("\n********\nYou or a %run:ed script called sys.stdin.close()" |
|
342 | warn("\n********\nYou or a %run:ed script called sys.stdin.close()" | |
338 | " or sys.stdout.close()!\nExiting IPython!") |
|
343 | " or sys.stdout.close()!\nExiting IPython!") |
@@ -159,7 +159,10 b' def deep_reload_hook(module):' | |||||
159 | return import_module(name[i+1:], name, parent) |
|
159 | return import_module(name[i+1:], name, parent) | |
160 |
|
160 | |||
161 | # Save the original hooks |
|
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 | # Replacement for reload() |
|
167 | # Replacement for reload() | |
165 | def reload(module, exclude=['sys', '__builtin__', '__main__']): |
|
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 | import os |
|
172 | import os | |
174 | import re |
|
173 | import re | |
175 | import shlex |
|
174 | import shlex | |
@@ -182,7 +181,7 b' from IPython.utils.text import marquee' | |||||
182 |
|
181 | |||
183 | __all__ = ['Demo','IPythonDemo','LineDemo','IPythonLineDemo','DemoError'] |
|
182 | __all__ = ['Demo','IPythonDemo','LineDemo','IPythonLineDemo','DemoError'] | |
184 |
|
183 | |||
185 |
class DemoError( |
|
184 | class DemoError(Exception): pass | |
186 |
|
185 | |||
187 | def re_mark(mark): |
|
186 | def re_mark(mark): | |
188 | return re.compile(r'^\s*#\s+<demo>\s+%s\s*$' % mark,re.MULTILINE) |
|
187 | return re.compile(r'^\s*#\s+<demo>\s+%s\s*$' % mark,re.MULTILINE) |
@@ -454,8 +454,10 b' class GroupQueue(object):' | |||||
454 | except ValueError: |
|
454 | except ValueError: | |
455 | pass |
|
455 | pass | |
456 |
|
456 | |||
457 |
|
457 | try: | ||
458 | _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__) |
|
458 | _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__) | |
|
459 | except AttributeError: # Python 3 | |||
|
460 | _baseclass_reprs = (object.__repr__,) | |||
459 |
|
461 | |||
460 |
|
462 | |||
461 | def _default_pprint(obj, p, cycle): |
|
463 | def _default_pprint(obj, p, cycle): | |
@@ -648,23 +650,33 b' _type_pprinters = {' | |||||
648 | tuple: _seq_pprinter_factory('(', ')', tuple), |
|
650 | tuple: _seq_pprinter_factory('(', ')', tuple), | |
649 | list: _seq_pprinter_factory('[', ']', list), |
|
651 | list: _seq_pprinter_factory('[', ']', list), | |
650 | dict: _dict_pprinter_factory('{', '}', dict), |
|
652 | dict: _dict_pprinter_factory('{', '}', dict), | |
651 | types.DictProxyType: _dict_pprinter_factory('<dictproxy {', '}>'), |
|
653 | ||
652 | set: _seq_pprinter_factory('set([', '])', set), |
|
654 | set: _seq_pprinter_factory('set([', '])', set), | |
653 | frozenset: _seq_pprinter_factory('frozenset([', '])', frozenset), |
|
655 | frozenset: _seq_pprinter_factory('frozenset([', '])', frozenset), | |
654 | super: _super_pprint, |
|
656 | super: _super_pprint, | |
655 | _re_pattern_type: _re_pattern_pprint, |
|
657 | _re_pattern_type: _re_pattern_pprint, | |
656 | type: _type_pprint, |
|
658 | type: _type_pprint, | |
657 | types.ClassType: _type_pprint, |
|
|||
658 | types.FunctionType: _function_pprint, |
|
659 | types.FunctionType: _function_pprint, | |
659 | types.BuiltinFunctionType: _function_pprint, |
|
660 | types.BuiltinFunctionType: _function_pprint, | |
660 | types.SliceType: _repr_pprint, |
|
661 | types.SliceType: _repr_pprint, | |
661 | types.MethodType: _repr_pprint, |
|
662 | types.MethodType: _repr_pprint, | |
662 | xrange: _repr_pprint, |
|
663 | ||
663 | datetime.datetime: _repr_pprint, |
|
664 | datetime.datetime: _repr_pprint, | |
664 | datetime.timedelta: _repr_pprint, |
|
665 | datetime.timedelta: _repr_pprint, | |
665 | _exception_base: _exception_pprint |
|
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 | #: printers for types specified by name |
|
680 | #: printers for types specified by name | |
669 | _deferred_type_pprinters = { |
|
681 | _deferred_type_pprinters = { | |
670 | } |
|
682 | } |
@@ -19,7 +19,7 b' Authors' | |||||
19 | # Imports |
|
19 | # Imports | |
20 | #----------------------------------------------------------------------------- |
|
20 | #----------------------------------------------------------------------------- | |
21 |
|
21 | |||
22 |
from |
|
22 | from io import BytesIO | |
23 |
|
23 | |||
24 | from IPython.utils.decorators import flag_calls |
|
24 | from IPython.utils.decorators import flag_calls | |
25 |
|
25 | |||
@@ -99,11 +99,11 b" def print_figure(fig, fmt='png'):" | |||||
99 | fig.set_facecolor('white') |
|
99 | fig.set_facecolor('white') | |
100 | fig.set_edgecolor('white') |
|
100 | fig.set_edgecolor('white') | |
101 | try: |
|
101 | try: | |
102 |
s |
|
102 | bytes_io = BytesIO() | |
103 | # use 72 dpi to match QTConsole's dpi |
|
103 | # use 72 dpi to match QTConsole's dpi | |
104 |
fig.canvas.print_figure(s |
|
104 | fig.canvas.print_figure(bytes_io, format=fmt, dpi=72, | |
105 | bbox_inches='tight') |
|
105 | bbox_inches='tight') | |
106 |
data = s |
|
106 | data = bytes_io.getvalue() | |
107 | finally: |
|
107 | finally: | |
108 | fig.set_facecolor(fc) |
|
108 | fig.set_facecolor(fc) | |
109 | fig.set_edgecolor(ec) |
|
109 | fig.set_edgecolor(ec) |
@@ -370,7 +370,7 b' class Client(HasTraits):' | |||||
370 | self.session = Session(**extra_args) |
|
370 | self.session = Session(**extra_args) | |
371 |
|
371 | |||
372 | self._query_socket = self._context.socket(zmq.DEALER) |
|
372 | self._query_socket = self._context.socket(zmq.DEALER) | |
373 |
self._query_socket.setsockopt(zmq.IDENTITY, |
|
373 | self._query_socket.setsockopt(zmq.IDENTITY, self.session.bsession) | |
374 | if self._ssh: |
|
374 | if self._ssh: | |
375 | tunnel.tunnel_connection(self._query_socket, url, sshserver, **ssh_kwargs) |
|
375 | tunnel.tunnel_connection(self._query_socket, url, sshserver, **ssh_kwargs) | |
376 | else: |
|
376 | else: | |
@@ -496,7 +496,7 b' class Client(HasTraits):' | |||||
496 | content = msg.content |
|
496 | content = msg.content | |
497 | self._config['registration'] = dict(content) |
|
497 | self._config['registration'] = dict(content) | |
498 | if content.status == 'ok': |
|
498 | if content.status == 'ok': | |
499 |
ident = |
|
499 | ident = self.session.bsession | |
500 | if content.mux: |
|
500 | if content.mux: | |
501 | self._mux_socket = self._context.socket(zmq.DEALER) |
|
501 | self._mux_socket = self._context.socket(zmq.DEALER) | |
502 | self._mux_socket.setsockopt(zmq.IDENTITY, ident) |
|
502 | self._mux_socket.setsockopt(zmq.IDENTITY, ident) | |
@@ -512,7 +512,7 b' class Client(HasTraits):' | |||||
512 | self._notification_socket.setsockopt(zmq.SUBSCRIBE, b'') |
|
512 | self._notification_socket.setsockopt(zmq.SUBSCRIBE, b'') | |
513 | # if content.query: |
|
513 | # if content.query: | |
514 | # self._query_socket = self._context.socket(zmq.DEALER) |
|
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 | # connect_socket(self._query_socket, content.query) |
|
516 | # connect_socket(self._query_socket, content.query) | |
517 | if content.control: |
|
517 | if content.control: | |
518 | self._control_socket = self._context.socket(zmq.DEALER) |
|
518 | self._control_socket = self._context.socket(zmq.DEALER) |
@@ -16,6 +16,7 b' from types import ModuleType' | |||||
16 | from IPython.parallel.client.asyncresult import AsyncResult |
|
16 | from IPython.parallel.client.asyncresult import AsyncResult | |
17 | from IPython.parallel.error import UnmetDependency |
|
17 | from IPython.parallel.error import UnmetDependency | |
18 | from IPython.parallel.util import interactive |
|
18 | from IPython.parallel.util import interactive | |
|
19 | from IPython.utils import py3compat | |||
19 |
|
20 | |||
20 | class depend(object): |
|
21 | class depend(object): | |
21 | """Dependency decorator, for use with tasks. |
|
22 | """Dependency decorator, for use with tasks. | |
@@ -65,9 +66,10 b' class dependent(object):' | |||||
65 | raise UnmetDependency() |
|
66 | raise UnmetDependency() | |
66 | return self.f(*args, **kwargs) |
|
67 | return self.f(*args, **kwargs) | |
67 |
|
68 | |||
68 | @property |
|
69 | if not py3compat.PY3: | |
69 | def __name__(self): |
|
70 | @property | |
70 | return self.func_name |
|
71 | def __name__(self): | |
|
72 | return self.func_name | |||
71 |
|
73 | |||
72 | @interactive |
|
74 | @interactive | |
73 | def _require(*names): |
|
75 | def _require(*names): |
@@ -288,7 +288,7 b' class HubFactory(RegistrationFactory):' | |||||
288 | # resubmit stream |
|
288 | # resubmit stream | |
289 | r = ZMQStream(ctx.socket(zmq.DEALER), loop) |
|
289 | r = ZMQStream(ctx.socket(zmq.DEALER), loop) | |
290 | url = util.disambiguate_url(self.client_info['task'][-1]) |
|
290 | url = util.disambiguate_url(self.client_info['task'][-1]) | |
291 |
r.setsockopt(zmq.IDENTITY, |
|
291 | r.setsockopt(zmq.IDENTITY, self.session.bsession) | |
292 | r.connect(url) |
|
292 | r.connect(url) | |
293 |
|
293 | |||
294 | self.hub = Hub(loop=loop, session=self.session, monitor=sub, heartmonitor=self.heartmonitor, |
|
294 | self.hub = Hub(loop=loop, session=self.session, monitor=sub, heartmonitor=self.heartmonitor, |
@@ -177,7 +177,7 b' class TaskScheduler(SessionFactory):' | |||||
177 | ident = CBytes() # ZMQ identity. This should just be self.session.session |
|
177 | ident = CBytes() # ZMQ identity. This should just be self.session.session | |
178 | # but ensure Bytes |
|
178 | # but ensure Bytes | |
179 | def _ident_default(self): |
|
179 | def _ident_default(self): | |
180 |
return |
|
180 | return self.session.bsession | |
181 |
|
181 | |||
182 | def start(self): |
|
182 | def start(self): | |
183 | self.engine_stream.on_recv(self.dispatch_result, copy=False) |
|
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 | # stdlib |
|
22 | # stdlib | |
23 | import __builtin__ |
|
23 | import __builtin__ as builtin_mod | |
24 | import os |
|
24 | import os | |
25 | import sys |
|
25 | import sys | |
26 | from types import MethodType |
|
|||
27 |
|
26 | |||
28 | # our own |
|
27 | # our own | |
29 | from . import tools |
|
28 | from . import tools | |
30 |
|
29 | |||
31 | from IPython.utils import io |
|
30 | from IPython.utils import io | |
|
31 | from IPython.utils import py3compat | |||
32 | from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell |
|
32 | from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell | |
33 |
|
33 | |||
34 | #----------------------------------------------------------------------------- |
|
34 | #----------------------------------------------------------------------------- | |
@@ -131,7 +131,7 b' class ipnsdict(dict):' | |||||
131 | # aggressive low-level cleaning of the execution namespace, we need to |
|
131 | # aggressive low-level cleaning of the execution namespace, we need to | |
132 | # correct for that ourselves, to ensure consitency with the 'real' |
|
132 | # correct for that ourselves, to ensure consitency with the 'real' | |
133 | # ipython. |
|
133 | # ipython. | |
134 |
self['__builtins__'] = |
|
134 | self['__builtins__'] = builtin_mod | |
135 |
|
135 | |||
136 | def __delitem__(self, key): |
|
136 | def __delitem__(self, key): | |
137 | """Part of the test suite checks that we can release all |
|
137 | """Part of the test suite checks that we can release all | |
@@ -204,11 +204,10 b' def start_ipython():' | |||||
204 | # Modify the IPython system call with one that uses getoutput, so that we |
|
204 | # Modify the IPython system call with one that uses getoutput, so that we | |
205 | # can capture subcommands and print them to Python's stdout, otherwise the |
|
205 | # can capture subcommands and print them to Python's stdout, otherwise the | |
206 | # doctest machinery would miss them. |
|
206 | # doctest machinery would miss them. | |
207 |
shell.system = MethodType(xsys, shell |
|
207 | shell.system = py3compat.MethodType(xsys, shell) | |
208 |
|
208 | |||
209 |
|
209 | |||
210 |
shell._showtraceback = MethodType(_showtraceback, shell |
|
210 | shell._showtraceback = py3compat.MethodType(_showtraceback, shell) | |
211 | TerminalInteractiveShell) |
|
|||
212 |
|
211 | |||
213 | # IPython is ready, now clean up some global state... |
|
212 | # IPython is ready, now clean up some global state... | |
214 |
|
213 | |||
@@ -223,8 +222,8 b' def start_ipython():' | |||||
223 | # now return this without recursively calling here again. |
|
222 | # now return this without recursively calling here again. | |
224 | _ip = shell |
|
223 | _ip = shell | |
225 | get_ipython = _ip.get_ipython |
|
224 | get_ipython = _ip.get_ipython | |
226 |
|
|
225 | builtin_mod._ip = _ip | |
227 |
|
|
226 | builtin_mod.get_ipython = get_ipython | |
228 |
|
227 | |||
229 | # To avoid extra IPython messages during testing, suppress io.stdout/stderr |
|
228 | # To avoid extra IPython messages during testing, suppress io.stdout/stderr | |
230 | io.stdout = StreamProxy('stdout') |
|
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 | import unittest |
|
19 | import unittest | |
|
20 | import sys | |||
20 | import nose.loader |
|
21 | import nose.loader | |
21 | from inspect import ismethod, isfunction |
|
22 | from inspect import ismethod, isfunction | |
22 |
|
23 | |||
@@ -64,5 +65,7 b' def getTestCaseNames(self, testCaseClass):' | |||||
64 |
|
65 | |||
65 | ########################################################################## |
|
66 | ########################################################################## | |
66 | # Apply monkeypatch here |
|
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 | # delete it. I have no clue why |
|
295 | # delete it. I have no clue why | |
296 | pass |
|
296 | pass | |
297 |
|
297 | |||
298 |
pair_fail_msg = ("Testing |
|
298 | pair_fail_msg = ("Testing {0}\n\n" | |
299 | "In:\n" |
|
299 | "In:\n" | |
300 | " {1!r}\n" |
|
300 | " {1!r}\n" | |
301 | "Expected:\n" |
|
301 | "Expected:\n" | |
@@ -318,9 +318,10 b' def check_pairs(func, pairs):' | |||||
318 | None. Raises an AssertionError if any output does not match the expected |
|
318 | None. Raises an AssertionError if any output does not match the expected | |
319 | value. |
|
319 | value. | |
320 | """ |
|
320 | """ | |
|
321 | name = getattr(func, "func_name", getattr(func, "__name__", "<unknown>")) | |||
321 | for inp, expected in pairs: |
|
322 | for inp, expected in pairs: | |
322 | out = func(inp) |
|
323 | out = func(inp) | |
323 |
assert out == expected, pair_fail_msg.format( |
|
324 | assert out == expected, pair_fail_msg.format(name, inp, expected, out) | |
324 |
|
325 | |||
325 | @contextmanager |
|
326 | @contextmanager | |
326 | def mute_warn(): |
|
327 | def mute_warn(): | |
@@ -342,4 +343,3 b' def make_tempfile(name):' | |||||
342 | yield |
|
343 | yield | |
343 | finally: |
|
344 | finally: | |
344 | os.unlink(name) |
|
345 | os.unlink(name) | |
345 |
|
@@ -42,6 +42,13 b' import sys' | |||||
42 | import token |
|
42 | import token | |
43 | import tokenize |
|
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 | from IPython.utils.coloransi import * |
|
52 | from IPython.utils.coloransi import * | |
46 |
|
53 | |||
47 | ############################################################################# |
|
54 | ############################################################################# | |
@@ -177,10 +184,11 b' class Parser:' | |||||
177 |
|
184 | |||
178 | error = False |
|
185 | error = False | |
179 | try: |
|
186 | try: | |
180 |
|
|
187 | for atoken in generate_tokens(text.readline): | |
181 | except tokenize.TokenError, ex: |
|
188 | self(*atoken) | |
182 | msg = ex[0] |
|
189 | except tokenize.TokenError as ex: | |
183 |
|
|
190 | msg = ex.args[0] | |
|
191 | line = ex.args[1][0] | |||
184 | self.out.write("%s\n\n*** ERROR: %s%s%s\n" % |
|
192 | self.out.write("%s\n\n*** ERROR: %s%s%s\n" % | |
185 | (colors[token.ERRORTOKEN], |
|
193 | (colors[token.ERRORTOKEN], | |
186 | msg, self.raw[self.lines[line]:], |
|
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 | import subprocess |
|
17 | import subprocess | |
18 | import sys |
|
18 | import sys | |
19 |
|
19 | |||
|
20 | from IPython.utils import py3compat | |||
|
21 | ||||
20 | #----------------------------------------------------------------------------- |
|
22 | #----------------------------------------------------------------------------- | |
21 | # Function definitions |
|
23 | # Function definitions | |
22 | #----------------------------------------------------------------------------- |
|
24 | #----------------------------------------------------------------------------- | |
@@ -116,8 +118,8 b' def getoutput(cmd):' | |||||
116 |
|
118 | |||
117 | out = process_handler(cmd, lambda p: p.communicate()[0], subprocess.STDOUT) |
|
119 | out = process_handler(cmd, lambda p: p.communicate()[0], subprocess.STDOUT) | |
118 | if out is None: |
|
120 | if out is None: | |
119 |
|
|
121 | return '' | |
120 | return out |
|
122 | return py3compat.bytes_to_str(out) | |
121 |
|
123 | |||
122 |
|
124 | |||
123 | def getoutputerror(cmd): |
|
125 | def getoutputerror(cmd): | |
@@ -138,5 +140,6 b' def getoutputerror(cmd):' | |||||
138 |
|
140 | |||
139 | out_err = process_handler(cmd, lambda p: p.communicate()) |
|
141 | out_err = process_handler(cmd, lambda p: p.communicate()) | |
140 | if out_err is None: |
|
142 | if out_err is None: | |
141 |
|
|
143 | return '', '' | |
142 |
|
|
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 | # Inspired by: |
|
103 | # Inspired by: | |
104 | # http://mail.python.org/pipermail/python-list/2007-May/442737.html |
|
104 | # http://mail.python.org/pipermail/python-list/2007-May/442737.html | |
105 |
|
105 | |||
106 |
def __init__(self, file_or_name, mode= |
|
106 | def __init__(self, file_or_name, mode="w", channel='stdout'): | |
107 | """Construct a new Tee object. |
|
107 | """Construct a new Tee object. | |
108 |
|
108 | |||
109 | Parameters |
|
109 | Parameters | |
@@ -119,7 +119,7 b' class Tee(object):' | |||||
119 | if channel not in ['stdout', 'stderr']: |
|
119 | if channel not in ['stdout', 'stderr']: | |
120 | raise ValueError('Invalid channel spec %s' % channel) |
|
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 | self.file = file_or_name |
|
123 | self.file = file_or_name | |
124 | else: |
|
124 | else: | |
125 | self.file = open(file_or_name, mode) |
|
125 | self.file = open(file_or_name, mode) |
@@ -16,6 +16,9 b' import sys' | |||||
16 | import types |
|
16 | import types | |
17 | from datetime import datetime |
|
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 | # Globals and constants |
|
23 | # Globals and constants | |
21 | #----------------------------------------------------------------------------- |
|
24 | #----------------------------------------------------------------------------- | |
@@ -134,7 +137,7 b' def json_clean(obj):' | |||||
134 | return obj.decode(sys.getdefaultencoding(), 'replace') |
|
137 | return obj.decode(sys.getdefaultencoding(), 'replace') | |
135 |
|
138 | |||
136 | if isinstance(obj, container_to_list) or ( |
|
139 | if isinstance(obj, container_to_list) or ( | |
137 |
hasattr(obj, '__iter__') and hasattr(obj, |
|
140 | hasattr(obj, '__iter__') and hasattr(obj, next_attr_name)): | |
138 | obj = list(obj) |
|
141 | obj = list(obj) | |
139 |
|
142 | |||
140 | if isinstance(obj, list): |
|
143 | if isinstance(obj, list): |
@@ -23,6 +23,7 b' import IPython' | |||||
23 | from IPython.utils import warn |
|
23 | from IPython.utils import warn | |
24 | from IPython.utils.process import system |
|
24 | from IPython.utils.process import system | |
25 | from IPython.utils.importstring import import_item |
|
25 | from IPython.utils.importstring import import_item | |
|
26 | from IPython.utils import py3compat | |||
26 |
|
27 | |||
27 | #----------------------------------------------------------------------------- |
|
28 | #----------------------------------------------------------------------------- | |
28 | # Code |
|
29 | # Code | |
@@ -30,14 +31,6 b' from IPython.utils.importstring import import_item' | |||||
30 |
|
31 | |||
31 | fs_encoding = sys.getfilesystemencoding() |
|
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 | def _get_long_path_name(path): |
|
34 | def _get_long_path_name(path): | |
42 | """Dummy no-op.""" |
|
35 | """Dummy no-op.""" | |
43 | return path |
|
36 | return path | |
@@ -203,7 +196,7 b' def get_home_dir():' | |||||
203 | root=os.path.abspath(root).rstrip('\\') |
|
196 | root=os.path.abspath(root).rstrip('\\') | |
204 | if _writable_dir(os.path.join(root, '_ipython')): |
|
197 | if _writable_dir(os.path.join(root, '_ipython')): | |
205 | os.environ["IPYKITROOT"] = root |
|
198 | os.environ["IPYKITROOT"] = root | |
206 |
return |
|
199 | return py3compat.cast_unicode(root, fs_encoding) | |
207 |
|
200 | |||
208 | if os.name == 'posix': |
|
201 | if os.name == 'posix': | |
209 | # Linux, Unix, AIX, OS X |
|
202 | # Linux, Unix, AIX, OS X | |
@@ -218,11 +211,11 b' def get_home_dir():' | |||||
218 | homedir = Popen('echo $HOME', shell=True, |
|
211 | homedir = Popen('echo $HOME', shell=True, | |
219 | stdout=PIPE).communicate()[0].strip() |
|
212 | stdout=PIPE).communicate()[0].strip() | |
220 | if homedir: |
|
213 | if homedir: | |
221 |
return |
|
214 | return py3compat.cast_unicode(homedir, fs_encoding) | |
222 | else: |
|
215 | else: | |
223 | raise HomeDirError('Undefined $HOME, IPython cannot proceed.') |
|
216 | raise HomeDirError('Undefined $HOME, IPython cannot proceed.') | |
224 | else: |
|
217 | else: | |
225 |
return |
|
218 | return py3compat.cast_unicode(homedir, fs_encoding) | |
226 | elif os.name == 'nt': |
|
219 | elif os.name == 'nt': | |
227 | # Now for win9x, XP, Vista, 7? |
|
220 | # Now for win9x, XP, Vista, 7? | |
228 | # For some strange reason all of these return 'nt' for os.name. |
|
221 | # For some strange reason all of these return 'nt' for os.name. | |
@@ -236,7 +229,7 b' def get_home_dir():' | |||||
236 | pass |
|
229 | pass | |
237 | else: |
|
230 | else: | |
238 | if _writable_dir(homedir): |
|
231 | if _writable_dir(homedir): | |
239 |
return |
|
232 | return py3compat.cast_unicode(homedir, fs_encoding) | |
240 |
|
233 | |||
241 | # Now look for a local home directory |
|
234 | # Now look for a local home directory | |
242 | try: |
|
235 | try: | |
@@ -245,7 +238,7 b' def get_home_dir():' | |||||
245 | pass |
|
238 | pass | |
246 | else: |
|
239 | else: | |
247 | if _writable_dir(homedir): |
|
240 | if _writable_dir(homedir): | |
248 |
return |
|
241 | return py3compat.cast_unicode(homedir, fs_encoding) | |
249 |
|
242 | |||
250 | # Now the users profile directory |
|
243 | # Now the users profile directory | |
251 | try: |
|
244 | try: | |
@@ -254,7 +247,7 b' def get_home_dir():' | |||||
254 | pass |
|
247 | pass | |
255 | else: |
|
248 | else: | |
256 | if _writable_dir(homedir): |
|
249 | if _writable_dir(homedir): | |
257 |
return |
|
250 | return py3compat.cast_unicode(homedir, fs_encoding) | |
258 |
|
251 | |||
259 | # Use the registry to get the 'My Documents' folder. |
|
252 | # Use the registry to get the 'My Documents' folder. | |
260 | try: |
|
253 | try: | |
@@ -269,7 +262,7 b' def get_home_dir():' | |||||
269 | pass |
|
262 | pass | |
270 | else: |
|
263 | else: | |
271 | if _writable_dir(homedir): |
|
264 | if _writable_dir(homedir): | |
272 |
return |
|
265 | return py3compat.cast_unicode(homedir, fs_encoding) | |
273 |
|
266 | |||
274 | # A user with a lot of unix tools in win32 may have defined $HOME. |
|
267 | # A user with a lot of unix tools in win32 may have defined $HOME. | |
275 | # Try this as a last ditch option. |
|
268 | # Try this as a last ditch option. | |
@@ -279,7 +272,7 b' def get_home_dir():' | |||||
279 | pass |
|
272 | pass | |
280 | else: |
|
273 | else: | |
281 | if _writable_dir(homedir): |
|
274 | if _writable_dir(homedir): | |
282 |
return |
|
275 | return py3compat.cast_unicode(homedir, fs_encoding) | |
283 |
|
276 | |||
284 | # If all else fails, raise HomeDirError |
|
277 | # If all else fails, raise HomeDirError | |
285 | raise HomeDirError('No valid home directory could be found') |
|
278 | raise HomeDirError('No valid home directory could be found') | |
@@ -302,7 +295,7 b' def get_xdg_dir():' | |||||
302 | # use ~/.config if not set OR empty |
|
295 | # use ~/.config if not set OR empty | |
303 | xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config') |
|
296 | xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config') | |
304 | if xdg and _writable_dir(xdg): |
|
297 | if xdg and _writable_dir(xdg): | |
305 |
return |
|
298 | return py3compat.cast_unicode(xdg, fs_encoding) | |
306 |
|
299 | |||
307 | return None |
|
300 | return None | |
308 |
|
301 | |||
@@ -311,7 +304,7 b' def get_ipython_dir():' | |||||
311 | """Get the IPython directory for this platform and user. |
|
304 | """Get the IPython directory for this platform and user. | |
312 |
|
305 | |||
313 | This uses the logic in `get_home_dir` to find the home directory |
|
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 | env = os.environ |
|
310 | env = os.environ | |
@@ -356,13 +349,13 b' def get_ipython_dir():' | |||||
356 | " using a temp directory."%parent) |
|
349 | " using a temp directory."%parent) | |
357 | ipdir = tempfile.mkdtemp() |
|
350 | ipdir = tempfile.mkdtemp() | |
358 |
|
351 | |||
359 |
return |
|
352 | return py3compat.cast_unicode(ipdir, fs_encoding) | |
360 |
|
353 | |||
361 |
|
354 | |||
362 | def get_ipython_package_dir(): |
|
355 | def get_ipython_package_dir(): | |
363 | """Get the base directory where IPython itself is installed.""" |
|
356 | """Get the base directory where IPython itself is installed.""" | |
364 | ipdir = os.path.dirname(IPython.__file__) |
|
357 | ipdir = os.path.dirname(IPython.__file__) | |
365 |
return |
|
358 | return py3compat.cast_unicode(ipdir, fs_encoding) | |
366 |
|
359 | |||
367 |
|
360 | |||
368 | def get_ipython_module_path(module_str): |
|
361 | def get_ipython_module_path(module_str): | |
@@ -377,7 +370,7 b' def get_ipython_module_path(module_str):' | |||||
377 | mod = import_item(module_str) |
|
370 | mod = import_item(module_str) | |
378 | the_path = mod.__file__.replace('.pyc', '.py') |
|
371 | the_path = mod.__file__.replace('.pyc', '.py') | |
379 | the_path = the_path.replace('.pyo', '.py') |
|
372 | the_path = the_path.replace('.pyo', '.py') | |
380 |
return |
|
373 | return py3compat.cast_unicode(the_path, fs_encoding) | |
381 |
|
374 | |||
382 |
|
375 | |||
383 | def expand_path(s): |
|
376 | def expand_path(s): | |
@@ -442,7 +435,7 b' def filehash(path):' | |||||
442 | """Make an MD5 hash of a file, ignoring any differences in line |
|
435 | """Make an MD5 hash of a file, ignoring any differences in line | |
443 | ending characters.""" |
|
436 | ending characters.""" | |
444 | with open(path, "rU") as f: |
|
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 | # If the config is unmodified from the default, we'll just delete it. |
|
440 | # If the config is unmodified from the default, we'll just delete it. | |
448 | # These are consistent for 0.10.x, thankfully. We're not going to worry about |
|
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 | from IPython.external.path import path as Path |
|
36 | from IPython.external.path import path as Path | |
37 | import os,stat,time |
|
37 | import os,stat,time | |
|
38 | import collections | |||
38 | import cPickle as pickle |
|
39 | import cPickle as pickle | |
39 | import UserDict |
|
|||
40 | import glob |
|
40 | import glob | |
41 |
|
41 | |||
42 | def gethashfile(key): |
|
42 | def gethashfile(key): | |
@@ -44,7 +44,7 b' def gethashfile(key):' | |||||
44 |
|
44 | |||
45 | _sentinel = object() |
|
45 | _sentinel = object() | |
46 |
|
46 | |||
47 |
class PickleShareDB( |
|
47 | class PickleShareDB(collections.MutableMapping): | |
48 | """ The main 'connection' object for PickleShare database """ |
|
48 | """ The main 'connection' object for PickleShare database """ | |
49 | def __init__(self,root): |
|
49 | def __init__(self,root): | |
50 | """ Return a db object that will manage the specied directory""" |
|
50 | """ Return a db object that will manage the specied directory""" | |
@@ -187,6 +187,12 b' class PickleShareDB(UserDict.DictMixin):' | |||||
187 | else: |
|
187 | else: | |
188 | files = [Path(p) for p in glob.glob(self.root/globpat)] |
|
188 | files = [Path(p) for p in glob.glob(self.root/globpat)] | |
189 | return [self._normalized(p) for p in files if p.isfile()] |
|
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 | def uncache(self,*items): |
|
197 | def uncache(self,*items): | |
192 | """ Removes all, or specified items from cache |
|
198 | """ Removes all, or specified items from cache |
@@ -27,6 +27,7 b' else:' | |||||
27 | from ._process_posix import _find_cmd, system, getoutput |
|
27 | from ._process_posix import _find_cmd, system, getoutput | |
28 |
|
28 | |||
29 | from ._process_common import getoutputerror |
|
29 | from ._process_common import getoutputerror | |
|
30 | from IPython.utils import py3compat | |||
30 |
|
31 | |||
31 | #----------------------------------------------------------------------------- |
|
32 | #----------------------------------------------------------------------------- | |
32 | # Code |
|
33 | # Code | |
@@ -65,7 +66,7 b' def find_cmd(cmd):' | |||||
65 | except OSError: |
|
66 | except OSError: | |
66 | raise FindCmdError('command could not be found: %s' % cmd) |
|
67 | raise FindCmdError('command could not be found: %s' % cmd) | |
67 | # which returns empty if not found |
|
68 | # which returns empty if not found | |
68 | if path == '': |
|
69 | if path == b'': | |
69 | raise FindCmdError('command could not be found: %s' % cmd) |
|
70 | raise FindCmdError('command could not be found: %s' % cmd) | |
70 | return os.path.abspath(path) |
|
71 | return os.path.abspath(path) | |
71 |
|
72 | |||
@@ -115,7 +116,7 b' def arg_split(s, posix=False):' | |||||
115 | # At least encoding the input when it's unicode seems to help, but there |
|
116 | # At least encoding the input when it's unicode seems to help, but there | |
116 | # may be more problems lurking. Apparently this is fixed in python3. |
|
117 | # may be more problems lurking. Apparently this is fixed in python3. | |
117 | is_unicode = False |
|
118 | is_unicode = False | |
118 | if isinstance(s, unicode): |
|
119 | if (not py3compat.PY3) and isinstance(s, unicode): | |
119 | is_unicode = True |
|
120 | is_unicode = True | |
120 | s = s.encode('utf-8') |
|
121 | s = s.encode('utf-8') | |
121 | lex = shlex.shlex(s, posix=posix) |
|
122 | lex = shlex.shlex(s, posix=posix) |
@@ -31,17 +31,24 b' from IPython.testing import decorators as dec' | |||||
31 | from IPython.testing.decorators import skip_if_not_win32, skip_win32 |
|
31 | from IPython.testing.decorators import skip_if_not_win32, skip_win32 | |
32 | from IPython.testing.tools import make_tempfile |
|
32 | from IPython.testing.tools import make_tempfile | |
33 | from IPython.utils import path, io |
|
33 | from IPython.utils import path, io | |
|
34 | from IPython.utils import py3compat | |||
34 |
|
35 | |||
35 | # Platform-dependent imports |
|
36 | # Platform-dependent imports | |
36 | try: |
|
37 | try: | |
37 | import _winreg as wreg |
|
38 | import _winreg as wreg | |
38 | except ImportError: |
|
39 | except ImportError: | |
39 | #Fake _winreg module on none windows platforms |
|
40 | #Fake _winreg module on none windows platforms | |
40 |
import |
|
41 | import types | |
41 | sys.modules["_winreg"] = new.module("_winreg") |
|
42 | wr_name = "winreg" if py3compat.PY3 else "_winreg" | |
|
43 | sys.modules[wr_name] = types.ModuleType(wr_name) | |||
42 | import _winreg as wreg |
|
44 | import _winreg as wreg | |
43 | #Add entries that needs to be stubbed by the testing code |
|
45 | #Add entries that needs to be stubbed by the testing code | |
44 | (wreg.OpenKey, wreg.QueryValueEx,) = (None, None) |
|
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 | # Globals |
|
54 | # Globals |
@@ -37,7 +37,7 b' def test_find_cmd_python():' | |||||
37 | def test_find_cmd_ls(): |
|
37 | def test_find_cmd_ls(): | |
38 | """Make sure we can find the full path to ls.""" |
|
38 | """Make sure we can find the full path to ls.""" | |
39 | path = find_cmd('ls') |
|
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 | def has_pywin32(): |
|
43 | def has_pywin32(): |
@@ -23,7 +23,7 b' import textwrap' | |||||
23 | from string import Formatter |
|
23 | from string import Formatter | |
24 |
|
24 | |||
25 | from IPython.external.path import path |
|
25 | from IPython.external.path import path | |
26 |
|
26 | from IPython.utils import py3compat | ||
27 | from IPython.utils.io import nlprint |
|
27 | from IPython.utils.io import nlprint | |
28 | from IPython.utils.data import flatten |
|
28 | from IPython.utils.data import flatten | |
29 |
|
29 | |||
@@ -284,7 +284,7 b' def make_quoted_expr(s):' | |||||
284 | tail = '' |
|
284 | tail = '' | |
285 | tailpadding = '' |
|
285 | tailpadding = '' | |
286 | raw = '' |
|
286 | raw = '' | |
287 | ucode = 'u' |
|
287 | ucode = '' if py3compat.PY3 else 'u' | |
288 | if "\\" in s: |
|
288 | if "\\" in s: | |
289 | raw = 'r' |
|
289 | raw = 'r' | |
290 | if s.endswith('\\'): |
|
290 | if s.endswith('\\'): | |
@@ -494,7 +494,7 b" def marquee(txt='',width=78,mark='*'):" | |||||
494 | """ |
|
494 | """ | |
495 | if not txt: |
|
495 | if not txt: | |
496 | return (mark*width)[:width] |
|
496 | return (mark*width)[:width] | |
497 | nmark = (width-len(txt)-2)/len(mark)/2 |
|
497 | nmark = (width-len(txt)-2)//len(mark)//2 | |
498 | if nmark < 0: nmark =0 |
|
498 | if nmark < 0: nmark =0 | |
499 | marks = mark*nmark |
|
499 | marks = mark*nmark | |
500 | return '%s %s %s' % (marks,txt,marks) |
|
500 | return '%s %s %s' % (marks,txt,marks) | |
@@ -587,10 +587,10 b' class EvalFormatter(Formatter):' | |||||
587 | -------- |
|
587 | -------- | |
588 |
|
588 | |||
589 | In [1]: f = EvalFormatter() |
|
589 | In [1]: f = EvalFormatter() | |
590 | In [2]: f.format('{n/4}', n=8) |
|
590 | In [2]: f.format('{n//4}', n=8) | |
591 | Out[2]: '2' |
|
591 | Out[2]: '2' | |
592 |
|
592 | |||
593 | In [3]: f.format('{range(3)}') |
|
593 | In [3]: f.format('{list(range(3))}') | |
594 | Out[3]: '[0, 1, 2]' |
|
594 | Out[3]: '[0, 1, 2]' | |
595 |
|
595 | |||
596 | In [4]: f.format('{3*2}') |
|
596 | In [4]: f.format('{3*2}') |
@@ -52,15 +52,17 b' import inspect' | |||||
52 | import re |
|
52 | import re | |
53 | import sys |
|
53 | import sys | |
54 | import types |
|
54 | import types | |
55 |
from types import |
|
55 | from types import FunctionType | |
56 | InstanceType, ClassType, FunctionType, |
|
56 | try: | |
57 | ListType, TupleType |
|
57 | from types import ClassType, InstanceType | |
58 | ) |
|
58 | ClassTypes = (ClassType, type) | |
|
59 | except: | |||
|
60 | ClassTypes = (type,) | |||
|
61 | ||||
59 | from .importstring import import_item |
|
62 | from .importstring import import_item | |
|
63 | from IPython.utils import py3compat | |||
60 |
|
64 | |||
61 | ClassTypes = (ClassType, type) |
|
65 | SequenceTypes = (list, tuple, set, frozenset) | |
62 |
|
||||
63 | SequenceTypes = (ListType, TupleType, set, frozenset) |
|
|||
64 |
|
66 | |||
65 | #----------------------------------------------------------------------------- |
|
67 | #----------------------------------------------------------------------------- | |
66 | # Basic classes |
|
68 | # Basic classes | |
@@ -108,7 +110,7 b' def repr_type(obj):' | |||||
108 | error messages. |
|
110 | error messages. | |
109 | """ |
|
111 | """ | |
110 | the_type = type(obj) |
|
112 | the_type = type(obj) | |
111 | if the_type is InstanceType: |
|
113 | if (not py3compat.PY3) and the_type is InstanceType: | |
112 | # Old-style class. |
|
114 | # Old-style class. | |
113 | the_type = obj.__class__ |
|
115 | the_type = obj.__class__ | |
114 | msg = '%r %r' % (obj, the_type) |
|
116 | msg = '%r %r' % (obj, the_type) | |
@@ -616,7 +618,7 b' class ClassBasedTraitType(TraitType):' | |||||
616 |
|
618 | |||
617 | def error(self, obj, value): |
|
619 | def error(self, obj, value): | |
618 | kind = type(value) |
|
620 | kind = type(value) | |
619 | if kind is InstanceType: |
|
621 | if (not py3compat.PY3) and kind is InstanceType: | |
620 | msg = 'class %s' % value.__class__.__name__ |
|
622 | msg = 'class %s' % value.__class__.__name__ | |
621 | else: |
|
623 | else: | |
622 | msg = '%s (i.e. %s)' % ( str( kind )[1:-1], repr( value ) ) |
|
624 | msg = '%s (i.e. %s)' % ( str( kind )[1:-1], repr( value ) ) | |
@@ -880,29 +882,31 b' class CInt(Int):' | |||||
880 | except: |
|
882 | except: | |
881 | self.error(obj, value) |
|
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): |
|
891 | default_value = 0L | |
885 | """A long integer trait.""" |
|
892 | info_text = 'a long' | |
886 |
|
||||
887 | default_value = 0L |
|
|||
888 | info_text = 'a long' |
|
|||
889 |
|
893 | |||
890 | def validate(self, obj, value): |
|
894 | def validate(self, obj, value): | |
891 | if isinstance(value, long): |
|
895 | if isinstance(value, long): | |
892 | return value |
|
896 | return value | |
893 | if isinstance(value, int): |
|
897 | if isinstance(value, int): | |
894 | return long(value) |
|
898 | return long(value) | |
895 | self.error(obj, value) |
|
899 | self.error(obj, value) | |
896 |
|
900 | |||
897 |
|
901 | |||
898 | class CLong(Long): |
|
902 | class CLong(Long): | |
899 | """A casting version of the long integer trait.""" |
|
903 | """A casting version of the long integer trait.""" | |
900 |
|
904 | |||
901 | def validate(self, obj, value): |
|
905 | def validate(self, obj, value): | |
902 | try: |
|
906 | try: | |
903 | return long(value) |
|
907 | return long(value) | |
904 | except: |
|
908 | except: | |
905 | self.error(obj, value) |
|
909 | self.error(obj, value) | |
906 |
|
910 | |||
907 |
|
911 | |||
908 | class Float(TraitType): |
|
912 | class Float(TraitType): | |
@@ -955,7 +959,7 b' class CComplex(Complex):' | |||||
955 | # for Python 3 conversion and for reliable unicode behaviour on Python 2. So |
|
959 | # for Python 3 conversion and for reliable unicode behaviour on Python 2. So | |
956 | # we don't have a Str type. |
|
960 | # we don't have a Str type. | |
957 | class Bytes(TraitType): |
|
961 | class Bytes(TraitType): | |
958 | """A trait for strings.""" |
|
962 | """A trait for byte strings.""" | |
959 |
|
963 | |||
960 | default_value = '' |
|
964 | default_value = '' | |
961 | info_text = 'a string' |
|
965 | info_text = 'a string' | |
@@ -967,7 +971,7 b' class Bytes(TraitType):' | |||||
967 |
|
971 | |||
968 |
|
972 | |||
969 | class CBytes(Bytes): |
|
973 | class CBytes(Bytes): | |
970 | """A casting version of the string trait.""" |
|
974 | """A casting version of the byte string trait.""" | |
971 |
|
975 | |||
972 | def validate(self, obj, value): |
|
976 | def validate(self, obj, value): | |
973 | try: |
|
977 | try: | |
@@ -1006,12 +1010,12 b' class ObjectName(TraitType):' | |||||
1006 | This does not check that the name exists in any scope.""" |
|
1010 | This does not check that the name exists in any scope.""" | |
1007 | info_text = "a valid object identifier in Python" |
|
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 | # Python 2: |
|
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 | def coerce_str(self, obj, value): |
|
1019 | def coerce_str(self, obj, value): | |
1016 | "In Python 2, coerce ascii-only unicode to str" |
|
1020 | "In Python 2, coerce ascii-only unicode to str" | |
1017 | if isinstance(value, unicode): |
|
1021 | if isinstance(value, unicode): | |
@@ -1021,15 +1025,10 b' class ObjectName(TraitType):' | |||||
1021 | self.error(obj, value) |
|
1025 | self.error(obj, value) | |
1022 | return value |
|
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 | def validate(self, obj, value): |
|
1028 | def validate(self, obj, value): | |
1030 | value = self.coerce_str(obj, value) |
|
1029 | value = self.coerce_str(obj, value) | |
1031 |
|
1030 | |||
1032 |
if isinstance(value, str) and |
|
1031 | if isinstance(value, str) and py3compat.isidentifier(value): | |
1033 | return value |
|
1032 | return value | |
1034 | self.error(obj, value) |
|
1033 | self.error(obj, value) | |
1035 |
|
1034 | |||
@@ -1038,8 +1037,7 b' class DottedObjectName(ObjectName):' | |||||
1038 | def validate(self, obj, value): |
|
1037 | def validate(self, obj, value): | |
1039 | value = self.coerce_str(obj, value) |
|
1038 | value = self.coerce_str(obj, value) | |
1040 |
|
1039 | |||
1041 |
if isinstance(value, str) and |
|
1040 | if isinstance(value, str) and py3compat.isidentifier(value, dotted=True): | |
1042 | for x in value.split('.')): |
|
|||
1043 | return value |
|
1041 | return value | |
1044 | self.error(obj, value) |
|
1042 | self.error(obj, value) | |
1045 |
|
1043 |
@@ -30,10 +30,10 b' class ZMQDisplayHook(object):' | |||||
30 | def _encode_binary(format_dict): |
|
30 | def _encode_binary(format_dict): | |
31 | pngdata = format_dict.get('image/png') |
|
31 | pngdata = format_dict.get('image/png') | |
32 | if pngdata is not None: |
|
32 | if pngdata is not None: | |
33 | format_dict['image/png'] = encodestring(pngdata) |
|
33 | format_dict['image/png'] = encodestring(pngdata).decode('ascii') | |
34 | jpegdata = format_dict.get('image/jpeg') |
|
34 | jpegdata = format_dict.get('image/jpeg') | |
35 | if jpegdata is not None: |
|
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 | class ZMQShellDisplayHook(DisplayHook): |
|
39 | class ZMQShellDisplayHook(DisplayHook): |
@@ -33,6 +33,7 b' from IPython.core.shellapp import (' | |||||
33 | InteractiveShellApp, shell_flags, shell_aliases |
|
33 | InteractiveShellApp, shell_flags, shell_aliases | |
34 | ) |
|
34 | ) | |
35 | from IPython.utils import io |
|
35 | from IPython.utils import io | |
|
36 | from IPython.utils import py3compat | |||
36 | from IPython.utils.jsonutil import json_clean |
|
37 | from IPython.utils.jsonutil import json_clean | |
37 | from IPython.lib import pylabtools |
|
38 | from IPython.lib import pylabtools | |
38 | from IPython.utils.traitlets import ( |
|
39 | from IPython.utils.traitlets import ( | |
@@ -219,7 +220,10 b' class Kernel(Configurable):' | |||||
219 | # Replace raw_input. Note that is not sufficient to replace |
|
220 | # Replace raw_input. Note that is not sufficient to replace | |
220 | # raw_input in the user namespace. |
|
221 | # raw_input in the user namespace. | |
221 | raw_input = lambda prompt='': self._raw_input(prompt, ident, parent) |
|
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 | # Set the parent message of the display hook and out streams. |
|
228 | # Set the parent message of the display hook and out streams. | |
225 | shell.displayhook.set_parent(parent) |
|
229 | shell.displayhook.set_parent(parent) |
@@ -188,7 +188,7 b' class ShellSocketChannel(ZMQSocketChannel):' | |||||
188 | def run(self): |
|
188 | def run(self): | |
189 | """The thread's main activity. Call start() instead.""" |
|
189 | """The thread's main activity. Call start() instead.""" | |
190 | self.socket = self.context.socket(zmq.DEALER) |
|
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 | self.socket.connect('tcp://%s:%i' % self.address) |
|
192 | self.socket.connect('tcp://%s:%i' % self.address) | |
193 | self.iostate = POLLERR|POLLIN |
|
193 | self.iostate = POLLERR|POLLIN | |
194 | self.ioloop.add_handler(self.socket, self._handle_events, |
|
194 | self.ioloop.add_handler(self.socket, self._handle_events, | |
@@ -394,8 +394,8 b' class SubSocketChannel(ZMQSocketChannel):' | |||||
394 | def run(self): |
|
394 | def run(self): | |
395 | """The thread's main activity. Call start() instead.""" |
|
395 | """The thread's main activity. Call start() instead.""" | |
396 | self.socket = self.context.socket(zmq.SUB) |
|
396 | self.socket = self.context.socket(zmq.SUB) | |
397 | self.socket.setsockopt(zmq.SUBSCRIBE,'') |
|
397 | self.socket.setsockopt(zmq.SUBSCRIBE,b'') | |
398 | self.socket.setsockopt(zmq.IDENTITY, self.session.session) |
|
398 | self.socket.setsockopt(zmq.IDENTITY, self.session.bsession) | |
399 | self.socket.connect('tcp://%s:%i' % self.address) |
|
399 | self.socket.connect('tcp://%s:%i' % self.address) | |
400 | self.iostate = POLLIN|POLLERR |
|
400 | self.iostate = POLLIN|POLLERR | |
401 | self.ioloop.add_handler(self.socket, self._handle_events, |
|
401 | self.ioloop.add_handler(self.socket, self._handle_events, | |
@@ -483,7 +483,7 b' class StdInSocketChannel(ZMQSocketChannel):' | |||||
483 | def run(self): |
|
483 | def run(self): | |
484 | """The thread's main activity. Call start() instead.""" |
|
484 | """The thread's main activity. Call start() instead.""" | |
485 | self.socket = self.context.socket(zmq.DEALER) |
|
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 | self.socket.connect('tcp://%s:%i' % self.address) |
|
487 | self.socket.connect('tcp://%s:%i' % self.address) | |
488 | self.iostate = POLLERR|POLLIN |
|
488 | self.iostate = POLLERR|POLLIN | |
489 | self.ioloop.add_handler(self.socket, self._handle_events, |
|
489 | self.ioloop.add_handler(self.socket, self._handle_events, | |
@@ -562,7 +562,7 b' class HBSocketChannel(ZMQSocketChannel):' | |||||
562 |
|
562 | |||
563 | def _create_socket(self): |
|
563 | def _create_socket(self): | |
564 | self.socket = self.context.socket(zmq.REQ) |
|
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 | self.socket.connect('tcp://%s:%i' % self.address) |
|
566 | self.socket.connect('tcp://%s:%i' % self.address) | |
567 | self.poller = zmq.Poller() |
|
567 | self.poller = zmq.Poller() | |
568 | self.poller.register(self.socket, zmq.POLLIN) |
|
568 | self.poller.register(self.socket, zmq.POLLIN) |
@@ -25,6 +25,7 b' import traceback' | |||||
25 | import zmq |
|
25 | import zmq | |
26 |
|
26 | |||
27 | # Local imports. |
|
27 | # Local imports. | |
|
28 | from IPython.utils import py3compat | |||
28 | from IPython.utils.traitlets import HasTraits, Instance, Dict, Float |
|
29 | from IPython.utils.traitlets import HasTraits, Instance, Dict, Float | |
29 | from completer import KernelCompleter |
|
30 | from completer import KernelCompleter | |
30 | from entry_point import base_launch_kernel |
|
31 | from entry_point import base_launch_kernel | |
@@ -116,7 +117,10 b' class Kernel(HasTraits):' | |||||
116 | # Replace raw_input. Note that is not sufficient to replace |
|
117 | # Replace raw_input. Note that is not sufficient to replace | |
117 | # raw_input in the user namespace. |
|
118 | # raw_input in the user namespace. | |
118 | raw_input = lambda prompt='': self._raw_input(prompt, ident, parent) |
|
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 | # Set the parent message of the display hook and out streams. |
|
125 | # Set the parent message of the display hook and out streams. | |
122 | sys.displayhook.set_parent(parent) |
|
126 | sys.displayhook.set_parent(parent) |
@@ -46,8 +46,9 b' from zmq.eventloop.zmqstream import ZMQStream' | |||||
46 | from IPython.config.configurable import Configurable, LoggingConfigurable |
|
46 | from IPython.config.configurable import Configurable, LoggingConfigurable | |
47 | from IPython.utils.importstring import import_item |
|
47 | from IPython.utils.importstring import import_item | |
48 | from IPython.utils.jsonutil import extract_dates, squash_dates, date_default |
|
48 | from IPython.utils.jsonutil import extract_dates, squash_dates, date_default | |
|
49 | from IPython.utils.py3compat import str_to_bytes | |||
49 | from IPython.utils.traitlets import (CBytes, Unicode, Bool, Any, Instance, Set, |
|
50 | from IPython.utils.traitlets import (CBytes, Unicode, Bool, Any, Instance, Set, | |
50 | DottedObjectName) |
|
51 | DottedObjectName, CUnicode) | |
51 |
|
52 | |||
52 | #----------------------------------------------------------------------------- |
|
53 | #----------------------------------------------------------------------------- | |
53 | # utility functions |
|
54 | # utility functions | |
@@ -238,10 +239,18 b' class Session(Configurable):' | |||||
238 | else: |
|
239 | else: | |
239 | self.unpack = import_item(str(new)) |
|
240 | self.unpack = import_item(str(new)) | |
240 |
|
241 | |||
241 |
session = C |
|
242 | session = CUnicode(u'', config=True, | |
242 | help="""The UUID identifying this session.""") |
|
243 | help="""The UUID identifying this session.""") | |
243 | def _session_default(self): |
|
244 | def _session_default(self): | |
244 |
|
|
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 | username = Unicode(os.environ.get('USER',u'username'), config=True, |
|
255 | username = Unicode(os.environ.get('USER',u'username'), config=True, | |
247 | help="""Username for the Session. Default is your system username.""") |
|
256 | help="""Username for the Session. Default is your system username.""") | |
@@ -295,9 +304,11 b' class Session(Configurable):' | |||||
295 | pack/unpack : callables |
|
304 | pack/unpack : callables | |
296 | You can also set the pack/unpack callables for serialization |
|
305 | You can also set the pack/unpack callables for serialization | |
297 | directly. |
|
306 | directly. | |
298 |
session : |
|
307 | session : unicode (must be ascii) | |
299 | the ID of this Session object. The default is to generate a new |
|
308 | the ID of this Session object. The default is to generate a new | |
300 | UUID. |
|
309 | UUID. | |
|
310 | bsession : bytes | |||
|
311 | The session as bytes | |||
301 | username : unicode |
|
312 | username : unicode | |
302 | username added to message headers. The default is to ask the OS. |
|
313 | username added to message headers. The default is to ask the OS. | |
303 | key : bytes |
|
314 | key : bytes | |
@@ -310,6 +321,8 b' class Session(Configurable):' | |||||
310 | super(Session, self).__init__(**kwargs) |
|
321 | super(Session, self).__init__(**kwargs) | |
311 | self._check_packers() |
|
322 | self._check_packers() | |
312 | self.none = self.pack({}) |
|
323 | self.none = self.pack({}) | |
|
324 | # ensure self._session_default() if necessary, so bsession is defined: | |||
|
325 | self.session | |||
313 |
|
326 | |||
314 | @property |
|
327 | @property | |
315 | def msg_id(self): |
|
328 | def msg_id(self): | |
@@ -380,7 +393,7 b' class Session(Configurable):' | |||||
380 | h = self.auth.copy() |
|
393 | h = self.auth.copy() | |
381 | for m in msg_list: |
|
394 | for m in msg_list: | |
382 | h.update(m) |
|
395 | h.update(m) | |
383 | return h.hexdigest() |
|
396 | return str_to_bytes(h.hexdigest()) | |
384 |
|
397 | |||
385 | def serialize(self, msg, ident=None): |
|
398 | def serialize(self, msg, ident=None): | |
386 | """Serialize the message components to bytes. |
|
399 | """Serialize the message components to bytes. | |
@@ -401,7 +414,7 b' class Session(Configurable):' | |||||
401 | [ident1,ident2,...,DELIM,HMAC,p_header,p_parent,p_content, |
|
414 | [ident1,ident2,...,DELIM,HMAC,p_header,p_parent,p_content, | |
402 | buffer1,buffer2,...]. In this list, the p_* entities are |
|
415 | buffer1,buffer2,...]. In this list, the p_* entities are | |
403 | the packed or serialized versions, so if JSON is used, these |
|
416 | the packed or serialized versions, so if JSON is used, these | |
404 |
are u |
|
417 | are utf8 encoded JSON strings. | |
405 | """ |
|
418 | """ | |
406 | content = msg.get('content', {}) |
|
419 | content = msg.get('content', {}) | |
407 | if content is None: |
|
420 | if content is None: |
@@ -185,4 +185,26 b' class TestSession(SessionTestCase):' | |||||
185 | content = dict(code='whoda',stuff=object()) |
|
185 | content = dict(code='whoda',stuff=object()) | |
186 | themsg = self.session.msg('execute',content=content) |
|
186 | themsg = self.session.msg('execute',content=content) | |
187 | pmsg = theids |
|
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 |
|
1 | """This calls the setup routine for Python 2 or 3 as required.""" | |
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 |
|
2 | |||
24 | import sys |
|
3 | import sys | |
25 |
|
4 | |||
26 | # This check is also made in IPython/__init__, don't forget to update both when |
|
5 | if sys.version_info[0] >= 3: | |
27 | # changing Python version requirements. |
|
6 | from setup3 import main | |
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: |
|
7 | else: | |
94 | print 'Unsupported operating system:',os.name |
|
8 | from setup2 import main | |
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 |
|
9 | |||
268 | if __name__ == '__main__': |
|
10 | main() | |
269 | setup(**setup_args) |
|
|||
270 | cleanup() |
|
@@ -23,7 +23,10 b' from __future__ import print_function' | |||||
23 | import os |
|
23 | import os | |
24 | import sys |
|
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 | from distutils.command.build_py import build_py |
|
30 | from distutils.command.build_py import build_py | |
28 | from glob import glob |
|
31 | from glob import glob | |
29 |
|
32 | |||
@@ -40,6 +43,13 b' pjoin = os.path.join' | |||||
40 | def oscmd(s): |
|
43 | def oscmd(s): | |
41 | print(">", s) |
|
44 | print(">", s) | |
42 | os.system(s) |
|
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 | # A little utility we'll need below, since glob() does NOT allow you to do |
|
54 | # A little utility we'll need below, since glob() does NOT allow you to do | |
45 | # exclusion on multiple endings! |
|
55 | # exclusion on multiple endings! | |
@@ -58,7 +68,7 b' def file_doesnt_endwith(test,endings):' | |||||
58 | #--------------------------------------------------------------------------- |
|
68 | #--------------------------------------------------------------------------- | |
59 |
|
69 | |||
60 | # release.py contains version, authors, license, url, keywords, etc. |
|
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 | # Create a dict with the basic information |
|
73 | # Create a dict with the basic information | |
64 | # This dict is eventually passed to setup after additional keys are added. |
|
74 | # This dict is eventually passed to setup after additional keys are added. | |
@@ -74,6 +84,7 b' setup_args = dict(' | |||||
74 | license = license, |
|
84 | license = license, | |
75 | platforms = platforms, |
|
85 | platforms = platforms, | |
76 | keywords = keywords, |
|
86 | keywords = keywords, | |
|
87 | classifiers = classifiers, | |||
77 | cmdclass = {'install_data': install_data_ext}, |
|
88 | cmdclass = {'install_data': install_data_ext}, | |
78 | ) |
|
89 | ) | |
79 |
|
90 | |||
@@ -235,28 +246,31 b' def make_man_update_target(manpage):' | |||||
235 | # Find scripts |
|
246 | # Find scripts | |
236 | #--------------------------------------------------------------------------- |
|
247 | #--------------------------------------------------------------------------- | |
237 |
|
248 | |||
238 | def find_scripts(entry_points=False): |
|
249 | def find_scripts(entry_points=False, suffix=''): | |
239 | """Find IPython's scripts. |
|
250 | """Find IPython's scripts. | |
240 |
|
251 | |||
241 | if entry_points is True: |
|
252 | if entry_points is True: | |
242 | return setuptools entry_point-style definitions |
|
253 | return setuptools entry_point-style definitions | |
243 | else: |
|
254 | else: | |
244 | return file paths of plain scripts [default] |
|
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 | if entry_points: |
|
260 | if entry_points: | |
247 | console_scripts = [ |
|
261 | console_scripts = [s % suffix for s in [ | |
248 | 'ipython = IPython.frontend.terminal.ipapp:launch_new_instance', |
|
262 | 'ipython%s = IPython.frontend.terminal.ipapp:launch_new_instance', | |
249 | 'pycolor = IPython.utils.PyColorize:main', |
|
263 | 'pycolor%s = IPython.utils.PyColorize:main', | |
250 | 'ipcontroller = IPython.parallel.apps.ipcontrollerapp:launch_new_instance', |
|
264 | 'ipcontroller%s = IPython.parallel.apps.ipcontrollerapp:launch_new_instance', | |
251 | 'ipengine = IPython.parallel.apps.ipengineapp:launch_new_instance', |
|
265 | 'ipengine%s = IPython.parallel.apps.ipengineapp:launch_new_instance', | |
252 | 'iplogger = IPython.parallel.apps.iploggerapp:launch_new_instance', |
|
266 | 'iplogger%s = IPython.parallel.apps.iploggerapp:launch_new_instance', | |
253 | 'ipcluster = IPython.parallel.apps.ipclusterapp:launch_new_instance', |
|
267 | 'ipcluster%s = IPython.parallel.apps.ipclusterapp:launch_new_instance', | |
254 | 'iptest = IPython.testing.iptest:main', |
|
268 | 'iptest%s = IPython.testing.iptest:main', | |
255 | 'irunner = IPython.lib.irunner:main' |
|
269 | 'irunner%s = IPython.lib.irunner:main' | |
256 | ] |
|
270 | ]] | |
257 | gui_scripts = [ |
|
271 | gui_scripts = [s % suffix for s in [ | |
258 | 'ipython-qtconsole = IPython.frontend.qt.console.qtconsoleapp:main', |
|
272 | 'ipython%s-qtconsole = IPython.frontend.qt.console.qtconsoleapp:main', | |
259 | ] |
|
273 | ]] | |
260 | scripts = dict(console_scripts=console_scripts, gui_scripts=gui_scripts) |
|
274 | scripts = dict(console_scripts=console_scripts, gui_scripts=gui_scripts) | |
261 | else: |
|
275 | else: | |
262 | parallel_scripts = pjoin('IPython','parallel','scripts') |
|
276 | parallel_scripts = pjoin('IPython','parallel','scripts') |
General Comments 0
You need to be logged in to leave comments.
Login now