##// END OF EJS Templates
Merge pull request #10105 from srinivasreddy/dead_code...
Thomas Kluyver -
r23070:748d7071 merge
parent child Browse files
Show More
@@ -1,257 +1,256 b''
1 1 # encoding: utf-8
2 2 """
3 3 System command aliases.
4 4
5 5 Authors:
6 6
7 7 * Fernando Perez
8 8 * Brian Granger
9 9 """
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Copyright (C) 2008-2011 The IPython Development Team
13 13 #
14 14 # Distributed under the terms of the BSD License.
15 15 #
16 16 # The full license is in the file COPYING.txt, distributed with this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 import os
24 24 import re
25 25 import sys
26 26
27 27 from traitlets.config.configurable import Configurable
28 28 from IPython.core.error import UsageError
29 29
30 from IPython.utils.py3compat import string_types
31 30 from traitlets import List, Instance
32 31 from logging import error
33 32
34 33 #-----------------------------------------------------------------------------
35 34 # Utilities
36 35 #-----------------------------------------------------------------------------
37 36
38 37 # This is used as the pattern for calls to split_user_input.
39 38 shell_line_split = re.compile(r'^(\s*)()(\S+)(.*$)')
40 39
41 40 def default_aliases():
42 41 """Return list of shell aliases to auto-define.
43 42 """
44 43 # Note: the aliases defined here should be safe to use on a kernel
45 44 # regardless of what frontend it is attached to. Frontends that use a
46 45 # kernel in-process can define additional aliases that will only work in
47 46 # their case. For example, things like 'less' or 'clear' that manipulate
48 47 # the terminal should NOT be declared here, as they will only work if the
49 48 # kernel is running inside a true terminal, and not over the network.
50 49
51 50 if os.name == 'posix':
52 51 default_aliases = [('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
53 52 ('mv', 'mv'), ('rm', 'rm'), ('cp', 'cp'),
54 53 ('cat', 'cat'),
55 54 ]
56 55 # Useful set of ls aliases. The GNU and BSD options are a little
57 56 # different, so we make aliases that provide as similar as possible
58 57 # behavior in ipython, by passing the right flags for each platform
59 58 if sys.platform.startswith('linux'):
60 59 ls_aliases = [('ls', 'ls -F --color'),
61 60 # long ls
62 61 ('ll', 'ls -F -o --color'),
63 62 # ls normal files only
64 63 ('lf', 'ls -F -o --color %l | grep ^-'),
65 64 # ls symbolic links
66 65 ('lk', 'ls -F -o --color %l | grep ^l'),
67 66 # directories or links to directories,
68 67 ('ldir', 'ls -F -o --color %l | grep /$'),
69 68 # things which are executable
70 69 ('lx', 'ls -F -o --color %l | grep ^-..x'),
71 70 ]
72 71 elif sys.platform.startswith('openbsd') or sys.platform.startswith('netbsd'):
73 72 # OpenBSD, NetBSD. The ls implementation on these platforms do not support
74 73 # the -G switch and lack the ability to use colorized output.
75 74 ls_aliases = [('ls', 'ls -F'),
76 75 # long ls
77 76 ('ll', 'ls -F -l'),
78 77 # ls normal files only
79 78 ('lf', 'ls -F -l %l | grep ^-'),
80 79 # ls symbolic links
81 80 ('lk', 'ls -F -l %l | grep ^l'),
82 81 # directories or links to directories,
83 82 ('ldir', 'ls -F -l %l | grep /$'),
84 83 # things which are executable
85 84 ('lx', 'ls -F -l %l | grep ^-..x'),
86 85 ]
87 86 else:
88 87 # BSD, OSX, etc.
89 88 ls_aliases = [('ls', 'ls -F -G'),
90 89 # long ls
91 90 ('ll', 'ls -F -l -G'),
92 91 # ls normal files only
93 92 ('lf', 'ls -F -l -G %l | grep ^-'),
94 93 # ls symbolic links
95 94 ('lk', 'ls -F -l -G %l | grep ^l'),
96 95 # directories or links to directories,
97 96 ('ldir', 'ls -F -G -l %l | grep /$'),
98 97 # things which are executable
99 98 ('lx', 'ls -F -l -G %l | grep ^-..x'),
100 99 ]
101 100 default_aliases = default_aliases + ls_aliases
102 101 elif os.name in ['nt', 'dos']:
103 102 default_aliases = [('ls', 'dir /on'),
104 103 ('ddir', 'dir /ad /on'), ('ldir', 'dir /ad /on'),
105 104 ('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
106 105 ('echo', 'echo'), ('ren', 'ren'), ('copy', 'copy'),
107 106 ]
108 107 else:
109 108 default_aliases = []
110 109
111 110 return default_aliases
112 111
113 112
114 113 class AliasError(Exception):
115 114 pass
116 115
117 116
118 117 class InvalidAliasError(AliasError):
119 118 pass
120 119
121 120 class Alias(object):
122 121 """Callable object storing the details of one alias.
123 122
124 123 Instances are registered as magic functions to allow use of aliases.
125 124 """
126 125
127 126 # Prepare blacklist
128 127 blacklist = {'cd','popd','pushd','dhist','alias','unalias'}
129 128
130 129 def __init__(self, shell, name, cmd):
131 130 self.shell = shell
132 131 self.name = name
133 132 self.cmd = cmd
134 133 self.__doc__ = "Alias for `!{}`".format(cmd)
135 134 self.nargs = self.validate()
136 135
137 136 def validate(self):
138 137 """Validate the alias, and return the number of arguments."""
139 138 if self.name in self.blacklist:
140 139 raise InvalidAliasError("The name %s can't be aliased "
141 140 "because it is a keyword or builtin." % self.name)
142 141 try:
143 142 caller = self.shell.magics_manager.magics['line'][self.name]
144 143 except KeyError:
145 144 pass
146 145 else:
147 146 if not isinstance(caller, Alias):
148 147 raise InvalidAliasError("The name %s can't be aliased "
149 148 "because it is another magic command." % self.name)
150 149
151 if not (isinstance(self.cmd, string_types)):
150 if not (isinstance(self.cmd, str)):
152 151 raise InvalidAliasError("An alias command must be a string, "
153 152 "got: %r" % self.cmd)
154 153
155 154 nargs = self.cmd.count('%s') - self.cmd.count('%%s')
156 155
157 156 if (nargs > 0) and (self.cmd.find('%l') >= 0):
158 157 raise InvalidAliasError('The %s and %l specifiers are mutually '
159 158 'exclusive in alias definitions.')
160 159
161 160 return nargs
162 161
163 162 def __repr__(self):
164 163 return "<alias {} for {!r}>".format(self.name, self.cmd)
165 164
166 165 def __call__(self, rest=''):
167 166 cmd = self.cmd
168 167 nargs = self.nargs
169 168 # Expand the %l special to be the user's input line
170 169 if cmd.find('%l') >= 0:
171 170 cmd = cmd.replace('%l', rest)
172 171 rest = ''
173 172
174 173 if nargs==0:
175 174 if cmd.find('%%s') >= 1:
176 175 cmd = cmd.replace('%%s', '%s')
177 176 # Simple, argument-less aliases
178 177 cmd = '%s %s' % (cmd, rest)
179 178 else:
180 179 # Handle aliases with positional arguments
181 180 args = rest.split(None, nargs)
182 181 if len(args) < nargs:
183 182 raise UsageError('Alias <%s> requires %s arguments, %s given.' %
184 183 (self.name, nargs, len(args)))
185 184 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
186 185
187 186 self.shell.system(cmd)
188 187
189 188 #-----------------------------------------------------------------------------
190 189 # Main AliasManager class
191 190 #-----------------------------------------------------------------------------
192 191
193 192 class AliasManager(Configurable):
194 193
195 194 default_aliases = List(default_aliases()).tag(config=True)
196 195 user_aliases = List(default_value=[]).tag(config=True)
197 196 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
198 197
199 198 def __init__(self, shell=None, **kwargs):
200 199 super(AliasManager, self).__init__(shell=shell, **kwargs)
201 200 # For convenient access
202 201 self.linemagics = self.shell.magics_manager.magics['line']
203 202 self.init_aliases()
204 203
205 204 def init_aliases(self):
206 205 # Load default & user aliases
207 206 for name, cmd in self.default_aliases + self.user_aliases:
208 207 self.soft_define_alias(name, cmd)
209 208
210 209 @property
211 210 def aliases(self):
212 211 return [(n, func.cmd) for (n, func) in self.linemagics.items()
213 212 if isinstance(func, Alias)]
214 213
215 214 def soft_define_alias(self, name, cmd):
216 215 """Define an alias, but don't raise on an AliasError."""
217 216 try:
218 217 self.define_alias(name, cmd)
219 218 except AliasError as e:
220 219 error("Invalid alias: %s" % e)
221 220
222 221 def define_alias(self, name, cmd):
223 222 """Define a new alias after validating it.
224 223
225 224 This will raise an :exc:`AliasError` if there are validation
226 225 problems.
227 226 """
228 227 caller = Alias(shell=self.shell, name=name, cmd=cmd)
229 228 self.shell.magics_manager.register_function(caller, magic_kind='line',
230 229 magic_name=name)
231 230
232 231 def get_alias(self, name):
233 232 """Return an alias, or None if no alias by that name exists."""
234 233 aname = self.linemagics.get(name, None)
235 234 return aname if isinstance(aname, Alias) else None
236 235
237 236 def is_alias(self, name):
238 237 """Return whether or not a given name has been defined as an alias"""
239 238 return self.get_alias(name) is not None
240 239
241 240 def undefine_alias(self, name):
242 241 if self.is_alias(name):
243 242 del self.linemagics[name]
244 243 else:
245 244 raise ValueError('%s is not an alias' % name)
246 245
247 246 def clear_aliases(self):
248 247 for name, cmd in self.aliases:
249 248 self.undefine_alias(name)
250 249
251 250 def retrieve_alias(self, name):
252 251 """Retrieve the command to which an alias expands."""
253 252 caller = self.get_alias(name)
254 253 if caller:
255 254 return caller.cmd
256 255 else:
257 256 raise ValueError('%s is not an alias' % name)
@@ -1,458 +1,458 b''
1 1 # encoding: utf-8
2 2 """
3 3 An application for IPython.
4 4
5 5 All top-level applications should use the classes in this module for
6 6 handling configuration and creating configurables.
7 7
8 8 The job of an :class:`Application` is to create the master configuration
9 9 object and then create the configurable objects, passing the config to them.
10 10 """
11 11
12 12 # Copyright (c) IPython Development Team.
13 13 # Distributed under the terms of the Modified BSD License.
14 14
15 15 import atexit
16 16 from copy import deepcopy
17 17 import glob
18 18 import logging
19 19 import os
20 20 import shutil
21 21 import sys
22 22
23 23 from traitlets.config.application import Application, catch_config_error
24 24 from traitlets.config.loader import ConfigFileNotFound, PyFileConfigLoader
25 25 from IPython.core import release, crashhandler
26 26 from IPython.core.profiledir import ProfileDir, ProfileDirError
27 27 from IPython.paths import get_ipython_dir, get_ipython_package_dir
28 28 from IPython.utils.path import ensure_dir_exists
29 29 from IPython.utils import py3compat
30 30 from traitlets import (
31 31 List, Unicode, Type, Bool, Dict, Set, Instance, Undefined,
32 32 default, observe,
33 33 )
34 34
35 35 if os.name == 'nt':
36 36 programdata = os.environ.get('PROGRAMDATA', None)
37 37 if programdata:
38 38 SYSTEM_CONFIG_DIRS = [os.path.join(programdata, 'ipython')]
39 39 else: # PROGRAMDATA is not defined by default on XP.
40 40 SYSTEM_CONFIG_DIRS = []
41 41 else:
42 42 SYSTEM_CONFIG_DIRS = [
43 43 "/usr/local/etc/ipython",
44 44 "/etc/ipython",
45 45 ]
46 46
47 47 _envvar = os.environ.get('IPYTHON_SUPPRESS_CONFIG_ERRORS')
48 48 if _envvar in {None, ''}:
49 49 IPYTHON_SUPPRESS_CONFIG_ERRORS = None
50 50 else:
51 51 if _envvar.lower() in {'1','true'}:
52 52 IPYTHON_SUPPRESS_CONFIG_ERRORS = True
53 53 elif _envvar.lower() in {'0','false'} :
54 54 IPYTHON_SUPPRESS_CONFIG_ERRORS = False
55 55 else:
56 56 sys.exit("Unsupported value for environment variable: 'IPYTHON_SUPPRESS_CONFIG_ERRORS' is set to '%s' which is none of {'0', '1', 'false', 'true', ''}."% _envvar )
57 57
58 58 # aliases and flags
59 59
60 60 base_aliases = {
61 61 'profile-dir' : 'ProfileDir.location',
62 62 'profile' : 'BaseIPythonApplication.profile',
63 63 'ipython-dir' : 'BaseIPythonApplication.ipython_dir',
64 64 'log-level' : 'Application.log_level',
65 65 'config' : 'BaseIPythonApplication.extra_config_file',
66 66 }
67 67
68 68 base_flags = dict(
69 69 debug = ({'Application' : {'log_level' : logging.DEBUG}},
70 70 "set log level to logging.DEBUG (maximize logging output)"),
71 71 quiet = ({'Application' : {'log_level' : logging.CRITICAL}},
72 72 "set log level to logging.CRITICAL (minimize logging output)"),
73 73 init = ({'BaseIPythonApplication' : {
74 74 'copy_config_files' : True,
75 75 'auto_create' : True}
76 76 }, """Initialize profile with default config files. This is equivalent
77 77 to running `ipython profile create <profile>` prior to startup.
78 78 """)
79 79 )
80 80
81 81 class ProfileAwareConfigLoader(PyFileConfigLoader):
82 82 """A Python file config loader that is aware of IPython profiles."""
83 83 def load_subconfig(self, fname, path=None, profile=None):
84 84 if profile is not None:
85 85 try:
86 86 profile_dir = ProfileDir.find_profile_dir_by_name(
87 87 get_ipython_dir(),
88 88 profile,
89 89 )
90 90 except ProfileDirError:
91 91 return
92 92 path = profile_dir.location
93 93 return super(ProfileAwareConfigLoader, self).load_subconfig(fname, path=path)
94 94
95 95 class BaseIPythonApplication(Application):
96 96
97 97 name = Unicode(u'ipython')
98 98 description = Unicode(u'IPython: an enhanced interactive Python shell.')
99 99 version = Unicode(release.version)
100 100
101 101 aliases = Dict(base_aliases)
102 102 flags = Dict(base_flags)
103 103 classes = List([ProfileDir])
104 104
105 105 # enable `load_subconfig('cfg.py', profile='name')`
106 106 python_config_loader_class = ProfileAwareConfigLoader
107 107
108 108 # Track whether the config_file has changed,
109 109 # because some logic happens only if we aren't using the default.
110 110 config_file_specified = Set()
111 111
112 112 config_file_name = Unicode()
113 113 @default('config_file_name')
114 114 def _config_file_name_default(self):
115 115 return self.name.replace('-','_') + u'_config.py'
116 116 @observe('config_file_name')
117 117 def _config_file_name_changed(self, change):
118 118 if change['new'] != change['old']:
119 119 self.config_file_specified.add(change['new'])
120 120
121 121 # The directory that contains IPython's builtin profiles.
122 122 builtin_profile_dir = Unicode(
123 123 os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
124 124 )
125 125
126 126 config_file_paths = List(Unicode())
127 127 @default('config_file_paths')
128 128 def _config_file_paths_default(self):
129 return [py3compat.getcwd()]
129 return [os.getcwd()]
130 130
131 131 extra_config_file = Unicode(
132 132 help="""Path to an extra config file to load.
133 133
134 134 If specified, load this config file in addition to any other IPython config.
135 135 """).tag(config=True)
136 136 @observe('extra_config_file')
137 137 def _extra_config_file_changed(self, change):
138 138 old = change['old']
139 139 new = change['new']
140 140 try:
141 141 self.config_files.remove(old)
142 142 except ValueError:
143 143 pass
144 144 self.config_file_specified.add(new)
145 145 self.config_files.append(new)
146 146
147 147 profile = Unicode(u'default',
148 148 help="""The IPython profile to use."""
149 149 ).tag(config=True)
150 150
151 151 @observe('profile')
152 152 def _profile_changed(self, change):
153 153 self.builtin_profile_dir = os.path.join(
154 154 get_ipython_package_dir(), u'config', u'profile', change['new']
155 155 )
156 156
157 157 ipython_dir = Unicode(
158 158 help="""
159 159 The name of the IPython directory. This directory is used for logging
160 160 configuration (through profiles), history storage, etc. The default
161 161 is usually $HOME/.ipython. This option can also be specified through
162 162 the environment variable IPYTHONDIR.
163 163 """
164 164 ).tag(config=True)
165 165 @default('ipython_dir')
166 166 def _ipython_dir_default(self):
167 167 d = get_ipython_dir()
168 168 self._ipython_dir_changed({
169 169 'name': 'ipython_dir',
170 170 'old': d,
171 171 'new': d,
172 172 })
173 173 return d
174 174
175 175 _in_init_profile_dir = False
176 176 profile_dir = Instance(ProfileDir, allow_none=True)
177 177 @default('profile_dir')
178 178 def _profile_dir_default(self):
179 179 # avoid recursion
180 180 if self._in_init_profile_dir:
181 181 return
182 182 # profile_dir requested early, force initialization
183 183 self.init_profile_dir()
184 184 return self.profile_dir
185 185
186 186 overwrite = Bool(False,
187 187 help="""Whether to overwrite existing config files when copying"""
188 188 ).tag(config=True)
189 189 auto_create = Bool(False,
190 190 help="""Whether to create profile dir if it doesn't exist"""
191 191 ).tag(config=True)
192 192
193 193 config_files = List(Unicode())
194 194 @default('config_files')
195 195 def _config_files_default(self):
196 196 return [self.config_file_name]
197 197
198 198 copy_config_files = Bool(False,
199 199 help="""Whether to install the default config files into the profile dir.
200 200 If a new profile is being created, and IPython contains config files for that
201 201 profile, then they will be staged into the new directory. Otherwise,
202 202 default config files will be automatically generated.
203 203 """).tag(config=True)
204 204
205 205 verbose_crash = Bool(False,
206 206 help="""Create a massive crash report when IPython encounters what may be an
207 207 internal error. The default is to append a short message to the
208 208 usual traceback""").tag(config=True)
209 209
210 210 # The class to use as the crash handler.
211 211 crash_handler_class = Type(crashhandler.CrashHandler)
212 212
213 213 @catch_config_error
214 214 def __init__(self, **kwargs):
215 215 super(BaseIPythonApplication, self).__init__(**kwargs)
216 216 # ensure current working directory exists
217 217 try:
218 py3compat.getcwd()
218 os.getcwd()
219 219 except:
220 220 # exit if cwd doesn't exist
221 221 self.log.error("Current working directory doesn't exist.")
222 222 self.exit(1)
223 223
224 224 #-------------------------------------------------------------------------
225 225 # Various stages of Application creation
226 226 #-------------------------------------------------------------------------
227 227
228 228 deprecated_subcommands = {}
229 229
230 230 def initialize_subcommand(self, subc, argv=None):
231 231 if subc in self.deprecated_subcommands:
232 232 self.log.warning("Subcommand `ipython {sub}` is deprecated and will be removed "
233 233 "in future versions.".format(sub=subc))
234 234 self.log.warning("You likely want to use `jupyter {sub}` in the "
235 235 "future".format(sub=subc))
236 236 return super(BaseIPythonApplication, self).initialize_subcommand(subc, argv)
237 237
238 238 def init_crash_handler(self):
239 239 """Create a crash handler, typically setting sys.excepthook to it."""
240 240 self.crash_handler = self.crash_handler_class(self)
241 241 sys.excepthook = self.excepthook
242 242 def unset_crashhandler():
243 243 sys.excepthook = sys.__excepthook__
244 244 atexit.register(unset_crashhandler)
245 245
246 246 def excepthook(self, etype, evalue, tb):
247 247 """this is sys.excepthook after init_crashhandler
248 248
249 249 set self.verbose_crash=True to use our full crashhandler, instead of
250 250 a regular traceback with a short message (crash_handler_lite)
251 251 """
252 252
253 253 if self.verbose_crash:
254 254 return self.crash_handler(etype, evalue, tb)
255 255 else:
256 256 return crashhandler.crash_handler_lite(etype, evalue, tb)
257 257
258 258 @observe('ipython_dir')
259 259 def _ipython_dir_changed(self, change):
260 260 old = change['old']
261 261 new = change['new']
262 262 if old is not Undefined:
263 263 str_old = py3compat.cast_bytes_py2(os.path.abspath(old),
264 264 sys.getfilesystemencoding()
265 265 )
266 266 if str_old in sys.path:
267 267 sys.path.remove(str_old)
268 268 str_path = py3compat.cast_bytes_py2(os.path.abspath(new),
269 269 sys.getfilesystemencoding()
270 270 )
271 271 sys.path.append(str_path)
272 272 ensure_dir_exists(new)
273 273 readme = os.path.join(new, 'README')
274 274 readme_src = os.path.join(get_ipython_package_dir(), u'config', u'profile', 'README')
275 275 if not os.path.exists(readme) and os.path.exists(readme_src):
276 276 shutil.copy(readme_src, readme)
277 277 for d in ('extensions', 'nbextensions'):
278 278 path = os.path.join(new, d)
279 279 try:
280 280 ensure_dir_exists(path)
281 281 except OSError as e:
282 282 # this will not be EEXIST
283 283 self.log.error("couldn't create path %s: %s", path, e)
284 284 self.log.debug("IPYTHONDIR set to: %s" % new)
285 285
286 286 def load_config_file(self, suppress_errors=IPYTHON_SUPPRESS_CONFIG_ERRORS):
287 287 """Load the config file.
288 288
289 289 By default, errors in loading config are handled, and a warning
290 290 printed on screen. For testing, the suppress_errors option is set
291 291 to False, so errors will make tests fail.
292 292
293 293 `supress_errors` default value is to be `None` in which case the
294 294 behavior default to the one of `traitlets.Application`.
295 295
296 296 The default value can be set :
297 297 - to `False` by setting 'IPYTHON_SUPPRESS_CONFIG_ERRORS' environment variable to '0', or 'false' (case insensitive).
298 298 - to `True` by setting 'IPYTHON_SUPPRESS_CONFIG_ERRORS' environment variable to '1' or 'true' (case insensitive).
299 299 - to `None` by setting 'IPYTHON_SUPPRESS_CONFIG_ERRORS' environment variable to '' (empty string) or leaving it unset.
300 300
301 301 Any other value are invalid, and will make IPython exit with a non-zero return code.
302 302 """
303 303
304 304
305 305 self.log.debug("Searching path %s for config files", self.config_file_paths)
306 306 base_config = 'ipython_config.py'
307 307 self.log.debug("Attempting to load config file: %s" %
308 308 base_config)
309 309 try:
310 310 if suppress_errors is not None:
311 311 old_value = Application.raise_config_file_errors
312 312 Application.raise_config_file_errors = not suppress_errors;
313 313 Application.load_config_file(
314 314 self,
315 315 base_config,
316 316 path=self.config_file_paths
317 317 )
318 318 except ConfigFileNotFound:
319 319 # ignore errors loading parent
320 320 self.log.debug("Config file %s not found", base_config)
321 321 pass
322 322 if suppress_errors is not None:
323 323 Application.raise_config_file_errors = old_value
324 324
325 325 for config_file_name in self.config_files:
326 326 if not config_file_name or config_file_name == base_config:
327 327 continue
328 328 self.log.debug("Attempting to load config file: %s" %
329 329 self.config_file_name)
330 330 try:
331 331 Application.load_config_file(
332 332 self,
333 333 config_file_name,
334 334 path=self.config_file_paths
335 335 )
336 336 except ConfigFileNotFound:
337 337 # Only warn if the default config file was NOT being used.
338 338 if config_file_name in self.config_file_specified:
339 339 msg = self.log.warning
340 340 else:
341 341 msg = self.log.debug
342 342 msg("Config file not found, skipping: %s", config_file_name)
343 343 except Exception:
344 344 # For testing purposes.
345 345 if not suppress_errors:
346 346 raise
347 347 self.log.warning("Error loading config file: %s" %
348 348 self.config_file_name, exc_info=True)
349 349
350 350 def init_profile_dir(self):
351 351 """initialize the profile dir"""
352 352 self._in_init_profile_dir = True
353 353 if self.profile_dir is not None:
354 354 # already ran
355 355 return
356 356 if 'ProfileDir.location' not in self.config:
357 357 # location not specified, find by profile name
358 358 try:
359 359 p = ProfileDir.find_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
360 360 except ProfileDirError:
361 361 # not found, maybe create it (always create default profile)
362 362 if self.auto_create or self.profile == 'default':
363 363 try:
364 364 p = ProfileDir.create_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
365 365 except ProfileDirError:
366 366 self.log.fatal("Could not create profile: %r"%self.profile)
367 367 self.exit(1)
368 368 else:
369 369 self.log.info("Created profile dir: %r"%p.location)
370 370 else:
371 371 self.log.fatal("Profile %r not found."%self.profile)
372 372 self.exit(1)
373 373 else:
374 374 self.log.debug("Using existing profile dir: %r"%p.location)
375 375 else:
376 376 location = self.config.ProfileDir.location
377 377 # location is fully specified
378 378 try:
379 379 p = ProfileDir.find_profile_dir(location, self.config)
380 380 except ProfileDirError:
381 381 # not found, maybe create it
382 382 if self.auto_create:
383 383 try:
384 384 p = ProfileDir.create_profile_dir(location, self.config)
385 385 except ProfileDirError:
386 386 self.log.fatal("Could not create profile directory: %r"%location)
387 387 self.exit(1)
388 388 else:
389 389 self.log.debug("Creating new profile dir: %r"%location)
390 390 else:
391 391 self.log.fatal("Profile directory %r not found."%location)
392 392 self.exit(1)
393 393 else:
394 394 self.log.info("Using existing profile dir: %r"%location)
395 395 # if profile_dir is specified explicitly, set profile name
396 396 dir_name = os.path.basename(p.location)
397 397 if dir_name.startswith('profile_'):
398 398 self.profile = dir_name[8:]
399 399
400 400 self.profile_dir = p
401 401 self.config_file_paths.append(p.location)
402 402 self._in_init_profile_dir = False
403 403
404 404 def init_config_files(self):
405 405 """[optionally] copy default config files into profile dir."""
406 406 self.config_file_paths.extend(SYSTEM_CONFIG_DIRS)
407 407 # copy config files
408 408 path = self.builtin_profile_dir
409 409 if self.copy_config_files:
410 410 src = self.profile
411 411
412 412 cfg = self.config_file_name
413 413 if path and os.path.exists(os.path.join(path, cfg)):
414 414 self.log.warning("Staging %r from %s into %r [overwrite=%s]"%(
415 415 cfg, src, self.profile_dir.location, self.overwrite)
416 416 )
417 417 self.profile_dir.copy_config_file(cfg, path=path, overwrite=self.overwrite)
418 418 else:
419 419 self.stage_default_config_file()
420 420 else:
421 421 # Still stage *bundled* config files, but not generated ones
422 422 # This is necessary for `ipython profile=sympy` to load the profile
423 423 # on the first go
424 424 files = glob.glob(os.path.join(path, '*.py'))
425 425 for fullpath in files:
426 426 cfg = os.path.basename(fullpath)
427 427 if self.profile_dir.copy_config_file(cfg, path=path, overwrite=False):
428 428 # file was copied
429 429 self.log.warning("Staging bundled %s from %s into %r"%(
430 430 cfg, self.profile, self.profile_dir.location)
431 431 )
432 432
433 433
434 434 def stage_default_config_file(self):
435 435 """auto generate default config file, and stage it into the profile."""
436 436 s = self.generate_config_file()
437 437 fname = os.path.join(self.profile_dir.location, self.config_file_name)
438 438 if self.overwrite or not os.path.exists(fname):
439 439 self.log.warning("Generating default config file: %r"%(fname))
440 440 with open(fname, 'w') as f:
441 441 f.write(s)
442 442
443 443 @catch_config_error
444 444 def initialize(self, argv=None):
445 445 # don't hook up crash handler before parsing command-line
446 446 self.parse_command_line(argv)
447 447 self.init_crash_handler()
448 448 if self.subapp is not None:
449 449 # stop here if subapp is taking over
450 450 return
451 451 # save a copy of CLI config to re-load after config files
452 452 # so that it has highest priority
453 453 cl_config = deepcopy(self.config)
454 454 self.init_profile_dir()
455 455 self.init_config_files()
456 456 self.load_config_file()
457 457 # enforce cl-opts override configfile opts:
458 458 self.update_config(cl_config)
@@ -1,103 +1,103 b''
1 1 """
2 2 A context manager for managing things injected into :mod:`__builtin__`.
3 3
4 4 Authors:
5 5
6 6 * Brian Granger
7 7 * Fernando Perez
8 8 """
9 9 #-----------------------------------------------------------------------------
10 10 # Copyright (C) 2010-2011 The IPython Development Team.
11 11 #
12 12 # Distributed under the terms of the BSD License.
13 13 #
14 14 # Complete license in the file COPYING.txt, distributed with this software.
15 15 #-----------------------------------------------------------------------------
16 16
17 17 #-----------------------------------------------------------------------------
18 18 # Imports
19 19 #-----------------------------------------------------------------------------
20 20
21 21 from traitlets.config.configurable import Configurable
22 22
23 from IPython.utils.py3compat import builtin_mod, iteritems
23 from IPython.utils.py3compat import builtin_mod
24 24 from traitlets import Instance
25 25
26 26 #-----------------------------------------------------------------------------
27 27 # Classes and functions
28 28 #-----------------------------------------------------------------------------
29 29
30 30 class __BuiltinUndefined(object): pass
31 31 BuiltinUndefined = __BuiltinUndefined()
32 32
33 33 class __HideBuiltin(object): pass
34 34 HideBuiltin = __HideBuiltin()
35 35
36 36
37 37 class BuiltinTrap(Configurable):
38 38
39 39 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
40 40 allow_none=True)
41 41
42 42 def __init__(self, shell=None):
43 43 super(BuiltinTrap, self).__init__(shell=shell, config=None)
44 44 self._orig_builtins = {}
45 45 # We define this to track if a single BuiltinTrap is nested.
46 46 # Only turn off the trap when the outermost call to __exit__ is made.
47 47 self._nested_level = 0
48 48 self.shell = shell
49 49 # builtins we always add - if set to HideBuiltin, they will just
50 50 # be removed instead of being replaced by something else
51 51 self.auto_builtins = {'exit': HideBuiltin,
52 52 'quit': HideBuiltin,
53 53 'get_ipython': self.shell.get_ipython,
54 54 }
55 55
56 56 def __enter__(self):
57 57 if self._nested_level == 0:
58 58 self.activate()
59 59 self._nested_level += 1
60 60 # I return self, so callers can use add_builtin in a with clause.
61 61 return self
62 62
63 63 def __exit__(self, type, value, traceback):
64 64 if self._nested_level == 1:
65 65 self.deactivate()
66 66 self._nested_level -= 1
67 67 # Returning False will cause exceptions to propagate
68 68 return False
69 69
70 70 def add_builtin(self, key, value):
71 71 """Add a builtin and save the original."""
72 72 bdict = builtin_mod.__dict__
73 73 orig = bdict.get(key, BuiltinUndefined)
74 74 if value is HideBuiltin:
75 75 if orig is not BuiltinUndefined: #same as 'key in bdict'
76 76 self._orig_builtins[key] = orig
77 77 del bdict[key]
78 78 else:
79 79 self._orig_builtins[key] = orig
80 80 bdict[key] = value
81 81
82 82 def remove_builtin(self, key, orig):
83 83 """Remove an added builtin and re-set the original."""
84 84 if orig is BuiltinUndefined:
85 85 del builtin_mod.__dict__[key]
86 86 else:
87 87 builtin_mod.__dict__[key] = orig
88 88
89 89 def activate(self):
90 90 """Store ipython references in the __builtin__ namespace."""
91 91
92 92 add_builtin = self.add_builtin
93 for name, func in iteritems(self.auto_builtins):
93 for name, func in self.auto_builtins.items():
94 94 add_builtin(name, func)
95 95
96 96 def deactivate(self):
97 97 """Remove any builtins which might have been added by add_builtins, or
98 98 restore overwritten ones to their previous values."""
99 99 remove_builtin = self.remove_builtin
100 for key, val in iteritems(self._orig_builtins):
100 for key, val in self._orig_builtins.items():
101 101 remove_builtin(key, val)
102 102 self._orig_builtins.clear()
103 103 self._builtins_added = False
@@ -1,1229 +1,1229 b''
1 1 # encoding: utf-8
2 2 """Word completion for IPython.
3 3
4 4 This module started as fork of the rlcompleter module in the Python standard
5 5 library. The original enhancements made to rlcompleter have been sent
6 6 upstream and were accepted as of Python 2.3,
7 7
8 8 """
9 9
10 10 # Copyright (c) IPython Development Team.
11 11 # Distributed under the terms of the Modified BSD License.
12 12 #
13 13 # Some of this code originated from rlcompleter in the Python standard library
14 14 # Copyright (C) 2001 Python Software Foundation, www.python.org
15 15
16 16
17 17 import __main__
18 18 import glob
19 19 import inspect
20 20 import itertools
21 21 import keyword
22 22 import os
23 23 import re
24 24 import sys
25 25 import unicodedata
26 26 import string
27 27 import warnings
28 28 from importlib import import_module
29 29
30 30 from traitlets.config.configurable import Configurable
31 31 from IPython.core.error import TryNext
32 32 from IPython.core.inputsplitter import ESC_MAGIC
33 33 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
34 34 from IPython.utils import generics
35 35 from IPython.utils.decorators import undoc
36 36 from IPython.utils.dir2 import dir2, get_real_method
37 37 from IPython.utils.process import arg_split
38 from IPython.utils.py3compat import builtin_mod, string_types, PY3, cast_unicode_py2
38 from IPython.utils.py3compat import builtin_mod, PY3, cast_unicode_py2
39 39 from traitlets import Bool, Enum, observe
40 40
41 41 from functools import wraps
42 42
43 43 #-----------------------------------------------------------------------------
44 44 # Globals
45 45 #-----------------------------------------------------------------------------
46 46
47 47 # Public API
48 48 __all__ = ['Completer','IPCompleter']
49 49
50 50 if sys.platform == 'win32':
51 51 PROTECTABLES = ' '
52 52 else:
53 53 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
54 54
55 55
56 56 #-----------------------------------------------------------------------------
57 57 # Work around BUG decorators.
58 58 #-----------------------------------------------------------------------------
59 59
60 60 def _strip_single_trailing_space(complete):
61 61 """
62 62 This is a workaround for a weird IPython/Prompt_toolkit behavior,
63 63 that can be removed once we rely on a slightly more recent prompt_toolkit
64 64 version (likely > 1.0.3). So this can likely be removed in IPython 6.0
65 65
66 66 cf https://github.com/ipython/ipython/issues/9658
67 67 and https://github.com/jonathanslenders/python-prompt-toolkit/pull/328
68 68
69 69 The bug is due to the fact that in PTK the completer will reinvoke itself
70 70 after trying to completer to the longuest common prefix of all the
71 71 completions, unless only one completion is available.
72 72
73 73 This logic is faulty if the completion ends with space, which can happen in
74 74 case like::
75 75
76 76 from foo import im<ta>
77 77
78 78 which only matching completion is `import `. Note the leading space at the
79 79 end. So leaving a space at the end is a reasonable request, but for now
80 80 we'll strip it.
81 81 """
82 82
83 83 @wraps(complete)
84 84 def comp(*args, **kwargs):
85 85 text, matches = complete(*args, **kwargs)
86 86 if len(matches) == 1:
87 87 return text, [matches[0].rstrip()]
88 88 return text, matches
89 89
90 90 return comp
91 91
92 92
93 93
94 94 #-----------------------------------------------------------------------------
95 95 # Main functions and classes
96 96 #-----------------------------------------------------------------------------
97 97
98 98 def has_open_quotes(s):
99 99 """Return whether a string has open quotes.
100 100
101 101 This simply counts whether the number of quote characters of either type in
102 102 the string is odd.
103 103
104 104 Returns
105 105 -------
106 106 If there is an open quote, the quote character is returned. Else, return
107 107 False.
108 108 """
109 109 # We check " first, then ', so complex cases with nested quotes will get
110 110 # the " to take precedence.
111 111 if s.count('"') % 2:
112 112 return '"'
113 113 elif s.count("'") % 2:
114 114 return "'"
115 115 else:
116 116 return False
117 117
118 118
119 119 def protect_filename(s):
120 120 """Escape a string to protect certain characters."""
121 121 if set(s) & set(PROTECTABLES):
122 122 if sys.platform == "win32":
123 123 return '"' + s + '"'
124 124 else:
125 125 return "".join(("\\" + c if c in PROTECTABLES else c) for c in s)
126 126 else:
127 127 return s
128 128
129 129
130 130 def expand_user(path):
131 131 """Expand '~'-style usernames in strings.
132 132
133 133 This is similar to :func:`os.path.expanduser`, but it computes and returns
134 134 extra information that will be useful if the input was being used in
135 135 computing completions, and you wish to return the completions with the
136 136 original '~' instead of its expanded value.
137 137
138 138 Parameters
139 139 ----------
140 140 path : str
141 141 String to be expanded. If no ~ is present, the output is the same as the
142 142 input.
143 143
144 144 Returns
145 145 -------
146 146 newpath : str
147 147 Result of ~ expansion in the input path.
148 148 tilde_expand : bool
149 149 Whether any expansion was performed or not.
150 150 tilde_val : str
151 151 The value that ~ was replaced with.
152 152 """
153 153 # Default values
154 154 tilde_expand = False
155 155 tilde_val = ''
156 156 newpath = path
157 157
158 158 if path.startswith('~'):
159 159 tilde_expand = True
160 160 rest = len(path)-1
161 161 newpath = os.path.expanduser(path)
162 162 if rest:
163 163 tilde_val = newpath[:-rest]
164 164 else:
165 165 tilde_val = newpath
166 166
167 167 return newpath, tilde_expand, tilde_val
168 168
169 169
170 170 def compress_user(path, tilde_expand, tilde_val):
171 171 """Does the opposite of expand_user, with its outputs.
172 172 """
173 173 if tilde_expand:
174 174 return path.replace(tilde_val, '~')
175 175 else:
176 176 return path
177 177
178 178
179 179 def completions_sorting_key(word):
180 180 """key for sorting completions
181 181
182 182 This does several things:
183 183
184 184 - Lowercase all completions, so they are sorted alphabetically with
185 185 upper and lower case words mingled
186 186 - Demote any completions starting with underscores to the end
187 187 - Insert any %magic and %%cellmagic completions in the alphabetical order
188 188 by their name
189 189 """
190 190 # Case insensitive sort
191 191 word = word.lower()
192 192
193 193 prio1, prio2 = 0, 0
194 194
195 195 if word.startswith('__'):
196 196 prio1 = 2
197 197 elif word.startswith('_'):
198 198 prio1 = 1
199 199
200 200 if word.endswith('='):
201 201 prio1 = -1
202 202
203 203 if word.startswith('%%'):
204 204 # If there's another % in there, this is something else, so leave it alone
205 205 if not "%" in word[2:]:
206 206 word = word[2:]
207 207 prio2 = 2
208 208 elif word.startswith('%'):
209 209 if not "%" in word[1:]:
210 210 word = word[1:]
211 211 prio2 = 1
212 212
213 213 return prio1, word, prio2
214 214
215 215
216 216 @undoc
217 217 class Bunch(object): pass
218 218
219 219
220 220 if sys.platform == 'win32':
221 221 DELIMS = ' \t\n`!@#$^&*()=+[{]}|;\'",<>?'
222 222 else:
223 223 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
224 224
225 225 GREEDY_DELIMS = ' =\r\n'
226 226
227 227
228 228 class CompletionSplitter(object):
229 229 """An object to split an input line in a manner similar to readline.
230 230
231 231 By having our own implementation, we can expose readline-like completion in
232 232 a uniform manner to all frontends. This object only needs to be given the
233 233 line of text to be split and the cursor position on said line, and it
234 234 returns the 'word' to be completed on at the cursor after splitting the
235 235 entire line.
236 236
237 237 What characters are used as splitting delimiters can be controlled by
238 238 setting the `delims` attribute (this is a property that internally
239 239 automatically builds the necessary regular expression)"""
240 240
241 241 # Private interface
242 242
243 243 # A string of delimiter characters. The default value makes sense for
244 244 # IPython's most typical usage patterns.
245 245 _delims = DELIMS
246 246
247 247 # The expression (a normal string) to be compiled into a regular expression
248 248 # for actual splitting. We store it as an attribute mostly for ease of
249 249 # debugging, since this type of code can be so tricky to debug.
250 250 _delim_expr = None
251 251
252 252 # The regular expression that does the actual splitting
253 253 _delim_re = None
254 254
255 255 def __init__(self, delims=None):
256 256 delims = CompletionSplitter._delims if delims is None else delims
257 257 self.delims = delims
258 258
259 259 @property
260 260 def delims(self):
261 261 """Return the string of delimiter characters."""
262 262 return self._delims
263 263
264 264 @delims.setter
265 265 def delims(self, delims):
266 266 """Set the delimiters for line splitting."""
267 267 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
268 268 self._delim_re = re.compile(expr)
269 269 self._delims = delims
270 270 self._delim_expr = expr
271 271
272 272 def split_line(self, line, cursor_pos=None):
273 273 """Split a line of text with a cursor at the given position.
274 274 """
275 275 l = line if cursor_pos is None else line[:cursor_pos]
276 276 return self._delim_re.split(l)[-1]
277 277
278 278
279 279 class Completer(Configurable):
280 280
281 281 greedy = Bool(False,
282 282 help="""Activate greedy completion
283 283 PENDING DEPRECTION. this is now mostly taken care of with Jedi.
284 284
285 285 This will enable completion on elements of lists, results of function calls, etc.,
286 286 but can be unsafe because the code is actually evaluated on TAB.
287 287 """
288 288 ).tag(config=True)
289 289
290 290
291 291 def __init__(self, namespace=None, global_namespace=None, **kwargs):
292 292 """Create a new completer for the command line.
293 293
294 294 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
295 295
296 296 If unspecified, the default namespace where completions are performed
297 297 is __main__ (technically, __main__.__dict__). Namespaces should be
298 298 given as dictionaries.
299 299
300 300 An optional second namespace can be given. This allows the completer
301 301 to handle cases where both the local and global scopes need to be
302 302 distinguished.
303 303
304 304 Completer instances should be used as the completion mechanism of
305 305 readline via the set_completer() call:
306 306
307 307 readline.set_completer(Completer(my_namespace).complete)
308 308 """
309 309
310 310 # Don't bind to namespace quite yet, but flag whether the user wants a
311 311 # specific namespace or to use __main__.__dict__. This will allow us
312 312 # to bind to __main__.__dict__ at completion time, not now.
313 313 if namespace is None:
314 314 self.use_main_ns = 1
315 315 else:
316 316 self.use_main_ns = 0
317 317 self.namespace = namespace
318 318
319 319 # The global namespace, if given, can be bound directly
320 320 if global_namespace is None:
321 321 self.global_namespace = {}
322 322 else:
323 323 self.global_namespace = global_namespace
324 324
325 325 super(Completer, self).__init__(**kwargs)
326 326
327 327 def complete(self, text, state):
328 328 """Return the next possible completion for 'text'.
329 329
330 330 This is called successively with state == 0, 1, 2, ... until it
331 331 returns None. The completion should begin with 'text'.
332 332
333 333 """
334 334 if self.use_main_ns:
335 335 self.namespace = __main__.__dict__
336 336
337 337 if state == 0:
338 338 if "." in text:
339 339 self.matches = self.attr_matches(text)
340 340 else:
341 341 self.matches = self.global_matches(text)
342 342 try:
343 343 return self.matches[state]
344 344 except IndexError:
345 345 return None
346 346
347 347 def global_matches(self, text):
348 348 """Compute matches when text is a simple name.
349 349
350 350 Return a list of all keywords, built-in functions and names currently
351 351 defined in self.namespace or self.global_namespace that match.
352 352
353 353 """
354 354 matches = []
355 355 match_append = matches.append
356 356 n = len(text)
357 357 for lst in [keyword.kwlist,
358 358 builtin_mod.__dict__.keys(),
359 359 self.namespace.keys(),
360 360 self.global_namespace.keys()]:
361 361 for word in lst:
362 362 if word[:n] == text and word != "__builtins__":
363 363 match_append(word)
364 364 return [cast_unicode_py2(m) for m in matches]
365 365
366 366 def attr_matches(self, text):
367 367 """Compute matches when text contains a dot.
368 368
369 369 Assuming the text is of the form NAME.NAME....[NAME], and is
370 370 evaluatable in self.namespace or self.global_namespace, it will be
371 371 evaluated and its attributes (as revealed by dir()) are used as
372 372 possible completions. (For class instances, class members are are
373 373 also considered.)
374 374
375 375 WARNING: this can still invoke arbitrary C code, if an object
376 376 with a __getattr__ hook is evaluated.
377 377
378 378 """
379 379
380 380 # Another option, seems to work great. Catches things like ''.<tab>
381 381 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
382 382
383 383 if m:
384 384 expr, attr = m.group(1, 3)
385 385 elif self.greedy:
386 386 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
387 387 if not m2:
388 388 return []
389 389 expr, attr = m2.group(1,2)
390 390 else:
391 391 return []
392 392
393 393 try:
394 394 obj = eval(expr, self.namespace)
395 395 except:
396 396 try:
397 397 obj = eval(expr, self.global_namespace)
398 398 except:
399 399 return []
400 400
401 401 if self.limit_to__all__ and hasattr(obj, '__all__'):
402 402 words = get__all__entries(obj)
403 403 else:
404 404 words = dir2(obj)
405 405
406 406 try:
407 407 words = generics.complete_object(obj, words)
408 408 except TryNext:
409 409 pass
410 410 except Exception:
411 411 # Silence errors from completion function
412 412 #raise # dbg
413 413 pass
414 414 # Build match list to return
415 415 n = len(attr)
416 416 return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ]
417 417
418 418
419 419 def get__all__entries(obj):
420 420 """returns the strings in the __all__ attribute"""
421 421 try:
422 422 words = getattr(obj, '__all__')
423 423 except:
424 424 return []
425 425
426 return [cast_unicode_py2(w) for w in words if isinstance(w, string_types)]
426 return [cast_unicode_py2(w) for w in words if isinstance(w, str)]
427 427
428 428
429 429 def match_dict_keys(keys, prefix, delims):
430 430 """Used by dict_key_matches, matching the prefix to a list of keys"""
431 431 if not prefix:
432 432 return None, 0, [repr(k) for k in keys
433 if isinstance(k, (string_types, bytes))]
433 if isinstance(k, (str, bytes))]
434 434 quote_match = re.search('["\']', prefix)
435 435 quote = quote_match.group()
436 436 try:
437 437 prefix_str = eval(prefix + quote, {})
438 438 except Exception:
439 439 return None, 0, []
440 440
441 441 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
442 442 token_match = re.search(pattern, prefix, re.UNICODE)
443 443 token_start = token_match.start()
444 444 token_prefix = token_match.group()
445 445
446 446 # TODO: support bytes in Py3k
447 447 matched = []
448 448 for key in keys:
449 449 try:
450 450 if not key.startswith(prefix_str):
451 451 continue
452 452 except (AttributeError, TypeError, UnicodeError):
453 453 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
454 454 continue
455 455
456 456 # reformat remainder of key to begin with prefix
457 457 rem = key[len(prefix_str):]
458 458 # force repr wrapped in '
459 459 rem_repr = repr(rem + '"')
460 460 if rem_repr.startswith('u') and prefix[0] not in 'uU':
461 461 # Found key is unicode, but prefix is Py2 string.
462 462 # Therefore attempt to interpret key as string.
463 463 try:
464 464 rem_repr = repr(rem.encode('ascii') + '"')
465 465 except UnicodeEncodeError:
466 466 continue
467 467
468 468 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
469 469 if quote == '"':
470 470 # The entered prefix is quoted with ",
471 471 # but the match is quoted with '.
472 472 # A contained " hence needs escaping for comparison:
473 473 rem_repr = rem_repr.replace('"', '\\"')
474 474
475 475 # then reinsert prefix from start of token
476 476 matched.append('%s%s' % (token_prefix, rem_repr))
477 477 return quote, token_start, matched
478 478
479 479
480 480 def _safe_isinstance(obj, module, class_name):
481 481 """Checks if obj is an instance of module.class_name if loaded
482 482 """
483 483 return (module in sys.modules and
484 484 isinstance(obj, getattr(import_module(module), class_name)))
485 485
486 486
487 487 def back_unicode_name_matches(text):
488 488 u"""Match unicode characters back to unicode name
489 489
490 490 This does ☃ -> \\snowman
491 491
492 492 Note that snowman is not a valid python3 combining character but will be expanded.
493 493 Though it will not recombine back to the snowman character by the completion machinery.
494 494
495 495 This will not either back-complete standard sequences like \\n, \\b ...
496 496
497 497 Used on Python 3 only.
498 498 """
499 499 if len(text)<2:
500 500 return u'', ()
501 501 maybe_slash = text[-2]
502 502 if maybe_slash != '\\':
503 503 return u'', ()
504 504
505 505 char = text[-1]
506 506 # no expand on quote for completion in strings.
507 507 # nor backcomplete standard ascii keys
508 508 if char in string.ascii_letters or char in ['"',"'"]:
509 509 return u'', ()
510 510 try :
511 511 unic = unicodedata.name(char)
512 512 return '\\'+char,['\\'+unic]
513 513 except KeyError:
514 514 pass
515 515 return u'', ()
516 516
517 517 def back_latex_name_matches(text):
518 518 u"""Match latex characters back to unicode name
519 519
520 520 This does ->\\sqrt
521 521
522 522 Used on Python 3 only.
523 523 """
524 524 if len(text)<2:
525 525 return u'', ()
526 526 maybe_slash = text[-2]
527 527 if maybe_slash != '\\':
528 528 return u'', ()
529 529
530 530
531 531 char = text[-1]
532 532 # no expand on quote for completion in strings.
533 533 # nor backcomplete standard ascii keys
534 534 if char in string.ascii_letters or char in ['"',"'"]:
535 535 return u'', ()
536 536 try :
537 537 latex = reverse_latex_symbol[char]
538 538 # '\\' replace the \ as well
539 539 return '\\'+char,[latex]
540 540 except KeyError:
541 541 pass
542 542 return u'', ()
543 543
544 544
545 545 class IPCompleter(Completer):
546 546 """Extension of the completer class with IPython-specific features"""
547 547
548 548 @observe('greedy')
549 549 def _greedy_changed(self, change):
550 550 """update the splitter and readline delims when greedy is changed"""
551 551 if change['new']:
552 552 self.splitter.delims = GREEDY_DELIMS
553 553 else:
554 554 self.splitter.delims = DELIMS
555 555
556 556 merge_completions = Bool(True,
557 557 help="""Whether to merge completion results into a single list
558 558
559 559 If False, only the completion results from the first non-empty
560 560 completer will be returned.
561 561 """
562 562 ).tag(config=True)
563 563 omit__names = Enum((0,1,2), default_value=2,
564 564 help="""Instruct the completer to omit private method names
565 565
566 566 Specifically, when completing on ``object.<tab>``.
567 567
568 568 When 2 [default]: all names that start with '_' will be excluded.
569 569
570 570 When 1: all 'magic' names (``__foo__``) will be excluded.
571 571
572 572 When 0: nothing will be excluded.
573 573 """
574 574 ).tag(config=True)
575 575 limit_to__all__ = Bool(False,
576 576 help="""
577 577 DEPRECATED as of version 5.0.
578 578
579 579 Instruct the completer to use __all__ for the completion
580 580
581 581 Specifically, when completing on ``object.<tab>``.
582 582
583 583 When True: only those names in obj.__all__ will be included.
584 584
585 585 When False [default]: the __all__ attribute is ignored
586 586 """,
587 587 ).tag(config=True)
588 588
589 589 def __init__(self, shell=None, namespace=None, global_namespace=None,
590 590 use_readline=False, config=None, **kwargs):
591 591 """IPCompleter() -> completer
592 592
593 593 Return a completer object suitable for use by the readline library
594 594 via readline.set_completer().
595 595
596 596 Inputs:
597 597
598 598 - shell: a pointer to the ipython shell itself. This is needed
599 599 because this completer knows about magic functions, and those can
600 600 only be accessed via the ipython instance.
601 601
602 602 - namespace: an optional dict where completions are performed.
603 603
604 604 - global_namespace: secondary optional dict for completions, to
605 605 handle cases (such as IPython embedded inside functions) where
606 606 both Python scopes are visible.
607 607
608 608 use_readline : bool, optional
609 609 DEPRECATED, ignored.
610 610 """
611 611
612 612 self.magic_escape = ESC_MAGIC
613 613 self.splitter = CompletionSplitter()
614 614
615 615 if use_readline:
616 616 warnings.warn('The use_readline parameter is deprecated and ignored since IPython 6.0.',
617 617 DeprecationWarning, stacklevel=2)
618 618
619 619 # _greedy_changed() depends on splitter and readline being defined:
620 620 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
621 621 config=config, **kwargs)
622 622
623 623 # List where completion matches will be stored
624 624 self.matches = []
625 625 self.shell = shell
626 626 # Regexp to split filenames with spaces in them
627 627 self.space_name_re = re.compile(r'([^\\] )')
628 628 # Hold a local ref. to glob.glob for speed
629 629 self.glob = glob.glob
630 630
631 631 # Determine if we are running on 'dumb' terminals, like (X)Emacs
632 632 # buffers, to avoid completion problems.
633 633 term = os.environ.get('TERM','xterm')
634 634 self.dumb_terminal = term in ['dumb','emacs']
635 635
636 636 # Special handling of backslashes needed in win32 platforms
637 637 if sys.platform == "win32":
638 638 self.clean_glob = self._clean_glob_win32
639 639 else:
640 640 self.clean_glob = self._clean_glob
641 641
642 642 #regexp to parse docstring for function signature
643 643 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
644 644 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
645 645 #use this if positional argument name is also needed
646 646 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
647 647
648 648 # All active matcher routines for completion
649 649 self.matchers = [
650 650 self.python_matches,
651 651 self.file_matches,
652 652 self.magic_matches,
653 653 self.python_func_kw_matches,
654 654 self.dict_key_matches,
655 655 ]
656 656
657 657 # This is set externally by InteractiveShell
658 658 self.custom_completers = None
659 659
660 660 def all_completions(self, text):
661 661 """
662 662 Wrapper around the complete method for the benefit of emacs.
663 663 """
664 664 return self.complete(text)[1]
665 665
666 666 def _clean_glob(self, text):
667 667 return self.glob("%s*" % text)
668 668
669 669 def _clean_glob_win32(self,text):
670 670 return [f.replace("\\","/")
671 671 for f in self.glob("%s*" % text)]
672 672
673 673 def file_matches(self, text):
674 674 """Match filenames, expanding ~USER type strings.
675 675
676 676 Most of the seemingly convoluted logic in this completer is an
677 677 attempt to handle filenames with spaces in them. And yet it's not
678 678 quite perfect, because Python's readline doesn't expose all of the
679 679 GNU readline details needed for this to be done correctly.
680 680
681 681 For a filename with a space in it, the printed completions will be
682 682 only the parts after what's already been typed (instead of the
683 683 full completions, as is normally done). I don't think with the
684 684 current (as of Python 2.3) Python readline it's possible to do
685 685 better."""
686 686
687 687 # chars that require escaping with backslash - i.e. chars
688 688 # that readline treats incorrectly as delimiters, but we
689 689 # don't want to treat as delimiters in filename matching
690 690 # when escaped with backslash
691 691 if text.startswith('!'):
692 692 text = text[1:]
693 693 text_prefix = u'!'
694 694 else:
695 695 text_prefix = u''
696 696
697 697 text_until_cursor = self.text_until_cursor
698 698 # track strings with open quotes
699 699 open_quotes = has_open_quotes(text_until_cursor)
700 700
701 701 if '(' in text_until_cursor or '[' in text_until_cursor:
702 702 lsplit = text
703 703 else:
704 704 try:
705 705 # arg_split ~ shlex.split, but with unicode bugs fixed by us
706 706 lsplit = arg_split(text_until_cursor)[-1]
707 707 except ValueError:
708 708 # typically an unmatched ", or backslash without escaped char.
709 709 if open_quotes:
710 710 lsplit = text_until_cursor.split(open_quotes)[-1]
711 711 else:
712 712 return []
713 713 except IndexError:
714 714 # tab pressed on empty line
715 715 lsplit = ""
716 716
717 717 if not open_quotes and lsplit != protect_filename(lsplit):
718 718 # if protectables are found, do matching on the whole escaped name
719 719 has_protectables = True
720 720 text0,text = text,lsplit
721 721 else:
722 722 has_protectables = False
723 723 text = os.path.expanduser(text)
724 724
725 725 if text == "":
726 726 return [text_prefix + cast_unicode_py2(protect_filename(f)) for f in self.glob("*")]
727 727
728 728 # Compute the matches from the filesystem
729 729 if sys.platform == 'win32':
730 730 m0 = self.clean_glob(text)
731 731 else:
732 732 m0 = self.clean_glob(text.replace('\\', ''))
733 733
734 734 if has_protectables:
735 735 # If we had protectables, we need to revert our changes to the
736 736 # beginning of filename so that we don't double-write the part
737 737 # of the filename we have so far
738 738 len_lsplit = len(lsplit)
739 739 matches = [text_prefix + text0 +
740 740 protect_filename(f[len_lsplit:]) for f in m0]
741 741 else:
742 742 if open_quotes:
743 743 # if we have a string with an open quote, we don't need to
744 744 # protect the names at all (and we _shouldn't_, as it
745 745 # would cause bugs when the filesystem call is made).
746 746 matches = m0
747 747 else:
748 748 matches = [text_prefix +
749 749 protect_filename(f) for f in m0]
750 750
751 751 # Mark directories in input list by appending '/' to their names.
752 752 return [cast_unicode_py2(x+'/') if os.path.isdir(x) else x for x in matches]
753 753
754 754 def magic_matches(self, text):
755 755 """Match magics"""
756 756 # Get all shell magics now rather than statically, so magics loaded at
757 757 # runtime show up too.
758 758 lsm = self.shell.magics_manager.lsmagic()
759 759 line_magics = lsm['line']
760 760 cell_magics = lsm['cell']
761 761 pre = self.magic_escape
762 762 pre2 = pre+pre
763 763
764 764 # Completion logic:
765 765 # - user gives %%: only do cell magics
766 766 # - user gives %: do both line and cell magics
767 767 # - no prefix: do both
768 768 # In other words, line magics are skipped if the user gives %% explicitly
769 769 bare_text = text.lstrip(pre)
770 770 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
771 771 if not text.startswith(pre2):
772 772 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
773 773 return [cast_unicode_py2(c) for c in comp]
774 774
775 775
776 776 def python_matches(self, text):
777 777 """Match attributes or global python names"""
778 778 if "." in text:
779 779 try:
780 780 matches = self.attr_matches(text)
781 781 if text.endswith('.') and self.omit__names:
782 782 if self.omit__names == 1:
783 783 # true if txt is _not_ a __ name, false otherwise:
784 784 no__name = (lambda txt:
785 785 re.match(r'.*\.__.*?__',txt) is None)
786 786 else:
787 787 # true if txt is _not_ a _ name, false otherwise:
788 788 no__name = (lambda txt:
789 789 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
790 790 matches = filter(no__name, matches)
791 791 except NameError:
792 792 # catches <undefined attributes>.<tab>
793 793 matches = []
794 794 else:
795 795 matches = self.global_matches(text)
796 796 return matches
797 797
798 798 def _default_arguments_from_docstring(self, doc):
799 799 """Parse the first line of docstring for call signature.
800 800
801 801 Docstring should be of the form 'min(iterable[, key=func])\n'.
802 802 It can also parse cython docstring of the form
803 803 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
804 804 """
805 805 if doc is None:
806 806 return []
807 807
808 808 #care only the firstline
809 809 line = doc.lstrip().splitlines()[0]
810 810
811 811 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
812 812 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
813 813 sig = self.docstring_sig_re.search(line)
814 814 if sig is None:
815 815 return []
816 816 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
817 817 sig = sig.groups()[0].split(',')
818 818 ret = []
819 819 for s in sig:
820 820 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
821 821 ret += self.docstring_kwd_re.findall(s)
822 822 return ret
823 823
824 824 def _default_arguments(self, obj):
825 825 """Return the list of default arguments of obj if it is callable,
826 826 or empty list otherwise."""
827 827 call_obj = obj
828 828 ret = []
829 829 if inspect.isbuiltin(obj):
830 830 pass
831 831 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
832 832 if inspect.isclass(obj):
833 833 #for cython embededsignature=True the constructor docstring
834 834 #belongs to the object itself not __init__
835 835 ret += self._default_arguments_from_docstring(
836 836 getattr(obj, '__doc__', ''))
837 837 # for classes, check for __init__,__new__
838 838 call_obj = (getattr(obj, '__init__', None) or
839 839 getattr(obj, '__new__', None))
840 840 # for all others, check if they are __call__able
841 841 elif hasattr(obj, '__call__'):
842 842 call_obj = obj.__call__
843 843 ret += self._default_arguments_from_docstring(
844 844 getattr(call_obj, '__doc__', ''))
845 845
846 846 _keeps = (inspect.Parameter.KEYWORD_ONLY,
847 847 inspect.Parameter.POSITIONAL_OR_KEYWORD)
848 848
849 849 try:
850 850 sig = inspect.signature(call_obj)
851 851 ret.extend(k for k, v in sig.parameters.items() if
852 852 v.kind in _keeps)
853 853 except ValueError:
854 854 pass
855 855
856 856 return list(set(ret))
857 857
858 858 def python_func_kw_matches(self,text):
859 859 """Match named parameters (kwargs) of the last open function"""
860 860
861 861 if "." in text: # a parameter cannot be dotted
862 862 return []
863 863 try: regexp = self.__funcParamsRegex
864 864 except AttributeError:
865 865 regexp = self.__funcParamsRegex = re.compile(r'''
866 866 '.*?(?<!\\)' | # single quoted strings or
867 867 ".*?(?<!\\)" | # double quoted strings or
868 868 \w+ | # identifier
869 869 \S # other characters
870 870 ''', re.VERBOSE | re.DOTALL)
871 871 # 1. find the nearest identifier that comes before an unclosed
872 872 # parenthesis before the cursor
873 873 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
874 874 tokens = regexp.findall(self.text_until_cursor)
875 875 iterTokens = reversed(tokens); openPar = 0
876 876
877 877 for token in iterTokens:
878 878 if token == ')':
879 879 openPar -= 1
880 880 elif token == '(':
881 881 openPar += 1
882 882 if openPar > 0:
883 883 # found the last unclosed parenthesis
884 884 break
885 885 else:
886 886 return []
887 887 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
888 888 ids = []
889 889 isId = re.compile(r'\w+$').match
890 890
891 891 while True:
892 892 try:
893 893 ids.append(next(iterTokens))
894 894 if not isId(ids[-1]):
895 895 ids.pop(); break
896 896 if not next(iterTokens) == '.':
897 897 break
898 898 except StopIteration:
899 899 break
900 900
901 901 # Find all named arguments already assigned to, as to avoid suggesting
902 902 # them again
903 903 usedNamedArgs = set()
904 904 par_level = -1
905 905 for token, next_token in zip(tokens, tokens[1:]):
906 906 if token == '(':
907 907 par_level += 1
908 908 elif token == ')':
909 909 par_level -= 1
910 910
911 911 if par_level != 0:
912 912 continue
913 913
914 914 if next_token != '=':
915 915 continue
916 916
917 917 usedNamedArgs.add(token)
918 918
919 919 # lookup the candidate callable matches either using global_matches
920 920 # or attr_matches for dotted names
921 921 if len(ids) == 1:
922 922 callableMatches = self.global_matches(ids[0])
923 923 else:
924 924 callableMatches = self.attr_matches('.'.join(ids[::-1]))
925 925 argMatches = []
926 926 for callableMatch in callableMatches:
927 927 try:
928 928 namedArgs = self._default_arguments(eval(callableMatch,
929 929 self.namespace))
930 930 except:
931 931 continue
932 932
933 933 # Remove used named arguments from the list, no need to show twice
934 934 for namedArg in set(namedArgs) - usedNamedArgs:
935 935 if namedArg.startswith(text):
936 936 argMatches.append(u"%s=" %namedArg)
937 937 return argMatches
938 938
939 939 def dict_key_matches(self, text):
940 940 "Match string keys in a dictionary, after e.g. 'foo[' "
941 941 def get_keys(obj):
942 942 # Objects can define their own completions by defining an
943 943 # _ipy_key_completions_() method.
944 944 method = get_real_method(obj, '_ipython_key_completions_')
945 945 if method is not None:
946 946 return method()
947 947
948 948 # Special case some common in-memory dict-like types
949 949 if isinstance(obj, dict) or\
950 950 _safe_isinstance(obj, 'pandas', 'DataFrame'):
951 951 try:
952 952 return list(obj.keys())
953 953 except Exception:
954 954 return []
955 955 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
956 956 _safe_isinstance(obj, 'numpy', 'void'):
957 957 return obj.dtype.names or []
958 958 return []
959 959
960 960 try:
961 961 regexps = self.__dict_key_regexps
962 962 except AttributeError:
963 963 dict_key_re_fmt = r'''(?x)
964 964 ( # match dict-referring expression wrt greedy setting
965 965 %s
966 966 )
967 967 \[ # open bracket
968 968 \s* # and optional whitespace
969 969 ([uUbB]? # string prefix (r not handled)
970 970 (?: # unclosed string
971 971 '(?:[^']|(?<!\\)\\')*
972 972 |
973 973 "(?:[^"]|(?<!\\)\\")*
974 974 )
975 975 )?
976 976 $
977 977 '''
978 978 regexps = self.__dict_key_regexps = {
979 979 False: re.compile(dict_key_re_fmt % '''
980 980 # identifiers separated by .
981 981 (?!\d)\w+
982 982 (?:\.(?!\d)\w+)*
983 983 '''),
984 984 True: re.compile(dict_key_re_fmt % '''
985 985 .+
986 986 ''')
987 987 }
988 988
989 989 match = regexps[self.greedy].search(self.text_until_cursor)
990 990 if match is None:
991 991 return []
992 992
993 993 expr, prefix = match.groups()
994 994 try:
995 995 obj = eval(expr, self.namespace)
996 996 except Exception:
997 997 try:
998 998 obj = eval(expr, self.global_namespace)
999 999 except Exception:
1000 1000 return []
1001 1001
1002 1002 keys = get_keys(obj)
1003 1003 if not keys:
1004 1004 return keys
1005 1005 closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims)
1006 1006 if not matches:
1007 1007 return matches
1008 1008
1009 1009 # get the cursor position of
1010 1010 # - the text being completed
1011 1011 # - the start of the key text
1012 1012 # - the start of the completion
1013 1013 text_start = len(self.text_until_cursor) - len(text)
1014 1014 if prefix:
1015 1015 key_start = match.start(2)
1016 1016 completion_start = key_start + token_offset
1017 1017 else:
1018 1018 key_start = completion_start = match.end()
1019 1019
1020 1020 # grab the leading prefix, to make sure all completions start with `text`
1021 1021 if text_start > key_start:
1022 1022 leading = ''
1023 1023 else:
1024 1024 leading = text[text_start:completion_start]
1025 1025
1026 1026 # the index of the `[` character
1027 1027 bracket_idx = match.end(1)
1028 1028
1029 1029 # append closing quote and bracket as appropriate
1030 1030 # this is *not* appropriate if the opening quote or bracket is outside
1031 1031 # the text given to this method
1032 1032 suf = ''
1033 1033 continuation = self.line_buffer[len(self.text_until_cursor):]
1034 1034 if key_start > text_start and closing_quote:
1035 1035 # quotes were opened inside text, maybe close them
1036 1036 if continuation.startswith(closing_quote):
1037 1037 continuation = continuation[len(closing_quote):]
1038 1038 else:
1039 1039 suf += closing_quote
1040 1040 if bracket_idx > text_start:
1041 1041 # brackets were opened inside text, maybe close them
1042 1042 if not continuation.startswith(']'):
1043 1043 suf += ']'
1044 1044
1045 1045 return [leading + k + suf for k in matches]
1046 1046
1047 1047 def unicode_name_matches(self, text):
1048 1048 u"""Match Latex-like syntax for unicode characters base
1049 1049 on the name of the character.
1050 1050
1051 1051 This does \\GREEK SMALL LETTER ETA -> η
1052 1052
1053 1053 Works only on valid python 3 identifier, or on combining characters that
1054 1054 will combine to form a valid identifier.
1055 1055
1056 1056 Used on Python 3 only.
1057 1057 """
1058 1058 slashpos = text.rfind('\\')
1059 1059 if slashpos > -1:
1060 1060 s = text[slashpos+1:]
1061 1061 try :
1062 1062 unic = unicodedata.lookup(s)
1063 1063 # allow combining chars
1064 1064 if ('a'+unic).isidentifier():
1065 1065 return '\\'+s,[unic]
1066 1066 except KeyError:
1067 1067 pass
1068 1068 return u'', []
1069 1069
1070 1070
1071 1071
1072 1072
1073 1073 def latex_matches(self, text):
1074 1074 u"""Match Latex syntax for unicode characters.
1075 1075
1076 1076 This does both \\alp -> \\alpha and \\alpha -> α
1077 1077
1078 1078 Used on Python 3 only.
1079 1079 """
1080 1080 slashpos = text.rfind('\\')
1081 1081 if slashpos > -1:
1082 1082 s = text[slashpos:]
1083 1083 if s in latex_symbols:
1084 1084 # Try to complete a full latex symbol to unicode
1085 1085 # \\alpha -> α
1086 1086 return s, [latex_symbols[s]]
1087 1087 else:
1088 1088 # If a user has partially typed a latex symbol, give them
1089 1089 # a full list of options \al -> [\aleph, \alpha]
1090 1090 matches = [k for k in latex_symbols if k.startswith(s)]
1091 1091 return s, matches
1092 1092 return u'', []
1093 1093
1094 1094 def dispatch_custom_completer(self, text):
1095 1095 if not self.custom_completers:
1096 1096 return
1097 1097
1098 1098 line = self.line_buffer
1099 1099 if not line.strip():
1100 1100 return None
1101 1101
1102 1102 # Create a little structure to pass all the relevant information about
1103 1103 # the current completion to any custom completer.
1104 1104 event = Bunch()
1105 1105 event.line = line
1106 1106 event.symbol = text
1107 1107 cmd = line.split(None,1)[0]
1108 1108 event.command = cmd
1109 1109 event.text_until_cursor = self.text_until_cursor
1110 1110
1111 1111 # for foo etc, try also to find completer for %foo
1112 1112 if not cmd.startswith(self.magic_escape):
1113 1113 try_magic = self.custom_completers.s_matches(
1114 1114 self.magic_escape + cmd)
1115 1115 else:
1116 1116 try_magic = []
1117 1117
1118 1118 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1119 1119 try_magic,
1120 1120 self.custom_completers.flat_matches(self.text_until_cursor)):
1121 1121 try:
1122 1122 res = c(event)
1123 1123 if res:
1124 1124 # first, try case sensitive match
1125 1125 withcase = [cast_unicode_py2(r) for r in res if r.startswith(text)]
1126 1126 if withcase:
1127 1127 return withcase
1128 1128 # if none, then case insensitive ones are ok too
1129 1129 text_low = text.lower()
1130 1130 return [cast_unicode_py2(r) for r in res if r.lower().startswith(text_low)]
1131 1131 except TryNext:
1132 1132 pass
1133 1133
1134 1134 return None
1135 1135
1136 1136 @_strip_single_trailing_space
1137 1137 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1138 1138 """Find completions for the given text and line context.
1139 1139
1140 1140 Note that both the text and the line_buffer are optional, but at least
1141 1141 one of them must be given.
1142 1142
1143 1143 Parameters
1144 1144 ----------
1145 1145 text : string, optional
1146 1146 Text to perform the completion on. If not given, the line buffer
1147 1147 is split using the instance's CompletionSplitter object.
1148 1148
1149 1149 line_buffer : string, optional
1150 1150 If not given, the completer attempts to obtain the current line
1151 1151 buffer via readline. This keyword allows clients which are
1152 1152 requesting for text completions in non-readline contexts to inform
1153 1153 the completer of the entire text.
1154 1154
1155 1155 cursor_pos : int, optional
1156 1156 Index of the cursor in the full line buffer. Should be provided by
1157 1157 remote frontends where kernel has no access to frontend state.
1158 1158
1159 1159 Returns
1160 1160 -------
1161 1161 text : str
1162 1162 Text that was actually used in the completion.
1163 1163
1164 1164 matches : list
1165 1165 A list of completion matches.
1166 1166 """
1167 1167 # if the cursor position isn't given, the only sane assumption we can
1168 1168 # make is that it's at the end of the line (the common case)
1169 1169 if cursor_pos is None:
1170 1170 cursor_pos = len(line_buffer) if text is None else len(text)
1171 1171
1172 1172 if self.use_main_ns:
1173 1173 self.namespace = __main__.__dict__
1174 1174
1175 1175 if PY3:
1176 1176
1177 1177 base_text = text if not line_buffer else line_buffer[:cursor_pos]
1178 1178 latex_text, latex_matches = self.latex_matches(base_text)
1179 1179 if latex_matches:
1180 1180 return latex_text, latex_matches
1181 1181 name_text = ''
1182 1182 name_matches = []
1183 1183 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches):
1184 1184 name_text, name_matches = meth(base_text)
1185 1185 if name_text:
1186 1186 return name_text, name_matches
1187 1187
1188 1188 # if text is either None or an empty string, rely on the line buffer
1189 1189 if not text:
1190 1190 text = self.splitter.split_line(line_buffer, cursor_pos)
1191 1191
1192 1192 # If no line buffer is given, assume the input text is all there was
1193 1193 if line_buffer is None:
1194 1194 line_buffer = text
1195 1195
1196 1196 self.line_buffer = line_buffer
1197 1197 self.text_until_cursor = self.line_buffer[:cursor_pos]
1198 1198
1199 1199 # Start with a clean slate of completions
1200 1200 self.matches[:] = []
1201 1201 custom_res = self.dispatch_custom_completer(text)
1202 1202 if custom_res is not None:
1203 1203 # did custom completers produce something?
1204 1204 self.matches = custom_res
1205 1205 else:
1206 1206 # Extend the list of completions with the results of each
1207 1207 # matcher, so we return results to the user from all
1208 1208 # namespaces.
1209 1209 if self.merge_completions:
1210 1210 self.matches = []
1211 1211 for matcher in self.matchers:
1212 1212 try:
1213 1213 self.matches.extend(matcher(text))
1214 1214 except:
1215 1215 # Show the ugly traceback if the matcher causes an
1216 1216 # exception, but do NOT crash the kernel!
1217 1217 sys.excepthook(*sys.exc_info())
1218 1218 else:
1219 1219 for matcher in self.matchers:
1220 1220 self.matches = matcher(text)
1221 1221 if self.matches:
1222 1222 break
1223 1223 # FIXME: we should extend our api to return a dict with completions for
1224 1224 # different types of objects. The rlcomplete() method could then
1225 1225 # simply collapse the dict into a list for readline, but we'd have
1226 1226 # richer completion semantics in other evironments.
1227 1227 self.matches = sorted(set(self.matches), key=completions_sorting_key)
1228 1228
1229 1229 return text, self.matches
@@ -1,343 +1,342 b''
1 1 # encoding: utf-8
2 2 """Implementations for various useful completers.
3 3
4 4 These are all loaded by default by IPython.
5 5 """
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (C) 2010-2011 The IPython Development Team.
8 8 #
9 9 # Distributed under the terms of the BSD License.
10 10 #
11 11 # The full license is in the file COPYING.txt, distributed with this software.
12 12 #-----------------------------------------------------------------------------
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Imports
16 16 #-----------------------------------------------------------------------------
17 17
18 18 # Stdlib imports
19 19 import glob
20 20 import inspect
21 21 import os
22 22 import re
23 23 import sys
24 24 from importlib import import_module
25 25 from importlib.machinery import all_suffixes
26 26
27 27
28 28 # Third-party imports
29 29 from time import time
30 30 from zipimport import zipimporter
31 31
32 32 # Our own imports
33 33 from IPython.core.completer import expand_user, compress_user
34 34 from IPython.core.error import TryNext
35 35 from IPython.utils._process_common import arg_split
36 from IPython.utils.py3compat import string_types
37 36
38 37 # FIXME: this should be pulled in with the right call via the component system
39 38 from IPython import get_ipython
40 39
41 40 #-----------------------------------------------------------------------------
42 41 # Globals and constants
43 42 #-----------------------------------------------------------------------------
44 43 _suffixes = all_suffixes()
45 44
46 45 # Time in seconds after which the rootmodules will be stored permanently in the
47 46 # ipython ip.db database (kept in the user's .ipython dir).
48 47 TIMEOUT_STORAGE = 2
49 48
50 49 # Time in seconds after which we give up
51 50 TIMEOUT_GIVEUP = 20
52 51
53 52 # Regular expression for the python import statement
54 53 import_re = re.compile(r'(?P<name>[a-zA-Z_][a-zA-Z0-9_]*?)'
55 54 r'(?P<package>[/\\]__init__)?'
56 55 r'(?P<suffix>%s)$' %
57 56 r'|'.join(re.escape(s) for s in _suffixes))
58 57
59 58 # RE for the ipython %run command (python + ipython scripts)
60 59 magic_run_re = re.compile(r'.*(\.ipy|\.ipynb|\.py[w]?)$')
61 60
62 61 #-----------------------------------------------------------------------------
63 62 # Local utilities
64 63 #-----------------------------------------------------------------------------
65 64
66 65 def module_list(path):
67 66 """
68 67 Return the list containing the names of the modules available in the given
69 68 folder.
70 69 """
71 70 # sys.path has the cwd as an empty string, but isdir/listdir need it as '.'
72 71 if path == '':
73 72 path = '.'
74 73
75 74 # A few local constants to be used in loops below
76 75 pjoin = os.path.join
77 76
78 77 if os.path.isdir(path):
79 78 # Build a list of all files in the directory and all files
80 79 # in its subdirectories. For performance reasons, do not
81 80 # recurse more than one level into subdirectories.
82 81 files = []
83 82 for root, dirs, nondirs in os.walk(path, followlinks=True):
84 83 subdir = root[len(path)+1:]
85 84 if subdir:
86 85 files.extend(pjoin(subdir, f) for f in nondirs)
87 86 dirs[:] = [] # Do not recurse into additional subdirectories.
88 87 else:
89 88 files.extend(nondirs)
90 89
91 90 else:
92 91 try:
93 92 files = list(zipimporter(path)._files.keys())
94 93 except:
95 94 files = []
96 95
97 96 # Build a list of modules which match the import_re regex.
98 97 modules = []
99 98 for f in files:
100 99 m = import_re.match(f)
101 100 if m:
102 101 modules.append(m.group('name'))
103 102 return list(set(modules))
104 103
105 104
106 105 def get_root_modules():
107 106 """
108 107 Returns a list containing the names of all the modules available in the
109 108 folders of the pythonpath.
110 109
111 110 ip.db['rootmodules_cache'] maps sys.path entries to list of modules.
112 111 """
113 112 ip = get_ipython()
114 113 rootmodules_cache = ip.db.get('rootmodules_cache', {})
115 114 rootmodules = list(sys.builtin_module_names)
116 115 start_time = time()
117 116 store = False
118 117 for path in sys.path:
119 118 try:
120 119 modules = rootmodules_cache[path]
121 120 except KeyError:
122 121 modules = module_list(path)
123 122 try:
124 123 modules.remove('__init__')
125 124 except ValueError:
126 125 pass
127 126 if path not in ('', '.'): # cwd modules should not be cached
128 127 rootmodules_cache[path] = modules
129 128 if time() - start_time > TIMEOUT_STORAGE and not store:
130 129 store = True
131 130 print("\nCaching the list of root modules, please wait!")
132 131 print("(This will only be done once - type '%rehashx' to "
133 132 "reset cache!)\n")
134 133 sys.stdout.flush()
135 134 if time() - start_time > TIMEOUT_GIVEUP:
136 135 print("This is taking too long, we give up.\n")
137 136 return []
138 137 rootmodules.extend(modules)
139 138 if store:
140 139 ip.db['rootmodules_cache'] = rootmodules_cache
141 140 rootmodules = list(set(rootmodules))
142 141 return rootmodules
143 142
144 143
145 144 def is_importable(module, attr, only_modules):
146 145 if only_modules:
147 146 return inspect.ismodule(getattr(module, attr))
148 147 else:
149 148 return not(attr[:2] == '__' and attr[-2:] == '__')
150 149
151 150 def try_import(mod, only_modules=False):
152 151 try:
153 152 m = import_module(mod)
154 153 except:
155 154 return []
156 155
157 156 m_is_init = hasattr(m, '__file__') and '__init__' in m.__file__
158 157
159 158 completions = []
160 159 if (not hasattr(m, '__file__')) or (not only_modules) or m_is_init:
161 160 completions.extend( [attr for attr in dir(m) if
162 161 is_importable(m, attr, only_modules)])
163 162
164 163 completions.extend(getattr(m, '__all__', []))
165 164 if m_is_init:
166 165 completions.extend(module_list(os.path.dirname(m.__file__)))
167 completions = {c for c in completions if isinstance(c, string_types)}
166 completions = {c for c in completions if isinstance(c, str)}
168 167 completions.discard('__init__')
169 168 return list(completions)
170 169
171 170
172 171 #-----------------------------------------------------------------------------
173 172 # Completion-related functions.
174 173 #-----------------------------------------------------------------------------
175 174
176 175 def quick_completer(cmd, completions):
177 176 """ Easily create a trivial completer for a command.
178 177
179 178 Takes either a list of completions, or all completions in string (that will
180 179 be split on whitespace).
181 180
182 181 Example::
183 182
184 183 [d:\ipython]|1> import ipy_completers
185 184 [d:\ipython]|2> ipy_completers.quick_completer('foo', ['bar','baz'])
186 185 [d:\ipython]|3> foo b<TAB>
187 186 bar baz
188 187 [d:\ipython]|3> foo ba
189 188 """
190 189
191 if isinstance(completions, string_types):
190 if isinstance(completions, str):
192 191 completions = completions.split()
193 192
194 193 def do_complete(self, event):
195 194 return completions
196 195
197 196 get_ipython().set_hook('complete_command',do_complete, str_key = cmd)
198 197
199 198 def module_completion(line):
200 199 """
201 200 Returns a list containing the completion possibilities for an import line.
202 201
203 202 The line looks like this :
204 203 'import xml.d'
205 204 'from xml.dom import'
206 205 """
207 206
208 207 words = line.split(' ')
209 208 nwords = len(words)
210 209
211 210 # from whatever <tab> -> 'import '
212 211 if nwords == 3 and words[0] == 'from':
213 212 return ['import ']
214 213
215 214 # 'from xy<tab>' or 'import xy<tab>'
216 215 if nwords < 3 and (words[0] in {'%aimport', 'import', 'from'}) :
217 216 if nwords == 1:
218 217 return get_root_modules()
219 218 mod = words[1].split('.')
220 219 if len(mod) < 2:
221 220 return get_root_modules()
222 221 completion_list = try_import('.'.join(mod[:-1]), True)
223 222 return ['.'.join(mod[:-1] + [el]) for el in completion_list]
224 223
225 224 # 'from xyz import abc<tab>'
226 225 if nwords >= 3 and words[0] == 'from':
227 226 mod = words[1]
228 227 return try_import(mod)
229 228
230 229 #-----------------------------------------------------------------------------
231 230 # Completers
232 231 #-----------------------------------------------------------------------------
233 232 # These all have the func(self, event) signature to be used as custom
234 233 # completers
235 234
236 235 def module_completer(self,event):
237 236 """Give completions after user has typed 'import ...' or 'from ...'"""
238 237
239 238 # This works in all versions of python. While 2.5 has
240 239 # pkgutil.walk_packages(), that particular routine is fairly dangerous,
241 240 # since it imports *EVERYTHING* on sys.path. That is: a) very slow b) full
242 241 # of possibly problematic side effects.
243 242 # This search the folders in the sys.path for available modules.
244 243
245 244 return module_completion(event.line)
246 245
247 246 # FIXME: there's a lot of logic common to the run, cd and builtin file
248 247 # completers, that is currently reimplemented in each.
249 248
250 249 def magic_run_completer(self, event):
251 250 """Complete files that end in .py or .ipy or .ipynb for the %run command.
252 251 """
253 252 comps = arg_split(event.line, strict=False)
254 253 # relpath should be the current token that we need to complete.
255 254 if (len(comps) > 1) and (not event.line.endswith(' ')):
256 255 relpath = comps[-1].strip("'\"")
257 256 else:
258 257 relpath = ''
259 258
260 259 #print("\nev=", event) # dbg
261 260 #print("rp=", relpath) # dbg
262 261 #print('comps=', comps) # dbg
263 262
264 263 lglob = glob.glob
265 264 isdir = os.path.isdir
266 265 relpath, tilde_expand, tilde_val = expand_user(relpath)
267 266
268 267 # Find if the user has already typed the first filename, after which we
269 268 # should complete on all files, since after the first one other files may
270 269 # be arguments to the input script.
271 270
272 271 if any(magic_run_re.match(c) for c in comps):
273 272 matches = [f.replace('\\','/') + ('/' if isdir(f) else '')
274 273 for f in lglob(relpath+'*')]
275 274 else:
276 275 dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*') if isdir(f)]
277 276 pys = [f.replace('\\','/')
278 277 for f in lglob(relpath+'*.py') + lglob(relpath+'*.ipy') +
279 278 lglob(relpath+'*.ipynb') + lglob(relpath + '*.pyw')]
280 279
281 280 matches = dirs + pys
282 281
283 282 #print('run comp:', dirs+pys) # dbg
284 283 return [compress_user(p, tilde_expand, tilde_val) for p in matches]
285 284
286 285
287 286 def cd_completer(self, event):
288 287 """Completer function for cd, which only returns directories."""
289 288 ip = get_ipython()
290 289 relpath = event.symbol
291 290
292 291 #print(event) # dbg
293 292 if event.line.endswith('-b') or ' -b ' in event.line:
294 293 # return only bookmark completions
295 294 bkms = self.db.get('bookmarks', None)
296 295 if bkms:
297 296 return bkms.keys()
298 297 else:
299 298 return []
300 299
301 300 if event.symbol == '-':
302 301 width_dh = str(len(str(len(ip.user_ns['_dh']) + 1)))
303 302 # jump in directory history by number
304 303 fmt = '-%0' + width_dh +'d [%s]'
305 304 ents = [ fmt % (i,s) for i,s in enumerate(ip.user_ns['_dh'])]
306 305 if len(ents) > 1:
307 306 return ents
308 307 return []
309 308
310 309 if event.symbol.startswith('--'):
311 310 return ["--" + os.path.basename(d) for d in ip.user_ns['_dh']]
312 311
313 312 # Expand ~ in path and normalize directory separators.
314 313 relpath, tilde_expand, tilde_val = expand_user(relpath)
315 314 relpath = relpath.replace('\\','/')
316 315
317 316 found = []
318 317 for d in [f.replace('\\','/') + '/' for f in glob.glob(relpath+'*')
319 318 if os.path.isdir(f)]:
320 319 if ' ' in d:
321 320 # we don't want to deal with any of that, complex code
322 321 # for this is elsewhere
323 322 raise TryNext
324 323
325 324 found.append(d)
326 325
327 326 if not found:
328 327 if os.path.isdir(relpath):
329 328 return [compress_user(relpath, tilde_expand, tilde_val)]
330 329
331 330 # if no completions so far, try bookmarks
332 331 bks = self.db.get('bookmarks',{})
333 332 bkmatches = [s for s in bks if s.startswith(event.symbol)]
334 333 if bkmatches:
335 334 return bkmatches
336 335
337 336 raise TryNext
338 337
339 338 return [compress_user(p, tilde_expand, tilde_val) for p in found]
340 339
341 340 def reset_completer(self, event):
342 341 "A completer for %reset magic"
343 342 return '-f -s in out array dhist'.split()
@@ -1,215 +1,215 b''
1 1 # encoding: utf-8
2 2 """sys.excepthook for IPython itself, leaves a detailed report on disk.
3 3
4 4 Authors:
5 5
6 6 * Fernando Perez
7 7 * Brian E. Granger
8 8 """
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
12 12 # Copyright (C) 2008-2011 The IPython Development Team
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is in
15 15 # the file COPYING, distributed as part of this software.
16 16 #-----------------------------------------------------------------------------
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Imports
20 20 #-----------------------------------------------------------------------------
21 21
22 22 import os
23 23 import sys
24 24 import traceback
25 25 from pprint import pformat
26 26
27 27 from IPython.core import ultratb
28 28 from IPython.core.release import author_email
29 29 from IPython.utils.sysinfo import sys_info
30 from IPython.utils.py3compat import input, getcwd
30 from IPython.utils.py3compat import input
31 31
32 32 #-----------------------------------------------------------------------------
33 33 # Code
34 34 #-----------------------------------------------------------------------------
35 35
36 36 # Template for the user message.
37 37 _default_message_template = """\
38 38 Oops, {app_name} crashed. We do our best to make it stable, but...
39 39
40 40 A crash report was automatically generated with the following information:
41 41 - A verbatim copy of the crash traceback.
42 42 - A copy of your input history during this session.
43 43 - Data on your current {app_name} configuration.
44 44
45 45 It was left in the file named:
46 46 \t'{crash_report_fname}'
47 47 If you can email this file to the developers, the information in it will help
48 48 them in understanding and correcting the problem.
49 49
50 50 You can mail it to: {contact_name} at {contact_email}
51 51 with the subject '{app_name} Crash Report'.
52 52
53 53 If you want to do it now, the following command will work (under Unix):
54 54 mail -s '{app_name} Crash Report' {contact_email} < {crash_report_fname}
55 55
56 56 To ensure accurate tracking of this issue, please file a report about it at:
57 57 {bug_tracker}
58 58 """
59 59
60 60 _lite_message_template = """
61 61 If you suspect this is an IPython bug, please report it at:
62 62 https://github.com/ipython/ipython/issues
63 63 or send an email to the mailing list at {email}
64 64
65 65 You can print a more detailed traceback right now with "%tb", or use "%debug"
66 66 to interactively debug it.
67 67
68 68 Extra-detailed tracebacks for bug-reporting purposes can be enabled via:
69 69 {config}Application.verbose_crash=True
70 70 """
71 71
72 72
73 73 class CrashHandler(object):
74 74 """Customizable crash handlers for IPython applications.
75 75
76 76 Instances of this class provide a :meth:`__call__` method which can be
77 77 used as a ``sys.excepthook``. The :meth:`__call__` signature is::
78 78
79 79 def __call__(self, etype, evalue, etb)
80 80 """
81 81
82 82 message_template = _default_message_template
83 83 section_sep = '\n\n'+'*'*75+'\n\n'
84 84
85 85 def __init__(self, app, contact_name=None, contact_email=None,
86 86 bug_tracker=None, show_crash_traceback=True, call_pdb=False):
87 87 """Create a new crash handler
88 88
89 89 Parameters
90 90 ----------
91 91 app : Application
92 92 A running :class:`Application` instance, which will be queried at
93 93 crash time for internal information.
94 94
95 95 contact_name : str
96 96 A string with the name of the person to contact.
97 97
98 98 contact_email : str
99 99 A string with the email address of the contact.
100 100
101 101 bug_tracker : str
102 102 A string with the URL for your project's bug tracker.
103 103
104 104 show_crash_traceback : bool
105 105 If false, don't print the crash traceback on stderr, only generate
106 106 the on-disk report
107 107
108 108 Non-argument instance attributes:
109 109
110 110 These instances contain some non-argument attributes which allow for
111 111 further customization of the crash handler's behavior. Please see the
112 112 source for further details.
113 113 """
114 114 self.crash_report_fname = "Crash_report_%s.txt" % app.name
115 115 self.app = app
116 116 self.call_pdb = call_pdb
117 117 #self.call_pdb = True # dbg
118 118 self.show_crash_traceback = show_crash_traceback
119 119 self.info = dict(app_name = app.name,
120 120 contact_name = contact_name,
121 121 contact_email = contact_email,
122 122 bug_tracker = bug_tracker,
123 123 crash_report_fname = self.crash_report_fname)
124 124
125 125
126 126 def __call__(self, etype, evalue, etb):
127 127 """Handle an exception, call for compatible with sys.excepthook"""
128 128
129 129 # do not allow the crash handler to be called twice without reinstalling it
130 130 # this prevents unlikely errors in the crash handling from entering an
131 131 # infinite loop.
132 132 sys.excepthook = sys.__excepthook__
133 133
134 134 # Report tracebacks shouldn't use color in general (safer for users)
135 135 color_scheme = 'NoColor'
136 136
137 137 # Use this ONLY for developer debugging (keep commented out for release)
138 138 #color_scheme = 'Linux' # dbg
139 139 try:
140 140 rptdir = self.app.ipython_dir
141 141 except:
142 rptdir = getcwd()
142 rptdir = os.getcwd()
143 143 if rptdir is None or not os.path.isdir(rptdir):
144 rptdir = getcwd()
144 rptdir = os.getcwd()
145 145 report_name = os.path.join(rptdir,self.crash_report_fname)
146 146 # write the report filename into the instance dict so it can get
147 147 # properly expanded out in the user message template
148 148 self.crash_report_fname = report_name
149 149 self.info['crash_report_fname'] = report_name
150 150 TBhandler = ultratb.VerboseTB(
151 151 color_scheme=color_scheme,
152 152 long_header=1,
153 153 call_pdb=self.call_pdb,
154 154 )
155 155 if self.call_pdb:
156 156 TBhandler(etype,evalue,etb)
157 157 return
158 158 else:
159 159 traceback = TBhandler.text(etype,evalue,etb,context=31)
160 160
161 161 # print traceback to screen
162 162 if self.show_crash_traceback:
163 163 print(traceback, file=sys.stderr)
164 164
165 165 # and generate a complete report on disk
166 166 try:
167 167 report = open(report_name,'w')
168 168 except:
169 169 print('Could not create crash report on disk.', file=sys.stderr)
170 170 return
171 171
172 172 # Inform user on stderr of what happened
173 173 print('\n'+'*'*70+'\n', file=sys.stderr)
174 174 print(self.message_template.format(**self.info), file=sys.stderr)
175 175
176 176 # Construct report on disk
177 177 report.write(self.make_report(traceback))
178 178 report.close()
179 179 input("Hit <Enter> to quit (your terminal may close):")
180 180
181 181 def make_report(self,traceback):
182 182 """Return a string containing a crash report."""
183 183
184 184 sec_sep = self.section_sep
185 185
186 186 report = ['*'*75+'\n\n'+'IPython post-mortem report\n\n']
187 187 rpt_add = report.append
188 188 rpt_add(sys_info())
189 189
190 190 try:
191 191 config = pformat(self.app.config)
192 192 rpt_add(sec_sep)
193 193 rpt_add('Application name: %s\n\n' % self.app_name)
194 194 rpt_add('Current user configuration structure:\n\n')
195 195 rpt_add(config)
196 196 except:
197 197 pass
198 198 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
199 199
200 200 return ''.join(report)
201 201
202 202
203 203 def crash_handler_lite(etype, evalue, tb):
204 204 """a light excepthook, adding a small message to the usual traceback"""
205 205 traceback.print_exception(etype, evalue, tb)
206 206
207 207 from IPython.core.interactiveshell import InteractiveShell
208 208 if InteractiveShell.initialized():
209 209 # we are in a Shell environment, give %magic example
210 210 config = "%config "
211 211 else:
212 212 # we are not in a shell, show generic config
213 213 config = "c."
214 214 print(_lite_message_template.format(email=author_email, config=config), file=sys.stderr)
215 215
@@ -1,1136 +1,1135 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Top-level display functions for displaying object in different formats."""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7
8 8 try:
9 9 from base64 import encodebytes as base64_encode
10 10 except ImportError:
11 11 from base64 import encodestring as base64_encode
12 12
13 13 from binascii import b2a_hex
14 14 import json
15 15 import mimetypes
16 16 import os
17 17 import struct
18 18 import sys
19 19 import warnings
20 20
21 from IPython.utils.py3compat import (string_types, cast_bytes_py2, cast_unicode,
22 unicode_type)
21 from IPython.utils.py3compat import cast_bytes_py2, cast_unicode
23 22 from IPython.testing.skipdoctest import skip_doctest
24 23
25 24 __all__ = ['display', 'display_pretty', 'display_html', 'display_markdown',
26 25 'display_svg', 'display_png', 'display_jpeg', 'display_latex', 'display_json',
27 26 'display_javascript', 'display_pdf', 'DisplayObject', 'TextDisplayObject',
28 27 'Pretty', 'HTML', 'Markdown', 'Math', 'Latex', 'SVG', 'JSON', 'Javascript',
29 28 'Image', 'clear_output', 'set_matplotlib_formats', 'set_matplotlib_close',
30 29 'publish_display_data', 'update_display', 'DisplayHandle']
31 30
32 31 #-----------------------------------------------------------------------------
33 32 # utility functions
34 33 #-----------------------------------------------------------------------------
35 34
36 35 def _safe_exists(path):
37 36 """Check path, but don't let exceptions raise"""
38 37 try:
39 38 return os.path.exists(path)
40 39 except Exception:
41 40 return False
42 41
43 42 def _merge(d1, d2):
44 43 """Like update, but merges sub-dicts instead of clobbering at the top level.
45 44
46 45 Updates d1 in-place
47 46 """
48 47
49 48 if not isinstance(d2, dict) or not isinstance(d1, dict):
50 49 return d2
51 50 for key, value in d2.items():
52 51 d1[key] = _merge(d1.get(key), value)
53 52 return d1
54 53
55 54 def _display_mimetype(mimetype, objs, raw=False, metadata=None):
56 55 """internal implementation of all display_foo methods
57 56
58 57 Parameters
59 58 ----------
60 59 mimetype : str
61 60 The mimetype to be published (e.g. 'image/png')
62 61 objs : tuple of objects
63 62 The Python objects to display, or if raw=True raw text data to
64 63 display.
65 64 raw : bool
66 65 Are the data objects raw data or Python objects that need to be
67 66 formatted before display? [default: False]
68 67 metadata : dict (optional)
69 68 Metadata to be associated with the specific mimetype output.
70 69 """
71 70 if metadata:
72 71 metadata = {mimetype: metadata}
73 72 if raw:
74 73 # turn list of pngdata into list of { 'image/png': pngdata }
75 74 objs = [ {mimetype: obj} for obj in objs ]
76 75 display(*objs, raw=raw, metadata=metadata, include=[mimetype])
77 76
78 77 #-----------------------------------------------------------------------------
79 78 # Main functions
80 79 #-----------------------------------------------------------------------------
81 80
82 81 # use * to indicate transient is keyword-only
83 82 def publish_display_data(data, metadata=None, source=None, *, transient=None, **kwargs):
84 83 """Publish data and metadata to all frontends.
85 84
86 85 See the ``display_data`` message in the messaging documentation for
87 86 more details about this message type.
88 87
89 88 The following MIME types are currently implemented:
90 89
91 90 * text/plain
92 91 * text/html
93 92 * text/markdown
94 93 * text/latex
95 94 * application/json
96 95 * application/javascript
97 96 * image/png
98 97 * image/jpeg
99 98 * image/svg+xml
100 99
101 100 Parameters
102 101 ----------
103 102 data : dict
104 103 A dictionary having keys that are valid MIME types (like
105 104 'text/plain' or 'image/svg+xml') and values that are the data for
106 105 that MIME type. The data itself must be a JSON'able data
107 106 structure. Minimally all data should have the 'text/plain' data,
108 107 which can be displayed by all frontends. If more than the plain
109 108 text is given, it is up to the frontend to decide which
110 109 representation to use.
111 110 metadata : dict
112 111 A dictionary for metadata related to the data. This can contain
113 112 arbitrary key, value pairs that frontends can use to interpret
114 113 the data. mime-type keys matching those in data can be used
115 114 to specify metadata about particular representations.
116 115 source : str, deprecated
117 116 Unused.
118 117 transient : dict, keyword-only
119 118 A dictionary of transient data, such as display_id.
120 119 """
121 120 from IPython.core.interactiveshell import InteractiveShell
122 121
123 122 display_pub = InteractiveShell.instance().display_pub
124 123
125 124 # only pass transient if supplied,
126 125 # to avoid errors with older ipykernel.
127 126 # TODO: We could check for ipykernel version and provide a detailed upgrade message.
128 127 if transient:
129 128 kwargs['transient'] = transient
130 129
131 130 display_pub.publish(
132 131 data=data,
133 132 metadata=metadata,
134 133 **kwargs
135 134 )
136 135
137 136
138 137 def _new_id():
139 138 """Generate a new random text id with urandom"""
140 139 return b2a_hex(os.urandom(16)).decode('ascii')
141 140
142 141
143 142 def display(*objs, include=None, exclude=None, metadata=None, transient=None, display_id=None, **kwargs):
144 143 """Display a Python object in all frontends.
145 144
146 145 By default all representations will be computed and sent to the frontends.
147 146 Frontends can decide which representation is used and how.
148 147
149 148 Parameters
150 149 ----------
151 150 objs : tuple of objects
152 151 The Python objects to display.
153 152 raw : bool, optional
154 153 Are the objects to be displayed already mimetype-keyed dicts of raw display data,
155 154 or Python objects that need to be formatted before display? [default: False]
156 155 include : list or tuple, optional
157 156 A list of format type strings (MIME types) to include in the
158 157 format data dict. If this is set *only* the format types included
159 158 in this list will be computed.
160 159 exclude : list or tuple, optional
161 160 A list of format type strings (MIME types) to exclude in the format
162 161 data dict. If this is set all format types will be computed,
163 162 except for those included in this argument.
164 163 metadata : dict, optional
165 164 A dictionary of metadata to associate with the output.
166 165 mime-type keys in this dictionary will be associated with the individual
167 166 representation formats, if they exist.
168 167 transient : dict, optional
169 168 A dictionary of transient data to associate with the output.
170 169 Data in this dict should not be persisted to files (e.g. notebooks).
171 170 display_id : str, optional
172 171 Set an id for the display.
173 172 This id can be used for updating this display area later via update_display.
174 173 If given as True, generate a new display_id
175 174 kwargs: additional keyword-args, optional
176 175 Additional keyword-arguments are passed through to the display publisher.
177 176
178 177 Returns
179 178 -------
180 179
181 180 handle: DisplayHandle
182 181 Returns a handle on updatable displays, if display_id is given.
183 182 Returns None if no display_id is given (default).
184 183 """
185 184 raw = kwargs.pop('raw', False)
186 185 if transient is None:
187 186 transient = {}
188 187 if display_id:
189 188 if display_id == True:
190 189 display_id = _new_id()
191 190 transient['display_id'] = display_id
192 191 if kwargs.get('update') and 'display_id' not in transient:
193 192 raise TypeError('display_id required for update_display')
194 193 if transient:
195 194 kwargs['transient'] = transient
196 195
197 196 from IPython.core.interactiveshell import InteractiveShell
198 197
199 198 if not raw:
200 199 format = InteractiveShell.instance().display_formatter.format
201 200
202 201 for obj in objs:
203 202 if raw:
204 203 publish_display_data(data=obj, metadata=metadata, **kwargs)
205 204 else:
206 205 format_dict, md_dict = format(obj, include=include, exclude=exclude)
207 206 if not format_dict:
208 207 # nothing to display (e.g. _ipython_display_ took over)
209 208 continue
210 209 if metadata:
211 210 # kwarg-specified metadata gets precedence
212 211 _merge(md_dict, metadata)
213 212 publish_display_data(data=format_dict, metadata=md_dict, **kwargs)
214 213 if display_id:
215 214 return DisplayHandle(display_id)
216 215
217 216
218 217 # use * for keyword-only display_id arg
219 218 def update_display(obj, *, display_id, **kwargs):
220 219 """Update an existing display by id
221 220
222 221 Parameters
223 222 ----------
224 223
225 224 obj:
226 225 The object with which to update the display
227 226 display_id: keyword-only
228 227 The id of the display to update
229 228 """
230 229 kwargs['update'] = True
231 230 display(obj, display_id=display_id, **kwargs)
232 231
233 232
234 233 class DisplayHandle(object):
235 234 """A handle on an updatable display
236 235
237 236 Call .update(obj) to display a new object.
238 237
239 238 Call .display(obj) to add a new instance of this display,
240 239 and update existing instances.
241 240 """
242 241
243 242 def __init__(self, display_id=None):
244 243 if display_id is None:
245 244 display_id = _new_id()
246 245 self.display_id = display_id
247 246
248 247 def __repr__(self):
249 248 return "<%s display_id=%s>" % (self.__class__.__name__, self.display_id)
250 249
251 250 def display(self, obj, **kwargs):
252 251 """Make a new display with my id, updating existing instances.
253 252
254 253 Parameters
255 254 ----------
256 255
257 256 obj:
258 257 object to display
259 258 **kwargs:
260 259 additional keyword arguments passed to display
261 260 """
262 261 display(obj, display_id=self.display_id, **kwargs)
263 262
264 263 def update(self, obj, **kwargs):
265 264 """Update existing displays with my id
266 265
267 266 Parameters
268 267 ----------
269 268
270 269 obj:
271 270 object to display
272 271 **kwargs:
273 272 additional keyword arguments passed to update_display
274 273 """
275 274 update_display(obj, display_id=self.display_id, **kwargs)
276 275
277 276
278 277 def display_pretty(*objs, **kwargs):
279 278 """Display the pretty (default) representation of an object.
280 279
281 280 Parameters
282 281 ----------
283 282 objs : tuple of objects
284 283 The Python objects to display, or if raw=True raw text data to
285 284 display.
286 285 raw : bool
287 286 Are the data objects raw data or Python objects that need to be
288 287 formatted before display? [default: False]
289 288 metadata : dict (optional)
290 289 Metadata to be associated with the specific mimetype output.
291 290 """
292 291 _display_mimetype('text/plain', objs, **kwargs)
293 292
294 293
295 294 def display_html(*objs, **kwargs):
296 295 """Display the HTML representation of an object.
297 296
298 297 Note: If raw=False and the object does not have a HTML
299 298 representation, no HTML will be shown.
300 299
301 300 Parameters
302 301 ----------
303 302 objs : tuple of objects
304 303 The Python objects to display, or if raw=True raw HTML data to
305 304 display.
306 305 raw : bool
307 306 Are the data objects raw data or Python objects that need to be
308 307 formatted before display? [default: False]
309 308 metadata : dict (optional)
310 309 Metadata to be associated with the specific mimetype output.
311 310 """
312 311 _display_mimetype('text/html', objs, **kwargs)
313 312
314 313
315 314 def display_markdown(*objs, **kwargs):
316 315 """Displays the Markdown representation of an object.
317 316
318 317 Parameters
319 318 ----------
320 319 objs : tuple of objects
321 320 The Python objects to display, or if raw=True raw markdown data to
322 321 display.
323 322 raw : bool
324 323 Are the data objects raw data or Python objects that need to be
325 324 formatted before display? [default: False]
326 325 metadata : dict (optional)
327 326 Metadata to be associated with the specific mimetype output.
328 327 """
329 328
330 329 _display_mimetype('text/markdown', objs, **kwargs)
331 330
332 331
333 332 def display_svg(*objs, **kwargs):
334 333 """Display the SVG representation of an object.
335 334
336 335 Parameters
337 336 ----------
338 337 objs : tuple of objects
339 338 The Python objects to display, or if raw=True raw svg data to
340 339 display.
341 340 raw : bool
342 341 Are the data objects raw data or Python objects that need to be
343 342 formatted before display? [default: False]
344 343 metadata : dict (optional)
345 344 Metadata to be associated with the specific mimetype output.
346 345 """
347 346 _display_mimetype('image/svg+xml', objs, **kwargs)
348 347
349 348
350 349 def display_png(*objs, **kwargs):
351 350 """Display the PNG representation of an object.
352 351
353 352 Parameters
354 353 ----------
355 354 objs : tuple of objects
356 355 The Python objects to display, or if raw=True raw png data to
357 356 display.
358 357 raw : bool
359 358 Are the data objects raw data or Python objects that need to be
360 359 formatted before display? [default: False]
361 360 metadata : dict (optional)
362 361 Metadata to be associated with the specific mimetype output.
363 362 """
364 363 _display_mimetype('image/png', objs, **kwargs)
365 364
366 365
367 366 def display_jpeg(*objs, **kwargs):
368 367 """Display the JPEG representation of an object.
369 368
370 369 Parameters
371 370 ----------
372 371 objs : tuple of objects
373 372 The Python objects to display, or if raw=True raw JPEG data to
374 373 display.
375 374 raw : bool
376 375 Are the data objects raw data or Python objects that need to be
377 376 formatted before display? [default: False]
378 377 metadata : dict (optional)
379 378 Metadata to be associated with the specific mimetype output.
380 379 """
381 380 _display_mimetype('image/jpeg', objs, **kwargs)
382 381
383 382
384 383 def display_latex(*objs, **kwargs):
385 384 """Display the LaTeX representation of an object.
386 385
387 386 Parameters
388 387 ----------
389 388 objs : tuple of objects
390 389 The Python objects to display, or if raw=True raw latex data to
391 390 display.
392 391 raw : bool
393 392 Are the data objects raw data or Python objects that need to be
394 393 formatted before display? [default: False]
395 394 metadata : dict (optional)
396 395 Metadata to be associated with the specific mimetype output.
397 396 """
398 397 _display_mimetype('text/latex', objs, **kwargs)
399 398
400 399
401 400 def display_json(*objs, **kwargs):
402 401 """Display the JSON representation of an object.
403 402
404 403 Note that not many frontends support displaying JSON.
405 404
406 405 Parameters
407 406 ----------
408 407 objs : tuple of objects
409 408 The Python objects to display, or if raw=True raw json data to
410 409 display.
411 410 raw : bool
412 411 Are the data objects raw data or Python objects that need to be
413 412 formatted before display? [default: False]
414 413 metadata : dict (optional)
415 414 Metadata to be associated with the specific mimetype output.
416 415 """
417 416 _display_mimetype('application/json', objs, **kwargs)
418 417
419 418
420 419 def display_javascript(*objs, **kwargs):
421 420 """Display the Javascript representation of an object.
422 421
423 422 Parameters
424 423 ----------
425 424 objs : tuple of objects
426 425 The Python objects to display, or if raw=True raw javascript data to
427 426 display.
428 427 raw : bool
429 428 Are the data objects raw data or Python objects that need to be
430 429 formatted before display? [default: False]
431 430 metadata : dict (optional)
432 431 Metadata to be associated with the specific mimetype output.
433 432 """
434 433 _display_mimetype('application/javascript', objs, **kwargs)
435 434
436 435
437 436 def display_pdf(*objs, **kwargs):
438 437 """Display the PDF representation of an object.
439 438
440 439 Parameters
441 440 ----------
442 441 objs : tuple of objects
443 442 The Python objects to display, or if raw=True raw javascript data to
444 443 display.
445 444 raw : bool
446 445 Are the data objects raw data or Python objects that need to be
447 446 formatted before display? [default: False]
448 447 metadata : dict (optional)
449 448 Metadata to be associated with the specific mimetype output.
450 449 """
451 450 _display_mimetype('application/pdf', objs, **kwargs)
452 451
453 452
454 453 #-----------------------------------------------------------------------------
455 454 # Smart classes
456 455 #-----------------------------------------------------------------------------
457 456
458 457
459 458 class DisplayObject(object):
460 459 """An object that wraps data to be displayed."""
461 460
462 461 _read_flags = 'r'
463 462 _show_mem_addr = False
464 463
465 464 def __init__(self, data=None, url=None, filename=None):
466 465 """Create a display object given raw data.
467 466
468 467 When this object is returned by an expression or passed to the
469 468 display function, it will result in the data being displayed
470 469 in the frontend. The MIME type of the data should match the
471 470 subclasses used, so the Png subclass should be used for 'image/png'
472 471 data. If the data is a URL, the data will first be downloaded
473 472 and then displayed. If
474 473
475 474 Parameters
476 475 ----------
477 476 data : unicode, str or bytes
478 477 The raw data or a URL or file to load the data from
479 478 url : unicode
480 479 A URL to download the data from.
481 480 filename : unicode
482 481 Path to a local file to load the data from.
483 482 """
484 if data is not None and isinstance(data, string_types):
483 if data is not None and isinstance(data, str):
485 484 if data.startswith('http') and url is None:
486 485 url = data
487 486 filename = None
488 487 data = None
489 488 elif _safe_exists(data) and filename is None:
490 489 url = None
491 490 filename = data
492 491 data = None
493 492
494 493 self.data = data
495 494 self.url = url
496 self.filename = None if filename is None else unicode_type(filename)
495 self.filename = filename
497 496
498 497 self.reload()
499 498 self._check_data()
500 499
501 500 def __repr__(self):
502 501 if not self._show_mem_addr:
503 502 cls = self.__class__
504 503 r = "<%s.%s object>" % (cls.__module__, cls.__name__)
505 504 else:
506 505 r = super(DisplayObject, self).__repr__()
507 506 return r
508 507
509 508 def _check_data(self):
510 509 """Override in subclasses if there's something to check."""
511 510 pass
512 511
513 512 def reload(self):
514 513 """Reload the raw data from file or URL."""
515 514 if self.filename is not None:
516 515 with open(self.filename, self._read_flags) as f:
517 516 self.data = f.read()
518 517 elif self.url is not None:
519 518 try:
520 519 try:
521 520 from urllib.request import urlopen # Py3
522 521 except ImportError:
523 522 from urllib2 import urlopen
524 523 response = urlopen(self.url)
525 524 self.data = response.read()
526 525 # extract encoding from header, if there is one:
527 526 encoding = None
528 527 for sub in response.headers['content-type'].split(';'):
529 528 sub = sub.strip()
530 529 if sub.startswith('charset'):
531 530 encoding = sub.split('=')[-1].strip()
532 531 break
533 532 # decode data, if an encoding was specified
534 533 if encoding:
535 534 self.data = self.data.decode(encoding, 'replace')
536 535 except:
537 536 self.data = None
538 537
539 538 class TextDisplayObject(DisplayObject):
540 539 """Validate that display data is text"""
541 540 def _check_data(self):
542 if self.data is not None and not isinstance(self.data, string_types):
541 if self.data is not None and not isinstance(self.data, str):
543 542 raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
544 543
545 544 class Pretty(TextDisplayObject):
546 545
547 546 def _repr_pretty_(self):
548 547 return self.data
549 548
550 549
551 550 class HTML(TextDisplayObject):
552 551
553 552 def _repr_html_(self):
554 553 return self.data
555 554
556 555 def __html__(self):
557 556 """
558 557 This method exists to inform other HTML-using modules (e.g. Markupsafe,
559 558 htmltag, etc) that this object is HTML and does not need things like
560 559 special characters (<>&) escaped.
561 560 """
562 561 return self._repr_html_()
563 562
564 563
565 564 class Markdown(TextDisplayObject):
566 565
567 566 def _repr_markdown_(self):
568 567 return self.data
569 568
570 569
571 570 class Math(TextDisplayObject):
572 571
573 572 def _repr_latex_(self):
574 573 s = self.data.strip('$')
575 574 return "$$%s$$" % s
576 575
577 576
578 577 class Latex(TextDisplayObject):
579 578
580 579 def _repr_latex_(self):
581 580 return self.data
582 581
583 582
584 583 class SVG(DisplayObject):
585 584
586 585 _read_flags = 'rb'
587 586 # wrap data in a property, which extracts the <svg> tag, discarding
588 587 # document headers
589 588 _data = None
590 589
591 590 @property
592 591 def data(self):
593 592 return self._data
594 593
595 594 @data.setter
596 595 def data(self, svg):
597 596 if svg is None:
598 597 self._data = None
599 598 return
600 599 # parse into dom object
601 600 from xml.dom import minidom
602 601 svg = cast_bytes_py2(svg)
603 602 x = minidom.parseString(svg)
604 603 # get svg tag (should be 1)
605 604 found_svg = x.getElementsByTagName('svg')
606 605 if found_svg:
607 606 svg = found_svg[0].toxml()
608 607 else:
609 608 # fallback on the input, trust the user
610 609 # but this is probably an error.
611 610 pass
612 611 svg = cast_unicode(svg)
613 612 self._data = svg
614 613
615 614 def _repr_svg_(self):
616 615 return self.data
617 616
618 617
619 618 class JSON(DisplayObject):
620 619 """JSON expects a JSON-able dict or list
621 620
622 621 not an already-serialized JSON string.
623 622
624 623 Scalar types (None, number, string) are not allowed, only dict or list containers.
625 624 """
626 625 # wrap data in a property, which warns about passing already-serialized JSON
627 626 _data = None
628 627 def __init__(self, data=None, url=None, filename=None, expanded=False, metadata=None):
629 628 """Create a JSON display object given raw data.
630 629
631 630 Parameters
632 631 ----------
633 632 data : dict or list
634 633 JSON data to display. Not an already-serialized JSON string.
635 634 Scalar types (None, number, string) are not allowed, only dict
636 635 or list containers.
637 636 url : unicode
638 637 A URL to download the data from.
639 638 filename : unicode
640 639 Path to a local file to load the data from.
641 640 expanded : boolean
642 641 Metadata to control whether a JSON display component is expanded.
643 642 metadata: dict
644 643 Specify extra metadata to attach to the json display object.
645 644 """
646 645 self.expanded = expanded
647 646 self.metadata = metadata
648 647 super(JSON, self).__init__(data=data, url=url, filename=filename)
649 648
650 649 def _check_data(self):
651 650 if self.data is not None and not isinstance(self.data, (dict, list)):
652 651 raise TypeError("%s expects JSONable dict or list, not %r" % (self.__class__.__name__, self.data))
653 652
654 653 @property
655 654 def data(self):
656 655 return self._data
657 656
658 657 @data.setter
659 658 def data(self, data):
660 if isinstance(data, string_types):
659 if isinstance(data, str):
661 660 warnings.warn("JSON expects JSONable dict or list, not JSON strings")
662 661 data = json.loads(data)
663 662 self._data = data
664 663
665 664 def _data_and_metadata(self):
666 665 md = {'expanded': self.expanded}
667 666 if self.metadata:
668 667 md.update(self.metadata)
669 668 return self.data, md
670 669
671 670 def _repr_json_(self):
672 671 return self._data_and_metadata()
673 672
674 673 css_t = """$("head").append($("<link/>").attr({
675 674 rel: "stylesheet",
676 675 type: "text/css",
677 676 href: "%s"
678 677 }));
679 678 """
680 679
681 680 lib_t1 = """$.getScript("%s", function () {
682 681 """
683 682 lib_t2 = """});
684 683 """
685 684
686 685 class Javascript(TextDisplayObject):
687 686
688 687 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
689 688 """Create a Javascript display object given raw data.
690 689
691 690 When this object is returned by an expression or passed to the
692 691 display function, it will result in the data being displayed
693 692 in the frontend. If the data is a URL, the data will first be
694 693 downloaded and then displayed.
695 694
696 695 In the Notebook, the containing element will be available as `element`,
697 696 and jQuery will be available. Content appended to `element` will be
698 697 visible in the output area.
699 698
700 699 Parameters
701 700 ----------
702 701 data : unicode, str or bytes
703 702 The Javascript source code or a URL to download it from.
704 703 url : unicode
705 704 A URL to download the data from.
706 705 filename : unicode
707 706 Path to a local file to load the data from.
708 707 lib : list or str
709 708 A sequence of Javascript library URLs to load asynchronously before
710 709 running the source code. The full URLs of the libraries should
711 710 be given. A single Javascript library URL can also be given as a
712 711 string.
713 712 css: : list or str
714 713 A sequence of css files to load before running the source code.
715 714 The full URLs of the css files should be given. A single css URL
716 715 can also be given as a string.
717 716 """
718 if isinstance(lib, string_types):
717 if isinstance(lib, str):
719 718 lib = [lib]
720 719 elif lib is None:
721 720 lib = []
722 if isinstance(css, string_types):
721 if isinstance(css, str):
723 722 css = [css]
724 723 elif css is None:
725 724 css = []
726 725 if not isinstance(lib, (list,tuple)):
727 726 raise TypeError('expected sequence, got: %r' % lib)
728 727 if not isinstance(css, (list,tuple)):
729 728 raise TypeError('expected sequence, got: %r' % css)
730 729 self.lib = lib
731 730 self.css = css
732 731 super(Javascript, self).__init__(data=data, url=url, filename=filename)
733 732
734 733 def _repr_javascript_(self):
735 734 r = ''
736 735 for c in self.css:
737 736 r += css_t % c
738 737 for l in self.lib:
739 738 r += lib_t1 % l
740 739 r += self.data
741 740 r += lib_t2*len(self.lib)
742 741 return r
743 742
744 743 # constants for identifying png/jpeg data
745 744 _PNG = b'\x89PNG\r\n\x1a\n'
746 745 _JPEG = b'\xff\xd8'
747 746
748 747 def _pngxy(data):
749 748 """read the (width, height) from a PNG header"""
750 749 ihdr = data.index(b'IHDR')
751 750 # next 8 bytes are width/height
752 751 w4h4 = data[ihdr+4:ihdr+12]
753 752 return struct.unpack('>ii', w4h4)
754 753
755 754 def _jpegxy(data):
756 755 """read the (width, height) from a JPEG header"""
757 756 # adapted from http://www.64lines.com/jpeg-width-height
758 757
759 758 idx = 4
760 759 while True:
761 760 block_size = struct.unpack('>H', data[idx:idx+2])[0]
762 761 idx = idx + block_size
763 762 if data[idx:idx+2] == b'\xFF\xC0':
764 763 # found Start of Frame
765 764 iSOF = idx
766 765 break
767 766 else:
768 767 # read another block
769 768 idx += 2
770 769
771 770 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
772 771 return w, h
773 772
774 773 class Image(DisplayObject):
775 774
776 775 _read_flags = 'rb'
777 776 _FMT_JPEG = u'jpeg'
778 777 _FMT_PNG = u'png'
779 778 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
780 779
781 780 def __init__(self, data=None, url=None, filename=None, format=None,
782 781 embed=None, width=None, height=None, retina=False,
783 782 unconfined=False, metadata=None):
784 783 """Create a PNG/JPEG image object given raw data.
785 784
786 785 When this object is returned by an input cell or passed to the
787 786 display function, it will result in the image being displayed
788 787 in the frontend.
789 788
790 789 Parameters
791 790 ----------
792 791 data : unicode, str or bytes
793 792 The raw image data or a URL or filename to load the data from.
794 793 This always results in embedded image data.
795 794 url : unicode
796 795 A URL to download the data from. If you specify `url=`,
797 796 the image data will not be embedded unless you also specify `embed=True`.
798 797 filename : unicode
799 798 Path to a local file to load the data from.
800 799 Images from a file are always embedded.
801 800 format : unicode
802 801 The format of the image data (png/jpeg/jpg). If a filename or URL is given
803 802 for format will be inferred from the filename extension.
804 803 embed : bool
805 804 Should the image data be embedded using a data URI (True) or be
806 805 loaded using an <img> tag. Set this to True if you want the image
807 806 to be viewable later with no internet connection in the notebook.
808 807
809 808 Default is `True`, unless the keyword argument `url` is set, then
810 809 default value is `False`.
811 810
812 811 Note that QtConsole is not able to display images if `embed` is set to `False`
813 812 width : int
814 813 Width in pixels to which to constrain the image in html
815 814 height : int
816 815 Height in pixels to which to constrain the image in html
817 816 retina : bool
818 817 Automatically set the width and height to half of the measured
819 818 width and height.
820 819 This only works for embedded images because it reads the width/height
821 820 from image data.
822 821 For non-embedded images, you can just set the desired display width
823 822 and height directly.
824 823 unconfined: bool
825 824 Set unconfined=True to disable max-width confinement of the image.
826 825 metadata: dict
827 826 Specify extra metadata to attach to the image.
828 827
829 828 Examples
830 829 --------
831 830 # embedded image data, works in qtconsole and notebook
832 831 # when passed positionally, the first arg can be any of raw image data,
833 832 # a URL, or a filename from which to load image data.
834 833 # The result is always embedding image data for inline images.
835 834 Image('http://www.google.fr/images/srpr/logo3w.png')
836 835 Image('/path/to/image.jpg')
837 836 Image(b'RAW_PNG_DATA...')
838 837
839 838 # Specifying Image(url=...) does not embed the image data,
840 839 # it only generates `<img>` tag with a link to the source.
841 840 # This will not work in the qtconsole or offline.
842 841 Image(url='http://www.google.fr/images/srpr/logo3w.png')
843 842
844 843 """
845 844 if filename is not None:
846 845 ext = self._find_ext(filename)
847 846 elif url is not None:
848 847 ext = self._find_ext(url)
849 848 elif data is None:
850 849 raise ValueError("No image data found. Expecting filename, url, or data.")
851 elif isinstance(data, string_types) and (
850 elif isinstance(data, str) and (
852 851 data.startswith('http') or _safe_exists(data)
853 852 ):
854 853 ext = self._find_ext(data)
855 854 else:
856 855 ext = None
857 856
858 857 if format is None:
859 858 if ext is not None:
860 859 if ext == u'jpg' or ext == u'jpeg':
861 860 format = self._FMT_JPEG
862 861 if ext == u'png':
863 862 format = self._FMT_PNG
864 863 else:
865 864 format = ext.lower()
866 865 elif isinstance(data, bytes):
867 866 # infer image type from image data header,
868 867 # only if format has not been specified.
869 868 if data[:2] == _JPEG:
870 869 format = self._FMT_JPEG
871 870
872 871 # failed to detect format, default png
873 872 if format is None:
874 873 format = 'png'
875 874
876 875 if format.lower() == 'jpg':
877 876 # jpg->jpeg
878 877 format = self._FMT_JPEG
879 878
880 self.format = unicode_type(format).lower()
879 self.format = format.lower()
881 880 self.embed = embed if embed is not None else (url is None)
882 881
883 882 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
884 883 raise ValueError("Cannot embed the '%s' image format" % (self.format))
885 884 self.width = width
886 885 self.height = height
887 886 self.retina = retina
888 887 self.unconfined = unconfined
889 888 self.metadata = metadata
890 889 super(Image, self).__init__(data=data, url=url, filename=filename)
891 890
892 891 if retina:
893 892 self._retina_shape()
894 893
895 894 def _retina_shape(self):
896 895 """load pixel-doubled width and height from image data"""
897 896 if not self.embed:
898 897 return
899 898 if self.format == 'png':
900 899 w, h = _pngxy(self.data)
901 900 elif self.format == 'jpeg':
902 901 w, h = _jpegxy(self.data)
903 902 else:
904 903 # retina only supports png
905 904 return
906 905 self.width = w // 2
907 906 self.height = h // 2
908 907
909 908 def reload(self):
910 909 """Reload the raw data from file or URL."""
911 910 if self.embed:
912 911 super(Image,self).reload()
913 912 if self.retina:
914 913 self._retina_shape()
915 914
916 915 def _repr_html_(self):
917 916 if not self.embed:
918 917 width = height = klass = ''
919 918 if self.width:
920 919 width = ' width="%d"' % self.width
921 920 if self.height:
922 921 height = ' height="%d"' % self.height
923 922 if self.unconfined:
924 923 klass = ' class="unconfined"'
925 924 return u'<img src="{url}"{width}{height}{klass}/>'.format(
926 925 url=self.url,
927 926 width=width,
928 927 height=height,
929 928 klass=klass,
930 929 )
931 930
932 931 def _data_and_metadata(self):
933 932 """shortcut for returning metadata with shape information, if defined"""
934 933 md = {}
935 934 if self.width:
936 935 md['width'] = self.width
937 936 if self.height:
938 937 md['height'] = self.height
939 938 if self.unconfined:
940 939 md['unconfined'] = self.unconfined
941 940 if self.metadata:
942 941 md.update(self.metadata)
943 942 if md:
944 943 return self.data, md
945 944 else:
946 945 return self.data
947 946
948 947 def _repr_png_(self):
949 948 if self.embed and self.format == u'png':
950 949 return self._data_and_metadata()
951 950
952 951 def _repr_jpeg_(self):
953 952 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
954 953 return self._data_and_metadata()
955 954
956 955 def _find_ext(self, s):
957 return unicode_type(s.split('.')[-1].lower())
956 return s.split('.')[-1].lower()
958 957
959 958 class Video(DisplayObject):
960 959
961 960 def __init__(self, data=None, url=None, filename=None, embed=False, mimetype=None):
962 961 """Create a video object given raw data or an URL.
963 962
964 963 When this object is returned by an input cell or passed to the
965 964 display function, it will result in the video being displayed
966 965 in the frontend.
967 966
968 967 Parameters
969 968 ----------
970 969 data : unicode, str or bytes
971 970 The raw video data or a URL or filename to load the data from.
972 971 Raw data will require passing `embed=True`.
973 972 url : unicode
974 973 A URL for the video. If you specify `url=`,
975 974 the image data will not be embedded.
976 975 filename : unicode
977 976 Path to a local file containing the video.
978 977 Will be interpreted as a local URL unless `embed=True`.
979 978 embed : bool
980 979 Should the video be embedded using a data URI (True) or be
981 980 loaded using a <video> tag (False).
982 981
983 982 Since videos are large, embedding them should be avoided, if possible.
984 983 You must confirm embedding as your intention by passing `embed=True`.
985 984
986 985 Local files can be displayed with URLs without embedding the content, via::
987 986
988 987 Video('./video.mp4')
989 988
990 989 mimetype: unicode
991 990 Specify the mimetype for embedded videos.
992 991 Default will be guessed from file extension, if available.
993 992
994 993 Examples
995 994 --------
996 995
997 996 Video('https://archive.org/download/Sita_Sings_the_Blues/Sita_Sings_the_Blues_small.mp4')
998 997 Video('path/to/video.mp4')
999 998 Video('path/to/video.mp4', embed=True)
1000 999 Video(b'raw-videodata', embed=True)
1001 1000 """
1002 if url is None and isinstance(data, string_types) and data.startswith(('http:', 'https:')):
1001 if url is None and isinstance(data, str) and data.startswith(('http:', 'https:')):
1003 1002 url = data
1004 1003 data = None
1005 1004 elif os.path.exists(data):
1006 1005 filename = data
1007 1006 data = None
1008 1007
1009 1008 if data and not embed:
1010 1009 msg = ''.join([
1011 1010 "To embed videos, you must pass embed=True ",
1012 1011 "(this may make your notebook files huge)\n",
1013 1012 "Consider passing Video(url='...')",
1014 1013 ])
1015 1014 raise ValueError(msg)
1016 1015
1017 1016 self.mimetype = mimetype
1018 1017 self.embed = embed
1019 1018 super(Video, self).__init__(data=data, url=url, filename=filename)
1020 1019
1021 1020 def _repr_html_(self):
1022 1021 # External URLs and potentially local files are not embedded into the
1023 1022 # notebook output.
1024 1023 if not self.embed:
1025 1024 url = self.url if self.url is not None else self.filename
1026 1025 output = """<video src="{0}" controls>
1027 1026 Your browser does not support the <code>video</code> element.
1028 1027 </video>""".format(url)
1029 1028 return output
1030 1029
1031 1030 # Embedded videos are base64-encoded.
1032 1031 mimetype = self.mimetype
1033 1032 if self.filename is not None:
1034 1033 if not mimetype:
1035 1034 mimetype, _ = mimetypes.guess_type(self.filename)
1036 1035
1037 1036 with open(self.filename, 'rb') as f:
1038 1037 video = f.read()
1039 1038 else:
1040 1039 video = self.data
1041 if isinstance(video, unicode_type):
1040 if isinstance(video, str):
1042 1041 # unicode input is already b64-encoded
1043 1042 b64_video = video
1044 1043 else:
1045 1044 b64_video = base64_encode(video).decode('ascii').rstrip()
1046 1045
1047 1046 output = """<video controls>
1048 1047 <source src="data:{0};base64,{1}" type="{0}">
1049 1048 Your browser does not support the video tag.
1050 1049 </video>""".format(mimetype, b64_video)
1051 1050 return output
1052 1051
1053 1052 def reload(self):
1054 1053 # TODO
1055 1054 pass
1056 1055
1057 1056 def _repr_png_(self):
1058 1057 # TODO
1059 1058 pass
1060 1059 def _repr_jpeg_(self):
1061 1060 # TODO
1062 1061 pass
1063 1062
1064 1063 def clear_output(wait=False):
1065 1064 """Clear the output of the current cell receiving output.
1066 1065
1067 1066 Parameters
1068 1067 ----------
1069 1068 wait : bool [default: false]
1070 1069 Wait to clear the output until new output is available to replace it."""
1071 1070 from IPython.core.interactiveshell import InteractiveShell
1072 1071 if InteractiveShell.initialized():
1073 1072 InteractiveShell.instance().display_pub.clear_output(wait)
1074 1073 else:
1075 1074 print('\033[2K\r', end='')
1076 1075 sys.stdout.flush()
1077 1076 print('\033[2K\r', end='')
1078 1077 sys.stderr.flush()
1079 1078
1080 1079
1081 1080 @skip_doctest
1082 1081 def set_matplotlib_formats(*formats, **kwargs):
1083 1082 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
1084 1083
1085 1084 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
1086 1085
1087 1086 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
1088 1087
1089 1088 To set this in your config files use the following::
1090 1089
1091 1090 c.InlineBackend.figure_formats = {'png', 'jpeg'}
1092 1091 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
1093 1092
1094 1093 Parameters
1095 1094 ----------
1096 1095 *formats : strs
1097 1096 One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
1098 1097 **kwargs :
1099 1098 Keyword args will be relayed to ``figure.canvas.print_figure``.
1100 1099 """
1101 1100 from IPython.core.interactiveshell import InteractiveShell
1102 1101 from IPython.core.pylabtools import select_figure_formats
1103 1102 # build kwargs, starting with InlineBackend config
1104 1103 kw = {}
1105 1104 from ipykernel.pylab.config import InlineBackend
1106 1105 cfg = InlineBackend.instance()
1107 1106 kw.update(cfg.print_figure_kwargs)
1108 1107 kw.update(**kwargs)
1109 1108 shell = InteractiveShell.instance()
1110 1109 select_figure_formats(shell, formats, **kw)
1111 1110
1112 1111 @skip_doctest
1113 1112 def set_matplotlib_close(close=True):
1114 1113 """Set whether the inline backend closes all figures automatically or not.
1115 1114
1116 1115 By default, the inline backend used in the IPython Notebook will close all
1117 1116 matplotlib figures automatically after each cell is run. This means that
1118 1117 plots in different cells won't interfere. Sometimes, you may want to make
1119 1118 a plot in one cell and then refine it in later cells. This can be accomplished
1120 1119 by::
1121 1120
1122 1121 In [1]: set_matplotlib_close(False)
1123 1122
1124 1123 To set this in your config files use the following::
1125 1124
1126 1125 c.InlineBackend.close_figures = False
1127 1126
1128 1127 Parameters
1129 1128 ----------
1130 1129 close : bool
1131 1130 Should all matplotlib figures be automatically closed after each cell is
1132 1131 run?
1133 1132 """
1134 1133 from ipykernel.pylab.config import InlineBackend
1135 1134 cfg = InlineBackend.instance()
1136 1135 cfg.close_figures = close
@@ -1,947 +1,947 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Display formatters.
3 3
4 4 Inheritance diagram:
5 5
6 6 .. inheritance-diagram:: IPython.core.formatters
7 7 :parts: 3
8 8 """
9 9
10 10 # Copyright (c) IPython Development Team.
11 11 # Distributed under the terms of the Modified BSD License.
12 12
13 13 import abc
14 14 import json
15 15 import sys
16 16 import traceback
17 17 import warnings
18 18
19 19 from decorator import decorator
20 20
21 21 from traitlets.config.configurable import Configurable
22 22 from IPython.core.getipython import get_ipython
23 23 from IPython.utils.sentinel import Sentinel
24 24 from IPython.utils.dir2 import get_real_method
25 25 from IPython.lib import pretty
26 26 from traitlets import (
27 27 Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List,
28 28 ForwardDeclaredInstance,
29 29 default, observe,
30 30 )
31 31 from IPython.utils.py3compat import (
32 with_metaclass, string_types, unicode_type,
32 with_metaclass
33 33 )
34 34
35 35
36 36 class DisplayFormatter(Configurable):
37 37
38 38 active_types = List(Unicode(),
39 39 help="""List of currently active mime-types to display.
40 40 You can use this to set a white-list for formats to display.
41 41
42 42 Most users will not need to change this value.
43 43 """).tag(config=True)
44 44
45 45 @default('active_types')
46 46 def _active_types_default(self):
47 47 return self.format_types
48 48
49 49 @observe('active_types')
50 50 def _active_types_changed(self, change):
51 51 for key, formatter in self.formatters.items():
52 52 if key in change['new']:
53 53 formatter.enabled = True
54 54 else:
55 55 formatter.enabled = False
56 56
57 57 ipython_display_formatter = ForwardDeclaredInstance('FormatterABC')
58 58 @default('ipython_display_formatter')
59 59 def _default_formatter(self):
60 60 return IPythonDisplayFormatter(parent=self)
61 61
62 62 # A dict of formatter whose keys are format types (MIME types) and whose
63 63 # values are subclasses of BaseFormatter.
64 64 formatters = Dict()
65 65 @default('formatters')
66 66 def _formatters_default(self):
67 67 """Activate the default formatters."""
68 68 formatter_classes = [
69 69 PlainTextFormatter,
70 70 HTMLFormatter,
71 71 MarkdownFormatter,
72 72 SVGFormatter,
73 73 PNGFormatter,
74 74 PDFFormatter,
75 75 JPEGFormatter,
76 76 LatexFormatter,
77 77 JSONFormatter,
78 78 JavascriptFormatter
79 79 ]
80 80 d = {}
81 81 for cls in formatter_classes:
82 82 f = cls(parent=self)
83 83 d[f.format_type] = f
84 84 return d
85 85
86 86 def format(self, obj, include=None, exclude=None):
87 87 """Return a format data dict for an object.
88 88
89 89 By default all format types will be computed.
90 90
91 91 The following MIME types are currently implemented:
92 92
93 93 * text/plain
94 94 * text/html
95 95 * text/markdown
96 96 * text/latex
97 97 * application/json
98 98 * application/javascript
99 99 * application/pdf
100 100 * image/png
101 101 * image/jpeg
102 102 * image/svg+xml
103 103
104 104 Parameters
105 105 ----------
106 106 obj : object
107 107 The Python object whose format data will be computed.
108 108 include : list or tuple, optional
109 109 A list of format type strings (MIME types) to include in the
110 110 format data dict. If this is set *only* the format types included
111 111 in this list will be computed.
112 112 exclude : list or tuple, optional
113 113 A list of format type string (MIME types) to exclude in the format
114 114 data dict. If this is set all format types will be computed,
115 115 except for those included in this argument.
116 116
117 117 Returns
118 118 -------
119 119 (format_dict, metadata_dict) : tuple of two dicts
120 120
121 121 format_dict is a dictionary of key/value pairs, one of each format that was
122 122 generated for the object. The keys are the format types, which
123 123 will usually be MIME type strings and the values and JSON'able
124 124 data structure containing the raw data for the representation in
125 125 that format.
126 126
127 127 metadata_dict is a dictionary of metadata about each mime-type output.
128 128 Its keys will be a strict subset of the keys in format_dict.
129 129 """
130 130 format_dict = {}
131 131 md_dict = {}
132 132
133 133 if self.ipython_display_formatter(obj):
134 134 # object handled itself, don't proceed
135 135 return {}, {}
136 136
137 137 for format_type, formatter in self.formatters.items():
138 138 if include and format_type not in include:
139 139 continue
140 140 if exclude and format_type in exclude:
141 141 continue
142 142
143 143 md = None
144 144 try:
145 145 data = formatter(obj)
146 146 except:
147 147 # FIXME: log the exception
148 148 raise
149 149
150 150 # formatters can return raw data or (data, metadata)
151 151 if isinstance(data, tuple) and len(data) == 2:
152 152 data, md = data
153 153
154 154 if data is not None:
155 155 format_dict[format_type] = data
156 156 if md is not None:
157 157 md_dict[format_type] = md
158 158
159 159 return format_dict, md_dict
160 160
161 161 @property
162 162 def format_types(self):
163 163 """Return the format types (MIME types) of the active formatters."""
164 164 return list(self.formatters.keys())
165 165
166 166
167 167 #-----------------------------------------------------------------------------
168 168 # Formatters for specific format types (text, html, svg, etc.)
169 169 #-----------------------------------------------------------------------------
170 170
171 171
172 172 def _safe_repr(obj):
173 173 """Try to return a repr of an object
174 174
175 175 always returns a string, at least.
176 176 """
177 177 try:
178 178 return repr(obj)
179 179 except Exception as e:
180 180 return "un-repr-able object (%r)" % e
181 181
182 182
183 183 class FormatterWarning(UserWarning):
184 184 """Warning class for errors in formatters"""
185 185
186 186 @decorator
187 187 def catch_format_error(method, self, *args, **kwargs):
188 188 """show traceback on failed format call"""
189 189 try:
190 190 r = method(self, *args, **kwargs)
191 191 except NotImplementedError:
192 192 # don't warn on NotImplementedErrors
193 193 return None
194 194 except Exception:
195 195 exc_info = sys.exc_info()
196 196 ip = get_ipython()
197 197 if ip is not None:
198 198 ip.showtraceback(exc_info)
199 199 else:
200 200 traceback.print_exception(*exc_info)
201 201 return None
202 202 return self._check_return(r, args[0])
203 203
204 204
205 205 class FormatterABC(with_metaclass(abc.ABCMeta, object)):
206 206 """ Abstract base class for Formatters.
207 207
208 208 A formatter is a callable class that is responsible for computing the
209 209 raw format data for a particular format type (MIME type). For example,
210 210 an HTML formatter would have a format type of `text/html` and would return
211 211 the HTML representation of the object when called.
212 212 """
213 213
214 214 # The format type of the data returned, usually a MIME type.
215 215 format_type = 'text/plain'
216 216
217 217 # Is the formatter enabled...
218 218 enabled = True
219 219
220 220 @abc.abstractmethod
221 221 def __call__(self, obj):
222 222 """Return a JSON'able representation of the object.
223 223
224 224 If the object cannot be formatted by this formatter,
225 225 warn and return None.
226 226 """
227 227 return repr(obj)
228 228
229 229
230 230 def _mod_name_key(typ):
231 231 """Return a (__module__, __name__) tuple for a type.
232 232
233 233 Used as key in Formatter.deferred_printers.
234 234 """
235 235 module = getattr(typ, '__module__', None)
236 236 name = getattr(typ, '__name__', None)
237 237 return (module, name)
238 238
239 239
240 240 def _get_type(obj):
241 241 """Return the type of an instance (old and new-style)"""
242 242 return getattr(obj, '__class__', None) or type(obj)
243 243
244 244
245 245 _raise_key_error = Sentinel('_raise_key_error', __name__,
246 246 """
247 247 Special value to raise a KeyError
248 248
249 249 Raise KeyError in `BaseFormatter.pop` if passed as the default value to `pop`
250 250 """)
251 251
252 252
253 253 class BaseFormatter(Configurable):
254 254 """A base formatter class that is configurable.
255 255
256 256 This formatter should usually be used as the base class of all formatters.
257 257 It is a traited :class:`Configurable` class and includes an extensible
258 258 API for users to determine how their objects are formatted. The following
259 259 logic is used to find a function to format an given object.
260 260
261 261 1. The object is introspected to see if it has a method with the name
262 262 :attr:`print_method`. If is does, that object is passed to that method
263 263 for formatting.
264 264 2. If no print method is found, three internal dictionaries are consulted
265 265 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
266 266 and :attr:`deferred_printers`.
267 267
268 268 Users should use these dictionaries to register functions that will be
269 269 used to compute the format data for their objects (if those objects don't
270 270 have the special print methods). The easiest way of using these
271 271 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
272 272 methods.
273 273
274 274 If no function/callable is found to compute the format data, ``None`` is
275 275 returned and this format type is not used.
276 276 """
277 277
278 278 format_type = Unicode('text/plain')
279 _return_type = string_types
279 _return_type = str
280 280
281 281 enabled = Bool(True).tag(config=True)
282 282
283 283 print_method = ObjectName('__repr__')
284 284
285 285 # The singleton printers.
286 286 # Maps the IDs of the builtin singleton objects to the format functions.
287 287 singleton_printers = Dict().tag(config=True)
288 288
289 289 # The type-specific printers.
290 290 # Map type objects to the format functions.
291 291 type_printers = Dict().tag(config=True)
292 292
293 293 # The deferred-import type-specific printers.
294 294 # Map (modulename, classname) pairs to the format functions.
295 295 deferred_printers = Dict().tag(config=True)
296 296
297 297 @catch_format_error
298 298 def __call__(self, obj):
299 299 """Compute the format for an object."""
300 300 if self.enabled:
301 301 # lookup registered printer
302 302 try:
303 303 printer = self.lookup(obj)
304 304 except KeyError:
305 305 pass
306 306 else:
307 307 return printer(obj)
308 308 # Finally look for special method names
309 309 method = get_real_method(obj, self.print_method)
310 310 if method is not None:
311 311 return method()
312 312 return None
313 313 else:
314 314 return None
315 315
316 316 def __contains__(self, typ):
317 317 """map in to lookup_by_type"""
318 318 try:
319 319 self.lookup_by_type(typ)
320 320 except KeyError:
321 321 return False
322 322 else:
323 323 return True
324 324
325 325 def _check_return(self, r, obj):
326 326 """Check that a return value is appropriate
327 327
328 328 Return the value if so, None otherwise, warning if invalid.
329 329 """
330 330 if r is None or isinstance(r, self._return_type) or \
331 331 (isinstance(r, tuple) and r and isinstance(r[0], self._return_type)):
332 332 return r
333 333 else:
334 334 warnings.warn(
335 335 "%s formatter returned invalid type %s (expected %s) for object: %s" % \
336 336 (self.format_type, type(r), self._return_type, _safe_repr(obj)),
337 337 FormatterWarning
338 338 )
339 339
340 340 def lookup(self, obj):
341 341 """Look up the formatter for a given instance.
342 342
343 343 Parameters
344 344 ----------
345 345 obj : object instance
346 346
347 347 Returns
348 348 -------
349 349 f : callable
350 350 The registered formatting callable for the type.
351 351
352 352 Raises
353 353 ------
354 354 KeyError if the type has not been registered.
355 355 """
356 356 # look for singleton first
357 357 obj_id = id(obj)
358 358 if obj_id in self.singleton_printers:
359 359 return self.singleton_printers[obj_id]
360 360 # then lookup by type
361 361 return self.lookup_by_type(_get_type(obj))
362 362
363 363 def lookup_by_type(self, typ):
364 364 """Look up the registered formatter for a type.
365 365
366 366 Parameters
367 367 ----------
368 368 typ : type or '__module__.__name__' string for a type
369 369
370 370 Returns
371 371 -------
372 372 f : callable
373 373 The registered formatting callable for the type.
374 374
375 375 Raises
376 376 ------
377 377 KeyError if the type has not been registered.
378 378 """
379 if isinstance(typ, string_types):
379 if isinstance(typ, str):
380 380 typ_key = tuple(typ.rsplit('.',1))
381 381 if typ_key not in self.deferred_printers:
382 382 # We may have it cached in the type map. We will have to
383 383 # iterate over all of the types to check.
384 384 for cls in self.type_printers:
385 385 if _mod_name_key(cls) == typ_key:
386 386 return self.type_printers[cls]
387 387 else:
388 388 return self.deferred_printers[typ_key]
389 389 else:
390 390 for cls in pretty._get_mro(typ):
391 391 if cls in self.type_printers or self._in_deferred_types(cls):
392 392 return self.type_printers[cls]
393 393
394 394 # If we have reached here, the lookup failed.
395 395 raise KeyError("No registered printer for {0!r}".format(typ))
396 396
397 397 def for_type(self, typ, func=None):
398 398 """Add a format function for a given type.
399 399
400 400 Parameters
401 401 -----------
402 402 typ : type or '__module__.__name__' string for a type
403 403 The class of the object that will be formatted using `func`.
404 404 func : callable
405 405 A callable for computing the format data.
406 406 `func` will be called with the object to be formatted,
407 407 and will return the raw data in this formatter's format.
408 408 Subclasses may use a different call signature for the
409 409 `func` argument.
410 410
411 411 If `func` is None or not specified, there will be no change,
412 412 only returning the current value.
413 413
414 414 Returns
415 415 -------
416 416 oldfunc : callable
417 417 The currently registered callable.
418 418 If you are registering a new formatter,
419 419 this will be the previous value (to enable restoring later).
420 420 """
421 421 # if string given, interpret as 'pkg.module.class_name'
422 if isinstance(typ, string_types):
422 if isinstance(typ, str):
423 423 type_module, type_name = typ.rsplit('.', 1)
424 424 return self.for_type_by_name(type_module, type_name, func)
425 425
426 426 try:
427 427 oldfunc = self.lookup_by_type(typ)
428 428 except KeyError:
429 429 oldfunc = None
430 430
431 431 if func is not None:
432 432 self.type_printers[typ] = func
433 433
434 434 return oldfunc
435 435
436 436 def for_type_by_name(self, type_module, type_name, func=None):
437 437 """Add a format function for a type specified by the full dotted
438 438 module and name of the type, rather than the type of the object.
439 439
440 440 Parameters
441 441 ----------
442 442 type_module : str
443 443 The full dotted name of the module the type is defined in, like
444 444 ``numpy``.
445 445 type_name : str
446 446 The name of the type (the class name), like ``dtype``
447 447 func : callable
448 448 A callable for computing the format data.
449 449 `func` will be called with the object to be formatted,
450 450 and will return the raw data in this formatter's format.
451 451 Subclasses may use a different call signature for the
452 452 `func` argument.
453 453
454 454 If `func` is None or unspecified, there will be no change,
455 455 only returning the current value.
456 456
457 457 Returns
458 458 -------
459 459 oldfunc : callable
460 460 The currently registered callable.
461 461 If you are registering a new formatter,
462 462 this will be the previous value (to enable restoring later).
463 463 """
464 464 key = (type_module, type_name)
465 465
466 466 try:
467 467 oldfunc = self.lookup_by_type("%s.%s" % key)
468 468 except KeyError:
469 469 oldfunc = None
470 470
471 471 if func is not None:
472 472 self.deferred_printers[key] = func
473 473 return oldfunc
474 474
475 475 def pop(self, typ, default=_raise_key_error):
476 476 """Pop a formatter for the given type.
477 477
478 478 Parameters
479 479 ----------
480 480 typ : type or '__module__.__name__' string for a type
481 481 default : object
482 482 value to be returned if no formatter is registered for typ.
483 483
484 484 Returns
485 485 -------
486 486 obj : object
487 487 The last registered object for the type.
488 488
489 489 Raises
490 490 ------
491 491 KeyError if the type is not registered and default is not specified.
492 492 """
493 493
494 if isinstance(typ, string_types):
494 if isinstance(typ, str):
495 495 typ_key = tuple(typ.rsplit('.',1))
496 496 if typ_key not in self.deferred_printers:
497 497 # We may have it cached in the type map. We will have to
498 498 # iterate over all of the types to check.
499 499 for cls in self.type_printers:
500 500 if _mod_name_key(cls) == typ_key:
501 501 old = self.type_printers.pop(cls)
502 502 break
503 503 else:
504 504 old = default
505 505 else:
506 506 old = self.deferred_printers.pop(typ_key)
507 507 else:
508 508 if typ in self.type_printers:
509 509 old = self.type_printers.pop(typ)
510 510 else:
511 511 old = self.deferred_printers.pop(_mod_name_key(typ), default)
512 512 if old is _raise_key_error:
513 513 raise KeyError("No registered value for {0!r}".format(typ))
514 514 return old
515 515
516 516 def _in_deferred_types(self, cls):
517 517 """
518 518 Check if the given class is specified in the deferred type registry.
519 519
520 520 Successful matches will be moved to the regular type registry for future use.
521 521 """
522 522 mod = getattr(cls, '__module__', None)
523 523 name = getattr(cls, '__name__', None)
524 524 key = (mod, name)
525 525 if key in self.deferred_printers:
526 526 # Move the printer over to the regular registry.
527 527 printer = self.deferred_printers.pop(key)
528 528 self.type_printers[cls] = printer
529 529 return True
530 530 return False
531 531
532 532
533 533 class PlainTextFormatter(BaseFormatter):
534 534 """The default pretty-printer.
535 535
536 536 This uses :mod:`IPython.lib.pretty` to compute the format data of
537 537 the object. If the object cannot be pretty printed, :func:`repr` is used.
538 538 See the documentation of :mod:`IPython.lib.pretty` for details on
539 539 how to write pretty printers. Here is a simple example::
540 540
541 541 def dtype_pprinter(obj, p, cycle):
542 542 if cycle:
543 543 return p.text('dtype(...)')
544 544 if hasattr(obj, 'fields'):
545 545 if obj.fields is None:
546 546 p.text(repr(obj))
547 547 else:
548 548 p.begin_group(7, 'dtype([')
549 549 for i, field in enumerate(obj.descr):
550 550 if i > 0:
551 551 p.text(',')
552 552 p.breakable()
553 553 p.pretty(field)
554 554 p.end_group(7, '])')
555 555 """
556 556
557 557 # The format type of data returned.
558 558 format_type = Unicode('text/plain')
559 559
560 560 # This subclass ignores this attribute as it always need to return
561 561 # something.
562 562 enabled = Bool(True).tag(config=False)
563 563
564 564 max_seq_length = Integer(pretty.MAX_SEQ_LENGTH,
565 565 help="""Truncate large collections (lists, dicts, tuples, sets) to this size.
566 566
567 567 Set to 0 to disable truncation.
568 568 """
569 569 ).tag(config=True)
570 570
571 571 # Look for a _repr_pretty_ methods to use for pretty printing.
572 572 print_method = ObjectName('_repr_pretty_')
573 573
574 574 # Whether to pretty-print or not.
575 575 pprint = Bool(True).tag(config=True)
576 576
577 577 # Whether to be verbose or not.
578 578 verbose = Bool(False).tag(config=True)
579 579
580 580 # The maximum width.
581 581 max_width = Integer(79).tag(config=True)
582 582
583 583 # The newline character.
584 584 newline = Unicode('\n').tag(config=True)
585 585
586 586 # format-string for pprinting floats
587 587 float_format = Unicode('%r')
588 588 # setter for float precision, either int or direct format-string
589 589 float_precision = CUnicode('').tag(config=True)
590 590
591 591 @observe('float_precision')
592 592 def _float_precision_changed(self, change):
593 593 """float_precision changed, set float_format accordingly.
594 594
595 595 float_precision can be set by int or str.
596 596 This will set float_format, after interpreting input.
597 597 If numpy has been imported, numpy print precision will also be set.
598 598
599 599 integer `n` sets format to '%.nf', otherwise, format set directly.
600 600
601 601 An empty string returns to defaults (repr for float, 8 for numpy).
602 602
603 603 This parameter can be set via the '%precision' magic.
604 604 """
605 605
606 606 new = change['new']
607 607 if '%' in new:
608 608 # got explicit format string
609 609 fmt = new
610 610 try:
611 611 fmt%3.14159
612 612 except Exception:
613 613 raise ValueError("Precision must be int or format string, not %r"%new)
614 614 elif new:
615 615 # otherwise, should be an int
616 616 try:
617 617 i = int(new)
618 618 assert i >= 0
619 619 except ValueError:
620 620 raise ValueError("Precision must be int or format string, not %r"%new)
621 621 except AssertionError:
622 622 raise ValueError("int precision must be non-negative, not %r"%i)
623 623
624 624 fmt = '%%.%if'%i
625 625 if 'numpy' in sys.modules:
626 626 # set numpy precision if it has been imported
627 627 import numpy
628 628 numpy.set_printoptions(precision=i)
629 629 else:
630 630 # default back to repr
631 631 fmt = '%r'
632 632 if 'numpy' in sys.modules:
633 633 import numpy
634 634 # numpy default is 8
635 635 numpy.set_printoptions(precision=8)
636 636 self.float_format = fmt
637 637
638 638 # Use the default pretty printers from IPython.lib.pretty.
639 639 @default('singleton_printers')
640 640 def _singleton_printers_default(self):
641 641 return pretty._singleton_pprinters.copy()
642 642
643 643 @default('type_printers')
644 644 def _type_printers_default(self):
645 645 d = pretty._type_pprinters.copy()
646 646 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
647 647 return d
648 648
649 649 @default('deferred_printers')
650 650 def _deferred_printers_default(self):
651 651 return pretty._deferred_type_pprinters.copy()
652 652
653 653 #### FormatterABC interface ####
654 654
655 655 @catch_format_error
656 656 def __call__(self, obj):
657 657 """Compute the pretty representation of the object."""
658 658 if not self.pprint:
659 659 return repr(obj)
660 660 else:
661 661 # handle str and unicode on Python 2
662 662 # io.StringIO only accepts unicode,
663 663 # cStringIO doesn't handle unicode on py2,
664 664 # StringIO allows str, unicode but only ascii str
665 665 stream = pretty.CUnicodeIO()
666 666 printer = pretty.RepresentationPrinter(stream, self.verbose,
667 667 self.max_width, self.newline,
668 668 max_seq_length=self.max_seq_length,
669 669 singleton_pprinters=self.singleton_printers,
670 670 type_pprinters=self.type_printers,
671 671 deferred_pprinters=self.deferred_printers)
672 672 printer.pretty(obj)
673 673 printer.flush()
674 674 return stream.getvalue()
675 675
676 676
677 677 class HTMLFormatter(BaseFormatter):
678 678 """An HTML formatter.
679 679
680 680 To define the callables that compute the HTML representation of your
681 681 objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
682 682 or :meth:`for_type_by_name` methods to register functions that handle
683 683 this.
684 684
685 685 The return value of this formatter should be a valid HTML snippet that
686 686 could be injected into an existing DOM. It should *not* include the
687 687 ```<html>`` or ```<body>`` tags.
688 688 """
689 689 format_type = Unicode('text/html')
690 690
691 691 print_method = ObjectName('_repr_html_')
692 692
693 693
694 694 class MarkdownFormatter(BaseFormatter):
695 695 """A Markdown formatter.
696 696
697 697 To define the callables that compute the Markdown representation of your
698 698 objects, define a :meth:`_repr_markdown_` method or use the :meth:`for_type`
699 699 or :meth:`for_type_by_name` methods to register functions that handle
700 700 this.
701 701
702 702 The return value of this formatter should be a valid Markdown.
703 703 """
704 704 format_type = Unicode('text/markdown')
705 705
706 706 print_method = ObjectName('_repr_markdown_')
707 707
708 708 class SVGFormatter(BaseFormatter):
709 709 """An SVG formatter.
710 710
711 711 To define the callables that compute the SVG representation of your
712 712 objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
713 713 or :meth:`for_type_by_name` methods to register functions that handle
714 714 this.
715 715
716 716 The return value of this formatter should be valid SVG enclosed in
717 717 ```<svg>``` tags, that could be injected into an existing DOM. It should
718 718 *not* include the ```<html>`` or ```<body>`` tags.
719 719 """
720 720 format_type = Unicode('image/svg+xml')
721 721
722 722 print_method = ObjectName('_repr_svg_')
723 723
724 724
725 725 class PNGFormatter(BaseFormatter):
726 726 """A PNG formatter.
727 727
728 728 To define the callables that compute the PNG representation of your
729 729 objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
730 730 or :meth:`for_type_by_name` methods to register functions that handle
731 731 this.
732 732
733 733 The return value of this formatter should be raw PNG data, *not*
734 734 base64 encoded.
735 735 """
736 736 format_type = Unicode('image/png')
737 737
738 738 print_method = ObjectName('_repr_png_')
739 739
740 _return_type = (bytes, unicode_type)
740 _return_type = (bytes, str)
741 741
742 742
743 743 class JPEGFormatter(BaseFormatter):
744 744 """A JPEG formatter.
745 745
746 746 To define the callables that compute the JPEG representation of your
747 747 objects, define a :meth:`_repr_jpeg_` method or use the :meth:`for_type`
748 748 or :meth:`for_type_by_name` methods to register functions that handle
749 749 this.
750 750
751 751 The return value of this formatter should be raw JPEG data, *not*
752 752 base64 encoded.
753 753 """
754 754 format_type = Unicode('image/jpeg')
755 755
756 756 print_method = ObjectName('_repr_jpeg_')
757 757
758 _return_type = (bytes, unicode_type)
758 _return_type = (bytes, str)
759 759
760 760
761 761 class LatexFormatter(BaseFormatter):
762 762 """A LaTeX formatter.
763 763
764 764 To define the callables that compute the LaTeX representation of your
765 765 objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
766 766 or :meth:`for_type_by_name` methods to register functions that handle
767 767 this.
768 768
769 769 The return value of this formatter should be a valid LaTeX equation,
770 770 enclosed in either ```$```, ```$$``` or another LaTeX equation
771 771 environment.
772 772 """
773 773 format_type = Unicode('text/latex')
774 774
775 775 print_method = ObjectName('_repr_latex_')
776 776
777 777
778 778 class JSONFormatter(BaseFormatter):
779 779 """A JSON string formatter.
780 780
781 781 To define the callables that compute the JSONable representation of
782 782 your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
783 783 or :meth:`for_type_by_name` methods to register functions that handle
784 784 this.
785 785
786 786 The return value of this formatter should be a JSONable list or dict.
787 787 JSON scalars (None, number, string) are not allowed, only dict or list containers.
788 788 """
789 789 format_type = Unicode('application/json')
790 790 _return_type = (list, dict)
791 791
792 792 print_method = ObjectName('_repr_json_')
793 793
794 794 def _check_return(self, r, obj):
795 795 """Check that a return value is appropriate
796 796
797 797 Return the value if so, None otherwise, warning if invalid.
798 798 """
799 799 if r is None:
800 800 return
801 801 md = None
802 802 if isinstance(r, tuple):
803 803 # unpack data, metadata tuple for type checking on first element
804 804 r, md = r
805 805
806 806 # handle deprecated JSON-as-string form from IPython < 3
807 if isinstance(r, string_types):
807 if isinstance(r, str):
808 808 warnings.warn("JSON expects JSONable list/dict containers, not JSON strings",
809 809 FormatterWarning)
810 810 r = json.loads(r)
811 811
812 812 if md is not None:
813 813 # put the tuple back together
814 814 r = (r, md)
815 815 return super(JSONFormatter, self)._check_return(r, obj)
816 816
817 817
818 818 class JavascriptFormatter(BaseFormatter):
819 819 """A Javascript formatter.
820 820
821 821 To define the callables that compute the Javascript representation of
822 822 your objects, define a :meth:`_repr_javascript_` method or use the
823 823 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
824 824 that handle this.
825 825
826 826 The return value of this formatter should be valid Javascript code and
827 827 should *not* be enclosed in ```<script>``` tags.
828 828 """
829 829 format_type = Unicode('application/javascript')
830 830
831 831 print_method = ObjectName('_repr_javascript_')
832 832
833 833
834 834 class PDFFormatter(BaseFormatter):
835 835 """A PDF formatter.
836 836
837 837 To define the callables that compute the PDF representation of your
838 838 objects, define a :meth:`_repr_pdf_` method or use the :meth:`for_type`
839 839 or :meth:`for_type_by_name` methods to register functions that handle
840 840 this.
841 841
842 842 The return value of this formatter should be raw PDF data, *not*
843 843 base64 encoded.
844 844 """
845 845 format_type = Unicode('application/pdf')
846 846
847 847 print_method = ObjectName('_repr_pdf_')
848 848
849 _return_type = (bytes, unicode_type)
849 _return_type = (bytes, str)
850 850
851 851 class IPythonDisplayFormatter(BaseFormatter):
852 852 """A Formatter for objects that know how to display themselves.
853 853
854 854 To define the callables that compute the representation of your
855 855 objects, define a :meth:`_ipython_display_` method or use the :meth:`for_type`
856 856 or :meth:`for_type_by_name` methods to register functions that handle
857 857 this. Unlike mime-type displays, this method should not return anything,
858 858 instead calling any appropriate display methods itself.
859 859
860 860 This display formatter has highest priority.
861 861 If it fires, no other display formatter will be called.
862 862 """
863 863 print_method = ObjectName('_ipython_display_')
864 864 _return_type = (type(None), bool)
865 865
866 866
867 867 @catch_format_error
868 868 def __call__(self, obj):
869 869 """Compute the format for an object."""
870 870 if self.enabled:
871 871 # lookup registered printer
872 872 try:
873 873 printer = self.lookup(obj)
874 874 except KeyError:
875 875 pass
876 876 else:
877 877 printer(obj)
878 878 return True
879 879 # Finally look for special method names
880 880 method = get_real_method(obj, self.print_method)
881 881 if method is not None:
882 882 method()
883 883 return True
884 884
885 885
886 886 FormatterABC.register(BaseFormatter)
887 887 FormatterABC.register(PlainTextFormatter)
888 888 FormatterABC.register(HTMLFormatter)
889 889 FormatterABC.register(MarkdownFormatter)
890 890 FormatterABC.register(SVGFormatter)
891 891 FormatterABC.register(PNGFormatter)
892 892 FormatterABC.register(PDFFormatter)
893 893 FormatterABC.register(JPEGFormatter)
894 894 FormatterABC.register(LatexFormatter)
895 895 FormatterABC.register(JSONFormatter)
896 896 FormatterABC.register(JavascriptFormatter)
897 897 FormatterABC.register(IPythonDisplayFormatter)
898 898
899 899
900 900 def format_display_data(obj, include=None, exclude=None):
901 901 """Return a format data dict for an object.
902 902
903 903 By default all format types will be computed.
904 904
905 905 The following MIME types are currently implemented:
906 906
907 907 * text/plain
908 908 * text/html
909 909 * text/markdown
910 910 * text/latex
911 911 * application/json
912 912 * application/javascript
913 913 * application/pdf
914 914 * image/png
915 915 * image/jpeg
916 916 * image/svg+xml
917 917
918 918 Parameters
919 919 ----------
920 920 obj : object
921 921 The Python object whose format data will be computed.
922 922
923 923 Returns
924 924 -------
925 925 format_dict : dict
926 926 A dictionary of key/value pairs, one or each format that was
927 927 generated for the object. The keys are the format types, which
928 928 will usually be MIME type strings and the values and JSON'able
929 929 data structure containing the raw data for the representation in
930 930 that format.
931 931 include : list or tuple, optional
932 932 A list of format type strings (MIME types) to include in the
933 933 format data dict. If this is set *only* the format types included
934 934 in this list will be computed.
935 935 exclude : list or tuple, optional
936 936 A list of format type string (MIME types) to exclue in the format
937 937 data dict. If this is set all format types will be computed,
938 938 except for those included in this argument.
939 939 """
940 940 from IPython.core.interactiveshell import InteractiveShell
941 941
942 942 return InteractiveShell.instance().display_formatter.format(
943 943 obj,
944 944 include,
945 945 exclude
946 946 )
947 947
@@ -1,910 +1,910 b''
1 1 """ History related magics and functionality """
2 2
3 3 # Copyright (c) IPython Development Team.
4 4 # Distributed under the terms of the Modified BSD License.
5 5
6 6
7 7 import atexit
8 8 import datetime
9 9 import os
10 10 import re
11 11 try:
12 12 import sqlite3
13 13 except ImportError:
14 14 try:
15 15 from pysqlite2 import dbapi2 as sqlite3
16 16 except ImportError:
17 17 sqlite3 = None
18 18 import threading
19 19
20 20 from traitlets.config.configurable import LoggingConfigurable
21 21 from decorator import decorator
22 22 from IPython.utils.decorators import undoc
23 23 from IPython.utils.path import locate_profile
24 24 from IPython.utils import py3compat
25 25 from traitlets import (
26 26 Any, Bool, Dict, Instance, Integer, List, Unicode, TraitError,
27 27 default, observe,
28 28 )
29 29 from warnings import warn
30 30
31 31 #-----------------------------------------------------------------------------
32 32 # Classes and functions
33 33 #-----------------------------------------------------------------------------
34 34
35 35 @undoc
36 36 class DummyDB(object):
37 37 """Dummy DB that will act as a black hole for history.
38 38
39 39 Only used in the absence of sqlite"""
40 40 def execute(*args, **kwargs):
41 41 return []
42 42
43 43 def commit(self, *args, **kwargs):
44 44 pass
45 45
46 46 def __enter__(self, *args, **kwargs):
47 47 pass
48 48
49 49 def __exit__(self, *args, **kwargs):
50 50 pass
51 51
52 52
53 53 @decorator
54 54 def needs_sqlite(f, self, *a, **kw):
55 55 """Decorator: return an empty list in the absence of sqlite."""
56 56 if sqlite3 is None or not self.enabled:
57 57 return []
58 58 else:
59 59 return f(self, *a, **kw)
60 60
61 61
62 62 if sqlite3 is not None:
63 63 DatabaseError = sqlite3.DatabaseError
64 64 OperationalError = sqlite3.OperationalError
65 65 else:
66 66 @undoc
67 67 class DatabaseError(Exception):
68 68 "Dummy exception when sqlite could not be imported. Should never occur."
69 69
70 70 @undoc
71 71 class OperationalError(Exception):
72 72 "Dummy exception when sqlite could not be imported. Should never occur."
73 73
74 74 # use 16kB as threshold for whether a corrupt history db should be saved
75 75 # that should be at least 100 entries or so
76 76 _SAVE_DB_SIZE = 16384
77 77
78 78 @decorator
79 79 def catch_corrupt_db(f, self, *a, **kw):
80 80 """A decorator which wraps HistoryAccessor method calls to catch errors from
81 81 a corrupt SQLite database, move the old database out of the way, and create
82 82 a new one.
83 83
84 84 We avoid clobbering larger databases because this may be triggered due to filesystem issues,
85 85 not just a corrupt file.
86 86 """
87 87 try:
88 88 return f(self, *a, **kw)
89 89 except (DatabaseError, OperationalError) as e:
90 90 self._corrupt_db_counter += 1
91 91 self.log.error("Failed to open SQLite history %s (%s).", self.hist_file, e)
92 92 if self.hist_file != ':memory:':
93 93 if self._corrupt_db_counter > self._corrupt_db_limit:
94 94 self.hist_file = ':memory:'
95 95 self.log.error("Failed to load history too many times, history will not be saved.")
96 96 elif os.path.isfile(self.hist_file):
97 97 # move the file out of the way
98 98 base, ext = os.path.splitext(self.hist_file)
99 99 size = os.stat(self.hist_file).st_size
100 100 if size >= _SAVE_DB_SIZE:
101 101 # if there's significant content, avoid clobbering
102 102 now = datetime.datetime.now().isoformat().replace(':', '.')
103 103 newpath = base + '-corrupt-' + now + ext
104 104 # don't clobber previous corrupt backups
105 105 for i in range(100):
106 106 if not os.path.isfile(newpath):
107 107 break
108 108 else:
109 109 newpath = base + '-corrupt-' + now + (u'-%i' % i) + ext
110 110 else:
111 111 # not much content, possibly empty; don't worry about clobbering
112 112 # maybe we should just delete it?
113 113 newpath = base + '-corrupt' + ext
114 114 os.rename(self.hist_file, newpath)
115 115 self.log.error("History file was moved to %s and a new file created.", newpath)
116 116 self.init_db()
117 117 return []
118 118 else:
119 119 # Failed with :memory:, something serious is wrong
120 120 raise
121 121
122 122 class HistoryAccessorBase(LoggingConfigurable):
123 123 """An abstract class for History Accessors """
124 124
125 125 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
126 126 raise NotImplementedError
127 127
128 128 def search(self, pattern="*", raw=True, search_raw=True,
129 129 output=False, n=None, unique=False):
130 130 raise NotImplementedError
131 131
132 132 def get_range(self, session, start=1, stop=None, raw=True,output=False):
133 133 raise NotImplementedError
134 134
135 135 def get_range_by_str(self, rangestr, raw=True, output=False):
136 136 raise NotImplementedError
137 137
138 138
139 139 class HistoryAccessor(HistoryAccessorBase):
140 140 """Access the history database without adding to it.
141 141
142 142 This is intended for use by standalone history tools. IPython shells use
143 143 HistoryManager, below, which is a subclass of this."""
144 144
145 145 # counter for init_db retries, so we don't keep trying over and over
146 146 _corrupt_db_counter = 0
147 147 # after two failures, fallback on :memory:
148 148 _corrupt_db_limit = 2
149 149
150 150 # String holding the path to the history file
151 151 hist_file = Unicode(
152 152 help="""Path to file to use for SQLite history database.
153 153
154 154 By default, IPython will put the history database in the IPython
155 155 profile directory. If you would rather share one history among
156 156 profiles, you can set this value in each, so that they are consistent.
157 157
158 158 Due to an issue with fcntl, SQLite is known to misbehave on some NFS
159 159 mounts. If you see IPython hanging, try setting this to something on a
160 160 local disk, e.g::
161 161
162 162 ipython --HistoryManager.hist_file=/tmp/ipython_hist.sqlite
163 163
164 164 you can also use the specific value `:memory:` (including the colon
165 165 at both end but not the back ticks), to avoid creating an history file.
166 166
167 167 """).tag(config=True)
168 168
169 169 enabled = Bool(True,
170 170 help="""enable the SQLite history
171 171
172 172 set enabled=False to disable the SQLite history,
173 173 in which case there will be no stored history, no SQLite connection,
174 174 and no background saving thread. This may be necessary in some
175 175 threaded environments where IPython is embedded.
176 176 """
177 177 ).tag(config=True)
178 178
179 179 connection_options = Dict(
180 180 help="""Options for configuring the SQLite connection
181 181
182 182 These options are passed as keyword args to sqlite3.connect
183 183 when establishing database conenctions.
184 184 """
185 185 ).tag(config=True)
186 186
187 187 # The SQLite database
188 188 db = Any()
189 189 @observe('db')
190 190 def _db_changed(self, change):
191 191 """validate the db, since it can be an Instance of two different types"""
192 192 new = change['new']
193 193 connection_types = (DummyDB,)
194 194 if sqlite3 is not None:
195 195 connection_types = (DummyDB, sqlite3.Connection)
196 196 if not isinstance(new, connection_types):
197 197 msg = "%s.db must be sqlite3 Connection or DummyDB, not %r" % \
198 198 (self.__class__.__name__, new)
199 199 raise TraitError(msg)
200 200
201 201 def __init__(self, profile='default', hist_file=u'', **traits):
202 202 """Create a new history accessor.
203 203
204 204 Parameters
205 205 ----------
206 206 profile : str
207 207 The name of the profile from which to open history.
208 208 hist_file : str
209 209 Path to an SQLite history database stored by IPython. If specified,
210 210 hist_file overrides profile.
211 211 config : :class:`~traitlets.config.loader.Config`
212 212 Config object. hist_file can also be set through this.
213 213 """
214 214 # We need a pointer back to the shell for various tasks.
215 215 super(HistoryAccessor, self).__init__(**traits)
216 216 # defer setting hist_file from kwarg until after init,
217 217 # otherwise the default kwarg value would clobber any value
218 218 # set by config
219 219 if hist_file:
220 220 self.hist_file = hist_file
221 221
222 222 if self.hist_file == u'':
223 223 # No one has set the hist_file, yet.
224 224 self.hist_file = self._get_hist_file_name(profile)
225 225
226 226 if sqlite3 is None and self.enabled:
227 227 warn("IPython History requires SQLite, your history will not be saved")
228 228 self.enabled = False
229 229
230 230 self.init_db()
231 231
232 232 def _get_hist_file_name(self, profile='default'):
233 233 """Find the history file for the given profile name.
234 234
235 235 This is overridden by the HistoryManager subclass, to use the shell's
236 236 active profile.
237 237
238 238 Parameters
239 239 ----------
240 240 profile : str
241 241 The name of a profile which has a history file.
242 242 """
243 243 return os.path.join(locate_profile(profile), 'history.sqlite')
244 244
245 245 @catch_corrupt_db
246 246 def init_db(self):
247 247 """Connect to the database, and create tables if necessary."""
248 248 if not self.enabled:
249 249 self.db = DummyDB()
250 250 return
251 251
252 252 # use detect_types so that timestamps return datetime objects
253 253 kwargs = dict(detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
254 254 kwargs.update(self.connection_options)
255 255 self.db = sqlite3.connect(self.hist_file, **kwargs)
256 256 self.db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
257 257 primary key autoincrement, start timestamp,
258 258 end timestamp, num_cmds integer, remark text)""")
259 259 self.db.execute("""CREATE TABLE IF NOT EXISTS history
260 260 (session integer, line integer, source text, source_raw text,
261 261 PRIMARY KEY (session, line))""")
262 262 # Output history is optional, but ensure the table's there so it can be
263 263 # enabled later.
264 264 self.db.execute("""CREATE TABLE IF NOT EXISTS output_history
265 265 (session integer, line integer, output text,
266 266 PRIMARY KEY (session, line))""")
267 267 self.db.commit()
268 268 # success! reset corrupt db count
269 269 self._corrupt_db_counter = 0
270 270
271 271 def writeout_cache(self):
272 272 """Overridden by HistoryManager to dump the cache before certain
273 273 database lookups."""
274 274 pass
275 275
276 276 ## -------------------------------
277 277 ## Methods for retrieving history:
278 278 ## -------------------------------
279 279 def _run_sql(self, sql, params, raw=True, output=False):
280 280 """Prepares and runs an SQL query for the history database.
281 281
282 282 Parameters
283 283 ----------
284 284 sql : str
285 285 Any filtering expressions to go after SELECT ... FROM ...
286 286 params : tuple
287 287 Parameters passed to the SQL query (to replace "?")
288 288 raw, output : bool
289 289 See :meth:`get_range`
290 290
291 291 Returns
292 292 -------
293 293 Tuples as :meth:`get_range`
294 294 """
295 295 toget = 'source_raw' if raw else 'source'
296 296 sqlfrom = "history"
297 297 if output:
298 298 sqlfrom = "history LEFT JOIN output_history USING (session, line)"
299 299 toget = "history.%s, output_history.output" % toget
300 300 cur = self.db.execute("SELECT session, line, %s FROM %s " %\
301 301 (toget, sqlfrom) + sql, params)
302 302 if output: # Regroup into 3-tuples, and parse JSON
303 303 return ((ses, lin, (inp, out)) for ses, lin, inp, out in cur)
304 304 return cur
305 305
306 306 @needs_sqlite
307 307 @catch_corrupt_db
308 308 def get_session_info(self, session):
309 309 """Get info about a session.
310 310
311 311 Parameters
312 312 ----------
313 313
314 314 session : int
315 315 Session number to retrieve.
316 316
317 317 Returns
318 318 -------
319 319
320 320 session_id : int
321 321 Session ID number
322 322 start : datetime
323 323 Timestamp for the start of the session.
324 324 end : datetime
325 325 Timestamp for the end of the session, or None if IPython crashed.
326 326 num_cmds : int
327 327 Number of commands run, or None if IPython crashed.
328 328 remark : unicode
329 329 A manually set description.
330 330 """
331 331 query = "SELECT * from sessions where session == ?"
332 332 return self.db.execute(query, (session,)).fetchone()
333 333
334 334 @catch_corrupt_db
335 335 def get_last_session_id(self):
336 336 """Get the last session ID currently in the database.
337 337
338 338 Within IPython, this should be the same as the value stored in
339 339 :attr:`HistoryManager.session_number`.
340 340 """
341 341 for record in self.get_tail(n=1, include_latest=True):
342 342 return record[0]
343 343
344 344 @catch_corrupt_db
345 345 def get_tail(self, n=10, raw=True, output=False, include_latest=False):
346 346 """Get the last n lines from the history database.
347 347
348 348 Parameters
349 349 ----------
350 350 n : int
351 351 The number of lines to get
352 352 raw, output : bool
353 353 See :meth:`get_range`
354 354 include_latest : bool
355 355 If False (default), n+1 lines are fetched, and the latest one
356 356 is discarded. This is intended to be used where the function
357 357 is called by a user command, which it should not return.
358 358
359 359 Returns
360 360 -------
361 361 Tuples as :meth:`get_range`
362 362 """
363 363 self.writeout_cache()
364 364 if not include_latest:
365 365 n += 1
366 366 cur = self._run_sql("ORDER BY session DESC, line DESC LIMIT ?",
367 367 (n,), raw=raw, output=output)
368 368 if not include_latest:
369 369 return reversed(list(cur)[1:])
370 370 return reversed(list(cur))
371 371
372 372 @catch_corrupt_db
373 373 def search(self, pattern="*", raw=True, search_raw=True,
374 374 output=False, n=None, unique=False):
375 375 """Search the database using unix glob-style matching (wildcards
376 376 * and ?).
377 377
378 378 Parameters
379 379 ----------
380 380 pattern : str
381 381 The wildcarded pattern to match when searching
382 382 search_raw : bool
383 383 If True, search the raw input, otherwise, the parsed input
384 384 raw, output : bool
385 385 See :meth:`get_range`
386 386 n : None or int
387 387 If an integer is given, it defines the limit of
388 388 returned entries.
389 389 unique : bool
390 390 When it is true, return only unique entries.
391 391
392 392 Returns
393 393 -------
394 394 Tuples as :meth:`get_range`
395 395 """
396 396 tosearch = "source_raw" if search_raw else "source"
397 397 if output:
398 398 tosearch = "history." + tosearch
399 399 self.writeout_cache()
400 400 sqlform = "WHERE %s GLOB ?" % tosearch
401 401 params = (pattern,)
402 402 if unique:
403 403 sqlform += ' GROUP BY {0}'.format(tosearch)
404 404 if n is not None:
405 405 sqlform += " ORDER BY session DESC, line DESC LIMIT ?"
406 406 params += (n,)
407 407 elif unique:
408 408 sqlform += " ORDER BY session, line"
409 409 cur = self._run_sql(sqlform, params, raw=raw, output=output)
410 410 if n is not None:
411 411 return reversed(list(cur))
412 412 return cur
413 413
414 414 @catch_corrupt_db
415 415 def get_range(self, session, start=1, stop=None, raw=True,output=False):
416 416 """Retrieve input by session.
417 417
418 418 Parameters
419 419 ----------
420 420 session : int
421 421 Session number to retrieve.
422 422 start : int
423 423 First line to retrieve.
424 424 stop : int
425 425 End of line range (excluded from output itself). If None, retrieve
426 426 to the end of the session.
427 427 raw : bool
428 428 If True, return untranslated input
429 429 output : bool
430 430 If True, attempt to include output. This will be 'real' Python
431 431 objects for the current session, or text reprs from previous
432 432 sessions if db_log_output was enabled at the time. Where no output
433 433 is found, None is used.
434 434
435 435 Returns
436 436 -------
437 437 entries
438 438 An iterator over the desired lines. Each line is a 3-tuple, either
439 439 (session, line, input) if output is False, or
440 440 (session, line, (input, output)) if output is True.
441 441 """
442 442 if stop:
443 443 lineclause = "line >= ? AND line < ?"
444 444 params = (session, start, stop)
445 445 else:
446 446 lineclause = "line>=?"
447 447 params = (session, start)
448 448
449 449 return self._run_sql("WHERE session==? AND %s" % lineclause,
450 450 params, raw=raw, output=output)
451 451
452 452 def get_range_by_str(self, rangestr, raw=True, output=False):
453 453 """Get lines of history from a string of ranges, as used by magic
454 454 commands %hist, %save, %macro, etc.
455 455
456 456 Parameters
457 457 ----------
458 458 rangestr : str
459 459 A string specifying ranges, e.g. "5 ~2/1-4". See
460 460 :func:`magic_history` for full details.
461 461 raw, output : bool
462 462 As :meth:`get_range`
463 463
464 464 Returns
465 465 -------
466 466 Tuples as :meth:`get_range`
467 467 """
468 468 for sess, s, e in extract_hist_ranges(rangestr):
469 469 for line in self.get_range(sess, s, e, raw=raw, output=output):
470 470 yield line
471 471
472 472
473 473 class HistoryManager(HistoryAccessor):
474 474 """A class to organize all history-related functionality in one place.
475 475 """
476 476 # Public interface
477 477
478 478 # An instance of the IPython shell we are attached to
479 479 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
480 480 allow_none=True)
481 481 # Lists to hold processed and raw history. These start with a blank entry
482 482 # so that we can index them starting from 1
483 483 input_hist_parsed = List([""])
484 484 input_hist_raw = List([""])
485 485 # A list of directories visited during session
486 486 dir_hist = List()
487 487 @default('dir_hist')
488 488 def _dir_hist_default(self):
489 489 try:
490 return [py3compat.getcwd()]
490 return [os.getcwd()]
491 491 except OSError:
492 492 return []
493 493
494 494 # A dict of output history, keyed with ints from the shell's
495 495 # execution count.
496 496 output_hist = Dict()
497 497 # The text/plain repr of outputs.
498 498 output_hist_reprs = Dict()
499 499
500 500 # The number of the current session in the history database
501 501 session_number = Integer()
502 502
503 503 db_log_output = Bool(False,
504 504 help="Should the history database include output? (default: no)"
505 505 ).tag(config=True)
506 506 db_cache_size = Integer(0,
507 507 help="Write to database every x commands (higher values save disk access & power).\n"
508 508 "Values of 1 or less effectively disable caching."
509 509 ).tag(config=True)
510 510 # The input and output caches
511 511 db_input_cache = List()
512 512 db_output_cache = List()
513 513
514 514 # History saving in separate thread
515 515 save_thread = Instance('IPython.core.history.HistorySavingThread',
516 516 allow_none=True)
517 517 try: # Event is a function returning an instance of _Event...
518 518 save_flag = Instance(threading._Event, allow_none=True)
519 519 except AttributeError: # ...until Python 3.3, when it's a class.
520 520 save_flag = Instance(threading.Event, allow_none=True)
521 521
522 522 # Private interface
523 523 # Variables used to store the three last inputs from the user. On each new
524 524 # history update, we populate the user's namespace with these, shifted as
525 525 # necessary.
526 526 _i00 = Unicode(u'')
527 527 _i = Unicode(u'')
528 528 _ii = Unicode(u'')
529 529 _iii = Unicode(u'')
530 530
531 531 # A regex matching all forms of the exit command, so that we don't store
532 532 # them in the history (it's annoying to rewind the first entry and land on
533 533 # an exit call).
534 534 _exit_re = re.compile(r"(exit|quit)(\s*\(.*\))?$")
535 535
536 536 def __init__(self, shell=None, config=None, **traits):
537 537 """Create a new history manager associated with a shell instance.
538 538 """
539 539 # We need a pointer back to the shell for various tasks.
540 540 super(HistoryManager, self).__init__(shell=shell, config=config,
541 541 **traits)
542 542 self.save_flag = threading.Event()
543 543 self.db_input_cache_lock = threading.Lock()
544 544 self.db_output_cache_lock = threading.Lock()
545 545
546 546 try:
547 547 self.new_session()
548 548 except OperationalError:
549 549 self.log.error("Failed to create history session in %s. History will not be saved.",
550 550 self.hist_file, exc_info=True)
551 551 self.hist_file = ':memory:'
552 552
553 553 if self.enabled and self.hist_file != ':memory:':
554 554 self.save_thread = HistorySavingThread(self)
555 555 self.save_thread.start()
556 556
557 557 def _get_hist_file_name(self, profile=None):
558 558 """Get default history file name based on the Shell's profile.
559 559
560 560 The profile parameter is ignored, but must exist for compatibility with
561 561 the parent class."""
562 562 profile_dir = self.shell.profile_dir.location
563 563 return os.path.join(profile_dir, 'history.sqlite')
564 564
565 565 @needs_sqlite
566 566 def new_session(self, conn=None):
567 567 """Get a new session number."""
568 568 if conn is None:
569 569 conn = self.db
570 570
571 571 with conn:
572 572 cur = conn.execute("""INSERT INTO sessions VALUES (NULL, ?, NULL,
573 573 NULL, "") """, (datetime.datetime.now(),))
574 574 self.session_number = cur.lastrowid
575 575
576 576 def end_session(self):
577 577 """Close the database session, filling in the end time and line count."""
578 578 self.writeout_cache()
579 579 with self.db:
580 580 self.db.execute("""UPDATE sessions SET end=?, num_cmds=? WHERE
581 581 session==?""", (datetime.datetime.now(),
582 582 len(self.input_hist_parsed)-1, self.session_number))
583 583 self.session_number = 0
584 584
585 585 def name_session(self, name):
586 586 """Give the current session a name in the history database."""
587 587 with self.db:
588 588 self.db.execute("UPDATE sessions SET remark=? WHERE session==?",
589 589 (name, self.session_number))
590 590
591 591 def reset(self, new_session=True):
592 592 """Clear the session history, releasing all object references, and
593 593 optionally open a new session."""
594 594 self.output_hist.clear()
595 595 # The directory history can't be completely empty
596 self.dir_hist[:] = [py3compat.getcwd()]
596 self.dir_hist[:] = [os.getcwd()]
597 597
598 598 if new_session:
599 599 if self.session_number:
600 600 self.end_session()
601 601 self.input_hist_parsed[:] = [""]
602 602 self.input_hist_raw[:] = [""]
603 603 self.new_session()
604 604
605 605 # ------------------------------
606 606 # Methods for retrieving history
607 607 # ------------------------------
608 608 def get_session_info(self, session=0):
609 609 """Get info about a session.
610 610
611 611 Parameters
612 612 ----------
613 613
614 614 session : int
615 615 Session number to retrieve. The current session is 0, and negative
616 616 numbers count back from current session, so -1 is the previous session.
617 617
618 618 Returns
619 619 -------
620 620
621 621 session_id : int
622 622 Session ID number
623 623 start : datetime
624 624 Timestamp for the start of the session.
625 625 end : datetime
626 626 Timestamp for the end of the session, or None if IPython crashed.
627 627 num_cmds : int
628 628 Number of commands run, or None if IPython crashed.
629 629 remark : unicode
630 630 A manually set description.
631 631 """
632 632 if session <= 0:
633 633 session += self.session_number
634 634
635 635 return super(HistoryManager, self).get_session_info(session=session)
636 636
637 637 def _get_range_session(self, start=1, stop=None, raw=True, output=False):
638 638 """Get input and output history from the current session. Called by
639 639 get_range, and takes similar parameters."""
640 640 input_hist = self.input_hist_raw if raw else self.input_hist_parsed
641 641
642 642 n = len(input_hist)
643 643 if start < 0:
644 644 start += n
645 645 if not stop or (stop > n):
646 646 stop = n
647 647 elif stop < 0:
648 648 stop += n
649 649
650 650 for i in range(start, stop):
651 651 if output:
652 652 line = (input_hist[i], self.output_hist_reprs.get(i))
653 653 else:
654 654 line = input_hist[i]
655 655 yield (0, i, line)
656 656
657 657 def get_range(self, session=0, start=1, stop=None, raw=True,output=False):
658 658 """Retrieve input by session.
659 659
660 660 Parameters
661 661 ----------
662 662 session : int
663 663 Session number to retrieve. The current session is 0, and negative
664 664 numbers count back from current session, so -1 is previous session.
665 665 start : int
666 666 First line to retrieve.
667 667 stop : int
668 668 End of line range (excluded from output itself). If None, retrieve
669 669 to the end of the session.
670 670 raw : bool
671 671 If True, return untranslated input
672 672 output : bool
673 673 If True, attempt to include output. This will be 'real' Python
674 674 objects for the current session, or text reprs from previous
675 675 sessions if db_log_output was enabled at the time. Where no output
676 676 is found, None is used.
677 677
678 678 Returns
679 679 -------
680 680 entries
681 681 An iterator over the desired lines. Each line is a 3-tuple, either
682 682 (session, line, input) if output is False, or
683 683 (session, line, (input, output)) if output is True.
684 684 """
685 685 if session <= 0:
686 686 session += self.session_number
687 687 if session==self.session_number: # Current session
688 688 return self._get_range_session(start, stop, raw, output)
689 689 return super(HistoryManager, self).get_range(session, start, stop, raw,
690 690 output)
691 691
692 692 ## ----------------------------
693 693 ## Methods for storing history:
694 694 ## ----------------------------
695 695 def store_inputs(self, line_num, source, source_raw=None):
696 696 """Store source and raw input in history and create input cache
697 697 variables ``_i*``.
698 698
699 699 Parameters
700 700 ----------
701 701 line_num : int
702 702 The prompt number of this input.
703 703
704 704 source : str
705 705 Python input.
706 706
707 707 source_raw : str, optional
708 708 If given, this is the raw input without any IPython transformations
709 709 applied to it. If not given, ``source`` is used.
710 710 """
711 711 if source_raw is None:
712 712 source_raw = source
713 713 source = source.rstrip('\n')
714 714 source_raw = source_raw.rstrip('\n')
715 715
716 716 # do not store exit/quit commands
717 717 if self._exit_re.match(source_raw.strip()):
718 718 return
719 719
720 720 self.input_hist_parsed.append(source)
721 721 self.input_hist_raw.append(source_raw)
722 722
723 723 with self.db_input_cache_lock:
724 724 self.db_input_cache.append((line_num, source, source_raw))
725 725 # Trigger to flush cache and write to DB.
726 726 if len(self.db_input_cache) >= self.db_cache_size:
727 727 self.save_flag.set()
728 728
729 729 # update the auto _i variables
730 730 self._iii = self._ii
731 731 self._ii = self._i
732 732 self._i = self._i00
733 733 self._i00 = source_raw
734 734
735 735 # hackish access to user namespace to create _i1,_i2... dynamically
736 736 new_i = '_i%s' % line_num
737 737 to_main = {'_i': self._i,
738 738 '_ii': self._ii,
739 739 '_iii': self._iii,
740 740 new_i : self._i00 }
741 741
742 742 if self.shell is not None:
743 743 self.shell.push(to_main, interactive=False)
744 744
745 745 def store_output(self, line_num):
746 746 """If database output logging is enabled, this saves all the
747 747 outputs from the indicated prompt number to the database. It's
748 748 called by run_cell after code has been executed.
749 749
750 750 Parameters
751 751 ----------
752 752 line_num : int
753 753 The line number from which to save outputs
754 754 """
755 755 if (not self.db_log_output) or (line_num not in self.output_hist_reprs):
756 756 return
757 757 output = self.output_hist_reprs[line_num]
758 758
759 759 with self.db_output_cache_lock:
760 760 self.db_output_cache.append((line_num, output))
761 761 if self.db_cache_size <= 1:
762 762 self.save_flag.set()
763 763
764 764 def _writeout_input_cache(self, conn):
765 765 with conn:
766 766 for line in self.db_input_cache:
767 767 conn.execute("INSERT INTO history VALUES (?, ?, ?, ?)",
768 768 (self.session_number,)+line)
769 769
770 770 def _writeout_output_cache(self, conn):
771 771 with conn:
772 772 for line in self.db_output_cache:
773 773 conn.execute("INSERT INTO output_history VALUES (?, ?, ?)",
774 774 (self.session_number,)+line)
775 775
776 776 @needs_sqlite
777 777 def writeout_cache(self, conn=None):
778 778 """Write any entries in the cache to the database."""
779 779 if conn is None:
780 780 conn = self.db
781 781
782 782 with self.db_input_cache_lock:
783 783 try:
784 784 self._writeout_input_cache(conn)
785 785 except sqlite3.IntegrityError:
786 786 self.new_session(conn)
787 787 print("ERROR! Session/line number was not unique in",
788 788 "database. History logging moved to new session",
789 789 self.session_number)
790 790 try:
791 791 # Try writing to the new session. If this fails, don't
792 792 # recurse
793 793 self._writeout_input_cache(conn)
794 794 except sqlite3.IntegrityError:
795 795 pass
796 796 finally:
797 797 self.db_input_cache = []
798 798
799 799 with self.db_output_cache_lock:
800 800 try:
801 801 self._writeout_output_cache(conn)
802 802 except sqlite3.IntegrityError:
803 803 print("!! Session/line number for output was not unique",
804 804 "in database. Output will not be stored.")
805 805 finally:
806 806 self.db_output_cache = []
807 807
808 808
809 809 class HistorySavingThread(threading.Thread):
810 810 """This thread takes care of writing history to the database, so that
811 811 the UI isn't held up while that happens.
812 812
813 813 It waits for the HistoryManager's save_flag to be set, then writes out
814 814 the history cache. The main thread is responsible for setting the flag when
815 815 the cache size reaches a defined threshold."""
816 816 daemon = True
817 817 stop_now = False
818 818 enabled = True
819 819 def __init__(self, history_manager):
820 820 super(HistorySavingThread, self).__init__(name="IPythonHistorySavingThread")
821 821 self.history_manager = history_manager
822 822 self.enabled = history_manager.enabled
823 823 atexit.register(self.stop)
824 824
825 825 @needs_sqlite
826 826 def run(self):
827 827 # We need a separate db connection per thread:
828 828 try:
829 829 self.db = sqlite3.connect(self.history_manager.hist_file,
830 830 **self.history_manager.connection_options
831 831 )
832 832 while True:
833 833 self.history_manager.save_flag.wait()
834 834 if self.stop_now:
835 835 self.db.close()
836 836 return
837 837 self.history_manager.save_flag.clear()
838 838 self.history_manager.writeout_cache(self.db)
839 839 except Exception as e:
840 840 print(("The history saving thread hit an unexpected error (%s)."
841 841 "History will not be written to the database.") % repr(e))
842 842
843 843 def stop(self):
844 844 """This can be called from the main thread to safely stop this thread.
845 845
846 846 Note that it does not attempt to write out remaining history before
847 847 exiting. That should be done by calling the HistoryManager's
848 848 end_session method."""
849 849 self.stop_now = True
850 850 self.history_manager.save_flag.set()
851 851 self.join()
852 852
853 853
854 854 # To match, e.g. ~5/8-~2/3
855 855 range_re = re.compile(r"""
856 856 ((?P<startsess>~?\d+)/)?
857 857 (?P<start>\d+)?
858 858 ((?P<sep>[\-:])
859 859 ((?P<endsess>~?\d+)/)?
860 860 (?P<end>\d+))?
861 861 $""", re.VERBOSE)
862 862
863 863
864 864 def extract_hist_ranges(ranges_str):
865 865 """Turn a string of history ranges into 3-tuples of (session, start, stop).
866 866
867 867 Examples
868 868 --------
869 869 >>> list(extract_hist_ranges("~8/5-~7/4 2"))
870 870 [(-8, 5, None), (-7, 1, 5), (0, 2, 3)]
871 871 """
872 872 for range_str in ranges_str.split():
873 873 rmatch = range_re.match(range_str)
874 874 if not rmatch:
875 875 continue
876 876 start = rmatch.group("start")
877 877 if start:
878 878 start = int(start)
879 879 end = rmatch.group("end")
880 880 # If no end specified, get (a, a + 1)
881 881 end = int(end) if end else start + 1
882 882 else: # start not specified
883 883 if not rmatch.group('startsess'): # no startsess
884 884 continue
885 885 start = 1
886 886 end = None # provide the entire session hist
887 887
888 888 if rmatch.group("sep") == "-": # 1-3 == 1:4 --> [1, 2, 3]
889 889 end += 1
890 890 startsess = rmatch.group("startsess") or "0"
891 891 endsess = rmatch.group("endsess") or startsess
892 892 startsess = int(startsess.replace("~","-"))
893 893 endsess = int(endsess.replace("~","-"))
894 894 assert endsess >= startsess, "start session must be earlier than end session"
895 895
896 896 if endsess == startsess:
897 897 yield (startsess, start, end)
898 898 continue
899 899 # Multiple sessions in one range:
900 900 yield (startsess, start, None)
901 901 for sess in range(startsess+1, endsess):
902 902 yield (sess, 1, None)
903 903 yield (endsess, 1, end)
904 904
905 905
906 906 def _format_lineno(session, line):
907 907 """Helper function to format line numbers properly."""
908 908 if session == 0:
909 909 return str(line)
910 910 return "%s#%s" % (session, line)
@@ -1,3226 +1,3223 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Main IPython class."""
3 3
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 7 # Copyright (C) 2008-2011 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13
14 14 import __future__
15 15 import abc
16 16 import ast
17 17 import atexit
18 18 import functools
19 19 import os
20 20 import re
21 21 import runpy
22 22 import sys
23 23 import tempfile
24 24 import traceback
25 25 import types
26 26 import subprocess
27 27 import warnings
28 28 from io import open as io_open
29 29
30 30 from pickleshare import PickleShareDB
31 31
32 32 from traitlets.config.configurable import SingletonConfigurable
33 33 from IPython.core import oinspect
34 34 from IPython.core import magic
35 35 from IPython.core import page
36 36 from IPython.core import prefilter
37 37 from IPython.core import shadowns
38 38 from IPython.core import ultratb
39 39 from IPython.core.alias import Alias, AliasManager
40 40 from IPython.core.autocall import ExitAutocall
41 41 from IPython.core.builtin_trap import BuiltinTrap
42 42 from IPython.core.events import EventManager, available_events
43 43 from IPython.core.compilerop import CachingCompiler, check_linecache_ipython
44 44 from IPython.core.debugger import Pdb
45 45 from IPython.core.display_trap import DisplayTrap
46 46 from IPython.core.displayhook import DisplayHook
47 47 from IPython.core.displaypub import DisplayPublisher
48 48 from IPython.core.error import InputRejected, UsageError
49 49 from IPython.core.extensions import ExtensionManager
50 50 from IPython.core.formatters import DisplayFormatter
51 51 from IPython.core.history import HistoryManager
52 52 from IPython.core.inputsplitter import ESC_MAGIC, ESC_MAGIC2
53 53 from IPython.core.logger import Logger
54 54 from IPython.core.macro import Macro
55 55 from IPython.core.payload import PayloadManager
56 56 from IPython.core.prefilter import PrefilterManager
57 57 from IPython.core.profiledir import ProfileDir
58 58 from IPython.core.usage import default_banner
59 59 from IPython.testing.skipdoctest import skip_doctest
60 60 from IPython.utils import PyColorize
61 61 from IPython.utils import io
62 62 from IPython.utils import py3compat
63 63 from IPython.utils import openpy
64 64 from IPython.utils.decorators import undoc
65 65 from IPython.utils.io import ask_yes_no
66 66 from IPython.utils.ipstruct import Struct
67 67 from IPython.paths import get_ipython_dir
68 68 from IPython.utils.path import get_home_dir, get_py_filename, ensure_dir_exists
69 69 from IPython.utils.process import system, getoutput
70 from IPython.utils.py3compat import (builtin_mod, unicode_type, string_types,
71 with_metaclass, iteritems)
70 from IPython.utils.py3compat import builtin_mod, with_metaclass
72 71 from IPython.utils.strdispatch import StrDispatch
73 72 from IPython.utils.syspathcontext import prepended_to_syspath
74 73 from IPython.utils.text import format_screen, LSString, SList, DollarFormatter
75 74 from IPython.utils.tempdir import TemporaryDirectory
76 75 from traitlets import (
77 76 Integer, Bool, CaselessStrEnum, Enum, List, Dict, Unicode, Instance, Type,
78 77 observe, default,
79 78 )
80 79 from warnings import warn
81 80 from logging import error
82 81 import IPython.core.hooks
83 82
84 83 # NoOpContext is deprecated, but ipykernel imports it from here.
85 84 # See https://github.com/ipython/ipykernel/issues/157
86 85 from IPython.utils.contexts import NoOpContext
87 86
88 87 try:
89 88 import docrepr.sphinxify as sphx
90 89
91 90 def sphinxify(doc):
92 91 with TemporaryDirectory() as dirname:
93 92 return {
94 93 'text/html': sphx.sphinxify(doc, dirname),
95 94 'text/plain': doc
96 95 }
97 96 except ImportError:
98 97 sphinxify = None
99 98
100 99
101 100 class ProvisionalWarning(DeprecationWarning):
102 101 """
103 102 Warning class for unstable features
104 103 """
105 104 pass
106 105
107 106 #-----------------------------------------------------------------------------
108 107 # Globals
109 108 #-----------------------------------------------------------------------------
110 109
111 110 # compiled regexps for autoindent management
112 111 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
113 112
114 113 #-----------------------------------------------------------------------------
115 114 # Utilities
116 115 #-----------------------------------------------------------------------------
117 116
118 117 @undoc
119 118 def softspace(file, newvalue):
120 119 """Copied from code.py, to remove the dependency"""
121 120
122 121 oldvalue = 0
123 122 try:
124 123 oldvalue = file.softspace
125 124 except AttributeError:
126 125 pass
127 126 try:
128 127 file.softspace = newvalue
129 128 except (AttributeError, TypeError):
130 129 # "attribute-less object" or "read-only attributes"
131 130 pass
132 131 return oldvalue
133 132
134 133 @undoc
135 134 def no_op(*a, **kw): pass
136 135
137 136
138 137 class SpaceInInput(Exception): pass
139 138
140 139
141 140 def get_default_colors():
142 141 "DEPRECATED"
143 142 warn('get_default_color is Deprecated, and is `Neutral` on all platforms.',
144 143 DeprecationWarning, stacklevel=2)
145 144 return 'Neutral'
146 145
147 146
148 147 class SeparateUnicode(Unicode):
149 148 r"""A Unicode subclass to validate separate_in, separate_out, etc.
150 149
151 150 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
152 151 """
153 152
154 153 def validate(self, obj, value):
155 154 if value == '0': value = ''
156 155 value = value.replace('\\n','\n')
157 156 return super(SeparateUnicode, self).validate(obj, value)
158 157
159 158
160 159 @undoc
161 160 class DummyMod(object):
162 161 """A dummy module used for IPython's interactive module when
163 162 a namespace must be assigned to the module's __dict__."""
164 163 pass
165 164
166 165
167 166 class ExecutionResult(object):
168 167 """The result of a call to :meth:`InteractiveShell.run_cell`
169 168
170 169 Stores information about what took place.
171 170 """
172 171 execution_count = None
173 172 error_before_exec = None
174 173 error_in_exec = None
175 174 result = None
176 175
177 176 @property
178 177 def success(self):
179 178 return (self.error_before_exec is None) and (self.error_in_exec is None)
180 179
181 180 def raise_error(self):
182 181 """Reraises error if `success` is `False`, otherwise does nothing"""
183 182 if self.error_before_exec is not None:
184 183 raise self.error_before_exec
185 184 if self.error_in_exec is not None:
186 185 raise self.error_in_exec
187 186
188 187 def __repr__(self):
189 188 name = self.__class__.__qualname__
190 189 return '<%s object at %x, execution_count=%s error_before_exec=%s error_in_exec=%s result=%s>' %\
191 190 (name, id(self), self.execution_count, self.error_before_exec, self.error_in_exec, repr(self.result))
192 191
193 192
194 193 class InteractiveShell(SingletonConfigurable):
195 194 """An enhanced, interactive shell for Python."""
196 195
197 196 _instance = None
198 197
199 198 ast_transformers = List([], help=
200 199 """
201 200 A list of ast.NodeTransformer subclass instances, which will be applied
202 201 to user input before code is run.
203 202 """
204 203 ).tag(config=True)
205 204
206 205 autocall = Enum((0,1,2), default_value=0, help=
207 206 """
208 207 Make IPython automatically call any callable object even if you didn't
209 208 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
210 209 automatically. The value can be '0' to disable the feature, '1' for
211 210 'smart' autocall, where it is not applied if there are no more
212 211 arguments on the line, and '2' for 'full' autocall, where all callable
213 212 objects are automatically called (even if no arguments are present).
214 213 """
215 214 ).tag(config=True)
216 215 # TODO: remove all autoindent logic and put into frontends.
217 216 # We can't do this yet because even runlines uses the autoindent.
218 217 autoindent = Bool(True, help=
219 218 """
220 219 Autoindent IPython code entered interactively.
221 220 """
222 221 ).tag(config=True)
223 222
224 223 automagic = Bool(True, help=
225 224 """
226 225 Enable magic commands to be called without the leading %.
227 226 """
228 227 ).tag(config=True)
229 228
230 229 banner1 = Unicode(default_banner,
231 230 help="""The part of the banner to be printed before the profile"""
232 231 ).tag(config=True)
233 232 banner2 = Unicode('',
234 233 help="""The part of the banner to be printed after the profile"""
235 234 ).tag(config=True)
236 235
237 236 cache_size = Integer(1000, help=
238 237 """
239 238 Set the size of the output cache. The default is 1000, you can
240 239 change it permanently in your config file. Setting it to 0 completely
241 240 disables the caching system, and the minimum value accepted is 20 (if
242 241 you provide a value less than 20, it is reset to 0 and a warning is
243 242 issued). This limit is defined because otherwise you'll spend more
244 243 time re-flushing a too small cache than working
245 244 """
246 245 ).tag(config=True)
247 246 color_info = Bool(True, help=
248 247 """
249 248 Use colors for displaying information about objects. Because this
250 249 information is passed through a pager (like 'less'), and some pagers
251 250 get confused with color codes, this capability can be turned off.
252 251 """
253 252 ).tag(config=True)
254 253 colors = CaselessStrEnum(('Neutral', 'NoColor','LightBG','Linux'),
255 254 default_value='Neutral',
256 255 help="Set the color scheme (NoColor, Neutral, Linux, or LightBG)."
257 256 ).tag(config=True)
258 257 debug = Bool(False).tag(config=True)
259 258 disable_failing_post_execute = Bool(False,
260 259 help="Don't call post-execute functions that have failed in the past."
261 260 ).tag(config=True)
262 261 display_formatter = Instance(DisplayFormatter, allow_none=True)
263 262 displayhook_class = Type(DisplayHook)
264 263 display_pub_class = Type(DisplayPublisher)
265 264
266 265 sphinxify_docstring = Bool(False, help=
267 266 """
268 267 Enables rich html representation of docstrings. (This requires the
269 268 docrepr module).
270 269 """).tag(config=True)
271 270
272 271 @observe("sphinxify_docstring")
273 272 def _sphinxify_docstring_changed(self, change):
274 273 if change['new']:
275 274 warn("`sphinxify_docstring` is provisional since IPython 5.0 and might change in future versions." , ProvisionalWarning)
276 275
277 276 enable_html_pager = Bool(False, help=
278 277 """
279 278 (Provisional API) enables html representation in mime bundles sent
280 279 to pagers.
281 280 """).tag(config=True)
282 281
283 282 @observe("enable_html_pager")
284 283 def _enable_html_pager_changed(self, change):
285 284 if change['new']:
286 285 warn("`enable_html_pager` is provisional since IPython 5.0 and might change in future versions.", ProvisionalWarning)
287 286
288 287 data_pub_class = None
289 288
290 289 exit_now = Bool(False)
291 290 exiter = Instance(ExitAutocall)
292 291 @default('exiter')
293 292 def _exiter_default(self):
294 293 return ExitAutocall(self)
295 294 # Monotonically increasing execution counter
296 295 execution_count = Integer(1)
297 296 filename = Unicode("<ipython console>")
298 297 ipython_dir= Unicode('').tag(config=True) # Set to get_ipython_dir() in __init__
299 298
300 299 # Input splitter, to transform input line by line and detect when a block
301 300 # is ready to be executed.
302 301 input_splitter = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
303 302 (), {'line_input_checker': True})
304 303
305 304 # This InputSplitter instance is used to transform completed cells before
306 305 # running them. It allows cell magics to contain blank lines.
307 306 input_transformer_manager = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
308 307 (), {'line_input_checker': False})
309 308
310 309 logstart = Bool(False, help=
311 310 """
312 311 Start logging to the default log file in overwrite mode.
313 312 Use `logappend` to specify a log file to **append** logs to.
314 313 """
315 314 ).tag(config=True)
316 315 logfile = Unicode('', help=
317 316 """
318 317 The name of the logfile to use.
319 318 """
320 319 ).tag(config=True)
321 320 logappend = Unicode('', help=
322 321 """
323 322 Start logging to the given file in append mode.
324 323 Use `logfile` to specify a log file to **overwrite** logs to.
325 324 """
326 325 ).tag(config=True)
327 326 object_info_string_level = Enum((0,1,2), default_value=0,
328 327 ).tag(config=True)
329 328 pdb = Bool(False, help=
330 329 """
331 330 Automatically call the pdb debugger after every exception.
332 331 """
333 332 ).tag(config=True)
334 333 display_page = Bool(False,
335 334 help="""If True, anything that would be passed to the pager
336 335 will be displayed as regular output instead."""
337 336 ).tag(config=True)
338 337
339 338 # deprecated prompt traits:
340 339
341 340 prompt_in1 = Unicode('In [\\#]: ',
342 341 help="Deprecated since IPython 4.0 and ignored since 5.0, set TerminalInteractiveShell.prompts object directly."
343 342 ).tag(config=True)
344 343 prompt_in2 = Unicode(' .\\D.: ',
345 344 help="Deprecated since IPython 4.0 and ignored since 5.0, set TerminalInteractiveShell.prompts object directly."
346 345 ).tag(config=True)
347 346 prompt_out = Unicode('Out[\\#]: ',
348 347 help="Deprecated since IPython 4.0 and ignored since 5.0, set TerminalInteractiveShell.prompts object directly."
349 348 ).tag(config=True)
350 349 prompts_pad_left = Bool(True,
351 350 help="Deprecated since IPython 4.0 and ignored since 5.0, set TerminalInteractiveShell.prompts object directly."
352 351 ).tag(config=True)
353 352
354 353 @observe('prompt_in1', 'prompt_in2', 'prompt_out', 'prompt_pad_left')
355 354 def _prompt_trait_changed(self, change):
356 355 name = change['name']
357 356 warn("InteractiveShell.{name} is deprecated since IPython 4.0"
358 357 " and ignored since 5.0, set TerminalInteractiveShell.prompts"
359 358 " object directly.".format(name=name))
360 359
361 360 # protect against weird cases where self.config may not exist:
362 361
363 362 show_rewritten_input = Bool(True,
364 363 help="Show rewritten input, e.g. for autocall."
365 364 ).tag(config=True)
366 365
367 366 quiet = Bool(False).tag(config=True)
368 367
369 368 history_length = Integer(10000,
370 369 help='Total length of command history'
371 370 ).tag(config=True)
372 371
373 372 history_load_length = Integer(1000, help=
374 373 """
375 374 The number of saved history entries to be loaded
376 375 into the history buffer at startup.
377 376 """
378 377 ).tag(config=True)
379 378
380 379 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none'],
381 380 default_value='last_expr',
382 381 help="""
383 382 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
384 383 run interactively (displaying output from expressions)."""
385 384 ).tag(config=True)
386 385
387 386 # TODO: this part of prompt management should be moved to the frontends.
388 387 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
389 388 separate_in = SeparateUnicode('\n').tag(config=True)
390 389 separate_out = SeparateUnicode('').tag(config=True)
391 390 separate_out2 = SeparateUnicode('').tag(config=True)
392 391 wildcards_case_sensitive = Bool(True).tag(config=True)
393 392 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
394 393 default_value='Context').tag(config=True)
395 394
396 395 # Subcomponents of InteractiveShell
397 396 alias_manager = Instance('IPython.core.alias.AliasManager', allow_none=True)
398 397 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
399 398 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap', allow_none=True)
400 399 display_trap = Instance('IPython.core.display_trap.DisplayTrap', allow_none=True)
401 400 extension_manager = Instance('IPython.core.extensions.ExtensionManager', allow_none=True)
402 401 payload_manager = Instance('IPython.core.payload.PayloadManager', allow_none=True)
403 402 history_manager = Instance('IPython.core.history.HistoryAccessorBase', allow_none=True)
404 403 magics_manager = Instance('IPython.core.magic.MagicsManager', allow_none=True)
405 404
406 405 profile_dir = Instance('IPython.core.application.ProfileDir', allow_none=True)
407 406 @property
408 407 def profile(self):
409 408 if self.profile_dir is not None:
410 409 name = os.path.basename(self.profile_dir.location)
411 410 return name.replace('profile_','')
412 411
413 412
414 413 # Private interface
415 414 _post_execute = Dict()
416 415
417 416 # Tracks any GUI loop loaded for pylab
418 417 pylab_gui_select = None
419 418
420 419 last_execution_succeeded = Bool(True, help='Did last executed command succeeded')
421 420
422 421 def __init__(self, ipython_dir=None, profile_dir=None,
423 422 user_module=None, user_ns=None,
424 423 custom_exceptions=((), None), **kwargs):
425 424
426 425 # This is where traits with a config_key argument are updated
427 426 # from the values on config.
428 427 super(InteractiveShell, self).__init__(**kwargs)
429 428 if 'PromptManager' in self.config:
430 429 warn('As of IPython 5.0 `PromptManager` config will have no effect'
431 430 ' and has been replaced by TerminalInteractiveShell.prompts_class')
432 431 self.configurables = [self]
433 432
434 433 # These are relatively independent and stateless
435 434 self.init_ipython_dir(ipython_dir)
436 435 self.init_profile_dir(profile_dir)
437 436 self.init_instance_attrs()
438 437 self.init_environment()
439 438
440 439 # Check if we're in a virtualenv, and set up sys.path.
441 440 self.init_virtualenv()
442 441
443 442 # Create namespaces (user_ns, user_global_ns, etc.)
444 443 self.init_create_namespaces(user_module, user_ns)
445 444 # This has to be done after init_create_namespaces because it uses
446 445 # something in self.user_ns, but before init_sys_modules, which
447 446 # is the first thing to modify sys.
448 447 # TODO: When we override sys.stdout and sys.stderr before this class
449 448 # is created, we are saving the overridden ones here. Not sure if this
450 449 # is what we want to do.
451 450 self.save_sys_module_state()
452 451 self.init_sys_modules()
453 452
454 453 # While we're trying to have each part of the code directly access what
455 454 # it needs without keeping redundant references to objects, we have too
456 455 # much legacy code that expects ip.db to exist.
457 456 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
458 457
459 458 self.init_history()
460 459 self.init_encoding()
461 460 self.init_prefilter()
462 461
463 462 self.init_syntax_highlighting()
464 463 self.init_hooks()
465 464 self.init_events()
466 465 self.init_pushd_popd_magic()
467 466 self.init_user_ns()
468 467 self.init_logger()
469 468 self.init_builtins()
470 469
471 470 # The following was in post_config_initialization
472 471 self.init_inspector()
473 472 self.raw_input_original = input
474 473 self.init_completer()
475 474 # TODO: init_io() needs to happen before init_traceback handlers
476 475 # because the traceback handlers hardcode the stdout/stderr streams.
477 476 # This logic in in debugger.Pdb and should eventually be changed.
478 477 self.init_io()
479 478 self.init_traceback_handlers(custom_exceptions)
480 479 self.init_prompts()
481 480 self.init_display_formatter()
482 481 self.init_display_pub()
483 482 self.init_data_pub()
484 483 self.init_displayhook()
485 484 self.init_magics()
486 485 self.init_alias()
487 486 self.init_logstart()
488 487 self.init_pdb()
489 488 self.init_extension_manager()
490 489 self.init_payload()
491 490 self.init_deprecation_warnings()
492 491 self.hooks.late_startup_hook()
493 492 self.events.trigger('shell_initialized', self)
494 493 atexit.register(self.atexit_operations)
495 494
496 495 def get_ipython(self):
497 496 """Return the currently running IPython instance."""
498 497 return self
499 498
500 499 #-------------------------------------------------------------------------
501 500 # Trait changed handlers
502 501 #-------------------------------------------------------------------------
503 502 @observe('ipython_dir')
504 503 def _ipython_dir_changed(self, change):
505 504 ensure_dir_exists(change['new'])
506 505
507 506 def set_autoindent(self,value=None):
508 507 """Set the autoindent flag.
509 508
510 509 If called with no arguments, it acts as a toggle."""
511 510 if value is None:
512 511 self.autoindent = not self.autoindent
513 512 else:
514 513 self.autoindent = value
515 514
516 515 #-------------------------------------------------------------------------
517 516 # init_* methods called by __init__
518 517 #-------------------------------------------------------------------------
519 518
520 519 def init_ipython_dir(self, ipython_dir):
521 520 if ipython_dir is not None:
522 521 self.ipython_dir = ipython_dir
523 522 return
524 523
525 524 self.ipython_dir = get_ipython_dir()
526 525
527 526 def init_profile_dir(self, profile_dir):
528 527 if profile_dir is not None:
529 528 self.profile_dir = profile_dir
530 529 return
531 530 self.profile_dir =\
532 531 ProfileDir.create_profile_dir_by_name(self.ipython_dir, 'default')
533 532
534 533 def init_instance_attrs(self):
535 534 self.more = False
536 535
537 536 # command compiler
538 537 self.compile = CachingCompiler()
539 538
540 539 # Make an empty namespace, which extension writers can rely on both
541 540 # existing and NEVER being used by ipython itself. This gives them a
542 541 # convenient location for storing additional information and state
543 542 # their extensions may require, without fear of collisions with other
544 543 # ipython names that may develop later.
545 544 self.meta = Struct()
546 545
547 546 # Temporary files used for various purposes. Deleted at exit.
548 547 self.tempfiles = []
549 548 self.tempdirs = []
550 549
551 550 # keep track of where we started running (mainly for crash post-mortem)
552 551 # This is not being used anywhere currently.
553 self.starting_dir = py3compat.getcwd()
552 self.starting_dir = os.getcwd()
554 553
555 554 # Indentation management
556 555 self.indent_current_nsp = 0
557 556
558 557 # Dict to track post-execution functions that have been registered
559 558 self._post_execute = {}
560 559
561 560 def init_environment(self):
562 561 """Any changes we need to make to the user's environment."""
563 562 pass
564 563
565 564 def init_encoding(self):
566 565 # Get system encoding at startup time. Certain terminals (like Emacs
567 566 # under Win32 have it set to None, and we need to have a known valid
568 567 # encoding to use in the raw_input() method
569 568 try:
570 569 self.stdin_encoding = sys.stdin.encoding or 'ascii'
571 570 except AttributeError:
572 571 self.stdin_encoding = 'ascii'
573 572
574 573
575 574 @observe('colors')
576 575 def init_syntax_highlighting(self, changes=None):
577 576 # Python source parser/formatter for syntax highlighting
578 577 pyformat = PyColorize.Parser(style=self.colors, parent=self).format
579 578 self.pycolorize = lambda src: pyformat(src,'str')
580 579
581 580 def refresh_style(self):
582 581 # No-op here, used in subclass
583 582 pass
584 583
585 584 def init_pushd_popd_magic(self):
586 585 # for pushd/popd management
587 586 self.home_dir = get_home_dir()
588 587
589 588 self.dir_stack = []
590 589
591 590 def init_logger(self):
592 591 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
593 592 logmode='rotate')
594 593
595 594 def init_logstart(self):
596 595 """Initialize logging in case it was requested at the command line.
597 596 """
598 597 if self.logappend:
599 598 self.magic('logstart %s append' % self.logappend)
600 599 elif self.logfile:
601 600 self.magic('logstart %s' % self.logfile)
602 601 elif self.logstart:
603 602 self.magic('logstart')
604 603
605 604 def init_deprecation_warnings(self):
606 605 """
607 606 register default filter for deprecation warning.
608 607
609 608 This will allow deprecation warning of function used interactively to show
610 609 warning to users, and still hide deprecation warning from libraries import.
611 610 """
612 611 warnings.filterwarnings("default", category=DeprecationWarning, module=self.user_ns.get("__name__"))
613 612
614 613 def init_builtins(self):
615 614 # A single, static flag that we set to True. Its presence indicates
616 615 # that an IPython shell has been created, and we make no attempts at
617 616 # removing on exit or representing the existence of more than one
618 617 # IPython at a time.
619 618 builtin_mod.__dict__['__IPYTHON__'] = True
620 619
621 620 self.builtin_trap = BuiltinTrap(shell=self)
622 621
623 622 def init_inspector(self):
624 623 # Object inspector
625 624 self.inspector = oinspect.Inspector(oinspect.InspectColors,
626 625 PyColorize.ANSICodeColors,
627 626 'NoColor',
628 627 self.object_info_string_level)
629 628
630 629 def init_io(self):
631 630 # This will just use sys.stdout and sys.stderr. If you want to
632 631 # override sys.stdout and sys.stderr themselves, you need to do that
633 632 # *before* instantiating this class, because io holds onto
634 633 # references to the underlying streams.
635 634 # io.std* are deprecated, but don't show our own deprecation warnings
636 635 # during initialization of the deprecated API.
637 636 with warnings.catch_warnings():
638 637 warnings.simplefilter('ignore', DeprecationWarning)
639 638 io.stdout = io.IOStream(sys.stdout)
640 639 io.stderr = io.IOStream(sys.stderr)
641 640
642 641 def init_prompts(self):
643 642 # Set system prompts, so that scripts can decide if they are running
644 643 # interactively.
645 644 sys.ps1 = 'In : '
646 645 sys.ps2 = '...: '
647 646 sys.ps3 = 'Out: '
648 647
649 648 def init_display_formatter(self):
650 649 self.display_formatter = DisplayFormatter(parent=self)
651 650 self.configurables.append(self.display_formatter)
652 651
653 652 def init_display_pub(self):
654 653 self.display_pub = self.display_pub_class(parent=self)
655 654 self.configurables.append(self.display_pub)
656 655
657 656 def init_data_pub(self):
658 657 if not self.data_pub_class:
659 658 self.data_pub = None
660 659 return
661 660 self.data_pub = self.data_pub_class(parent=self)
662 661 self.configurables.append(self.data_pub)
663 662
664 663 def init_displayhook(self):
665 664 # Initialize displayhook, set in/out prompts and printing system
666 665 self.displayhook = self.displayhook_class(
667 666 parent=self,
668 667 shell=self,
669 668 cache_size=self.cache_size,
670 669 )
671 670 self.configurables.append(self.displayhook)
672 671 # This is a context manager that installs/revmoes the displayhook at
673 672 # the appropriate time.
674 673 self.display_trap = DisplayTrap(hook=self.displayhook)
675 674
676 675 def init_virtualenv(self):
677 676 """Add a virtualenv to sys.path so the user can import modules from it.
678 677 This isn't perfect: it doesn't use the Python interpreter with which the
679 678 virtualenv was built, and it ignores the --no-site-packages option. A
680 679 warning will appear suggesting the user installs IPython in the
681 680 virtualenv, but for many cases, it probably works well enough.
682 681
683 682 Adapted from code snippets online.
684 683
685 684 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
686 685 """
687 686 if 'VIRTUAL_ENV' not in os.environ:
688 687 # Not in a virtualenv
689 688 return
690 689
691 690 # venv detection:
692 691 # stdlib venv may symlink sys.executable, so we can't use realpath.
693 692 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
694 693 # So we just check every item in the symlink tree (generally <= 3)
695 694 p = os.path.normcase(sys.executable)
696 695 paths = [p]
697 696 while os.path.islink(p):
698 697 p = os.path.normcase(os.path.join(os.path.dirname(p), os.readlink(p)))
699 698 paths.append(p)
700 699 p_venv = os.path.normcase(os.environ['VIRTUAL_ENV'])
701 700 if any(p.startswith(p_venv) for p in paths):
702 701 # Running properly in the virtualenv, don't need to do anything
703 702 return
704 703
705 704 warn("Attempting to work in a virtualenv. If you encounter problems, please "
706 705 "install IPython inside the virtualenv.")
707 706 if sys.platform == "win32":
708 707 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'Lib', 'site-packages')
709 708 else:
710 709 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'lib',
711 710 'python%d.%d' % sys.version_info[:2], 'site-packages')
712 711
713 712 import site
714 713 sys.path.insert(0, virtual_env)
715 714 site.addsitedir(virtual_env)
716 715
717 716 #-------------------------------------------------------------------------
718 717 # Things related to injections into the sys module
719 718 #-------------------------------------------------------------------------
720 719
721 720 def save_sys_module_state(self):
722 721 """Save the state of hooks in the sys module.
723 722
724 723 This has to be called after self.user_module is created.
725 724 """
726 725 self._orig_sys_module_state = {'stdin': sys.stdin,
727 726 'stdout': sys.stdout,
728 727 'stderr': sys.stderr,
729 728 'excepthook': sys.excepthook}
730 729 self._orig_sys_modules_main_name = self.user_module.__name__
731 730 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
732 731
733 732 def restore_sys_module_state(self):
734 733 """Restore the state of the sys module."""
735 734 try:
736 for k, v in iteritems(self._orig_sys_module_state):
735 for k, v in self._orig_sys_module_state.items():
737 736 setattr(sys, k, v)
738 737 except AttributeError:
739 738 pass
740 739 # Reset what what done in self.init_sys_modules
741 740 if self._orig_sys_modules_main_mod is not None:
742 741 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
743 742
744 743 #-------------------------------------------------------------------------
745 744 # Things related to the banner
746 745 #-------------------------------------------------------------------------
747 746
748 747 @property
749 748 def banner(self):
750 749 banner = self.banner1
751 750 if self.profile and self.profile != 'default':
752 751 banner += '\nIPython profile: %s\n' % self.profile
753 752 if self.banner2:
754 753 banner += '\n' + self.banner2
755 754 return banner
756 755
757 756 def show_banner(self, banner=None):
758 757 if banner is None:
759 758 banner = self.banner
760 759 sys.stdout.write(banner)
761 760
762 761 #-------------------------------------------------------------------------
763 762 # Things related to hooks
764 763 #-------------------------------------------------------------------------
765 764
766 765 def init_hooks(self):
767 766 # hooks holds pointers used for user-side customizations
768 767 self.hooks = Struct()
769 768
770 769 self.strdispatchers = {}
771 770
772 771 # Set all default hooks, defined in the IPython.hooks module.
773 772 hooks = IPython.core.hooks
774 773 for hook_name in hooks.__all__:
775 774 # default hooks have priority 100, i.e. low; user hooks should have
776 775 # 0-100 priority
777 776 self.set_hook(hook_name,getattr(hooks,hook_name), 100, _warn_deprecated=False)
778 777
779 778 if self.display_page:
780 779 self.set_hook('show_in_pager', page.as_hook(page.display_page), 90)
781 780
782 781 def set_hook(self,name,hook, priority=50, str_key=None, re_key=None,
783 782 _warn_deprecated=True):
784 783 """set_hook(name,hook) -> sets an internal IPython hook.
785 784
786 785 IPython exposes some of its internal API as user-modifiable hooks. By
787 786 adding your function to one of these hooks, you can modify IPython's
788 787 behavior to call at runtime your own routines."""
789 788
790 789 # At some point in the future, this should validate the hook before it
791 790 # accepts it. Probably at least check that the hook takes the number
792 791 # of args it's supposed to.
793 792
794 793 f = types.MethodType(hook,self)
795 794
796 795 # check if the hook is for strdispatcher first
797 796 if str_key is not None:
798 797 sdp = self.strdispatchers.get(name, StrDispatch())
799 798 sdp.add_s(str_key, f, priority )
800 799 self.strdispatchers[name] = sdp
801 800 return
802 801 if re_key is not None:
803 802 sdp = self.strdispatchers.get(name, StrDispatch())
804 803 sdp.add_re(re.compile(re_key), f, priority )
805 804 self.strdispatchers[name] = sdp
806 805 return
807 806
808 807 dp = getattr(self.hooks, name, None)
809 808 if name not in IPython.core.hooks.__all__:
810 809 print("Warning! Hook '%s' is not one of %s" % \
811 810 (name, IPython.core.hooks.__all__ ))
812 811
813 812 if _warn_deprecated and (name in IPython.core.hooks.deprecated):
814 813 alternative = IPython.core.hooks.deprecated[name]
815 814 warn("Hook {} is deprecated. Use {} instead.".format(name, alternative), stacklevel=2)
816 815
817 816 if not dp:
818 817 dp = IPython.core.hooks.CommandChainDispatcher()
819 818
820 819 try:
821 820 dp.add(f,priority)
822 821 except AttributeError:
823 822 # it was not commandchain, plain old func - replace
824 823 dp = f
825 824
826 825 setattr(self.hooks,name, dp)
827 826
828 827 #-------------------------------------------------------------------------
829 828 # Things related to events
830 829 #-------------------------------------------------------------------------
831 830
832 831 def init_events(self):
833 832 self.events = EventManager(self, available_events)
834 833
835 834 self.events.register("pre_execute", self._clear_warning_registry)
836 835
837 836 def register_post_execute(self, func):
838 837 """DEPRECATED: Use ip.events.register('post_run_cell', func)
839 838
840 839 Register a function for calling after code execution.
841 840 """
842 841 warn("ip.register_post_execute is deprecated, use "
843 842 "ip.events.register('post_run_cell', func) instead.", stacklevel=2)
844 843 self.events.register('post_run_cell', func)
845 844
846 845 def _clear_warning_registry(self):
847 846 # clear the warning registry, so that different code blocks with
848 847 # overlapping line number ranges don't cause spurious suppression of
849 848 # warnings (see gh-6611 for details)
850 849 if "__warningregistry__" in self.user_global_ns:
851 850 del self.user_global_ns["__warningregistry__"]
852 851
853 852 #-------------------------------------------------------------------------
854 853 # Things related to the "main" module
855 854 #-------------------------------------------------------------------------
856 855
857 856 def new_main_mod(self, filename, modname):
858 857 """Return a new 'main' module object for user code execution.
859 858
860 859 ``filename`` should be the path of the script which will be run in the
861 860 module. Requests with the same filename will get the same module, with
862 861 its namespace cleared.
863 862
864 863 ``modname`` should be the module name - normally either '__main__' or
865 864 the basename of the file without the extension.
866 865
867 866 When scripts are executed via %run, we must keep a reference to their
868 867 __main__ module around so that Python doesn't
869 868 clear it, rendering references to module globals useless.
870 869
871 870 This method keeps said reference in a private dict, keyed by the
872 871 absolute path of the script. This way, for multiple executions of the
873 872 same script we only keep one copy of the namespace (the last one),
874 873 thus preventing memory leaks from old references while allowing the
875 874 objects from the last execution to be accessible.
876 875 """
877 876 filename = os.path.abspath(filename)
878 877 try:
879 878 main_mod = self._main_mod_cache[filename]
880 879 except KeyError:
881 880 main_mod = self._main_mod_cache[filename] = types.ModuleType(
882 881 py3compat.cast_bytes_py2(modname),
883 882 doc="Module created for script run in IPython")
884 883 else:
885 884 main_mod.__dict__.clear()
886 885 main_mod.__name__ = modname
887 886
888 887 main_mod.__file__ = filename
889 888 # It seems pydoc (and perhaps others) needs any module instance to
890 889 # implement a __nonzero__ method
891 890 main_mod.__nonzero__ = lambda : True
892 891
893 892 return main_mod
894 893
895 894 def clear_main_mod_cache(self):
896 895 """Clear the cache of main modules.
897 896
898 897 Mainly for use by utilities like %reset.
899 898
900 899 Examples
901 900 --------
902 901
903 902 In [15]: import IPython
904 903
905 904 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
906 905
907 906 In [17]: len(_ip._main_mod_cache) > 0
908 907 Out[17]: True
909 908
910 909 In [18]: _ip.clear_main_mod_cache()
911 910
912 911 In [19]: len(_ip._main_mod_cache) == 0
913 912 Out[19]: True
914 913 """
915 914 self._main_mod_cache.clear()
916 915
917 916 #-------------------------------------------------------------------------
918 917 # Things related to debugging
919 918 #-------------------------------------------------------------------------
920 919
921 920 def init_pdb(self):
922 921 # Set calling of pdb on exceptions
923 922 # self.call_pdb is a property
924 923 self.call_pdb = self.pdb
925 924
926 925 def _get_call_pdb(self):
927 926 return self._call_pdb
928 927
929 928 def _set_call_pdb(self,val):
930 929
931 930 if val not in (0,1,False,True):
932 931 raise ValueError('new call_pdb value must be boolean')
933 932
934 933 # store value in instance
935 934 self._call_pdb = val
936 935
937 936 # notify the actual exception handlers
938 937 self.InteractiveTB.call_pdb = val
939 938
940 939 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
941 940 'Control auto-activation of pdb at exceptions')
942 941
943 942 def debugger(self,force=False):
944 943 """Call the pdb debugger.
945 944
946 945 Keywords:
947 946
948 947 - force(False): by default, this routine checks the instance call_pdb
949 948 flag and does not actually invoke the debugger if the flag is false.
950 949 The 'force' option forces the debugger to activate even if the flag
951 950 is false.
952 951 """
953 952
954 953 if not (force or self.call_pdb):
955 954 return
956 955
957 956 if not hasattr(sys,'last_traceback'):
958 957 error('No traceback has been produced, nothing to debug.')
959 958 return
960 959
961 960 self.InteractiveTB.debugger(force=True)
962 961
963 962 #-------------------------------------------------------------------------
964 963 # Things related to IPython's various namespaces
965 964 #-------------------------------------------------------------------------
966 965 default_user_namespaces = True
967 966
968 967 def init_create_namespaces(self, user_module=None, user_ns=None):
969 968 # Create the namespace where the user will operate. user_ns is
970 969 # normally the only one used, and it is passed to the exec calls as
971 970 # the locals argument. But we do carry a user_global_ns namespace
972 971 # given as the exec 'globals' argument, This is useful in embedding
973 972 # situations where the ipython shell opens in a context where the
974 973 # distinction between locals and globals is meaningful. For
975 974 # non-embedded contexts, it is just the same object as the user_ns dict.
976 975
977 976 # FIXME. For some strange reason, __builtins__ is showing up at user
978 977 # level as a dict instead of a module. This is a manual fix, but I
979 978 # should really track down where the problem is coming from. Alex
980 979 # Schmolck reported this problem first.
981 980
982 981 # A useful post by Alex Martelli on this topic:
983 982 # Re: inconsistent value from __builtins__
984 983 # Von: Alex Martelli <aleaxit@yahoo.com>
985 984 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
986 985 # Gruppen: comp.lang.python
987 986
988 987 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
989 988 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
990 989 # > <type 'dict'>
991 990 # > >>> print type(__builtins__)
992 991 # > <type 'module'>
993 992 # > Is this difference in return value intentional?
994 993
995 994 # Well, it's documented that '__builtins__' can be either a dictionary
996 995 # or a module, and it's been that way for a long time. Whether it's
997 996 # intentional (or sensible), I don't know. In any case, the idea is
998 997 # that if you need to access the built-in namespace directly, you
999 998 # should start with "import __builtin__" (note, no 's') which will
1000 999 # definitely give you a module. Yeah, it's somewhat confusing:-(.
1001 1000
1002 1001 # These routines return a properly built module and dict as needed by
1003 1002 # the rest of the code, and can also be used by extension writers to
1004 1003 # generate properly initialized namespaces.
1005 1004 if (user_ns is not None) or (user_module is not None):
1006 1005 self.default_user_namespaces = False
1007 1006 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
1008 1007
1009 1008 # A record of hidden variables we have added to the user namespace, so
1010 1009 # we can list later only variables defined in actual interactive use.
1011 1010 self.user_ns_hidden = {}
1012 1011
1013 1012 # Now that FakeModule produces a real module, we've run into a nasty
1014 1013 # problem: after script execution (via %run), the module where the user
1015 1014 # code ran is deleted. Now that this object is a true module (needed
1016 1015 # so doctest and other tools work correctly), the Python module
1017 1016 # teardown mechanism runs over it, and sets to None every variable
1018 1017 # present in that module. Top-level references to objects from the
1019 1018 # script survive, because the user_ns is updated with them. However,
1020 1019 # calling functions defined in the script that use other things from
1021 1020 # the script will fail, because the function's closure had references
1022 1021 # to the original objects, which are now all None. So we must protect
1023 1022 # these modules from deletion by keeping a cache.
1024 1023 #
1025 1024 # To avoid keeping stale modules around (we only need the one from the
1026 1025 # last run), we use a dict keyed with the full path to the script, so
1027 1026 # only the last version of the module is held in the cache. Note,
1028 1027 # however, that we must cache the module *namespace contents* (their
1029 1028 # __dict__). Because if we try to cache the actual modules, old ones
1030 1029 # (uncached) could be destroyed while still holding references (such as
1031 1030 # those held by GUI objects that tend to be long-lived)>
1032 1031 #
1033 1032 # The %reset command will flush this cache. See the cache_main_mod()
1034 1033 # and clear_main_mod_cache() methods for details on use.
1035 1034
1036 1035 # This is the cache used for 'main' namespaces
1037 1036 self._main_mod_cache = {}
1038 1037
1039 1038 # A table holding all the namespaces IPython deals with, so that
1040 1039 # introspection facilities can search easily.
1041 1040 self.ns_table = {'user_global':self.user_module.__dict__,
1042 1041 'user_local':self.user_ns,
1043 1042 'builtin':builtin_mod.__dict__
1044 1043 }
1045 1044
1046 1045 @property
1047 1046 def user_global_ns(self):
1048 1047 return self.user_module.__dict__
1049 1048
1050 1049 def prepare_user_module(self, user_module=None, user_ns=None):
1051 1050 """Prepare the module and namespace in which user code will be run.
1052 1051
1053 1052 When IPython is started normally, both parameters are None: a new module
1054 1053 is created automatically, and its __dict__ used as the namespace.
1055 1054
1056 1055 If only user_module is provided, its __dict__ is used as the namespace.
1057 1056 If only user_ns is provided, a dummy module is created, and user_ns
1058 1057 becomes the global namespace. If both are provided (as they may be
1059 1058 when embedding), user_ns is the local namespace, and user_module
1060 1059 provides the global namespace.
1061 1060
1062 1061 Parameters
1063 1062 ----------
1064 1063 user_module : module, optional
1065 1064 The current user module in which IPython is being run. If None,
1066 1065 a clean module will be created.
1067 1066 user_ns : dict, optional
1068 1067 A namespace in which to run interactive commands.
1069 1068
1070 1069 Returns
1071 1070 -------
1072 1071 A tuple of user_module and user_ns, each properly initialised.
1073 1072 """
1074 1073 if user_module is None and user_ns is not None:
1075 1074 user_ns.setdefault("__name__", "__main__")
1076 1075 user_module = DummyMod()
1077 1076 user_module.__dict__ = user_ns
1078 1077
1079 1078 if user_module is None:
1080 1079 user_module = types.ModuleType("__main__",
1081 1080 doc="Automatically created module for IPython interactive environment")
1082 1081
1083 1082 # We must ensure that __builtin__ (without the final 's') is always
1084 1083 # available and pointing to the __builtin__ *module*. For more details:
1085 1084 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1086 1085 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1087 1086 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1088 1087
1089 1088 if user_ns is None:
1090 1089 user_ns = user_module.__dict__
1091 1090
1092 1091 return user_module, user_ns
1093 1092
1094 1093 def init_sys_modules(self):
1095 1094 # We need to insert into sys.modules something that looks like a
1096 1095 # module but which accesses the IPython namespace, for shelve and
1097 1096 # pickle to work interactively. Normally they rely on getting
1098 1097 # everything out of __main__, but for embedding purposes each IPython
1099 1098 # instance has its own private namespace, so we can't go shoving
1100 1099 # everything into __main__.
1101 1100
1102 1101 # note, however, that we should only do this for non-embedded
1103 1102 # ipythons, which really mimic the __main__.__dict__ with their own
1104 1103 # namespace. Embedded instances, on the other hand, should not do
1105 1104 # this because they need to manage the user local/global namespaces
1106 1105 # only, but they live within a 'normal' __main__ (meaning, they
1107 1106 # shouldn't overtake the execution environment of the script they're
1108 1107 # embedded in).
1109 1108
1110 1109 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1111 1110 main_name = self.user_module.__name__
1112 1111 sys.modules[main_name] = self.user_module
1113 1112
1114 1113 def init_user_ns(self):
1115 1114 """Initialize all user-visible namespaces to their minimum defaults.
1116 1115
1117 1116 Certain history lists are also initialized here, as they effectively
1118 1117 act as user namespaces.
1119 1118
1120 1119 Notes
1121 1120 -----
1122 1121 All data structures here are only filled in, they are NOT reset by this
1123 1122 method. If they were not empty before, data will simply be added to
1124 1123 therm.
1125 1124 """
1126 1125 # This function works in two parts: first we put a few things in
1127 1126 # user_ns, and we sync that contents into user_ns_hidden so that these
1128 1127 # initial variables aren't shown by %who. After the sync, we add the
1129 1128 # rest of what we *do* want the user to see with %who even on a new
1130 1129 # session (probably nothing, so they really only see their own stuff)
1131 1130
1132 1131 # The user dict must *always* have a __builtin__ reference to the
1133 1132 # Python standard __builtin__ namespace, which must be imported.
1134 1133 # This is so that certain operations in prompt evaluation can be
1135 1134 # reliably executed with builtins. Note that we can NOT use
1136 1135 # __builtins__ (note the 's'), because that can either be a dict or a
1137 1136 # module, and can even mutate at runtime, depending on the context
1138 1137 # (Python makes no guarantees on it). In contrast, __builtin__ is
1139 1138 # always a module object, though it must be explicitly imported.
1140 1139
1141 1140 # For more details:
1142 1141 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1143 1142 ns = dict()
1144 1143
1145 1144 # make global variables for user access to the histories
1146 1145 ns['_ih'] = self.history_manager.input_hist_parsed
1147 1146 ns['_oh'] = self.history_manager.output_hist
1148 1147 ns['_dh'] = self.history_manager.dir_hist
1149 1148
1150 1149 ns['_sh'] = shadowns
1151 1150
1152 1151 # user aliases to input and output histories. These shouldn't show up
1153 1152 # in %who, as they can have very large reprs.
1154 1153 ns['In'] = self.history_manager.input_hist_parsed
1155 1154 ns['Out'] = self.history_manager.output_hist
1156 1155
1157 1156 # Store myself as the public api!!!
1158 1157 ns['get_ipython'] = self.get_ipython
1159 1158
1160 1159 ns['exit'] = self.exiter
1161 1160 ns['quit'] = self.exiter
1162 1161
1163 1162 # Sync what we've added so far to user_ns_hidden so these aren't seen
1164 1163 # by %who
1165 1164 self.user_ns_hidden.update(ns)
1166 1165
1167 1166 # Anything put into ns now would show up in %who. Think twice before
1168 1167 # putting anything here, as we really want %who to show the user their
1169 1168 # stuff, not our variables.
1170 1169
1171 1170 # Finally, update the real user's namespace
1172 1171 self.user_ns.update(ns)
1173 1172
1174 1173 @property
1175 1174 def all_ns_refs(self):
1176 1175 """Get a list of references to all the namespace dictionaries in which
1177 1176 IPython might store a user-created object.
1178 1177
1179 1178 Note that this does not include the displayhook, which also caches
1180 1179 objects from the output."""
1181 1180 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1182 1181 [m.__dict__ for m in self._main_mod_cache.values()]
1183 1182
1184 1183 def reset(self, new_session=True):
1185 1184 """Clear all internal namespaces, and attempt to release references to
1186 1185 user objects.
1187 1186
1188 1187 If new_session is True, a new history session will be opened.
1189 1188 """
1190 1189 # Clear histories
1191 1190 self.history_manager.reset(new_session)
1192 1191 # Reset counter used to index all histories
1193 1192 if new_session:
1194 1193 self.execution_count = 1
1195 1194
1196 1195 # Flush cached output items
1197 1196 if self.displayhook.do_full_cache:
1198 1197 self.displayhook.flush()
1199 1198
1200 1199 # The main execution namespaces must be cleared very carefully,
1201 1200 # skipping the deletion of the builtin-related keys, because doing so
1202 1201 # would cause errors in many object's __del__ methods.
1203 1202 if self.user_ns is not self.user_global_ns:
1204 1203 self.user_ns.clear()
1205 1204 ns = self.user_global_ns
1206 1205 drop_keys = set(ns.keys())
1207 1206 drop_keys.discard('__builtin__')
1208 1207 drop_keys.discard('__builtins__')
1209 1208 drop_keys.discard('__name__')
1210 1209 for k in drop_keys:
1211 1210 del ns[k]
1212 1211
1213 1212 self.user_ns_hidden.clear()
1214 1213
1215 1214 # Restore the user namespaces to minimal usability
1216 1215 self.init_user_ns()
1217 1216
1218 1217 # Restore the default and user aliases
1219 1218 self.alias_manager.clear_aliases()
1220 1219 self.alias_manager.init_aliases()
1221 1220
1222 1221 # Flush the private list of module references kept for script
1223 1222 # execution protection
1224 1223 self.clear_main_mod_cache()
1225 1224
1226 1225 def del_var(self, varname, by_name=False):
1227 1226 """Delete a variable from the various namespaces, so that, as
1228 1227 far as possible, we're not keeping any hidden references to it.
1229 1228
1230 1229 Parameters
1231 1230 ----------
1232 1231 varname : str
1233 1232 The name of the variable to delete.
1234 1233 by_name : bool
1235 1234 If True, delete variables with the given name in each
1236 1235 namespace. If False (default), find the variable in the user
1237 1236 namespace, and delete references to it.
1238 1237 """
1239 1238 if varname in ('__builtin__', '__builtins__'):
1240 1239 raise ValueError("Refusing to delete %s" % varname)
1241 1240
1242 1241 ns_refs = self.all_ns_refs
1243 1242
1244 1243 if by_name: # Delete by name
1245 1244 for ns in ns_refs:
1246 1245 try:
1247 1246 del ns[varname]
1248 1247 except KeyError:
1249 1248 pass
1250 1249 else: # Delete by object
1251 1250 try:
1252 1251 obj = self.user_ns[varname]
1253 1252 except KeyError:
1254 1253 raise NameError("name '%s' is not defined" % varname)
1255 1254 # Also check in output history
1256 1255 ns_refs.append(self.history_manager.output_hist)
1257 1256 for ns in ns_refs:
1258 to_delete = [n for n, o in iteritems(ns) if o is obj]
1257 to_delete = [n for n, o in ns.items() if o is obj]
1259 1258 for name in to_delete:
1260 1259 del ns[name]
1261 1260
1262 1261 # displayhook keeps extra references, but not in a dictionary
1263 1262 for name in ('_', '__', '___'):
1264 1263 if getattr(self.displayhook, name) is obj:
1265 1264 setattr(self.displayhook, name, None)
1266 1265
1267 1266 def reset_selective(self, regex=None):
1268 1267 """Clear selective variables from internal namespaces based on a
1269 1268 specified regular expression.
1270 1269
1271 1270 Parameters
1272 1271 ----------
1273 1272 regex : string or compiled pattern, optional
1274 1273 A regular expression pattern that will be used in searching
1275 1274 variable names in the users namespaces.
1276 1275 """
1277 1276 if regex is not None:
1278 1277 try:
1279 1278 m = re.compile(regex)
1280 1279 except TypeError:
1281 1280 raise TypeError('regex must be a string or compiled pattern')
1282 1281 # Search for keys in each namespace that match the given regex
1283 1282 # If a match is found, delete the key/value pair.
1284 1283 for ns in self.all_ns_refs:
1285 1284 for var in ns:
1286 1285 if m.search(var):
1287 1286 del ns[var]
1288 1287
1289 1288 def push(self, variables, interactive=True):
1290 1289 """Inject a group of variables into the IPython user namespace.
1291 1290
1292 1291 Parameters
1293 1292 ----------
1294 1293 variables : dict, str or list/tuple of str
1295 1294 The variables to inject into the user's namespace. If a dict, a
1296 1295 simple update is done. If a str, the string is assumed to have
1297 1296 variable names separated by spaces. A list/tuple of str can also
1298 1297 be used to give the variable names. If just the variable names are
1299 1298 give (list/tuple/str) then the variable values looked up in the
1300 1299 callers frame.
1301 1300 interactive : bool
1302 1301 If True (default), the variables will be listed with the ``who``
1303 1302 magic.
1304 1303 """
1305 1304 vdict = None
1306 1305
1307 1306 # We need a dict of name/value pairs to do namespace updates.
1308 1307 if isinstance(variables, dict):
1309 1308 vdict = variables
1310 elif isinstance(variables, string_types+(list, tuple)):
1311 if isinstance(variables, string_types):
1309 elif isinstance(variables, (str, list, tuple)):
1310 if isinstance(variables, str):
1312 1311 vlist = variables.split()
1313 1312 else:
1314 1313 vlist = variables
1315 1314 vdict = {}
1316 1315 cf = sys._getframe(1)
1317 1316 for name in vlist:
1318 1317 try:
1319 1318 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1320 1319 except:
1321 1320 print('Could not get variable %s from %s' %
1322 1321 (name,cf.f_code.co_name))
1323 1322 else:
1324 1323 raise ValueError('variables must be a dict/str/list/tuple')
1325 1324
1326 1325 # Propagate variables to user namespace
1327 1326 self.user_ns.update(vdict)
1328 1327
1329 1328 # And configure interactive visibility
1330 1329 user_ns_hidden = self.user_ns_hidden
1331 1330 if interactive:
1332 1331 for name in vdict:
1333 1332 user_ns_hidden.pop(name, None)
1334 1333 else:
1335 1334 user_ns_hidden.update(vdict)
1336 1335
1337 1336 def drop_by_id(self, variables):
1338 1337 """Remove a dict of variables from the user namespace, if they are the
1339 1338 same as the values in the dictionary.
1340 1339
1341 1340 This is intended for use by extensions: variables that they've added can
1342 1341 be taken back out if they are unloaded, without removing any that the
1343 1342 user has overwritten.
1344 1343
1345 1344 Parameters
1346 1345 ----------
1347 1346 variables : dict
1348 1347 A dictionary mapping object names (as strings) to the objects.
1349 1348 """
1350 for name, obj in iteritems(variables):
1349 for name, obj in variables.items():
1351 1350 if name in self.user_ns and self.user_ns[name] is obj:
1352 1351 del self.user_ns[name]
1353 1352 self.user_ns_hidden.pop(name, None)
1354 1353
1355 1354 #-------------------------------------------------------------------------
1356 1355 # Things related to object introspection
1357 1356 #-------------------------------------------------------------------------
1358 1357
1359 1358 def _ofind(self, oname, namespaces=None):
1360 1359 """Find an object in the available namespaces.
1361 1360
1362 1361 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1363 1362
1364 1363 Has special code to detect magic functions.
1365 1364 """
1366 1365 oname = oname.strip()
1367 1366 #print '1- oname: <%r>' % oname # dbg
1368 1367 if not oname.startswith(ESC_MAGIC) and \
1369 1368 not oname.startswith(ESC_MAGIC2) and \
1370 1369 not py3compat.isidentifier(oname, dotted=True):
1371 1370 return dict(found=False)
1372 1371
1373 1372 if namespaces is None:
1374 1373 # Namespaces to search in:
1375 1374 # Put them in a list. The order is important so that we
1376 1375 # find things in the same order that Python finds them.
1377 1376 namespaces = [ ('Interactive', self.user_ns),
1378 1377 ('Interactive (global)', self.user_global_ns),
1379 1378 ('Python builtin', builtin_mod.__dict__),
1380 1379 ]
1381 1380
1382 1381 # initialize results to 'null'
1383 1382 found = False; obj = None; ospace = None;
1384 1383 ismagic = False; isalias = False; parent = None
1385 1384
1386 1385 # We need to special-case 'print', which as of python2.6 registers as a
1387 1386 # function but should only be treated as one if print_function was
1388 1387 # loaded with a future import. In this case, just bail.
1389 1388 if (oname == 'print' and not py3compat.PY3 and not \
1390 1389 (self.compile.compiler_flags & __future__.CO_FUTURE_PRINT_FUNCTION)):
1391 1390 return {'found':found, 'obj':obj, 'namespace':ospace,
1392 1391 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1393 1392
1394 1393 # Look for the given name by splitting it in parts. If the head is
1395 1394 # found, then we look for all the remaining parts as members, and only
1396 1395 # declare success if we can find them all.
1397 1396 oname_parts = oname.split('.')
1398 1397 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1399 1398 for nsname,ns in namespaces:
1400 1399 try:
1401 1400 obj = ns[oname_head]
1402 1401 except KeyError:
1403 1402 continue
1404 1403 else:
1405 1404 #print 'oname_rest:', oname_rest # dbg
1406 1405 for idx, part in enumerate(oname_rest):
1407 1406 try:
1408 1407 parent = obj
1409 1408 # The last part is looked up in a special way to avoid
1410 1409 # descriptor invocation as it may raise or have side
1411 1410 # effects.
1412 1411 if idx == len(oname_rest) - 1:
1413 1412 obj = self._getattr_property(obj, part)
1414 1413 else:
1415 1414 obj = getattr(obj, part)
1416 1415 except:
1417 1416 # Blanket except b/c some badly implemented objects
1418 1417 # allow __getattr__ to raise exceptions other than
1419 1418 # AttributeError, which then crashes IPython.
1420 1419 break
1421 1420 else:
1422 1421 # If we finish the for loop (no break), we got all members
1423 1422 found = True
1424 1423 ospace = nsname
1425 1424 break # namespace loop
1426 1425
1427 1426 # Try to see if it's magic
1428 1427 if not found:
1429 1428 obj = None
1430 1429 if oname.startswith(ESC_MAGIC2):
1431 1430 oname = oname.lstrip(ESC_MAGIC2)
1432 1431 obj = self.find_cell_magic(oname)
1433 1432 elif oname.startswith(ESC_MAGIC):
1434 1433 oname = oname.lstrip(ESC_MAGIC)
1435 1434 obj = self.find_line_magic(oname)
1436 1435 else:
1437 1436 # search without prefix, so run? will find %run?
1438 1437 obj = self.find_line_magic(oname)
1439 1438 if obj is None:
1440 1439 obj = self.find_cell_magic(oname)
1441 1440 if obj is not None:
1442 1441 found = True
1443 1442 ospace = 'IPython internal'
1444 1443 ismagic = True
1445 1444 isalias = isinstance(obj, Alias)
1446 1445
1447 1446 # Last try: special-case some literals like '', [], {}, etc:
1448 1447 if not found and oname_head in ["''",'""','[]','{}','()']:
1449 1448 obj = eval(oname_head)
1450 1449 found = True
1451 1450 ospace = 'Interactive'
1452 1451
1453 1452 return {'found':found, 'obj':obj, 'namespace':ospace,
1454 1453 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1455 1454
1456 1455 @staticmethod
1457 1456 def _getattr_property(obj, attrname):
1458 1457 """Property-aware getattr to use in object finding.
1459 1458
1460 1459 If attrname represents a property, return it unevaluated (in case it has
1461 1460 side effects or raises an error.
1462 1461
1463 1462 """
1464 1463 if not isinstance(obj, type):
1465 1464 try:
1466 1465 # `getattr(type(obj), attrname)` is not guaranteed to return
1467 1466 # `obj`, but does so for property:
1468 1467 #
1469 1468 # property.__get__(self, None, cls) -> self
1470 1469 #
1471 1470 # The universal alternative is to traverse the mro manually
1472 1471 # searching for attrname in class dicts.
1473 1472 attr = getattr(type(obj), attrname)
1474 1473 except AttributeError:
1475 1474 pass
1476 1475 else:
1477 1476 # This relies on the fact that data descriptors (with both
1478 1477 # __get__ & __set__ magic methods) take precedence over
1479 1478 # instance-level attributes:
1480 1479 #
1481 1480 # class A(object):
1482 1481 # @property
1483 1482 # def foobar(self): return 123
1484 1483 # a = A()
1485 1484 # a.__dict__['foobar'] = 345
1486 1485 # a.foobar # == 123
1487 1486 #
1488 1487 # So, a property may be returned right away.
1489 1488 if isinstance(attr, property):
1490 1489 return attr
1491 1490
1492 1491 # Nothing helped, fall back.
1493 1492 return getattr(obj, attrname)
1494 1493
1495 1494 def _object_find(self, oname, namespaces=None):
1496 1495 """Find an object and return a struct with info about it."""
1497 1496 return Struct(self._ofind(oname, namespaces))
1498 1497
1499 1498 def _inspect(self, meth, oname, namespaces=None, **kw):
1500 1499 """Generic interface to the inspector system.
1501 1500
1502 1501 This function is meant to be called by pdef, pdoc & friends.
1503 1502 """
1504 1503 info = self._object_find(oname, namespaces)
1505 1504 docformat = sphinxify if self.sphinxify_docstring else None
1506 1505 if info.found:
1507 1506 pmethod = getattr(self.inspector, meth)
1508 1507 # TODO: only apply format_screen to the plain/text repr of the mime
1509 1508 # bundle.
1510 1509 formatter = format_screen if info.ismagic else docformat
1511 1510 if meth == 'pdoc':
1512 1511 pmethod(info.obj, oname, formatter)
1513 1512 elif meth == 'pinfo':
1514 1513 pmethod(info.obj, oname, formatter, info,
1515 1514 enable_html_pager=self.enable_html_pager, **kw)
1516 1515 else:
1517 1516 pmethod(info.obj, oname)
1518 1517 else:
1519 1518 print('Object `%s` not found.' % oname)
1520 1519 return 'not found' # so callers can take other action
1521 1520
1522 1521 def object_inspect(self, oname, detail_level=0):
1523 1522 """Get object info about oname"""
1524 1523 with self.builtin_trap:
1525 1524 info = self._object_find(oname)
1526 1525 if info.found:
1527 1526 return self.inspector.info(info.obj, oname, info=info,
1528 1527 detail_level=detail_level
1529 1528 )
1530 1529 else:
1531 1530 return oinspect.object_info(name=oname, found=False)
1532 1531
1533 1532 def object_inspect_text(self, oname, detail_level=0):
1534 1533 """Get object info as formatted text"""
1535 1534 return self.object_inspect_mime(oname, detail_level)['text/plain']
1536 1535
1537 1536 def object_inspect_mime(self, oname, detail_level=0):
1538 1537 """Get object info as a mimebundle of formatted representations.
1539 1538
1540 1539 A mimebundle is a dictionary, keyed by mime-type.
1541 1540 It must always have the key `'text/plain'`.
1542 1541 """
1543 1542 with self.builtin_trap:
1544 1543 info = self._object_find(oname)
1545 1544 if info.found:
1546 1545 return self.inspector._get_info(info.obj, oname, info=info,
1547 1546 detail_level=detail_level
1548 1547 )
1549 1548 else:
1550 1549 raise KeyError(oname)
1551 1550
1552 1551 #-------------------------------------------------------------------------
1553 1552 # Things related to history management
1554 1553 #-------------------------------------------------------------------------
1555 1554
1556 1555 def init_history(self):
1557 1556 """Sets up the command history, and starts regular autosaves."""
1558 1557 self.history_manager = HistoryManager(shell=self, parent=self)
1559 1558 self.configurables.append(self.history_manager)
1560 1559
1561 1560 #-------------------------------------------------------------------------
1562 1561 # Things related to exception handling and tracebacks (not debugging)
1563 1562 #-------------------------------------------------------------------------
1564 1563
1565 1564 debugger_cls = Pdb
1566 1565
1567 1566 def init_traceback_handlers(self, custom_exceptions):
1568 1567 # Syntax error handler.
1569 1568 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor', parent=self)
1570 1569
1571 1570 # The interactive one is initialized with an offset, meaning we always
1572 1571 # want to remove the topmost item in the traceback, which is our own
1573 1572 # internal code. Valid modes: ['Plain','Context','Verbose']
1574 1573 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1575 1574 color_scheme='NoColor',
1576 1575 tb_offset = 1,
1577 1576 check_cache=check_linecache_ipython,
1578 1577 debugger_cls=self.debugger_cls, parent=self)
1579 1578
1580 1579 # The instance will store a pointer to the system-wide exception hook,
1581 1580 # so that runtime code (such as magics) can access it. This is because
1582 1581 # during the read-eval loop, it may get temporarily overwritten.
1583 1582 self.sys_excepthook = sys.excepthook
1584 1583
1585 1584 # and add any custom exception handlers the user may have specified
1586 1585 self.set_custom_exc(*custom_exceptions)
1587 1586
1588 1587 # Set the exception mode
1589 1588 self.InteractiveTB.set_mode(mode=self.xmode)
1590 1589
1591 1590 def set_custom_exc(self, exc_tuple, handler):
1592 1591 """set_custom_exc(exc_tuple, handler)
1593 1592
1594 1593 Set a custom exception handler, which will be called if any of the
1595 1594 exceptions in exc_tuple occur in the mainloop (specifically, in the
1596 1595 run_code() method).
1597 1596
1598 1597 Parameters
1599 1598 ----------
1600 1599
1601 1600 exc_tuple : tuple of exception classes
1602 1601 A *tuple* of exception classes, for which to call the defined
1603 1602 handler. It is very important that you use a tuple, and NOT A
1604 1603 LIST here, because of the way Python's except statement works. If
1605 1604 you only want to trap a single exception, use a singleton tuple::
1606 1605
1607 1606 exc_tuple == (MyCustomException,)
1608 1607
1609 1608 handler : callable
1610 1609 handler must have the following signature::
1611 1610
1612 1611 def my_handler(self, etype, value, tb, tb_offset=None):
1613 1612 ...
1614 1613 return structured_traceback
1615 1614
1616 1615 Your handler must return a structured traceback (a list of strings),
1617 1616 or None.
1618 1617
1619 1618 This will be made into an instance method (via types.MethodType)
1620 1619 of IPython itself, and it will be called if any of the exceptions
1621 1620 listed in the exc_tuple are caught. If the handler is None, an
1622 1621 internal basic one is used, which just prints basic info.
1623 1622
1624 1623 To protect IPython from crashes, if your handler ever raises an
1625 1624 exception or returns an invalid result, it will be immediately
1626 1625 disabled.
1627 1626
1628 1627 WARNING: by putting in your own exception handler into IPython's main
1629 1628 execution loop, you run a very good chance of nasty crashes. This
1630 1629 facility should only be used if you really know what you are doing."""
1631 1630
1632 1631 assert type(exc_tuple)==type(()) , \
1633 1632 "The custom exceptions must be given AS A TUPLE."
1634 1633
1635 1634 def dummy_handler(self, etype, value, tb, tb_offset=None):
1636 1635 print('*** Simple custom exception handler ***')
1637 1636 print('Exception type :',etype)
1638 1637 print('Exception value:',value)
1639 1638 print('Traceback :',tb)
1640 1639 #print 'Source code :','\n'.join(self.buffer)
1641 1640
1642 1641 def validate_stb(stb):
1643 1642 """validate structured traceback return type
1644 1643
1645 1644 return type of CustomTB *should* be a list of strings, but allow
1646 1645 single strings or None, which are harmless.
1647 1646
1648 1647 This function will *always* return a list of strings,
1649 1648 and will raise a TypeError if stb is inappropriate.
1650 1649 """
1651 1650 msg = "CustomTB must return list of strings, not %r" % stb
1652 1651 if stb is None:
1653 1652 return []
1654 elif isinstance(stb, string_types):
1653 elif isinstance(stb, str):
1655 1654 return [stb]
1656 1655 elif not isinstance(stb, list):
1657 1656 raise TypeError(msg)
1658 1657 # it's a list
1659 1658 for line in stb:
1660 1659 # check every element
1661 if not isinstance(line, string_types):
1660 if not isinstance(line, str):
1662 1661 raise TypeError(msg)
1663 1662 return stb
1664 1663
1665 1664 if handler is None:
1666 1665 wrapped = dummy_handler
1667 1666 else:
1668 1667 def wrapped(self,etype,value,tb,tb_offset=None):
1669 1668 """wrap CustomTB handler, to protect IPython from user code
1670 1669
1671 1670 This makes it harder (but not impossible) for custom exception
1672 1671 handlers to crash IPython.
1673 1672 """
1674 1673 try:
1675 1674 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1676 1675 return validate_stb(stb)
1677 1676 except:
1678 1677 # clear custom handler immediately
1679 1678 self.set_custom_exc((), None)
1680 1679 print("Custom TB Handler failed, unregistering", file=sys.stderr)
1681 1680 # show the exception in handler first
1682 1681 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1683 1682 print(self.InteractiveTB.stb2text(stb))
1684 1683 print("The original exception:")
1685 1684 stb = self.InteractiveTB.structured_traceback(
1686 1685 (etype,value,tb), tb_offset=tb_offset
1687 1686 )
1688 1687 return stb
1689 1688
1690 1689 self.CustomTB = types.MethodType(wrapped,self)
1691 1690 self.custom_exceptions = exc_tuple
1692 1691
1693 1692 def excepthook(self, etype, value, tb):
1694 1693 """One more defense for GUI apps that call sys.excepthook.
1695 1694
1696 1695 GUI frameworks like wxPython trap exceptions and call
1697 1696 sys.excepthook themselves. I guess this is a feature that
1698 1697 enables them to keep running after exceptions that would
1699 1698 otherwise kill their mainloop. This is a bother for IPython
1700 1699 which excepts to catch all of the program exceptions with a try:
1701 1700 except: statement.
1702 1701
1703 1702 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1704 1703 any app directly invokes sys.excepthook, it will look to the user like
1705 1704 IPython crashed. In order to work around this, we can disable the
1706 1705 CrashHandler and replace it with this excepthook instead, which prints a
1707 1706 regular traceback using our InteractiveTB. In this fashion, apps which
1708 1707 call sys.excepthook will generate a regular-looking exception from
1709 1708 IPython, and the CrashHandler will only be triggered by real IPython
1710 1709 crashes.
1711 1710
1712 1711 This hook should be used sparingly, only in places which are not likely
1713 1712 to be true IPython errors.
1714 1713 """
1715 1714 self.showtraceback((etype, value, tb), tb_offset=0)
1716 1715
1717 1716 def _get_exc_info(self, exc_tuple=None):
1718 1717 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1719 1718
1720 1719 Ensures sys.last_type,value,traceback hold the exc_info we found,
1721 1720 from whichever source.
1722 1721
1723 1722 raises ValueError if none of these contain any information
1724 1723 """
1725 1724 if exc_tuple is None:
1726 1725 etype, value, tb = sys.exc_info()
1727 1726 else:
1728 1727 etype, value, tb = exc_tuple
1729 1728
1730 1729 if etype is None:
1731 1730 if hasattr(sys, 'last_type'):
1732 1731 etype, value, tb = sys.last_type, sys.last_value, \
1733 1732 sys.last_traceback
1734 1733
1735 1734 if etype is None:
1736 1735 raise ValueError("No exception to find")
1737 1736
1738 1737 # Now store the exception info in sys.last_type etc.
1739 1738 # WARNING: these variables are somewhat deprecated and not
1740 1739 # necessarily safe to use in a threaded environment, but tools
1741 1740 # like pdb depend on their existence, so let's set them. If we
1742 1741 # find problems in the field, we'll need to revisit their use.
1743 1742 sys.last_type = etype
1744 1743 sys.last_value = value
1745 1744 sys.last_traceback = tb
1746 1745
1747 1746 return etype, value, tb
1748 1747
1749 1748 def show_usage_error(self, exc):
1750 1749 """Show a short message for UsageErrors
1751 1750
1752 1751 These are special exceptions that shouldn't show a traceback.
1753 1752 """
1754 1753 print("UsageError: %s" % exc, file=sys.stderr)
1755 1754
1756 1755 def get_exception_only(self, exc_tuple=None):
1757 1756 """
1758 1757 Return as a string (ending with a newline) the exception that
1759 1758 just occurred, without any traceback.
1760 1759 """
1761 1760 etype, value, tb = self._get_exc_info(exc_tuple)
1762 1761 msg = traceback.format_exception_only(etype, value)
1763 1762 return ''.join(msg)
1764 1763
1765 1764 def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None,
1766 1765 exception_only=False):
1767 1766 """Display the exception that just occurred.
1768 1767
1769 1768 If nothing is known about the exception, this is the method which
1770 1769 should be used throughout the code for presenting user tracebacks,
1771 1770 rather than directly invoking the InteractiveTB object.
1772 1771
1773 1772 A specific showsyntaxerror() also exists, but this method can take
1774 1773 care of calling it if needed, so unless you are explicitly catching a
1775 1774 SyntaxError exception, don't try to analyze the stack manually and
1776 1775 simply call this method."""
1777 1776
1778 1777 try:
1779 1778 try:
1780 1779 etype, value, tb = self._get_exc_info(exc_tuple)
1781 1780 except ValueError:
1782 1781 print('No traceback available to show.', file=sys.stderr)
1783 1782 return
1784 1783
1785 1784 if issubclass(etype, SyntaxError):
1786 1785 # Though this won't be called by syntax errors in the input
1787 1786 # line, there may be SyntaxError cases with imported code.
1788 1787 self.showsyntaxerror(filename)
1789 1788 elif etype is UsageError:
1790 1789 self.show_usage_error(value)
1791 1790 else:
1792 1791 if exception_only:
1793 1792 stb = ['An exception has occurred, use %tb to see '
1794 1793 'the full traceback.\n']
1795 1794 stb.extend(self.InteractiveTB.get_exception_only(etype,
1796 1795 value))
1797 1796 else:
1798 1797 try:
1799 1798 # Exception classes can customise their traceback - we
1800 1799 # use this in IPython.parallel for exceptions occurring
1801 1800 # in the engines. This should return a list of strings.
1802 1801 stb = value._render_traceback_()
1803 1802 except Exception:
1804 1803 stb = self.InteractiveTB.structured_traceback(etype,
1805 1804 value, tb, tb_offset=tb_offset)
1806 1805
1807 1806 self._showtraceback(etype, value, stb)
1808 1807 if self.call_pdb:
1809 1808 # drop into debugger
1810 1809 self.debugger(force=True)
1811 1810 return
1812 1811
1813 1812 # Actually show the traceback
1814 1813 self._showtraceback(etype, value, stb)
1815 1814
1816 1815 except KeyboardInterrupt:
1817 1816 print('\n' + self.get_exception_only(), file=sys.stderr)
1818 1817
1819 1818 def _showtraceback(self, etype, evalue, stb):
1820 1819 """Actually show a traceback.
1821 1820
1822 1821 Subclasses may override this method to put the traceback on a different
1823 1822 place, like a side channel.
1824 1823 """
1825 1824 print(self.InteractiveTB.stb2text(stb))
1826 1825
1827 1826 def showsyntaxerror(self, filename=None):
1828 1827 """Display the syntax error that just occurred.
1829 1828
1830 1829 This doesn't display a stack trace because there isn't one.
1831 1830
1832 1831 If a filename is given, it is stuffed in the exception instead
1833 1832 of what was there before (because Python's parser always uses
1834 1833 "<string>" when reading from a string).
1835 1834 """
1836 1835 etype, value, last_traceback = self._get_exc_info()
1837 1836
1838 1837 if filename and issubclass(etype, SyntaxError):
1839 1838 try:
1840 1839 value.filename = filename
1841 1840 except:
1842 1841 # Not the format we expect; leave it alone
1843 1842 pass
1844 1843
1845 1844 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1846 1845 self._showtraceback(etype, value, stb)
1847 1846
1848 1847 # This is overridden in TerminalInteractiveShell to show a message about
1849 1848 # the %paste magic.
1850 1849 def showindentationerror(self):
1851 1850 """Called by run_cell when there's an IndentationError in code entered
1852 1851 at the prompt.
1853 1852
1854 1853 This is overridden in TerminalInteractiveShell to show a message about
1855 1854 the %paste magic."""
1856 1855 self.showsyntaxerror()
1857 1856
1858 1857 #-------------------------------------------------------------------------
1859 1858 # Things related to readline
1860 1859 #-------------------------------------------------------------------------
1861 1860
1862 1861 def init_readline(self):
1863 1862 """DEPRECATED
1864 1863
1865 1864 Moved to terminal subclass, here only to simplify the init logic."""
1866 1865 # Set a number of methods that depend on readline to be no-op
1867 1866 warnings.warn('`init_readline` is no-op since IPython 5.0 and is Deprecated',
1868 1867 DeprecationWarning, stacklevel=2)
1869 1868 self.set_custom_completer = no_op
1870 1869
1871 1870 @skip_doctest
1872 1871 def set_next_input(self, s, replace=False):
1873 1872 """ Sets the 'default' input string for the next command line.
1874 1873
1875 1874 Example::
1876 1875
1877 1876 In [1]: _ip.set_next_input("Hello Word")
1878 1877 In [2]: Hello Word_ # cursor is here
1879 1878 """
1880 1879 self.rl_next_input = py3compat.cast_bytes_py2(s)
1881 1880
1882 1881 def _indent_current_str(self):
1883 1882 """return the current level of indentation as a string"""
1884 1883 return self.input_splitter.indent_spaces * ' '
1885 1884
1886 1885 #-------------------------------------------------------------------------
1887 1886 # Things related to text completion
1888 1887 #-------------------------------------------------------------------------
1889 1888
1890 1889 def init_completer(self):
1891 1890 """Initialize the completion machinery.
1892 1891
1893 1892 This creates completion machinery that can be used by client code,
1894 1893 either interactively in-process (typically triggered by the readline
1895 1894 library), programmatically (such as in test suites) or out-of-process
1896 1895 (typically over the network by remote frontends).
1897 1896 """
1898 1897 from IPython.core.completer import IPCompleter
1899 1898 from IPython.core.completerlib import (module_completer,
1900 1899 magic_run_completer, cd_completer, reset_completer)
1901 1900
1902 1901 self.Completer = IPCompleter(shell=self,
1903 1902 namespace=self.user_ns,
1904 1903 global_namespace=self.user_global_ns,
1905 1904 parent=self,
1906 1905 )
1907 1906 self.configurables.append(self.Completer)
1908 1907
1909 1908 # Add custom completers to the basic ones built into IPCompleter
1910 1909 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1911 1910 self.strdispatchers['complete_command'] = sdisp
1912 1911 self.Completer.custom_completers = sdisp
1913 1912
1914 1913 self.set_hook('complete_command', module_completer, str_key = 'import')
1915 1914 self.set_hook('complete_command', module_completer, str_key = 'from')
1916 1915 self.set_hook('complete_command', module_completer, str_key = '%aimport')
1917 1916 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
1918 1917 self.set_hook('complete_command', cd_completer, str_key = '%cd')
1919 1918 self.set_hook('complete_command', reset_completer, str_key = '%reset')
1920 1919
1921 1920
1922 1921 def complete(self, text, line=None, cursor_pos=None):
1923 1922 """Return the completed text and a list of completions.
1924 1923
1925 1924 Parameters
1926 1925 ----------
1927 1926
1928 1927 text : string
1929 1928 A string of text to be completed on. It can be given as empty and
1930 1929 instead a line/position pair are given. In this case, the
1931 1930 completer itself will split the line like readline does.
1932 1931
1933 1932 line : string, optional
1934 1933 The complete line that text is part of.
1935 1934
1936 1935 cursor_pos : int, optional
1937 1936 The position of the cursor on the input line.
1938 1937
1939 1938 Returns
1940 1939 -------
1941 1940 text : string
1942 1941 The actual text that was completed.
1943 1942
1944 1943 matches : list
1945 1944 A sorted list with all possible completions.
1946 1945
1947 1946 The optional arguments allow the completion to take more context into
1948 1947 account, and are part of the low-level completion API.
1949 1948
1950 1949 This is a wrapper around the completion mechanism, similar to what
1951 1950 readline does at the command line when the TAB key is hit. By
1952 1951 exposing it as a method, it can be used by other non-readline
1953 1952 environments (such as GUIs) for text completion.
1954 1953
1955 1954 Simple usage example:
1956 1955
1957 1956 In [1]: x = 'hello'
1958 1957
1959 1958 In [2]: _ip.complete('x.l')
1960 1959 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
1961 1960 """
1962 1961
1963 1962 # Inject names into __builtin__ so we can complete on the added names.
1964 1963 with self.builtin_trap:
1965 1964 return self.Completer.complete(text, line, cursor_pos)
1966 1965
1967 1966 def set_custom_completer(self, completer, pos=0):
1968 1967 """Adds a new custom completer function.
1969 1968
1970 1969 The position argument (defaults to 0) is the index in the completers
1971 1970 list where you want the completer to be inserted."""
1972 1971
1973 1972 newcomp = types.MethodType(completer,self.Completer)
1974 1973 self.Completer.matchers.insert(pos,newcomp)
1975 1974
1976 1975 def set_completer_frame(self, frame=None):
1977 1976 """Set the frame of the completer."""
1978 1977 if frame:
1979 1978 self.Completer.namespace = frame.f_locals
1980 1979 self.Completer.global_namespace = frame.f_globals
1981 1980 else:
1982 1981 self.Completer.namespace = self.user_ns
1983 1982 self.Completer.global_namespace = self.user_global_ns
1984 1983
1985 1984 #-------------------------------------------------------------------------
1986 1985 # Things related to magics
1987 1986 #-------------------------------------------------------------------------
1988 1987
1989 1988 def init_magics(self):
1990 1989 from IPython.core import magics as m
1991 1990 self.magics_manager = magic.MagicsManager(shell=self,
1992 1991 parent=self,
1993 1992 user_magics=m.UserMagics(self))
1994 1993 self.configurables.append(self.magics_manager)
1995 1994
1996 1995 # Expose as public API from the magics manager
1997 1996 self.register_magics = self.magics_manager.register
1998 1997
1999 1998 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2000 1999 m.ConfigMagics, m.DisplayMagics, m.ExecutionMagics,
2001 2000 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2002 2001 m.NamespaceMagics, m.OSMagics, m.PylabMagics, m.ScriptMagics,
2003 2002 )
2004 2003
2005 2004 # Register Magic Aliases
2006 2005 mman = self.magics_manager
2007 2006 # FIXME: magic aliases should be defined by the Magics classes
2008 2007 # or in MagicsManager, not here
2009 2008 mman.register_alias('ed', 'edit')
2010 2009 mman.register_alias('hist', 'history')
2011 2010 mman.register_alias('rep', 'recall')
2012 2011 mman.register_alias('SVG', 'svg', 'cell')
2013 2012 mman.register_alias('HTML', 'html', 'cell')
2014 2013 mman.register_alias('file', 'writefile', 'cell')
2015 2014
2016 2015 # FIXME: Move the color initialization to the DisplayHook, which
2017 2016 # should be split into a prompt manager and displayhook. We probably
2018 2017 # even need a centralize colors management object.
2019 2018 self.magic('colors %s' % self.colors)
2020 2019
2021 2020 # Defined here so that it's included in the documentation
2022 2021 @functools.wraps(magic.MagicsManager.register_function)
2023 2022 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2024 2023 self.magics_manager.register_function(func,
2025 2024 magic_kind=magic_kind, magic_name=magic_name)
2026 2025
2027 2026 def run_line_magic(self, magic_name, line):
2028 2027 """Execute the given line magic.
2029 2028
2030 2029 Parameters
2031 2030 ----------
2032 2031 magic_name : str
2033 2032 Name of the desired magic function, without '%' prefix.
2034 2033
2035 2034 line : str
2036 2035 The rest of the input line as a single string.
2037 2036 """
2038 2037 fn = self.find_line_magic(magic_name)
2039 2038 if fn is None:
2040 2039 cm = self.find_cell_magic(magic_name)
2041 2040 etpl = "Line magic function `%%%s` not found%s."
2042 2041 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2043 2042 'did you mean that instead?)' % magic_name )
2044 2043 error(etpl % (magic_name, extra))
2045 2044 else:
2046 2045 # Note: this is the distance in the stack to the user's frame.
2047 2046 # This will need to be updated if the internal calling logic gets
2048 2047 # refactored, or else we'll be expanding the wrong variables.
2049 2048 stack_depth = 2
2050 2049 magic_arg_s = self.var_expand(line, stack_depth)
2051 2050 # Put magic args in a list so we can call with f(*a) syntax
2052 2051 args = [magic_arg_s]
2053 2052 kwargs = {}
2054 2053 # Grab local namespace if we need it:
2055 2054 if getattr(fn, "needs_local_scope", False):
2056 2055 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
2057 2056 with self.builtin_trap:
2058 2057 result = fn(*args,**kwargs)
2059 2058 return result
2060 2059
2061 2060 def run_cell_magic(self, magic_name, line, cell):
2062 2061 """Execute the given cell magic.
2063 2062
2064 2063 Parameters
2065 2064 ----------
2066 2065 magic_name : str
2067 2066 Name of the desired magic function, without '%' prefix.
2068 2067
2069 2068 line : str
2070 2069 The rest of the first input line as a single string.
2071 2070
2072 2071 cell : str
2073 2072 The body of the cell as a (possibly multiline) string.
2074 2073 """
2075 2074 fn = self.find_cell_magic(magic_name)
2076 2075 if fn is None:
2077 2076 lm = self.find_line_magic(magic_name)
2078 2077 etpl = "Cell magic `%%{0}` not found{1}."
2079 2078 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2080 2079 'did you mean that instead?)'.format(magic_name))
2081 2080 error(etpl.format(magic_name, extra))
2082 2081 elif cell == '':
2083 2082 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2084 2083 if self.find_line_magic(magic_name) is not None:
2085 2084 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2086 2085 raise UsageError(message)
2087 2086 else:
2088 2087 # Note: this is the distance in the stack to the user's frame.
2089 2088 # This will need to be updated if the internal calling logic gets
2090 2089 # refactored, or else we'll be expanding the wrong variables.
2091 2090 stack_depth = 2
2092 2091 magic_arg_s = self.var_expand(line, stack_depth)
2093 2092 with self.builtin_trap:
2094 2093 result = fn(magic_arg_s, cell)
2095 2094 return result
2096 2095
2097 2096 def find_line_magic(self, magic_name):
2098 2097 """Find and return a line magic by name.
2099 2098
2100 2099 Returns None if the magic isn't found."""
2101 2100 return self.magics_manager.magics['line'].get(magic_name)
2102 2101
2103 2102 def find_cell_magic(self, magic_name):
2104 2103 """Find and return a cell magic by name.
2105 2104
2106 2105 Returns None if the magic isn't found."""
2107 2106 return self.magics_manager.magics['cell'].get(magic_name)
2108 2107
2109 2108 def find_magic(self, magic_name, magic_kind='line'):
2110 2109 """Find and return a magic of the given type by name.
2111 2110
2112 2111 Returns None if the magic isn't found."""
2113 2112 return self.magics_manager.magics[magic_kind].get(magic_name)
2114 2113
2115 2114 def magic(self, arg_s):
2116 2115 """DEPRECATED. Use run_line_magic() instead.
2117 2116
2118 2117 Call a magic function by name.
2119 2118
2120 2119 Input: a string containing the name of the magic function to call and
2121 2120 any additional arguments to be passed to the magic.
2122 2121
2123 2122 magic('name -opt foo bar') is equivalent to typing at the ipython
2124 2123 prompt:
2125 2124
2126 2125 In[1]: %name -opt foo bar
2127 2126
2128 2127 To call a magic without arguments, simply use magic('name').
2129 2128
2130 2129 This provides a proper Python function to call IPython's magics in any
2131 2130 valid Python code you can type at the interpreter, including loops and
2132 2131 compound statements.
2133 2132 """
2134 2133 # TODO: should we issue a loud deprecation warning here?
2135 2134 magic_name, _, magic_arg_s = arg_s.partition(' ')
2136 2135 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2137 2136 return self.run_line_magic(magic_name, magic_arg_s)
2138 2137
2139 2138 #-------------------------------------------------------------------------
2140 2139 # Things related to macros
2141 2140 #-------------------------------------------------------------------------
2142 2141
2143 2142 def define_macro(self, name, themacro):
2144 2143 """Define a new macro
2145 2144
2146 2145 Parameters
2147 2146 ----------
2148 2147 name : str
2149 2148 The name of the macro.
2150 2149 themacro : str or Macro
2151 2150 The action to do upon invoking the macro. If a string, a new
2152 2151 Macro object is created by passing the string to it.
2153 2152 """
2154 2153
2155 2154 from IPython.core import macro
2156 2155
2157 if isinstance(themacro, string_types):
2156 if isinstance(themacro, str):
2158 2157 themacro = macro.Macro(themacro)
2159 2158 if not isinstance(themacro, macro.Macro):
2160 2159 raise ValueError('A macro must be a string or a Macro instance.')
2161 2160 self.user_ns[name] = themacro
2162 2161
2163 2162 #-------------------------------------------------------------------------
2164 2163 # Things related to the running of system commands
2165 2164 #-------------------------------------------------------------------------
2166 2165
2167 2166 def system_piped(self, cmd):
2168 2167 """Call the given cmd in a subprocess, piping stdout/err
2169 2168
2170 2169 Parameters
2171 2170 ----------
2172 2171 cmd : str
2173 2172 Command to execute (can not end in '&', as background processes are
2174 2173 not supported. Should not be a command that expects input
2175 2174 other than simple text.
2176 2175 """
2177 2176 if cmd.rstrip().endswith('&'):
2178 2177 # this is *far* from a rigorous test
2179 2178 # We do not support backgrounding processes because we either use
2180 2179 # pexpect or pipes to read from. Users can always just call
2181 2180 # os.system() or use ip.system=ip.system_raw
2182 2181 # if they really want a background process.
2183 2182 raise OSError("Background processes not supported.")
2184 2183
2185 2184 # we explicitly do NOT return the subprocess status code, because
2186 2185 # a non-None value would trigger :func:`sys.displayhook` calls.
2187 2186 # Instead, we store the exit_code in user_ns.
2188 2187 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2189 2188
2190 2189 def system_raw(self, cmd):
2191 2190 """Call the given cmd in a subprocess using os.system on Windows or
2192 2191 subprocess.call using the system shell on other platforms.
2193 2192
2194 2193 Parameters
2195 2194 ----------
2196 2195 cmd : str
2197 2196 Command to execute.
2198 2197 """
2199 2198 cmd = self.var_expand(cmd, depth=1)
2200 2199 # protect os.system from UNC paths on Windows, which it can't handle:
2201 2200 if sys.platform == 'win32':
2202 2201 from IPython.utils._process_win32 import AvoidUNCPath
2203 2202 with AvoidUNCPath() as path:
2204 2203 if path is not None:
2205 2204 cmd = '"pushd %s &&"%s' % (path, cmd)
2206 cmd = py3compat.unicode_to_str(cmd)
2207 2205 try:
2208 2206 ec = os.system(cmd)
2209 2207 except KeyboardInterrupt:
2210 2208 print('\n' + self.get_exception_only(), file=sys.stderr)
2211 2209 ec = -2
2212 2210 else:
2213 cmd = py3compat.unicode_to_str(cmd)
2214 2211 # For posix the result of the subprocess.call() below is an exit
2215 2212 # code, which by convention is zero for success, positive for
2216 2213 # program failure. Exit codes above 128 are reserved for signals,
2217 2214 # and the formula for converting a signal to an exit code is usually
2218 2215 # signal_number+128. To more easily differentiate between exit
2219 2216 # codes and signals, ipython uses negative numbers. For instance
2220 2217 # since control-c is signal 2 but exit code 130, ipython's
2221 2218 # _exit_code variable will read -2. Note that some shells like
2222 2219 # csh and fish don't follow sh/bash conventions for exit codes.
2223 2220 executable = os.environ.get('SHELL', None)
2224 2221 try:
2225 2222 # Use env shell instead of default /bin/sh
2226 2223 ec = subprocess.call(cmd, shell=True, executable=executable)
2227 2224 except KeyboardInterrupt:
2228 2225 # intercept control-C; a long traceback is not useful here
2229 2226 print('\n' + self.get_exception_only(), file=sys.stderr)
2230 2227 ec = 130
2231 2228 if ec > 128:
2232 2229 ec = -(ec - 128)
2233 2230
2234 2231 # We explicitly do NOT return the subprocess status code, because
2235 2232 # a non-None value would trigger :func:`sys.displayhook` calls.
2236 2233 # Instead, we store the exit_code in user_ns. Note the semantics
2237 2234 # of _exit_code: for control-c, _exit_code == -signal.SIGNIT,
2238 2235 # but raising SystemExit(_exit_code) will give status 254!
2239 2236 self.user_ns['_exit_code'] = ec
2240 2237
2241 2238 # use piped system by default, because it is better behaved
2242 2239 system = system_piped
2243 2240
2244 2241 def getoutput(self, cmd, split=True, depth=0):
2245 2242 """Get output (possibly including stderr) from a subprocess.
2246 2243
2247 2244 Parameters
2248 2245 ----------
2249 2246 cmd : str
2250 2247 Command to execute (can not end in '&', as background processes are
2251 2248 not supported.
2252 2249 split : bool, optional
2253 2250 If True, split the output into an IPython SList. Otherwise, an
2254 2251 IPython LSString is returned. These are objects similar to normal
2255 2252 lists and strings, with a few convenience attributes for easier
2256 2253 manipulation of line-based output. You can use '?' on them for
2257 2254 details.
2258 2255 depth : int, optional
2259 2256 How many frames above the caller are the local variables which should
2260 2257 be expanded in the command string? The default (0) assumes that the
2261 2258 expansion variables are in the stack frame calling this function.
2262 2259 """
2263 2260 if cmd.rstrip().endswith('&'):
2264 2261 # this is *far* from a rigorous test
2265 2262 raise OSError("Background processes not supported.")
2266 2263 out = getoutput(self.var_expand(cmd, depth=depth+1))
2267 2264 if split:
2268 2265 out = SList(out.splitlines())
2269 2266 else:
2270 2267 out = LSString(out)
2271 2268 return out
2272 2269
2273 2270 #-------------------------------------------------------------------------
2274 2271 # Things related to aliases
2275 2272 #-------------------------------------------------------------------------
2276 2273
2277 2274 def init_alias(self):
2278 2275 self.alias_manager = AliasManager(shell=self, parent=self)
2279 2276 self.configurables.append(self.alias_manager)
2280 2277
2281 2278 #-------------------------------------------------------------------------
2282 2279 # Things related to extensions
2283 2280 #-------------------------------------------------------------------------
2284 2281
2285 2282 def init_extension_manager(self):
2286 2283 self.extension_manager = ExtensionManager(shell=self, parent=self)
2287 2284 self.configurables.append(self.extension_manager)
2288 2285
2289 2286 #-------------------------------------------------------------------------
2290 2287 # Things related to payloads
2291 2288 #-------------------------------------------------------------------------
2292 2289
2293 2290 def init_payload(self):
2294 2291 self.payload_manager = PayloadManager(parent=self)
2295 2292 self.configurables.append(self.payload_manager)
2296 2293
2297 2294 #-------------------------------------------------------------------------
2298 2295 # Things related to the prefilter
2299 2296 #-------------------------------------------------------------------------
2300 2297
2301 2298 def init_prefilter(self):
2302 2299 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2303 2300 self.configurables.append(self.prefilter_manager)
2304 2301 # Ultimately this will be refactored in the new interpreter code, but
2305 2302 # for now, we should expose the main prefilter method (there's legacy
2306 2303 # code out there that may rely on this).
2307 2304 self.prefilter = self.prefilter_manager.prefilter_lines
2308 2305
2309 2306 def auto_rewrite_input(self, cmd):
2310 2307 """Print to the screen the rewritten form of the user's command.
2311 2308
2312 2309 This shows visual feedback by rewriting input lines that cause
2313 2310 automatic calling to kick in, like::
2314 2311
2315 2312 /f x
2316 2313
2317 2314 into::
2318 2315
2319 2316 ------> f(x)
2320 2317
2321 2318 after the user's input prompt. This helps the user understand that the
2322 2319 input line was transformed automatically by IPython.
2323 2320 """
2324 2321 if not self.show_rewritten_input:
2325 2322 return
2326 2323
2327 2324 # This is overridden in TerminalInteractiveShell to use fancy prompts
2328 2325 print("------> " + cmd)
2329 2326
2330 2327 #-------------------------------------------------------------------------
2331 2328 # Things related to extracting values/expressions from kernel and user_ns
2332 2329 #-------------------------------------------------------------------------
2333 2330
2334 2331 def _user_obj_error(self):
2335 2332 """return simple exception dict
2336 2333
2337 2334 for use in user_expressions
2338 2335 """
2339 2336
2340 2337 etype, evalue, tb = self._get_exc_info()
2341 2338 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2342 2339
2343 2340 exc_info = {
2344 2341 u'status' : 'error',
2345 2342 u'traceback' : stb,
2346 u'ename' : unicode_type(etype.__name__),
2343 u'ename' : etype.__name__,
2347 2344 u'evalue' : py3compat.safe_unicode(evalue),
2348 2345 }
2349 2346
2350 2347 return exc_info
2351 2348
2352 2349 def _format_user_obj(self, obj):
2353 2350 """format a user object to display dict
2354 2351
2355 2352 for use in user_expressions
2356 2353 """
2357 2354
2358 2355 data, md = self.display_formatter.format(obj)
2359 2356 value = {
2360 2357 'status' : 'ok',
2361 2358 'data' : data,
2362 2359 'metadata' : md,
2363 2360 }
2364 2361 return value
2365 2362
2366 2363 def user_expressions(self, expressions):
2367 2364 """Evaluate a dict of expressions in the user's namespace.
2368 2365
2369 2366 Parameters
2370 2367 ----------
2371 2368 expressions : dict
2372 2369 A dict with string keys and string values. The expression values
2373 2370 should be valid Python expressions, each of which will be evaluated
2374 2371 in the user namespace.
2375 2372
2376 2373 Returns
2377 2374 -------
2378 2375 A dict, keyed like the input expressions dict, with the rich mime-typed
2379 2376 display_data of each value.
2380 2377 """
2381 2378 out = {}
2382 2379 user_ns = self.user_ns
2383 2380 global_ns = self.user_global_ns
2384 2381
2385 for key, expr in iteritems(expressions):
2382 for key, expr in expressions.items():
2386 2383 try:
2387 2384 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2388 2385 except:
2389 2386 value = self._user_obj_error()
2390 2387 out[key] = value
2391 2388 return out
2392 2389
2393 2390 #-------------------------------------------------------------------------
2394 2391 # Things related to the running of code
2395 2392 #-------------------------------------------------------------------------
2396 2393
2397 2394 def ex(self, cmd):
2398 2395 """Execute a normal python statement in user namespace."""
2399 2396 with self.builtin_trap:
2400 2397 exec(cmd, self.user_global_ns, self.user_ns)
2401 2398
2402 2399 def ev(self, expr):
2403 2400 """Evaluate python expression expr in user namespace.
2404 2401
2405 2402 Returns the result of evaluation
2406 2403 """
2407 2404 with self.builtin_trap:
2408 2405 return eval(expr, self.user_global_ns, self.user_ns)
2409 2406
2410 2407 def safe_execfile(self, fname, *where, **kw):
2411 2408 """A safe version of the builtin execfile().
2412 2409
2413 2410 This version will never throw an exception, but instead print
2414 2411 helpful error messages to the screen. This only works on pure
2415 2412 Python files with the .py extension.
2416 2413
2417 2414 Parameters
2418 2415 ----------
2419 2416 fname : string
2420 2417 The name of the file to be executed.
2421 2418 where : tuple
2422 2419 One or two namespaces, passed to execfile() as (globals,locals).
2423 2420 If only one is given, it is passed as both.
2424 2421 exit_ignore : bool (False)
2425 2422 If True, then silence SystemExit for non-zero status (it is always
2426 2423 silenced for zero status, as it is so common).
2427 2424 raise_exceptions : bool (False)
2428 2425 If True raise exceptions everywhere. Meant for testing.
2429 2426 shell_futures : bool (False)
2430 2427 If True, the code will share future statements with the interactive
2431 2428 shell. It will both be affected by previous __future__ imports, and
2432 2429 any __future__ imports in the code will affect the shell. If False,
2433 2430 __future__ imports are not shared in either direction.
2434 2431
2435 2432 """
2436 2433 kw.setdefault('exit_ignore', False)
2437 2434 kw.setdefault('raise_exceptions', False)
2438 2435 kw.setdefault('shell_futures', False)
2439 2436
2440 2437 fname = os.path.abspath(os.path.expanduser(fname))
2441 2438
2442 2439 # Make sure we can open the file
2443 2440 try:
2444 2441 with open(fname):
2445 2442 pass
2446 2443 except:
2447 2444 warn('Could not open file <%s> for safe execution.' % fname)
2448 2445 return
2449 2446
2450 2447 # Find things also in current directory. This is needed to mimic the
2451 2448 # behavior of running a script from the system command line, where
2452 2449 # Python inserts the script's directory into sys.path
2453 2450 dname = os.path.dirname(fname)
2454 2451
2455 2452 with prepended_to_syspath(dname), self.builtin_trap:
2456 2453 try:
2457 2454 glob, loc = (where + (None, ))[:2]
2458 2455 py3compat.execfile(
2459 2456 fname, glob, loc,
2460 2457 self.compile if kw['shell_futures'] else None)
2461 2458 except SystemExit as status:
2462 2459 # If the call was made with 0 or None exit status (sys.exit(0)
2463 2460 # or sys.exit() ), don't bother showing a traceback, as both of
2464 2461 # these are considered normal by the OS:
2465 2462 # > python -c'import sys;sys.exit(0)'; echo $?
2466 2463 # 0
2467 2464 # > python -c'import sys;sys.exit()'; echo $?
2468 2465 # 0
2469 2466 # For other exit status, we show the exception unless
2470 2467 # explicitly silenced, but only in short form.
2471 2468 if status.code:
2472 2469 if kw['raise_exceptions']:
2473 2470 raise
2474 2471 if not kw['exit_ignore']:
2475 2472 self.showtraceback(exception_only=True)
2476 2473 except:
2477 2474 if kw['raise_exceptions']:
2478 2475 raise
2479 2476 # tb offset is 2 because we wrap execfile
2480 2477 self.showtraceback(tb_offset=2)
2481 2478
2482 2479 def safe_execfile_ipy(self, fname, shell_futures=False, raise_exceptions=False):
2483 2480 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2484 2481
2485 2482 Parameters
2486 2483 ----------
2487 2484 fname : str
2488 2485 The name of the file to execute. The filename must have a
2489 2486 .ipy or .ipynb extension.
2490 2487 shell_futures : bool (False)
2491 2488 If True, the code will share future statements with the interactive
2492 2489 shell. It will both be affected by previous __future__ imports, and
2493 2490 any __future__ imports in the code will affect the shell. If False,
2494 2491 __future__ imports are not shared in either direction.
2495 2492 raise_exceptions : bool (False)
2496 2493 If True raise exceptions everywhere. Meant for testing.
2497 2494 """
2498 2495 fname = os.path.abspath(os.path.expanduser(fname))
2499 2496
2500 2497 # Make sure we can open the file
2501 2498 try:
2502 2499 with open(fname):
2503 2500 pass
2504 2501 except:
2505 2502 warn('Could not open file <%s> for safe execution.' % fname)
2506 2503 return
2507 2504
2508 2505 # Find things also in current directory. This is needed to mimic the
2509 2506 # behavior of running a script from the system command line, where
2510 2507 # Python inserts the script's directory into sys.path
2511 2508 dname = os.path.dirname(fname)
2512 2509
2513 2510 def get_cells():
2514 2511 """generator for sequence of code blocks to run"""
2515 2512 if fname.endswith('.ipynb'):
2516 2513 from nbformat import read
2517 2514 with io_open(fname) as f:
2518 2515 nb = read(f, as_version=4)
2519 2516 if not nb.cells:
2520 2517 return
2521 2518 for cell in nb.cells:
2522 2519 if cell.cell_type == 'code':
2523 2520 yield cell.source
2524 2521 else:
2525 2522 with open(fname) as f:
2526 2523 yield f.read()
2527 2524
2528 2525 with prepended_to_syspath(dname):
2529 2526 try:
2530 2527 for cell in get_cells():
2531 2528 result = self.run_cell(cell, silent=True, shell_futures=shell_futures)
2532 2529 if raise_exceptions:
2533 2530 result.raise_error()
2534 2531 elif not result.success:
2535 2532 break
2536 2533 except:
2537 2534 if raise_exceptions:
2538 2535 raise
2539 2536 self.showtraceback()
2540 2537 warn('Unknown failure executing file: <%s>' % fname)
2541 2538
2542 2539 def safe_run_module(self, mod_name, where):
2543 2540 """A safe version of runpy.run_module().
2544 2541
2545 2542 This version will never throw an exception, but instead print
2546 2543 helpful error messages to the screen.
2547 2544
2548 2545 `SystemExit` exceptions with status code 0 or None are ignored.
2549 2546
2550 2547 Parameters
2551 2548 ----------
2552 2549 mod_name : string
2553 2550 The name of the module to be executed.
2554 2551 where : dict
2555 2552 The globals namespace.
2556 2553 """
2557 2554 try:
2558 2555 try:
2559 2556 where.update(
2560 2557 runpy.run_module(str(mod_name), run_name="__main__",
2561 2558 alter_sys=True)
2562 2559 )
2563 2560 except SystemExit as status:
2564 2561 if status.code:
2565 2562 raise
2566 2563 except:
2567 2564 self.showtraceback()
2568 2565 warn('Unknown failure executing module: <%s>' % mod_name)
2569 2566
2570 2567 def run_cell(self, raw_cell, store_history=False, silent=False, shell_futures=True):
2571 2568 """Run a complete IPython cell.
2572 2569
2573 2570 Parameters
2574 2571 ----------
2575 2572 raw_cell : str
2576 2573 The code (including IPython code such as %magic functions) to run.
2577 2574 store_history : bool
2578 2575 If True, the raw and translated cell will be stored in IPython's
2579 2576 history. For user code calling back into IPython's machinery, this
2580 2577 should be set to False.
2581 2578 silent : bool
2582 2579 If True, avoid side-effects, such as implicit displayhooks and
2583 2580 and logging. silent=True forces store_history=False.
2584 2581 shell_futures : bool
2585 2582 If True, the code will share future statements with the interactive
2586 2583 shell. It will both be affected by previous __future__ imports, and
2587 2584 any __future__ imports in the code will affect the shell. If False,
2588 2585 __future__ imports are not shared in either direction.
2589 2586
2590 2587 Returns
2591 2588 -------
2592 2589 result : :class:`ExecutionResult`
2593 2590 """
2594 2591 result = ExecutionResult()
2595 2592
2596 2593 if (not raw_cell) or raw_cell.isspace():
2597 2594 self.last_execution_succeeded = True
2598 2595 return result
2599 2596
2600 2597 if silent:
2601 2598 store_history = False
2602 2599
2603 2600 if store_history:
2604 2601 result.execution_count = self.execution_count
2605 2602
2606 2603 def error_before_exec(value):
2607 2604 result.error_before_exec = value
2608 2605 self.last_execution_succeeded = False
2609 2606 return result
2610 2607
2611 2608 self.events.trigger('pre_execute')
2612 2609 if not silent:
2613 2610 self.events.trigger('pre_run_cell')
2614 2611
2615 2612 # If any of our input transformation (input_transformer_manager or
2616 2613 # prefilter_manager) raises an exception, we store it in this variable
2617 2614 # so that we can display the error after logging the input and storing
2618 2615 # it in the history.
2619 2616 preprocessing_exc_tuple = None
2620 2617 try:
2621 2618 # Static input transformations
2622 2619 cell = self.input_transformer_manager.transform_cell(raw_cell)
2623 2620 except SyntaxError:
2624 2621 preprocessing_exc_tuple = sys.exc_info()
2625 2622 cell = raw_cell # cell has to exist so it can be stored/logged
2626 2623 else:
2627 2624 if len(cell.splitlines()) == 1:
2628 2625 # Dynamic transformations - only applied for single line commands
2629 2626 with self.builtin_trap:
2630 2627 try:
2631 2628 # use prefilter_lines to handle trailing newlines
2632 2629 # restore trailing newline for ast.parse
2633 2630 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
2634 2631 except Exception:
2635 2632 # don't allow prefilter errors to crash IPython
2636 2633 preprocessing_exc_tuple = sys.exc_info()
2637 2634
2638 2635 # Store raw and processed history
2639 2636 if store_history:
2640 2637 self.history_manager.store_inputs(self.execution_count,
2641 2638 cell, raw_cell)
2642 2639 if not silent:
2643 2640 self.logger.log(cell, raw_cell)
2644 2641
2645 2642 # Display the exception if input processing failed.
2646 2643 if preprocessing_exc_tuple is not None:
2647 2644 self.showtraceback(preprocessing_exc_tuple)
2648 2645 if store_history:
2649 2646 self.execution_count += 1
2650 2647 return error_before_exec(preprocessing_exc_tuple[2])
2651 2648
2652 2649 # Our own compiler remembers the __future__ environment. If we want to
2653 2650 # run code with a separate __future__ environment, use the default
2654 2651 # compiler
2655 2652 compiler = self.compile if shell_futures else CachingCompiler()
2656 2653
2657 2654 with self.builtin_trap:
2658 2655 cell_name = self.compile.cache(cell, self.execution_count)
2659 2656
2660 2657 with self.display_trap:
2661 2658 # Compile to bytecode
2662 2659 try:
2663 2660 code_ast = compiler.ast_parse(cell, filename=cell_name)
2664 2661 except self.custom_exceptions as e:
2665 2662 etype, value, tb = sys.exc_info()
2666 2663 self.CustomTB(etype, value, tb)
2667 2664 return error_before_exec(e)
2668 2665 except IndentationError as e:
2669 2666 self.showindentationerror()
2670 2667 if store_history:
2671 2668 self.execution_count += 1
2672 2669 return error_before_exec(e)
2673 2670 except (OverflowError, SyntaxError, ValueError, TypeError,
2674 2671 MemoryError) as e:
2675 2672 self.showsyntaxerror()
2676 2673 if store_history:
2677 2674 self.execution_count += 1
2678 2675 return error_before_exec(e)
2679 2676
2680 2677 # Apply AST transformations
2681 2678 try:
2682 2679 code_ast = self.transform_ast(code_ast)
2683 2680 except InputRejected as e:
2684 2681 self.showtraceback()
2685 2682 if store_history:
2686 2683 self.execution_count += 1
2687 2684 return error_before_exec(e)
2688 2685
2689 2686 # Give the displayhook a reference to our ExecutionResult so it
2690 2687 # can fill in the output value.
2691 2688 self.displayhook.exec_result = result
2692 2689
2693 2690 # Execute the user code
2694 2691 interactivity = "none" if silent else self.ast_node_interactivity
2695 2692 has_raised = self.run_ast_nodes(code_ast.body, cell_name,
2696 2693 interactivity=interactivity, compiler=compiler, result=result)
2697 2694
2698 2695 self.last_execution_succeeded = not has_raised
2699 2696
2700 2697 # Reset this so later displayed values do not modify the
2701 2698 # ExecutionResult
2702 2699 self.displayhook.exec_result = None
2703 2700
2704 2701 self.events.trigger('post_execute')
2705 2702 if not silent:
2706 2703 self.events.trigger('post_run_cell')
2707 2704
2708 2705 if store_history:
2709 2706 # Write output to the database. Does nothing unless
2710 2707 # history output logging is enabled.
2711 2708 self.history_manager.store_output(self.execution_count)
2712 2709 # Each cell is a *single* input, regardless of how many lines it has
2713 2710 self.execution_count += 1
2714 2711
2715 2712 return result
2716 2713
2717 2714 def transform_ast(self, node):
2718 2715 """Apply the AST transformations from self.ast_transformers
2719 2716
2720 2717 Parameters
2721 2718 ----------
2722 2719 node : ast.Node
2723 2720 The root node to be transformed. Typically called with the ast.Module
2724 2721 produced by parsing user input.
2725 2722
2726 2723 Returns
2727 2724 -------
2728 2725 An ast.Node corresponding to the node it was called with. Note that it
2729 2726 may also modify the passed object, so don't rely on references to the
2730 2727 original AST.
2731 2728 """
2732 2729 for transformer in self.ast_transformers:
2733 2730 try:
2734 2731 node = transformer.visit(node)
2735 2732 except InputRejected:
2736 2733 # User-supplied AST transformers can reject an input by raising
2737 2734 # an InputRejected. Short-circuit in this case so that we
2738 2735 # don't unregister the transform.
2739 2736 raise
2740 2737 except Exception:
2741 2738 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
2742 2739 self.ast_transformers.remove(transformer)
2743 2740
2744 2741 if self.ast_transformers:
2745 2742 ast.fix_missing_locations(node)
2746 2743 return node
2747 2744
2748 2745
2749 2746 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr',
2750 2747 compiler=compile, result=None):
2751 2748 """Run a sequence of AST nodes. The execution mode depends on the
2752 2749 interactivity parameter.
2753 2750
2754 2751 Parameters
2755 2752 ----------
2756 2753 nodelist : list
2757 2754 A sequence of AST nodes to run.
2758 2755 cell_name : str
2759 2756 Will be passed to the compiler as the filename of the cell. Typically
2760 2757 the value returned by ip.compile.cache(cell).
2761 2758 interactivity : str
2762 2759 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
2763 2760 run interactively (displaying output from expressions). 'last_expr'
2764 2761 will run the last node interactively only if it is an expression (i.e.
2765 2762 expressions in loops or other blocks are not displayed. Other values
2766 2763 for this parameter will raise a ValueError.
2767 2764 compiler : callable
2768 2765 A function with the same interface as the built-in compile(), to turn
2769 2766 the AST nodes into code objects. Default is the built-in compile().
2770 2767 result : ExecutionResult, optional
2771 2768 An object to store exceptions that occur during execution.
2772 2769
2773 2770 Returns
2774 2771 -------
2775 2772 True if an exception occurred while running code, False if it finished
2776 2773 running.
2777 2774 """
2778 2775 if not nodelist:
2779 2776 return
2780 2777
2781 2778 if interactivity == 'last_expr':
2782 2779 if isinstance(nodelist[-1], ast.Expr):
2783 2780 interactivity = "last"
2784 2781 else:
2785 2782 interactivity = "none"
2786 2783
2787 2784 if interactivity == 'none':
2788 2785 to_run_exec, to_run_interactive = nodelist, []
2789 2786 elif interactivity == 'last':
2790 2787 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
2791 2788 elif interactivity == 'all':
2792 2789 to_run_exec, to_run_interactive = [], nodelist
2793 2790 else:
2794 2791 raise ValueError("Interactivity was %r" % interactivity)
2795 2792
2796 2793 try:
2797 2794 for i, node in enumerate(to_run_exec):
2798 2795 mod = ast.Module([node])
2799 2796 code = compiler(mod, cell_name, "exec")
2800 2797 if self.run_code(code, result):
2801 2798 return True
2802 2799
2803 2800 for i, node in enumerate(to_run_interactive):
2804 2801 mod = ast.Interactive([node])
2805 2802 code = compiler(mod, cell_name, "single")
2806 2803 if self.run_code(code, result):
2807 2804 return True
2808 2805
2809 2806 # Flush softspace
2810 2807 if softspace(sys.stdout, 0):
2811 2808 print()
2812 2809
2813 2810 except:
2814 2811 # It's possible to have exceptions raised here, typically by
2815 2812 # compilation of odd code (such as a naked 'return' outside a
2816 2813 # function) that did parse but isn't valid. Typically the exception
2817 2814 # is a SyntaxError, but it's safest just to catch anything and show
2818 2815 # the user a traceback.
2819 2816
2820 2817 # We do only one try/except outside the loop to minimize the impact
2821 2818 # on runtime, and also because if any node in the node list is
2822 2819 # broken, we should stop execution completely.
2823 2820 if result:
2824 2821 result.error_before_exec = sys.exc_info()[1]
2825 2822 self.showtraceback()
2826 2823 return True
2827 2824
2828 2825 return False
2829 2826
2830 2827 def run_code(self, code_obj, result=None):
2831 2828 """Execute a code object.
2832 2829
2833 2830 When an exception occurs, self.showtraceback() is called to display a
2834 2831 traceback.
2835 2832
2836 2833 Parameters
2837 2834 ----------
2838 2835 code_obj : code object
2839 2836 A compiled code object, to be executed
2840 2837 result : ExecutionResult, optional
2841 2838 An object to store exceptions that occur during execution.
2842 2839
2843 2840 Returns
2844 2841 -------
2845 2842 False : successful execution.
2846 2843 True : an error occurred.
2847 2844 """
2848 2845 # Set our own excepthook in case the user code tries to call it
2849 2846 # directly, so that the IPython crash handler doesn't get triggered
2850 2847 old_excepthook, sys.excepthook = sys.excepthook, self.excepthook
2851 2848
2852 2849 # we save the original sys.excepthook in the instance, in case config
2853 2850 # code (such as magics) needs access to it.
2854 2851 self.sys_excepthook = old_excepthook
2855 2852 outflag = 1 # happens in more places, so it's easier as default
2856 2853 try:
2857 2854 try:
2858 2855 self.hooks.pre_run_code_hook()
2859 2856 #rprint('Running code', repr(code_obj)) # dbg
2860 2857 exec(code_obj, self.user_global_ns, self.user_ns)
2861 2858 finally:
2862 2859 # Reset our crash handler in place
2863 2860 sys.excepthook = old_excepthook
2864 2861 except SystemExit as e:
2865 2862 if result is not None:
2866 2863 result.error_in_exec = e
2867 2864 self.showtraceback(exception_only=True)
2868 2865 warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
2869 2866 except self.custom_exceptions:
2870 2867 etype, value, tb = sys.exc_info()
2871 2868 if result is not None:
2872 2869 result.error_in_exec = value
2873 2870 self.CustomTB(etype, value, tb)
2874 2871 except:
2875 2872 if result is not None:
2876 2873 result.error_in_exec = sys.exc_info()[1]
2877 2874 self.showtraceback()
2878 2875 else:
2879 2876 outflag = 0
2880 2877 return outflag
2881 2878
2882 2879 # For backwards compatibility
2883 2880 runcode = run_code
2884 2881
2885 2882 #-------------------------------------------------------------------------
2886 2883 # Things related to GUI support and pylab
2887 2884 #-------------------------------------------------------------------------
2888 2885
2889 2886 active_eventloop = None
2890 2887
2891 2888 def enable_gui(self, gui=None):
2892 2889 raise NotImplementedError('Implement enable_gui in a subclass')
2893 2890
2894 2891 def enable_matplotlib(self, gui=None):
2895 2892 """Enable interactive matplotlib and inline figure support.
2896 2893
2897 2894 This takes the following steps:
2898 2895
2899 2896 1. select the appropriate eventloop and matplotlib backend
2900 2897 2. set up matplotlib for interactive use with that backend
2901 2898 3. configure formatters for inline figure display
2902 2899 4. enable the selected gui eventloop
2903 2900
2904 2901 Parameters
2905 2902 ----------
2906 2903 gui : optional, string
2907 2904 If given, dictates the choice of matplotlib GUI backend to use
2908 2905 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2909 2906 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2910 2907 matplotlib (as dictated by the matplotlib build-time options plus the
2911 2908 user's matplotlibrc configuration file). Note that not all backends
2912 2909 make sense in all contexts, for example a terminal ipython can't
2913 2910 display figures inline.
2914 2911 """
2915 2912 from IPython.core import pylabtools as pt
2916 2913 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
2917 2914
2918 2915 if gui != 'inline':
2919 2916 # If we have our first gui selection, store it
2920 2917 if self.pylab_gui_select is None:
2921 2918 self.pylab_gui_select = gui
2922 2919 # Otherwise if they are different
2923 2920 elif gui != self.pylab_gui_select:
2924 2921 print ('Warning: Cannot change to a different GUI toolkit: %s.'
2925 2922 ' Using %s instead.' % (gui, self.pylab_gui_select))
2926 2923 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
2927 2924
2928 2925 pt.activate_matplotlib(backend)
2929 2926 pt.configure_inline_support(self, backend)
2930 2927
2931 2928 # Now we must activate the gui pylab wants to use, and fix %run to take
2932 2929 # plot updates into account
2933 2930 self.enable_gui(gui)
2934 2931 self.magics_manager.registry['ExecutionMagics'].default_runner = \
2935 2932 pt.mpl_runner(self.safe_execfile)
2936 2933
2937 2934 return gui, backend
2938 2935
2939 2936 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
2940 2937 """Activate pylab support at runtime.
2941 2938
2942 2939 This turns on support for matplotlib, preloads into the interactive
2943 2940 namespace all of numpy and pylab, and configures IPython to correctly
2944 2941 interact with the GUI event loop. The GUI backend to be used can be
2945 2942 optionally selected with the optional ``gui`` argument.
2946 2943
2947 2944 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
2948 2945
2949 2946 Parameters
2950 2947 ----------
2951 2948 gui : optional, string
2952 2949 If given, dictates the choice of matplotlib GUI backend to use
2953 2950 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2954 2951 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2955 2952 matplotlib (as dictated by the matplotlib build-time options plus the
2956 2953 user's matplotlibrc configuration file). Note that not all backends
2957 2954 make sense in all contexts, for example a terminal ipython can't
2958 2955 display figures inline.
2959 2956 import_all : optional, bool, default: True
2960 2957 Whether to do `from numpy import *` and `from pylab import *`
2961 2958 in addition to module imports.
2962 2959 welcome_message : deprecated
2963 2960 This argument is ignored, no welcome message will be displayed.
2964 2961 """
2965 2962 from IPython.core.pylabtools import import_pylab
2966 2963
2967 2964 gui, backend = self.enable_matplotlib(gui)
2968 2965
2969 2966 # We want to prevent the loading of pylab to pollute the user's
2970 2967 # namespace as shown by the %who* magics, so we execute the activation
2971 2968 # code in an empty namespace, and we update *both* user_ns and
2972 2969 # user_ns_hidden with this information.
2973 2970 ns = {}
2974 2971 import_pylab(ns, import_all)
2975 2972 # warn about clobbered names
2976 2973 ignored = {"__builtins__"}
2977 2974 both = set(ns).intersection(self.user_ns).difference(ignored)
2978 2975 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
2979 2976 self.user_ns.update(ns)
2980 2977 self.user_ns_hidden.update(ns)
2981 2978 return gui, backend, clobbered
2982 2979
2983 2980 #-------------------------------------------------------------------------
2984 2981 # Utilities
2985 2982 #-------------------------------------------------------------------------
2986 2983
2987 2984 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
2988 2985 """Expand python variables in a string.
2989 2986
2990 2987 The depth argument indicates how many frames above the caller should
2991 2988 be walked to look for the local namespace where to expand variables.
2992 2989
2993 2990 The global namespace for expansion is always the user's interactive
2994 2991 namespace.
2995 2992 """
2996 2993 ns = self.user_ns.copy()
2997 2994 try:
2998 2995 frame = sys._getframe(depth+1)
2999 2996 except ValueError:
3000 2997 # This is thrown if there aren't that many frames on the stack,
3001 2998 # e.g. if a script called run_line_magic() directly.
3002 2999 pass
3003 3000 else:
3004 3001 ns.update(frame.f_locals)
3005 3002
3006 3003 try:
3007 3004 # We have to use .vformat() here, because 'self' is a valid and common
3008 3005 # name, and expanding **ns for .format() would make it collide with
3009 3006 # the 'self' argument of the method.
3010 3007 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3011 3008 except Exception:
3012 3009 # if formatter couldn't format, just let it go untransformed
3013 3010 pass
3014 3011 return cmd
3015 3012
3016 3013 def mktempfile(self, data=None, prefix='ipython_edit_'):
3017 3014 """Make a new tempfile and return its filename.
3018 3015
3019 3016 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3020 3017 but it registers the created filename internally so ipython cleans it up
3021 3018 at exit time.
3022 3019
3023 3020 Optional inputs:
3024 3021
3025 3022 - data(None): if data is given, it gets written out to the temp file
3026 3023 immediately, and the file is closed again."""
3027 3024
3028 3025 dirname = tempfile.mkdtemp(prefix=prefix)
3029 3026 self.tempdirs.append(dirname)
3030 3027
3031 3028 handle, filename = tempfile.mkstemp('.py', prefix, dir=dirname)
3032 3029 os.close(handle) # On Windows, there can only be one open handle on a file
3033 3030 self.tempfiles.append(filename)
3034 3031
3035 3032 if data:
3036 3033 tmp_file = open(filename,'w')
3037 3034 tmp_file.write(data)
3038 3035 tmp_file.close()
3039 3036 return filename
3040 3037
3041 3038 @undoc
3042 3039 def write(self,data):
3043 3040 """DEPRECATED: Write a string to the default output"""
3044 3041 warn('InteractiveShell.write() is deprecated, use sys.stdout instead',
3045 3042 DeprecationWarning, stacklevel=2)
3046 3043 sys.stdout.write(data)
3047 3044
3048 3045 @undoc
3049 3046 def write_err(self,data):
3050 3047 """DEPRECATED: Write a string to the default error output"""
3051 3048 warn('InteractiveShell.write_err() is deprecated, use sys.stderr instead',
3052 3049 DeprecationWarning, stacklevel=2)
3053 3050 sys.stderr.write(data)
3054 3051
3055 3052 def ask_yes_no(self, prompt, default=None, interrupt=None):
3056 3053 if self.quiet:
3057 3054 return True
3058 3055 return ask_yes_no(prompt,default,interrupt)
3059 3056
3060 3057 def show_usage(self):
3061 3058 """Show a usage message"""
3062 3059 page.page(IPython.core.usage.interactive_usage)
3063 3060
3064 3061 def extract_input_lines(self, range_str, raw=False):
3065 3062 """Return as a string a set of input history slices.
3066 3063
3067 3064 Parameters
3068 3065 ----------
3069 3066 range_str : string
3070 3067 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3071 3068 since this function is for use by magic functions which get their
3072 3069 arguments as strings. The number before the / is the session
3073 3070 number: ~n goes n back from the current session.
3074 3071
3075 3072 raw : bool, optional
3076 3073 By default, the processed input is used. If this is true, the raw
3077 3074 input history is used instead.
3078 3075
3079 3076 Notes
3080 3077 -----
3081 3078
3082 3079 Slices can be described with two notations:
3083 3080
3084 3081 * ``N:M`` -> standard python form, means including items N...(M-1).
3085 3082 * ``N-M`` -> include items N..M (closed endpoint).
3086 3083 """
3087 3084 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3088 3085 return "\n".join(x for _, _, x in lines)
3089 3086
3090 3087 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False):
3091 3088 """Get a code string from history, file, url, or a string or macro.
3092 3089
3093 3090 This is mainly used by magic functions.
3094 3091
3095 3092 Parameters
3096 3093 ----------
3097 3094
3098 3095 target : str
3099 3096
3100 3097 A string specifying code to retrieve. This will be tried respectively
3101 3098 as: ranges of input history (see %history for syntax), url,
3102 3099 corresponding .py file, filename, or an expression evaluating to a
3103 3100 string or Macro in the user namespace.
3104 3101
3105 3102 raw : bool
3106 3103 If true (default), retrieve raw history. Has no effect on the other
3107 3104 retrieval mechanisms.
3108 3105
3109 3106 py_only : bool (default False)
3110 3107 Only try to fetch python code, do not try alternative methods to decode file
3111 3108 if unicode fails.
3112 3109
3113 3110 Returns
3114 3111 -------
3115 3112 A string of code.
3116 3113
3117 3114 ValueError is raised if nothing is found, and TypeError if it evaluates
3118 3115 to an object of another type. In each case, .args[0] is a printable
3119 3116 message.
3120 3117 """
3121 3118 code = self.extract_input_lines(target, raw=raw) # Grab history
3122 3119 if code:
3123 3120 return code
3124 3121 try:
3125 3122 if target.startswith(('http://', 'https://')):
3126 3123 return openpy.read_py_url(target, skip_encoding_cookie=skip_encoding_cookie)
3127 3124 except UnicodeDecodeError:
3128 3125 if not py_only :
3129 3126 # Deferred import
3130 3127 try:
3131 3128 from urllib.request import urlopen # Py3
3132 3129 except ImportError:
3133 3130 from urllib import urlopen
3134 3131 response = urlopen(target)
3135 3132 return response.read().decode('latin1')
3136 3133 raise ValueError(("'%s' seem to be unreadable.") % target)
3137 3134
3138 3135 potential_target = [target]
3139 3136 try :
3140 3137 potential_target.insert(0,get_py_filename(target))
3141 3138 except IOError:
3142 3139 pass
3143 3140
3144 3141 for tgt in potential_target :
3145 3142 if os.path.isfile(tgt): # Read file
3146 3143 try :
3147 3144 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3148 3145 except UnicodeDecodeError :
3149 3146 if not py_only :
3150 3147 with io_open(tgt,'r', encoding='latin1') as f :
3151 3148 return f.read()
3152 3149 raise ValueError(("'%s' seem to be unreadable.") % target)
3153 3150 elif os.path.isdir(os.path.expanduser(tgt)):
3154 3151 raise ValueError("'%s' is a directory, not a regular file." % target)
3155 3152
3156 3153 if search_ns:
3157 3154 # Inspect namespace to load object source
3158 3155 object_info = self.object_inspect(target, detail_level=1)
3159 3156 if object_info['found'] and object_info['source']:
3160 3157 return object_info['source']
3161 3158
3162 3159 try: # User namespace
3163 3160 codeobj = eval(target, self.user_ns)
3164 3161 except Exception:
3165 3162 raise ValueError(("'%s' was not found in history, as a file, url, "
3166 3163 "nor in the user namespace.") % target)
3167 3164
3168 if isinstance(codeobj, string_types):
3165 if isinstance(codeobj, str):
3169 3166 return codeobj
3170 3167 elif isinstance(codeobj, Macro):
3171 3168 return codeobj.value
3172 3169
3173 3170 raise TypeError("%s is neither a string nor a macro." % target,
3174 3171 codeobj)
3175 3172
3176 3173 #-------------------------------------------------------------------------
3177 3174 # Things related to IPython exiting
3178 3175 #-------------------------------------------------------------------------
3179 3176 def atexit_operations(self):
3180 3177 """This will be executed at the time of exit.
3181 3178
3182 3179 Cleanup operations and saving of persistent data that is done
3183 3180 unconditionally by IPython should be performed here.
3184 3181
3185 3182 For things that may depend on startup flags or platform specifics (such
3186 3183 as having readline or not), register a separate atexit function in the
3187 3184 code that has the appropriate information, rather than trying to
3188 3185 clutter
3189 3186 """
3190 3187 # Close the history session (this stores the end time and line count)
3191 3188 # this must be *before* the tempfile cleanup, in case of temporary
3192 3189 # history db
3193 3190 self.history_manager.end_session()
3194 3191
3195 3192 # Cleanup all tempfiles and folders left around
3196 3193 for tfile in self.tempfiles:
3197 3194 try:
3198 3195 os.unlink(tfile)
3199 3196 except OSError:
3200 3197 pass
3201 3198
3202 3199 for tdir in self.tempdirs:
3203 3200 try:
3204 3201 os.rmdir(tdir)
3205 3202 except OSError:
3206 3203 pass
3207 3204
3208 3205 # Clear all user namespaces to release all references cleanly.
3209 3206 self.reset(new_session=False)
3210 3207
3211 3208 # Run user hooks
3212 3209 self.hooks.shutdown_hook()
3213 3210
3214 3211 def cleanup(self):
3215 3212 self.restore_sys_module_state()
3216 3213
3217 3214
3218 3215 # Overridden in terminal subclass to change prompts
3219 3216 def switch_doctest_mode(self, mode):
3220 3217 pass
3221 3218
3222 3219
3223 3220 class InteractiveShellABC(with_metaclass(abc.ABCMeta, object)):
3224 3221 """An abstract base class for InteractiveShell."""
3225 3222
3226 3223 InteractiveShellABC.register(InteractiveShell)
@@ -1,220 +1,218 b''
1 1 """Logger class for IPython's logging facilities.
2 2 """
3 3
4 4 #*****************************************************************************
5 5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
6 6 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
7 7 #
8 8 # Distributed under the terms of the BSD License. The full license is in
9 9 # the file COPYING, distributed as part of this software.
10 10 #*****************************************************************************
11 11
12 12 #****************************************************************************
13 13 # Modules and globals
14 14
15 15 # Python standard modules
16 16 import glob
17 17 import io
18 18 import os
19 19 import time
20 20
21 from IPython.utils.py3compat import str_to_unicode
22 21
23 22 #****************************************************************************
24 23 # FIXME: This class isn't a mixin anymore, but it still needs attributes from
25 24 # ipython and does input cache management. Finish cleanup later...
26 25
27 26 class Logger(object):
28 27 """A Logfile class with different policies for file creation"""
29 28
30 29 def __init__(self, home_dir, logfname='Logger.log', loghead=u'',
31 30 logmode='over'):
32 31
33 32 # this is the full ipython instance, we need some attributes from it
34 33 # which won't exist until later. What a mess, clean up later...
35 34 self.home_dir = home_dir
36 35
37 36 self.logfname = logfname
38 37 self.loghead = loghead
39 38 self.logmode = logmode
40 39 self.logfile = None
41 40
42 41 # Whether to log raw or processed input
43 42 self.log_raw_input = False
44 43
45 44 # whether to also log output
46 45 self.log_output = False
47 46
48 47 # whether to put timestamps before each log entry
49 48 self.timestamp = False
50 49
51 50 # activity control flags
52 51 self.log_active = False
53 52
54 53 # logmode is a validated property
55 54 def _set_mode(self,mode):
56 55 if mode not in ['append','backup','global','over','rotate']:
57 56 raise ValueError('invalid log mode %s given' % mode)
58 57 self._logmode = mode
59 58
60 59 def _get_mode(self):
61 60 return self._logmode
62 61
63 62 logmode = property(_get_mode,_set_mode)
64 63
65 64 def logstart(self, logfname=None, loghead=None, logmode=None,
66 65 log_output=False, timestamp=False, log_raw_input=False):
67 66 """Generate a new log-file with a default header.
68 67
69 68 Raises RuntimeError if the log has already been started"""
70 69
71 70 if self.logfile is not None:
72 71 raise RuntimeError('Log file is already active: %s' %
73 72 self.logfname)
74 73
75 74 # The parameters can override constructor defaults
76 75 if logfname is not None: self.logfname = logfname
77 76 if loghead is not None: self.loghead = loghead
78 77 if logmode is not None: self.logmode = logmode
79 78
80 79 # Parameters not part of the constructor
81 80 self.timestamp = timestamp
82 81 self.log_output = log_output
83 82 self.log_raw_input = log_raw_input
84 83
85 84 # init depending on the log mode requested
86 85 isfile = os.path.isfile
87 86 logmode = self.logmode
88 87
89 88 if logmode == 'append':
90 89 self.logfile = io.open(self.logfname, 'a', encoding='utf-8')
91 90
92 91 elif logmode == 'backup':
93 92 if isfile(self.logfname):
94 93 backup_logname = self.logfname+'~'
95 94 # Manually remove any old backup, since os.rename may fail
96 95 # under Windows.
97 96 if isfile(backup_logname):
98 97 os.remove(backup_logname)
99 98 os.rename(self.logfname,backup_logname)
100 99 self.logfile = io.open(self.logfname, 'w', encoding='utf-8')
101 100
102 101 elif logmode == 'global':
103 102 self.logfname = os.path.join(self.home_dir,self.logfname)
104 103 self.logfile = io.open(self.logfname, 'a', encoding='utf-8')
105 104
106 105 elif logmode == 'over':
107 106 if isfile(self.logfname):
108 107 os.remove(self.logfname)
109 108 self.logfile = io.open(self.logfname,'w', encoding='utf-8')
110 109
111 110 elif logmode == 'rotate':
112 111 if isfile(self.logfname):
113 112 if isfile(self.logfname+'.001~'):
114 113 old = glob.glob(self.logfname+'.*~')
115 114 old.sort()
116 115 old.reverse()
117 116 for f in old:
118 117 root, ext = os.path.splitext(f)
119 118 num = int(ext[1:-1])+1
120 119 os.rename(f, root+'.'+repr(num).zfill(3)+'~')
121 120 os.rename(self.logfname, self.logfname+'.001~')
122 121 self.logfile = io.open(self.logfname, 'w', encoding='utf-8')
123 122
124 123 if logmode != 'append':
125 124 self.logfile.write(self.loghead)
126 125
127 126 self.logfile.flush()
128 127 self.log_active = True
129 128
130 129 def switch_log(self,val):
131 130 """Switch logging on/off. val should be ONLY a boolean."""
132 131
133 132 if val not in [False,True,0,1]:
134 133 raise ValueError('Call switch_log ONLY with a boolean argument, '
135 134 'not with: %s' % val)
136 135
137 136 label = {0:'OFF',1:'ON',False:'OFF',True:'ON'}
138 137
139 138 if self.logfile is None:
140 139 print("""
141 140 Logging hasn't been started yet (use logstart for that).
142 141
143 142 %logon/%logoff are for temporarily starting and stopping logging for a logfile
144 143 which already exists. But you must first start the logging process with
145 144 %logstart (optionally giving a logfile name).""")
146 145
147 146 else:
148 147 if self.log_active == val:
149 148 print('Logging is already',label[val])
150 149 else:
151 150 print('Switching logging',label[val])
152 151 self.log_active = not self.log_active
153 152 self.log_active_out = self.log_active
154 153
155 154 def logstate(self):
156 155 """Print a status message about the logger."""
157 156 if self.logfile is None:
158 157 print('Logging has not been activated.')
159 158 else:
160 159 state = self.log_active and 'active' or 'temporarily suspended'
161 160 print('Filename :', self.logfname)
162 161 print('Mode :', self.logmode)
163 162 print('Output logging :', self.log_output)
164 163 print('Raw input log :', self.log_raw_input)
165 164 print('Timestamping :', self.timestamp)
166 165 print('State :', state)
167 166
168 167 def log(self, line_mod, line_ori):
169 168 """Write the sources to a log.
170 169
171 170 Inputs:
172 171
173 172 - line_mod: possibly modified input, such as the transformations made
174 173 by input prefilters or input handlers of various kinds. This should
175 174 always be valid Python.
176 175
177 176 - line_ori: unmodified input line from the user. This is not
178 177 necessarily valid Python.
179 178 """
180 179
181 180 # Write the log line, but decide which one according to the
182 181 # log_raw_input flag, set when the log is started.
183 182 if self.log_raw_input:
184 183 self.log_write(line_ori)
185 184 else:
186 185 self.log_write(line_mod)
187 186
188 187 def log_write(self, data, kind='input'):
189 188 """Write data to the log file, if active"""
190 189
191 190 #print 'data: %r' % data # dbg
192 191 if self.log_active and data:
193 192 write = self.logfile.write
194 193 if kind=='input':
195 194 if self.timestamp:
196 write(str_to_unicode(time.strftime('# %a, %d %b %Y %H:%M:%S\n',
197 time.localtime())))
195 write(time.strftime('# %a, %d %b %Y %H:%M:%S\n', time.localtime()))
198 196 write(data)
199 197 elif kind=='output' and self.log_output:
200 198 odata = u'\n'.join([u'#[Out]# %s' % s
201 199 for s in data.splitlines()])
202 200 write(u'%s\n' % odata)
203 201 self.logfile.flush()
204 202
205 203 def logstop(self):
206 204 """Fully stop logging and close log file.
207 205
208 206 In order to start logging again, a new logstart() call needs to be
209 207 made, possibly (though not necessarily) with a new filename, mode and
210 208 other options."""
211 209
212 210 if self.logfile is not None:
213 211 self.logfile.close()
214 212 self.logfile = None
215 213 else:
216 214 print("Logging hadn't been started.")
217 215 self.log_active = False
218 216
219 217 # For backwards compatibility, in case anyone was using this.
220 218 close_log = logstop
@@ -1,57 +1,57 b''
1 1 """Support for interactive macros in IPython"""
2 2
3 3 #*****************************************************************************
4 4 # Copyright (C) 2001-2005 Fernando Perez <fperez@colorado.edu>
5 5 #
6 6 # Distributed under the terms of the BSD License. The full license is in
7 7 # the file COPYING, distributed as part of this software.
8 8 #*****************************************************************************
9 9
10 10 import re
11 11
12 12 from IPython.utils import py3compat
13 13 from IPython.utils.encoding import DEFAULT_ENCODING
14 14
15 15 coding_declaration = re.compile(r"#\s*coding[:=]\s*([-\w.]+)")
16 16
17 17 class Macro(object):
18 18 """Simple class to store the value of macros as strings.
19 19
20 20 Macro is just a callable that executes a string of IPython
21 21 input when called.
22 22 """
23 23
24 24 def __init__(self,code):
25 25 """store the macro value, as a single string which can be executed"""
26 26 lines = []
27 27 enc = None
28 28 for line in code.splitlines():
29 29 coding_match = coding_declaration.match(line)
30 30 if coding_match:
31 31 enc = coding_match.group(1)
32 32 else:
33 33 lines.append(line)
34 34 code = "\n".join(lines)
35 35 if isinstance(code, bytes):
36 36 code = code.decode(enc or DEFAULT_ENCODING)
37 37 self.value = code + '\n'
38 38
39 39 def __str__(self):
40 return py3compat.unicode_to_str(self.value)
40 return self.value
41 41
42 42 def __unicode__(self):
43 43 return self.value
44 44
45 45 def __repr__(self):
46 46 return 'IPython.macro.Macro(%s)' % repr(self.value)
47 47
48 48 def __getstate__(self):
49 49 """ needed for safe pickling via %store """
50 50 return {'value': self.value}
51 51
52 52 def __add__(self, other):
53 53 if isinstance(other, Macro):
54 54 return Macro(self.value + other.value)
55 elif isinstance(other, py3compat.string_types):
55 elif isinstance(other, str):
56 56 return Macro(self.value + other)
57 57 raise TypeError
@@ -1,679 +1,678 b''
1 1 # encoding: utf-8
2 2 """Magic functions for InteractiveShell.
3 3 """
4 4
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
7 7 # Copyright (C) 2001 Fernando Perez <fperez@colorado.edu>
8 8 # Copyright (C) 2008 The IPython Development Team
9 9
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #-----------------------------------------------------------------------------
13 13
14 14 import os
15 15 import re
16 16 import sys
17 17 import types
18 18 from getopt import getopt, GetoptError
19 19
20 20 from traitlets.config.configurable import Configurable
21 21 from IPython.core import oinspect
22 22 from IPython.core.error import UsageError
23 23 from IPython.core.inputsplitter import ESC_MAGIC, ESC_MAGIC2
24 24 from decorator import decorator
25 25 from IPython.utils.ipstruct import Struct
26 26 from IPython.utils.process import arg_split
27 from IPython.utils.py3compat import string_types, iteritems
28 27 from IPython.utils.text import dedent
29 28 from traitlets import Bool, Dict, Instance, observe
30 29 from logging import error
31 30
32 31 #-----------------------------------------------------------------------------
33 32 # Globals
34 33 #-----------------------------------------------------------------------------
35 34
36 35 # A dict we'll use for each class that has magics, used as temporary storage to
37 36 # pass information between the @line/cell_magic method decorators and the
38 37 # @magics_class class decorator, because the method decorators have no
39 38 # access to the class when they run. See for more details:
40 39 # http://stackoverflow.com/questions/2366713/can-a-python-decorator-of-an-instance-method-access-the-class
41 40
42 41 magics = dict(line={}, cell={})
43 42
44 43 magic_kinds = ('line', 'cell')
45 44 magic_spec = ('line', 'cell', 'line_cell')
46 45 magic_escapes = dict(line=ESC_MAGIC, cell=ESC_MAGIC2)
47 46
48 47 #-----------------------------------------------------------------------------
49 48 # Utility classes and functions
50 49 #-----------------------------------------------------------------------------
51 50
52 51 class Bunch: pass
53 52
54 53
55 54 def on_off(tag):
56 55 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
57 56 return ['OFF','ON'][tag]
58 57
59 58
60 59 def compress_dhist(dh):
61 60 """Compress a directory history into a new one with at most 20 entries.
62 61
63 62 Return a new list made from the first and last 10 elements of dhist after
64 63 removal of duplicates.
65 64 """
66 65 head, tail = dh[:-10], dh[-10:]
67 66
68 67 newhead = []
69 68 done = set()
70 69 for h in head:
71 70 if h in done:
72 71 continue
73 72 newhead.append(h)
74 73 done.add(h)
75 74
76 75 return newhead + tail
77 76
78 77
79 78 def needs_local_scope(func):
80 79 """Decorator to mark magic functions which need to local scope to run."""
81 80 func.needs_local_scope = True
82 81 return func
83 82
84 83 #-----------------------------------------------------------------------------
85 84 # Class and method decorators for registering magics
86 85 #-----------------------------------------------------------------------------
87 86
88 87 def magics_class(cls):
89 88 """Class decorator for all subclasses of the main Magics class.
90 89
91 90 Any class that subclasses Magics *must* also apply this decorator, to
92 91 ensure that all the methods that have been decorated as line/cell magics
93 92 get correctly registered in the class instance. This is necessary because
94 93 when method decorators run, the class does not exist yet, so they
95 94 temporarily store their information into a module global. Application of
96 95 this class decorator copies that global data to the class instance and
97 96 clears the global.
98 97
99 98 Obviously, this mechanism is not thread-safe, which means that the
100 99 *creation* of subclasses of Magic should only be done in a single-thread
101 100 context. Instantiation of the classes has no restrictions. Given that
102 101 these classes are typically created at IPython startup time and before user
103 102 application code becomes active, in practice this should not pose any
104 103 problems.
105 104 """
106 105 cls.registered = True
107 106 cls.magics = dict(line = magics['line'],
108 107 cell = magics['cell'])
109 108 magics['line'] = {}
110 109 magics['cell'] = {}
111 110 return cls
112 111
113 112
114 113 def record_magic(dct, magic_kind, magic_name, func):
115 114 """Utility function to store a function as a magic of a specific kind.
116 115
117 116 Parameters
118 117 ----------
119 118 dct : dict
120 119 A dictionary with 'line' and 'cell' subdicts.
121 120
122 121 magic_kind : str
123 122 Kind of magic to be stored.
124 123
125 124 magic_name : str
126 125 Key to store the magic as.
127 126
128 127 func : function
129 128 Callable object to store.
130 129 """
131 130 if magic_kind == 'line_cell':
132 131 dct['line'][magic_name] = dct['cell'][magic_name] = func
133 132 else:
134 133 dct[magic_kind][magic_name] = func
135 134
136 135
137 136 def validate_type(magic_kind):
138 137 """Ensure that the given magic_kind is valid.
139 138
140 139 Check that the given magic_kind is one of the accepted spec types (stored
141 140 in the global `magic_spec`), raise ValueError otherwise.
142 141 """
143 142 if magic_kind not in magic_spec:
144 143 raise ValueError('magic_kind must be one of %s, %s given' %
145 144 magic_kinds, magic_kind)
146 145
147 146
148 147 # The docstrings for the decorator below will be fairly similar for the two
149 148 # types (method and function), so we generate them here once and reuse the
150 149 # templates below.
151 150 _docstring_template = \
152 151 """Decorate the given {0} as {1} magic.
153 152
154 153 The decorator can be used with or without arguments, as follows.
155 154
156 155 i) without arguments: it will create a {1} magic named as the {0} being
157 156 decorated::
158 157
159 158 @deco
160 159 def foo(...)
161 160
162 161 will create a {1} magic named `foo`.
163 162
164 163 ii) with one string argument: which will be used as the actual name of the
165 164 resulting magic::
166 165
167 166 @deco('bar')
168 167 def foo(...)
169 168
170 169 will create a {1} magic named `bar`.
171 170 """
172 171
173 172 # These two are decorator factories. While they are conceptually very similar,
174 173 # there are enough differences in the details that it's simpler to have them
175 174 # written as completely standalone functions rather than trying to share code
176 175 # and make a single one with convoluted logic.
177 176
178 177 def _method_magic_marker(magic_kind):
179 178 """Decorator factory for methods in Magics subclasses.
180 179 """
181 180
182 181 validate_type(magic_kind)
183 182
184 183 # This is a closure to capture the magic_kind. We could also use a class,
185 184 # but it's overkill for just that one bit of state.
186 185 def magic_deco(arg):
187 186 call = lambda f, *a, **k: f(*a, **k)
188 187
189 188 if callable(arg):
190 189 # "Naked" decorator call (just @foo, no args)
191 190 func = arg
192 191 name = func.__name__
193 192 retval = decorator(call, func)
194 193 record_magic(magics, magic_kind, name, name)
195 elif isinstance(arg, string_types):
194 elif isinstance(arg, str):
196 195 # Decorator called with arguments (@foo('bar'))
197 196 name = arg
198 197 def mark(func, *a, **kw):
199 198 record_magic(magics, magic_kind, name, func.__name__)
200 199 return decorator(call, func)
201 200 retval = mark
202 201 else:
203 202 raise TypeError("Decorator can only be called with "
204 203 "string or function")
205 204 return retval
206 205
207 206 # Ensure the resulting decorator has a usable docstring
208 207 magic_deco.__doc__ = _docstring_template.format('method', magic_kind)
209 208 return magic_deco
210 209
211 210
212 211 def _function_magic_marker(magic_kind):
213 212 """Decorator factory for standalone functions.
214 213 """
215 214 validate_type(magic_kind)
216 215
217 216 # This is a closure to capture the magic_kind. We could also use a class,
218 217 # but it's overkill for just that one bit of state.
219 218 def magic_deco(arg):
220 219 call = lambda f, *a, **k: f(*a, **k)
221 220
222 221 # Find get_ipython() in the caller's namespace
223 222 caller = sys._getframe(1)
224 223 for ns in ['f_locals', 'f_globals', 'f_builtins']:
225 224 get_ipython = getattr(caller, ns).get('get_ipython')
226 225 if get_ipython is not None:
227 226 break
228 227 else:
229 228 raise NameError('Decorator can only run in context where '
230 229 '`get_ipython` exists')
231 230
232 231 ip = get_ipython()
233 232
234 233 if callable(arg):
235 234 # "Naked" decorator call (just @foo, no args)
236 235 func = arg
237 236 name = func.__name__
238 237 ip.register_magic_function(func, magic_kind, name)
239 238 retval = decorator(call, func)
240 elif isinstance(arg, string_types):
239 elif isinstance(arg, str):
241 240 # Decorator called with arguments (@foo('bar'))
242 241 name = arg
243 242 def mark(func, *a, **kw):
244 243 ip.register_magic_function(func, magic_kind, name)
245 244 return decorator(call, func)
246 245 retval = mark
247 246 else:
248 247 raise TypeError("Decorator can only be called with "
249 248 "string or function")
250 249 return retval
251 250
252 251 # Ensure the resulting decorator has a usable docstring
253 252 ds = _docstring_template.format('function', magic_kind)
254 253
255 254 ds += dedent("""
256 255 Note: this decorator can only be used in a context where IPython is already
257 256 active, so that the `get_ipython()` call succeeds. You can therefore use
258 257 it in your startup files loaded after IPython initializes, but *not* in the
259 258 IPython configuration file itself, which is executed before IPython is
260 259 fully up and running. Any file located in the `startup` subdirectory of
261 260 your configuration profile will be OK in this sense.
262 261 """)
263 262
264 263 magic_deco.__doc__ = ds
265 264 return magic_deco
266 265
267 266
268 267 # Create the actual decorators for public use
269 268
270 269 # These three are used to decorate methods in class definitions
271 270 line_magic = _method_magic_marker('line')
272 271 cell_magic = _method_magic_marker('cell')
273 272 line_cell_magic = _method_magic_marker('line_cell')
274 273
275 274 # These three decorate standalone functions and perform the decoration
276 275 # immediately. They can only run where get_ipython() works
277 276 register_line_magic = _function_magic_marker('line')
278 277 register_cell_magic = _function_magic_marker('cell')
279 278 register_line_cell_magic = _function_magic_marker('line_cell')
280 279
281 280 #-----------------------------------------------------------------------------
282 281 # Core Magic classes
283 282 #-----------------------------------------------------------------------------
284 283
285 284 class MagicsManager(Configurable):
286 285 """Object that handles all magic-related functionality for IPython.
287 286 """
288 287 # Non-configurable class attributes
289 288
290 289 # A two-level dict, first keyed by magic type, then by magic function, and
291 290 # holding the actual callable object as value. This is the dict used for
292 291 # magic function dispatch
293 292 magics = Dict()
294 293
295 294 # A registry of the original objects that we've been given holding magics.
296 295 registry = Dict()
297 296
298 297 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
299 298
300 299 auto_magic = Bool(True, help=
301 300 "Automatically call line magics without requiring explicit % prefix"
302 301 ).tag(config=True)
303 302 @observe('auto_magic')
304 303 def _auto_magic_changed(self, change):
305 304 self.shell.automagic = change['new']
306 305
307 306 _auto_status = [
308 307 'Automagic is OFF, % prefix IS needed for line magics.',
309 308 'Automagic is ON, % prefix IS NOT needed for line magics.']
310 309
311 310 user_magics = Instance('IPython.core.magics.UserMagics', allow_none=True)
312 311
313 312 def __init__(self, shell=None, config=None, user_magics=None, **traits):
314 313
315 314 super(MagicsManager, self).__init__(shell=shell, config=config,
316 315 user_magics=user_magics, **traits)
317 316 self.magics = dict(line={}, cell={})
318 317 # Let's add the user_magics to the registry for uniformity, so *all*
319 318 # registered magic containers can be found there.
320 319 self.registry[user_magics.__class__.__name__] = user_magics
321 320
322 321 def auto_status(self):
323 322 """Return descriptive string with automagic status."""
324 323 return self._auto_status[self.auto_magic]
325 324
326 325 def lsmagic(self):
327 326 """Return a dict of currently available magic functions.
328 327
329 328 The return dict has the keys 'line' and 'cell', corresponding to the
330 329 two types of magics we support. Each value is a list of names.
331 330 """
332 331 return self.magics
333 332
334 333 def lsmagic_docs(self, brief=False, missing=''):
335 334 """Return dict of documentation of magic functions.
336 335
337 336 The return dict has the keys 'line' and 'cell', corresponding to the
338 337 two types of magics we support. Each value is a dict keyed by magic
339 338 name whose value is the function docstring. If a docstring is
340 339 unavailable, the value of `missing` is used instead.
341 340
342 341 If brief is True, only the first line of each docstring will be returned.
343 342 """
344 343 docs = {}
345 344 for m_type in self.magics:
346 345 m_docs = {}
347 for m_name, m_func in iteritems(self.magics[m_type]):
346 for m_name, m_func in self.magics[m_type].items():
348 347 if m_func.__doc__:
349 348 if brief:
350 349 m_docs[m_name] = m_func.__doc__.split('\n', 1)[0]
351 350 else:
352 351 m_docs[m_name] = m_func.__doc__.rstrip()
353 352 else:
354 353 m_docs[m_name] = missing
355 354 docs[m_type] = m_docs
356 355 return docs
357 356
358 357 def register(self, *magic_objects):
359 358 """Register one or more instances of Magics.
360 359
361 360 Take one or more classes or instances of classes that subclass the main
362 361 `core.Magic` class, and register them with IPython to use the magic
363 362 functions they provide. The registration process will then ensure that
364 363 any methods that have decorated to provide line and/or cell magics will
365 364 be recognized with the `%x`/`%%x` syntax as a line/cell magic
366 365 respectively.
367 366
368 367 If classes are given, they will be instantiated with the default
369 368 constructor. If your classes need a custom constructor, you should
370 369 instanitate them first and pass the instance.
371 370
372 371 The provided arguments can be an arbitrary mix of classes and instances.
373 372
374 373 Parameters
375 374 ----------
376 375 magic_objects : one or more classes or instances
377 376 """
378 377 # Start by validating them to ensure they have all had their magic
379 378 # methods registered at the instance level
380 379 for m in magic_objects:
381 380 if not m.registered:
382 381 raise ValueError("Class of magics %r was constructed without "
383 382 "the @register_magics class decorator")
384 383 if isinstance(m, type):
385 384 # If we're given an uninstantiated class
386 385 m = m(shell=self.shell)
387 386
388 387 # Now that we have an instance, we can register it and update the
389 388 # table of callables
390 389 self.registry[m.__class__.__name__] = m
391 390 for mtype in magic_kinds:
392 391 self.magics[mtype].update(m.magics[mtype])
393 392
394 393 def register_function(self, func, magic_kind='line', magic_name=None):
395 394 """Expose a standalone function as magic function for IPython.
396 395
397 396 This will create an IPython magic (line, cell or both) from a
398 397 standalone function. The functions should have the following
399 398 signatures:
400 399
401 400 * For line magics: `def f(line)`
402 401 * For cell magics: `def f(line, cell)`
403 402 * For a function that does both: `def f(line, cell=None)`
404 403
405 404 In the latter case, the function will be called with `cell==None` when
406 405 invoked as `%f`, and with cell as a string when invoked as `%%f`.
407 406
408 407 Parameters
409 408 ----------
410 409 func : callable
411 410 Function to be registered as a magic.
412 411
413 412 magic_kind : str
414 413 Kind of magic, one of 'line', 'cell' or 'line_cell'
415 414
416 415 magic_name : optional str
417 416 If given, the name the magic will have in the IPython namespace. By
418 417 default, the name of the function itself is used.
419 418 """
420 419
421 420 # Create the new method in the user_magics and register it in the
422 421 # global table
423 422 validate_type(magic_kind)
424 423 magic_name = func.__name__ if magic_name is None else magic_name
425 424 setattr(self.user_magics, magic_name, func)
426 425 record_magic(self.magics, magic_kind, magic_name, func)
427 426
428 427 def register_alias(self, alias_name, magic_name, magic_kind='line'):
429 428 """Register an alias to a magic function.
430 429
431 430 The alias is an instance of :class:`MagicAlias`, which holds the
432 431 name and kind of the magic it should call. Binding is done at
433 432 call time, so if the underlying magic function is changed the alias
434 433 will call the new function.
435 434
436 435 Parameters
437 436 ----------
438 437 alias_name : str
439 438 The name of the magic to be registered.
440 439
441 440 magic_name : str
442 441 The name of an existing magic.
443 442
444 443 magic_kind : str
445 444 Kind of magic, one of 'line' or 'cell'
446 445 """
447 446
448 447 # `validate_type` is too permissive, as it allows 'line_cell'
449 448 # which we do not handle.
450 449 if magic_kind not in magic_kinds:
451 450 raise ValueError('magic_kind must be one of %s, %s given' %
452 451 magic_kinds, magic_kind)
453 452
454 453 alias = MagicAlias(self.shell, magic_name, magic_kind)
455 454 setattr(self.user_magics, alias_name, alias)
456 455 record_magic(self.magics, magic_kind, alias_name, alias)
457 456
458 457 # Key base class that provides the central functionality for magics.
459 458
460 459
461 460 class Magics(Configurable):
462 461 """Base class for implementing magic functions.
463 462
464 463 Shell functions which can be reached as %function_name. All magic
465 464 functions should accept a string, which they can parse for their own
466 465 needs. This can make some functions easier to type, eg `%cd ../`
467 466 vs. `%cd("../")`
468 467
469 468 Classes providing magic functions need to subclass this class, and they
470 469 MUST:
471 470
472 471 - Use the method decorators `@line_magic` and `@cell_magic` to decorate
473 472 individual methods as magic functions, AND
474 473
475 474 - Use the class decorator `@magics_class` to ensure that the magic
476 475 methods are properly registered at the instance level upon instance
477 476 initialization.
478 477
479 478 See :mod:`magic_functions` for examples of actual implementation classes.
480 479 """
481 480 # Dict holding all command-line options for each magic.
482 481 options_table = None
483 482 # Dict for the mapping of magic names to methods, set by class decorator
484 483 magics = None
485 484 # Flag to check that the class decorator was properly applied
486 485 registered = False
487 486 # Instance of IPython shell
488 487 shell = None
489 488
490 489 def __init__(self, shell=None, **kwargs):
491 490 if not(self.__class__.registered):
492 491 raise ValueError('Magics subclass without registration - '
493 492 'did you forget to apply @magics_class?')
494 493 if shell is not None:
495 494 if hasattr(shell, 'configurables'):
496 495 shell.configurables.append(self)
497 496 if hasattr(shell, 'config'):
498 497 kwargs.setdefault('parent', shell)
499 498
500 499 self.shell = shell
501 500 self.options_table = {}
502 501 # The method decorators are run when the instance doesn't exist yet, so
503 502 # they can only record the names of the methods they are supposed to
504 503 # grab. Only now, that the instance exists, can we create the proper
505 504 # mapping to bound methods. So we read the info off the original names
506 505 # table and replace each method name by the actual bound method.
507 506 # But we mustn't clobber the *class* mapping, in case of multiple instances.
508 507 class_magics = self.magics
509 508 self.magics = {}
510 509 for mtype in magic_kinds:
511 510 tab = self.magics[mtype] = {}
512 511 cls_tab = class_magics[mtype]
513 for magic_name, meth_name in iteritems(cls_tab):
514 if isinstance(meth_name, string_types):
512 for magic_name, meth_name in cls_tab.items():
513 if isinstance(meth_name, str):
515 514 # it's a method name, grab it
516 515 tab[magic_name] = getattr(self, meth_name)
517 516 else:
518 517 # it's the real thing
519 518 tab[magic_name] = meth_name
520 519 # Configurable **needs** to be initiated at the end or the config
521 520 # magics get screwed up.
522 521 super(Magics, self).__init__(**kwargs)
523 522
524 523 def arg_err(self,func):
525 524 """Print docstring if incorrect arguments were passed"""
526 525 print('Error in arguments:')
527 526 print(oinspect.getdoc(func))
528 527
529 528 def format_latex(self, strng):
530 529 """Format a string for latex inclusion."""
531 530
532 531 # Characters that need to be escaped for latex:
533 532 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
534 533 # Magic command names as headers:
535 534 cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC,
536 535 re.MULTILINE)
537 536 # Magic commands
538 537 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC,
539 538 re.MULTILINE)
540 539 # Paragraph continue
541 540 par_re = re.compile(r'\\$',re.MULTILINE)
542 541
543 542 # The "\n" symbol
544 543 newline_re = re.compile(r'\\n')
545 544
546 545 # Now build the string for output:
547 546 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
548 547 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
549 548 strng)
550 549 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
551 550 strng = par_re.sub(r'\\\\',strng)
552 551 strng = escape_re.sub(r'\\\1',strng)
553 552 strng = newline_re.sub(r'\\textbackslash{}n',strng)
554 553 return strng
555 554
556 555 def parse_options(self, arg_str, opt_str, *long_opts, **kw):
557 556 """Parse options passed to an argument string.
558 557
559 558 The interface is similar to that of :func:`getopt.getopt`, but it
560 559 returns a :class:`~IPython.utils.struct.Struct` with the options as keys
561 560 and the stripped argument string still as a string.
562 561
563 562 arg_str is quoted as a true sys.argv vector by using shlex.split.
564 563 This allows us to easily expand variables, glob files, quote
565 564 arguments, etc.
566 565
567 566 Parameters
568 567 ----------
569 568
570 569 arg_str : str
571 570 The arguments to parse.
572 571
573 572 opt_str : str
574 573 The options specification.
575 574
576 575 mode : str, default 'string'
577 576 If given as 'list', the argument string is returned as a list (split
578 577 on whitespace) instead of a string.
579 578
580 579 list_all : bool, default False
581 580 Put all option values in lists. Normally only options
582 581 appearing more than once are put in a list.
583 582
584 583 posix : bool, default True
585 584 Whether to split the input line in POSIX mode or not, as per the
586 585 conventions outlined in the :mod:`shlex` module from the standard
587 586 library.
588 587 """
589 588
590 589 # inject default options at the beginning of the input line
591 590 caller = sys._getframe(1).f_code.co_name
592 591 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
593 592
594 593 mode = kw.get('mode','string')
595 594 if mode not in ['string','list']:
596 595 raise ValueError('incorrect mode given: %s' % mode)
597 596 # Get options
598 597 list_all = kw.get('list_all',0)
599 598 posix = kw.get('posix', os.name == 'posix')
600 599 strict = kw.get('strict', True)
601 600
602 601 # Check if we have more than one argument to warrant extra processing:
603 602 odict = {} # Dictionary with options
604 603 args = arg_str.split()
605 604 if len(args) >= 1:
606 605 # If the list of inputs only has 0 or 1 thing in it, there's no
607 606 # need to look for options
608 607 argv = arg_split(arg_str, posix, strict)
609 608 # Do regular option processing
610 609 try:
611 610 opts,args = getopt(argv, opt_str, long_opts)
612 611 except GetoptError as e:
613 612 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
614 613 " ".join(long_opts)))
615 614 for o,a in opts:
616 615 if o.startswith('--'):
617 616 o = o[2:]
618 617 else:
619 618 o = o[1:]
620 619 try:
621 620 odict[o].append(a)
622 621 except AttributeError:
623 622 odict[o] = [odict[o],a]
624 623 except KeyError:
625 624 if list_all:
626 625 odict[o] = [a]
627 626 else:
628 627 odict[o] = a
629 628
630 629 # Prepare opts,args for return
631 630 opts = Struct(odict)
632 631 if mode == 'string':
633 632 args = ' '.join(args)
634 633
635 634 return opts,args
636 635
637 636 def default_option(self, fn, optstr):
638 637 """Make an entry in the options_table for fn, with value optstr"""
639 638
640 639 if fn not in self.lsmagic():
641 640 error("%s is not a magic function" % fn)
642 641 self.options_table[fn] = optstr
643 642
644 643
645 644 class MagicAlias(object):
646 645 """An alias to another magic function.
647 646
648 647 An alias is determined by its magic name and magic kind. Lookup
649 648 is done at call time, so if the underlying magic changes the alias
650 649 will call the new function.
651 650
652 651 Use the :meth:`MagicsManager.register_alias` method or the
653 652 `%alias_magic` magic function to create and register a new alias.
654 653 """
655 654 def __init__(self, shell, magic_name, magic_kind):
656 655 self.shell = shell
657 656 self.magic_name = magic_name
658 657 self.magic_kind = magic_kind
659 658
660 659 self.pretty_target = '%s%s' % (magic_escapes[self.magic_kind], self.magic_name)
661 660 self.__doc__ = "Alias for `%s`." % self.pretty_target
662 661
663 662 self._in_call = False
664 663
665 664 def __call__(self, *args, **kwargs):
666 665 """Call the magic alias."""
667 666 fn = self.shell.find_magic(self.magic_name, self.magic_kind)
668 667 if fn is None:
669 668 raise UsageError("Magic `%s` not found." % self.pretty_target)
670 669
671 670 # Protect against infinite recursion.
672 671 if self._in_call:
673 672 raise UsageError("Infinite recursion detected; "
674 673 "magic aliases cannot call themselves.")
675 674 self._in_call = True
676 675 try:
677 676 return fn(*args, **kwargs)
678 677 finally:
679 678 self._in_call = False
@@ -1,581 +1,580 b''
1 1 """Implementation of basic magic functions."""
2 2
3 3
4 4 import argparse
5 5 import io
6 6 import sys
7 7 from pprint import pformat
8 8
9 9 from IPython.core import magic_arguments, page
10 10 from IPython.core.error import UsageError
11 11 from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
12 12 from IPython.utils.text import format_screen, dedent, indent
13 13 from IPython.testing.skipdoctest import skip_doctest
14 14 from IPython.utils.ipstruct import Struct
15 from IPython.utils.py3compat import unicode_type
16 15 from warnings import warn
17 16 from logging import error
18 17
19 18
20 19 class MagicsDisplay(object):
21 20 def __init__(self, magics_manager):
22 21 self.magics_manager = magics_manager
23 22
24 23 def _lsmagic(self):
25 24 """The main implementation of the %lsmagic"""
26 25 mesc = magic_escapes['line']
27 26 cesc = magic_escapes['cell']
28 27 mman = self.magics_manager
29 28 magics = mman.lsmagic()
30 29 out = ['Available line magics:',
31 30 mesc + (' '+mesc).join(sorted(magics['line'])),
32 31 '',
33 32 'Available cell magics:',
34 33 cesc + (' '+cesc).join(sorted(magics['cell'])),
35 34 '',
36 35 mman.auto_status()]
37 36 return '\n'.join(out)
38 37
39 38 def _repr_pretty_(self, p, cycle):
40 39 p.text(self._lsmagic())
41 40
42 41 def __str__(self):
43 42 return self._lsmagic()
44 43
45 44 def _jsonable(self):
46 45 """turn magics dict into jsonable dict of the same structure
47 46
48 47 replaces object instances with their class names as strings
49 48 """
50 49 magic_dict = {}
51 50 mman = self.magics_manager
52 51 magics = mman.lsmagic()
53 52 for key, subdict in magics.items():
54 53 d = {}
55 54 magic_dict[key] = d
56 55 for name, obj in subdict.items():
57 56 try:
58 57 classname = obj.__self__.__class__.__name__
59 58 except AttributeError:
60 59 classname = 'Other'
61 60
62 61 d[name] = classname
63 62 return magic_dict
64 63
65 64 def _repr_json_(self):
66 65 return self._jsonable()
67 66
68 67
69 68 @magics_class
70 69 class BasicMagics(Magics):
71 70 """Magics that provide central IPython functionality.
72 71
73 72 These are various magics that don't fit into specific categories but that
74 73 are all part of the base 'IPython experience'."""
75 74
76 75 @magic_arguments.magic_arguments()
77 76 @magic_arguments.argument(
78 77 '-l', '--line', action='store_true',
79 78 help="""Create a line magic alias."""
80 79 )
81 80 @magic_arguments.argument(
82 81 '-c', '--cell', action='store_true',
83 82 help="""Create a cell magic alias."""
84 83 )
85 84 @magic_arguments.argument(
86 85 'name',
87 86 help="""Name of the magic to be created."""
88 87 )
89 88 @magic_arguments.argument(
90 89 'target',
91 90 help="""Name of the existing line or cell magic."""
92 91 )
93 92 @line_magic
94 93 def alias_magic(self, line=''):
95 94 """Create an alias for an existing line or cell magic.
96 95
97 96 Examples
98 97 --------
99 98 ::
100 99
101 100 In [1]: %alias_magic t timeit
102 101 Created `%t` as an alias for `%timeit`.
103 102 Created `%%t` as an alias for `%%timeit`.
104 103
105 104 In [2]: %t -n1 pass
106 105 1 loops, best of 3: 954 ns per loop
107 106
108 107 In [3]: %%t -n1
109 108 ...: pass
110 109 ...:
111 110 1 loops, best of 3: 954 ns per loop
112 111
113 112 In [4]: %alias_magic --cell whereami pwd
114 113 UsageError: Cell magic function `%%pwd` not found.
115 114 In [5]: %alias_magic --line whereami pwd
116 115 Created `%whereami` as an alias for `%pwd`.
117 116
118 117 In [6]: %whereami
119 118 Out[6]: u'/home/testuser'
120 119 """
121 120 args = magic_arguments.parse_argstring(self.alias_magic, line)
122 121 shell = self.shell
123 122 mman = self.shell.magics_manager
124 123 escs = ''.join(magic_escapes.values())
125 124
126 125 target = args.target.lstrip(escs)
127 126 name = args.name.lstrip(escs)
128 127
129 128 # Find the requested magics.
130 129 m_line = shell.find_magic(target, 'line')
131 130 m_cell = shell.find_magic(target, 'cell')
132 131 if args.line and m_line is None:
133 132 raise UsageError('Line magic function `%s%s` not found.' %
134 133 (magic_escapes['line'], target))
135 134 if args.cell and m_cell is None:
136 135 raise UsageError('Cell magic function `%s%s` not found.' %
137 136 (magic_escapes['cell'], target))
138 137
139 138 # If --line and --cell are not specified, default to the ones
140 139 # that are available.
141 140 if not args.line and not args.cell:
142 141 if not m_line and not m_cell:
143 142 raise UsageError(
144 143 'No line or cell magic with name `%s` found.' % target
145 144 )
146 145 args.line = bool(m_line)
147 146 args.cell = bool(m_cell)
148 147
149 148 if args.line:
150 149 mman.register_alias(name, target, 'line')
151 150 print('Created `%s%s` as an alias for `%s%s`.' % (
152 151 magic_escapes['line'], name,
153 152 magic_escapes['line'], target))
154 153
155 154 if args.cell:
156 155 mman.register_alias(name, target, 'cell')
157 156 print('Created `%s%s` as an alias for `%s%s`.' % (
158 157 magic_escapes['cell'], name,
159 158 magic_escapes['cell'], target))
160 159
161 160 @line_magic
162 161 def lsmagic(self, parameter_s=''):
163 162 """List currently available magic functions."""
164 163 return MagicsDisplay(self.shell.magics_manager)
165 164
166 165 def _magic_docs(self, brief=False, rest=False):
167 166 """Return docstrings from magic functions."""
168 167 mman = self.shell.magics_manager
169 168 docs = mman.lsmagic_docs(brief, missing='No documentation')
170 169
171 170 if rest:
172 171 format_string = '**%s%s**::\n\n%s\n\n'
173 172 else:
174 173 format_string = '%s%s:\n%s\n'
175 174
176 175 return ''.join(
177 176 [format_string % (magic_escapes['line'], fname,
178 177 indent(dedent(fndoc)))
179 178 for fname, fndoc in sorted(docs['line'].items())]
180 179 +
181 180 [format_string % (magic_escapes['cell'], fname,
182 181 indent(dedent(fndoc)))
183 182 for fname, fndoc in sorted(docs['cell'].items())]
184 183 )
185 184
186 185 @line_magic
187 186 def magic(self, parameter_s=''):
188 187 """Print information about the magic function system.
189 188
190 189 Supported formats: -latex, -brief, -rest
191 190 """
192 191
193 192 mode = ''
194 193 try:
195 194 mode = parameter_s.split()[0][1:]
196 195 except IndexError:
197 196 pass
198 197
199 198 brief = (mode == 'brief')
200 199 rest = (mode == 'rest')
201 200 magic_docs = self._magic_docs(brief, rest)
202 201
203 202 if mode == 'latex':
204 203 print(self.format_latex(magic_docs))
205 204 return
206 205 else:
207 206 magic_docs = format_screen(magic_docs)
208 207
209 208 out = ["""
210 209 IPython's 'magic' functions
211 210 ===========================
212 211
213 212 The magic function system provides a series of functions which allow you to
214 213 control the behavior of IPython itself, plus a lot of system-type
215 214 features. There are two kinds of magics, line-oriented and cell-oriented.
216 215
217 216 Line magics are prefixed with the % character and work much like OS
218 217 command-line calls: they get as an argument the rest of the line, where
219 218 arguments are passed without parentheses or quotes. For example, this will
220 219 time the given statement::
221 220
222 221 %timeit range(1000)
223 222
224 223 Cell magics are prefixed with a double %%, and they are functions that get as
225 224 an argument not only the rest of the line, but also the lines below it in a
226 225 separate argument. These magics are called with two arguments: the rest of the
227 226 call line and the body of the cell, consisting of the lines below the first.
228 227 For example::
229 228
230 229 %%timeit x = numpy.random.randn((100, 100))
231 230 numpy.linalg.svd(x)
232 231
233 232 will time the execution of the numpy svd routine, running the assignment of x
234 233 as part of the setup phase, which is not timed.
235 234
236 235 In a line-oriented client (the terminal or Qt console IPython), starting a new
237 236 input with %% will automatically enter cell mode, and IPython will continue
238 237 reading input until a blank line is given. In the notebook, simply type the
239 238 whole cell as one entity, but keep in mind that the %% escape can only be at
240 239 the very start of the cell.
241 240
242 241 NOTE: If you have 'automagic' enabled (via the command line option or with the
243 242 %automagic function), you don't need to type in the % explicitly for line
244 243 magics; cell magics always require an explicit '%%' escape. By default,
245 244 IPython ships with automagic on, so you should only rarely need the % escape.
246 245
247 246 Example: typing '%cd mydir' (without the quotes) changes your working directory
248 247 to 'mydir', if it exists.
249 248
250 249 For a list of the available magic functions, use %lsmagic. For a description
251 250 of any of them, type %magic_name?, e.g. '%cd?'.
252 251
253 252 Currently the magic system has the following functions:""",
254 253 magic_docs,
255 254 "Summary of magic functions (from %slsmagic):" % magic_escapes['line'],
256 255 str(self.lsmagic()),
257 256 ]
258 257 page.page('\n'.join(out))
259 258
260 259
261 260 @line_magic
262 261 def page(self, parameter_s=''):
263 262 """Pretty print the object and display it through a pager.
264 263
265 264 %page [options] OBJECT
266 265
267 266 If no object is given, use _ (last output).
268 267
269 268 Options:
270 269
271 270 -r: page str(object), don't pretty-print it."""
272 271
273 272 # After a function contributed by Olivier Aubert, slightly modified.
274 273
275 274 # Process options/args
276 275 opts, args = self.parse_options(parameter_s, 'r')
277 276 raw = 'r' in opts
278 277
279 278 oname = args and args or '_'
280 279 info = self.shell._ofind(oname)
281 280 if info['found']:
282 281 txt = (raw and str or pformat)( info['obj'] )
283 282 page.page(txt)
284 283 else:
285 284 print('Object `%s` not found' % oname)
286 285
287 286 @line_magic
288 287 def profile(self, parameter_s=''):
289 288 """Print your currently active IPython profile.
290 289
291 290 See Also
292 291 --------
293 292 prun : run code using the Python profiler
294 293 (:meth:`~IPython.core.magics.execution.ExecutionMagics.prun`)
295 294 """
296 295 warn("%profile is now deprecated. Please use get_ipython().profile instead.")
297 296 from IPython.core.application import BaseIPythonApplication
298 297 if BaseIPythonApplication.initialized():
299 298 print(BaseIPythonApplication.instance().profile)
300 299 else:
301 300 error("profile is an application-level value, but you don't appear to be in an IPython application")
302 301
303 302 @line_magic
304 303 def pprint(self, parameter_s=''):
305 304 """Toggle pretty printing on/off."""
306 305 ptformatter = self.shell.display_formatter.formatters['text/plain']
307 306 ptformatter.pprint = bool(1 - ptformatter.pprint)
308 307 print('Pretty printing has been turned',
309 308 ['OFF','ON'][ptformatter.pprint])
310 309
311 310 @line_magic
312 311 def colors(self, parameter_s=''):
313 312 """Switch color scheme for prompts, info system and exception handlers.
314 313
315 314 Currently implemented schemes: NoColor, Linux, LightBG.
316 315
317 316 Color scheme names are not case-sensitive.
318 317
319 318 Examples
320 319 --------
321 320 To get a plain black and white terminal::
322 321
323 322 %colors nocolor
324 323 """
325 324 def color_switch_err(name):
326 325 warn('Error changing %s color schemes.\n%s' %
327 326 (name, sys.exc_info()[1]), stacklevel=2)
328 327
329 328
330 329 new_scheme = parameter_s.strip()
331 330 if not new_scheme:
332 331 raise UsageError(
333 332 "%colors: you must specify a color scheme. See '%colors?'")
334 333 # local shortcut
335 334 shell = self.shell
336 335
337 336 # Set shell colour scheme
338 337 try:
339 338 shell.colors = new_scheme
340 339 shell.refresh_style()
341 340 except:
342 341 color_switch_err('shell')
343 342
344 343 # Set exception colors
345 344 try:
346 345 shell.InteractiveTB.set_colors(scheme = new_scheme)
347 346 shell.SyntaxTB.set_colors(scheme = new_scheme)
348 347 except:
349 348 color_switch_err('exception')
350 349
351 350 # Set info (for 'object?') colors
352 351 if shell.color_info:
353 352 try:
354 353 shell.inspector.set_active_scheme(new_scheme)
355 354 except:
356 355 color_switch_err('object inspector')
357 356 else:
358 357 shell.inspector.set_active_scheme('NoColor')
359 358
360 359 @line_magic
361 360 def xmode(self, parameter_s=''):
362 361 """Switch modes for the exception handlers.
363 362
364 363 Valid modes: Plain, Context and Verbose.
365 364
366 365 If called without arguments, acts as a toggle."""
367 366
368 367 def xmode_switch_err(name):
369 368 warn('Error changing %s exception modes.\n%s' %
370 369 (name,sys.exc_info()[1]))
371 370
372 371 shell = self.shell
373 372 new_mode = parameter_s.strip().capitalize()
374 373 try:
375 374 shell.InteractiveTB.set_mode(mode=new_mode)
376 375 print('Exception reporting mode:',shell.InteractiveTB.mode)
377 376 except:
378 377 xmode_switch_err('user')
379 378
380 379 @line_magic
381 380 def quickref(self,arg):
382 381 """ Show a quick reference sheet """
383 382 from IPython.core.usage import quick_reference
384 383 qr = quick_reference + self._magic_docs(brief=True)
385 384 page.page(qr)
386 385
387 386 @line_magic
388 387 def doctest_mode(self, parameter_s=''):
389 388 """Toggle doctest mode on and off.
390 389
391 390 This mode is intended to make IPython behave as much as possible like a
392 391 plain Python shell, from the perspective of how its prompts, exceptions
393 392 and output look. This makes it easy to copy and paste parts of a
394 393 session into doctests. It does so by:
395 394
396 395 - Changing the prompts to the classic ``>>>`` ones.
397 396 - Changing the exception reporting mode to 'Plain'.
398 397 - Disabling pretty-printing of output.
399 398
400 399 Note that IPython also supports the pasting of code snippets that have
401 400 leading '>>>' and '...' prompts in them. This means that you can paste
402 401 doctests from files or docstrings (even if they have leading
403 402 whitespace), and the code will execute correctly. You can then use
404 403 '%history -t' to see the translated history; this will give you the
405 404 input after removal of all the leading prompts and whitespace, which
406 405 can be pasted back into an editor.
407 406
408 407 With these features, you can switch into this mode easily whenever you
409 408 need to do testing and changes to doctests, without having to leave
410 409 your existing IPython session.
411 410 """
412 411
413 412 # Shorthands
414 413 shell = self.shell
415 414 meta = shell.meta
416 415 disp_formatter = self.shell.display_formatter
417 416 ptformatter = disp_formatter.formatters['text/plain']
418 417 # dstore is a data store kept in the instance metadata bag to track any
419 418 # changes we make, so we can undo them later.
420 419 dstore = meta.setdefault('doctest_mode',Struct())
421 420 save_dstore = dstore.setdefault
422 421
423 422 # save a few values we'll need to recover later
424 423 mode = save_dstore('mode',False)
425 424 save_dstore('rc_pprint',ptformatter.pprint)
426 425 save_dstore('xmode',shell.InteractiveTB.mode)
427 426 save_dstore('rc_separate_out',shell.separate_out)
428 427 save_dstore('rc_separate_out2',shell.separate_out2)
429 428 save_dstore('rc_separate_in',shell.separate_in)
430 429 save_dstore('rc_active_types',disp_formatter.active_types)
431 430
432 431 if not mode:
433 432 # turn on
434 433
435 434 # Prompt separators like plain python
436 435 shell.separate_in = ''
437 436 shell.separate_out = ''
438 437 shell.separate_out2 = ''
439 438
440 439
441 440 ptformatter.pprint = False
442 441 disp_formatter.active_types = ['text/plain']
443 442
444 443 shell.magic('xmode Plain')
445 444 else:
446 445 # turn off
447 446 shell.separate_in = dstore.rc_separate_in
448 447
449 448 shell.separate_out = dstore.rc_separate_out
450 449 shell.separate_out2 = dstore.rc_separate_out2
451 450
452 451 ptformatter.pprint = dstore.rc_pprint
453 452 disp_formatter.active_types = dstore.rc_active_types
454 453
455 454 shell.magic('xmode ' + dstore.xmode)
456 455
457 456 # mode here is the state before we switch; switch_doctest_mode takes
458 457 # the mode we're switching to.
459 458 shell.switch_doctest_mode(not mode)
460 459
461 460 # Store new mode and inform
462 461 dstore.mode = bool(not mode)
463 462 mode_label = ['OFF','ON'][dstore.mode]
464 463 print('Doctest mode is:', mode_label)
465 464
466 465 @line_magic
467 466 def gui(self, parameter_s=''):
468 467 """Enable or disable IPython GUI event loop integration.
469 468
470 469 %gui [GUINAME]
471 470
472 471 This magic replaces IPython's threaded shells that were activated
473 472 using the (pylab/wthread/etc.) command line flags. GUI toolkits
474 473 can now be enabled at runtime and keyboard
475 474 interrupts should work without any problems. The following toolkits
476 475 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
477 476
478 477 %gui wx # enable wxPython event loop integration
479 478 %gui qt4|qt # enable PyQt4 event loop integration
480 479 %gui qt5 # enable PyQt5 event loop integration
481 480 %gui gtk # enable PyGTK event loop integration
482 481 %gui gtk3 # enable Gtk3 event loop integration
483 482 %gui tk # enable Tk event loop integration
484 483 %gui osx # enable Cocoa event loop integration
485 484 # (requires %matplotlib 1.1)
486 485 %gui # disable all event loop integration
487 486
488 487 WARNING: after any of these has been called you can simply create
489 488 an application object, but DO NOT start the event loop yourself, as
490 489 we have already handled that.
491 490 """
492 491 opts, arg = self.parse_options(parameter_s, '')
493 492 if arg=='': arg = None
494 493 try:
495 494 return self.shell.enable_gui(arg)
496 495 except Exception as e:
497 496 # print simple error message, rather than traceback if we can't
498 497 # hook up the GUI
499 498 error(str(e))
500 499
501 500 @skip_doctest
502 501 @line_magic
503 502 def precision(self, s=''):
504 503 """Set floating point precision for pretty printing.
505 504
506 505 Can set either integer precision or a format string.
507 506
508 507 If numpy has been imported and precision is an int,
509 508 numpy display precision will also be set, via ``numpy.set_printoptions``.
510 509
511 510 If no argument is given, defaults will be restored.
512 511
513 512 Examples
514 513 --------
515 514 ::
516 515
517 516 In [1]: from math import pi
518 517
519 518 In [2]: %precision 3
520 519 Out[2]: u'%.3f'
521 520
522 521 In [3]: pi
523 522 Out[3]: 3.142
524 523
525 524 In [4]: %precision %i
526 525 Out[4]: u'%i'
527 526
528 527 In [5]: pi
529 528 Out[5]: 3
530 529
531 530 In [6]: %precision %e
532 531 Out[6]: u'%e'
533 532
534 533 In [7]: pi**10
535 534 Out[7]: 9.364805e+04
536 535
537 536 In [8]: %precision
538 537 Out[8]: u'%r'
539 538
540 539 In [9]: pi**10
541 540 Out[9]: 93648.047476082982
542 541 """
543 542 ptformatter = self.shell.display_formatter.formatters['text/plain']
544 543 ptformatter.float_precision = s
545 544 return ptformatter.float_format
546 545
547 546 @magic_arguments.magic_arguments()
548 547 @magic_arguments.argument(
549 548 '-e', '--export', action='store_true', default=False,
550 549 help=argparse.SUPPRESS
551 550 )
552 551 @magic_arguments.argument(
553 'filename', type=unicode_type,
552 'filename', type=str,
554 553 help='Notebook name or filename'
555 554 )
556 555 @line_magic
557 556 def notebook(self, s):
558 557 """Export and convert IPython notebooks.
559 558
560 559 This function can export the current IPython history to a notebook file.
561 560 For example, to export the history to "foo.ipynb" do "%notebook foo.ipynb".
562 561
563 562 The -e or --export flag is deprecated in IPython 5.2, and will be
564 563 removed in the future.
565 564 """
566 565 args = magic_arguments.parse_argstring(self.notebook, s)
567 566
568 567 from nbformat import write, v4
569 568
570 569 cells = []
571 570 hist = list(self.shell.history_manager.get_range())
572 571 if(len(hist)<=1):
573 572 raise ValueError('History is empty, cannot export')
574 573 for session, execution_count, source in hist[:-1]:
575 574 cells.append(v4.new_code_cell(
576 575 execution_count=execution_count,
577 576 source=source
578 577 ))
579 578 nb = v4.new_notebook(cells=cells)
580 579 with io.open(args.filename, 'w', encoding='utf-8') as f:
581 580 write(nb, f, version=4)
@@ -1,744 +1,743 b''
1 1 """Implementation of code management magic functions.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (c) 2012 The IPython Development Team.
5 5 #
6 6 # Distributed under the terms of the Modified BSD License.
7 7 #
8 8 # The full license is in the file COPYING.txt, distributed with this software.
9 9 #-----------------------------------------------------------------------------
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14
15 15 # Stdlib
16 16 import inspect
17 17 import io
18 18 import os
19 19 import re
20 20 import sys
21 21 import ast
22 22 from itertools import chain
23 23
24 24 # Our own packages
25 25 from IPython.core.error import TryNext, StdinNotImplementedError, UsageError
26 26 from IPython.core.macro import Macro
27 27 from IPython.core.magic import Magics, magics_class, line_magic
28 28 from IPython.core.oinspect import find_file, find_source_lines
29 29 from IPython.testing.skipdoctest import skip_doctest
30 30 from IPython.utils import py3compat
31 from IPython.utils.py3compat import string_types
32 31 from IPython.utils.contexts import preserve_keys
33 32 from IPython.utils.path import get_py_filename
34 33 from warnings import warn
35 34 from logging import error
36 35 from IPython.utils.text import get_text_list
37 36
38 37 #-----------------------------------------------------------------------------
39 38 # Magic implementation classes
40 39 #-----------------------------------------------------------------------------
41 40
42 41 # Used for exception handling in magic_edit
43 42 class MacroToEdit(ValueError): pass
44 43
45 44 ipython_input_pat = re.compile(r"<ipython\-input\-(\d+)-[a-z\d]+>$")
46 45
47 46 # To match, e.g. 8-10 1:5 :10 3-
48 47 range_re = re.compile(r"""
49 48 (?P<start>\d+)?
50 49 ((?P<sep>[\-:])
51 50 (?P<end>\d+)?)?
52 51 $""", re.VERBOSE)
53 52
54 53
55 54 def extract_code_ranges(ranges_str):
56 55 """Turn a string of range for %%load into 2-tuples of (start, stop)
57 56 ready to use as a slice of the content splitted by lines.
58 57
59 58 Examples
60 59 --------
61 60 list(extract_input_ranges("5-10 2"))
62 61 [(4, 10), (1, 2)]
63 62 """
64 63 for range_str in ranges_str.split():
65 64 rmatch = range_re.match(range_str)
66 65 if not rmatch:
67 66 continue
68 67 sep = rmatch.group("sep")
69 68 start = rmatch.group("start")
70 69 end = rmatch.group("end")
71 70
72 71 if sep == '-':
73 72 start = int(start) - 1 if start else None
74 73 end = int(end) if end else None
75 74 elif sep == ':':
76 75 start = int(start) - 1 if start else None
77 76 end = int(end) - 1 if end else None
78 77 else:
79 78 end = int(start)
80 79 start = int(start) - 1
81 80 yield (start, end)
82 81
83 82
84 83 @skip_doctest
85 84 def extract_symbols(code, symbols):
86 85 """
87 86 Return a tuple (blocks, not_found)
88 87 where ``blocks`` is a list of code fragments
89 88 for each symbol parsed from code, and ``not_found`` are
90 89 symbols not found in the code.
91 90
92 91 For example::
93 92
94 93 >>> code = '''a = 10
95 94
96 95 def b(): return 42
97 96
98 97 class A: pass'''
99 98
100 99 >>> extract_symbols(code, 'A,b,z')
101 100 (["class A: pass", "def b(): return 42"], ['z'])
102 101 """
103 102 symbols = symbols.split(',')
104 103
105 104 # this will raise SyntaxError if code isn't valid Python
106 105 py_code = ast.parse(code)
107 106
108 107 marks = [(getattr(s, 'name', None), s.lineno) for s in py_code.body]
109 108 code = code.split('\n')
110 109
111 110 symbols_lines = {}
112 111
113 112 # we already know the start_lineno of each symbol (marks).
114 113 # To find each end_lineno, we traverse in reverse order until each
115 114 # non-blank line
116 115 end = len(code)
117 116 for name, start in reversed(marks):
118 117 while not code[end - 1].strip():
119 118 end -= 1
120 119 if name:
121 120 symbols_lines[name] = (start - 1, end)
122 121 end = start - 1
123 122
124 123 # Now symbols_lines is a map
125 124 # {'symbol_name': (start_lineno, end_lineno), ...}
126 125
127 126 # fill a list with chunks of codes for each requested symbol
128 127 blocks = []
129 128 not_found = []
130 129 for symbol in symbols:
131 130 if symbol in symbols_lines:
132 131 start, end = symbols_lines[symbol]
133 132 blocks.append('\n'.join(code[start:end]) + '\n')
134 133 else:
135 134 not_found.append(symbol)
136 135
137 136 return blocks, not_found
138 137
139 138 def strip_initial_indent(lines):
140 139 """For %load, strip indent from lines until finding an unindented line.
141 140
142 141 https://github.com/ipython/ipython/issues/9775
143 142 """
144 143 indent_re = re.compile(r'\s+')
145 144
146 145 it = iter(lines)
147 146 first_line = next(it)
148 147 indent_match = indent_re.match(first_line)
149 148
150 149 if indent_match:
151 150 # First line was indented
152 151 indent = indent_match.group()
153 152 yield first_line[len(indent):]
154 153
155 154 for line in it:
156 155 if line.startswith(indent):
157 156 yield line[len(indent):]
158 157 else:
159 158 # Less indented than the first line - stop dedenting
160 159 yield line
161 160 break
162 161 else:
163 162 yield first_line
164 163
165 164 # Pass the remaining lines through without dedenting
166 165 for line in it:
167 166 yield line
168 167
169 168
170 169 class InteractivelyDefined(Exception):
171 170 """Exception for interactively defined variable in magic_edit"""
172 171 def __init__(self, index):
173 172 self.index = index
174 173
175 174
176 175 @magics_class
177 176 class CodeMagics(Magics):
178 177 """Magics related to code management (loading, saving, editing, ...)."""
179 178
180 179 def __init__(self, *args, **kwargs):
181 180 self._knowntemps = set()
182 181 super(CodeMagics, self).__init__(*args, **kwargs)
183 182
184 183 @line_magic
185 184 def save(self, parameter_s=''):
186 185 """Save a set of lines or a macro to a given filename.
187 186
188 187 Usage:\\
189 188 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
190 189
191 190 Options:
192 191
193 192 -r: use 'raw' input. By default, the 'processed' history is used,
194 193 so that magics are loaded in their transformed version to valid
195 194 Python. If this option is given, the raw input as typed as the
196 195 command line is used instead.
197 196
198 197 -f: force overwrite. If file exists, %save will prompt for overwrite
199 198 unless -f is given.
200 199
201 200 -a: append to the file instead of overwriting it.
202 201
203 202 This function uses the same syntax as %history for input ranges,
204 203 then saves the lines to the filename you specify.
205 204
206 205 It adds a '.py' extension to the file if you don't do so yourself, and
207 206 it asks for confirmation before overwriting existing files.
208 207
209 208 If `-r` option is used, the default extension is `.ipy`.
210 209 """
211 210
212 211 opts,args = self.parse_options(parameter_s,'fra',mode='list')
213 212 if not args:
214 213 raise UsageError('Missing filename.')
215 214 raw = 'r' in opts
216 215 force = 'f' in opts
217 216 append = 'a' in opts
218 217 mode = 'a' if append else 'w'
219 218 ext = u'.ipy' if raw else u'.py'
220 219 fname, codefrom = args[0], " ".join(args[1:])
221 220 if not fname.endswith((u'.py',u'.ipy')):
222 221 fname += ext
223 222 file_exists = os.path.isfile(fname)
224 223 if file_exists and not force and not append:
225 224 try:
226 225 overwrite = self.shell.ask_yes_no('File `%s` exists. Overwrite (y/[N])? ' % fname, default='n')
227 226 except StdinNotImplementedError:
228 227 print("File `%s` exists. Use `%%save -f %s` to force overwrite" % (fname, parameter_s))
229 228 return
230 229 if not overwrite :
231 230 print('Operation cancelled.')
232 231 return
233 232 try:
234 233 cmds = self.shell.find_user_code(codefrom,raw)
235 234 except (TypeError, ValueError) as e:
236 235 print(e.args[0])
237 236 return
238 237 out = py3compat.cast_unicode(cmds)
239 238 with io.open(fname, mode, encoding="utf-8") as f:
240 239 if not file_exists or not append:
241 240 f.write(u"# coding: utf-8\n")
242 241 f.write(out)
243 242 # make sure we end on a newline
244 243 if not out.endswith(u'\n'):
245 244 f.write(u'\n')
246 245 print('The following commands were written to file `%s`:' % fname)
247 246 print(cmds)
248 247
249 248 @line_magic
250 249 def pastebin(self, parameter_s=''):
251 250 """Upload code to Github's Gist paste bin, returning the URL.
252 251
253 252 Usage:\\
254 253 %pastebin [-d "Custom description"] 1-7
255 254
256 255 The argument can be an input history range, a filename, or the name of a
257 256 string or macro.
258 257
259 258 Options:
260 259
261 260 -d: Pass a custom description for the gist. The default will say
262 261 "Pasted from IPython".
263 262 """
264 263 opts, args = self.parse_options(parameter_s, 'd:')
265 264
266 265 try:
267 266 code = self.shell.find_user_code(args)
268 267 except (ValueError, TypeError) as e:
269 268 print(e.args[0])
270 269 return
271 270
272 271 # Deferred import
273 272 try:
274 273 from urllib.request import urlopen # Py 3
275 274 except ImportError:
276 275 from urllib2 import urlopen
277 276 import json
278 277 post_data = json.dumps({
279 278 "description": opts.get('d', "Pasted from IPython"),
280 279 "public": True,
281 280 "files": {
282 281 "file1.py": {
283 282 "content": code
284 283 }
285 284 }
286 285 }).encode('utf-8')
287 286
288 287 response = urlopen("https://api.github.com/gists", post_data)
289 288 response_data = json.loads(response.read().decode('utf-8'))
290 289 return response_data['html_url']
291 290
292 291 @line_magic
293 292 def loadpy(self, arg_s):
294 293 """Alias of `%load`
295 294
296 295 `%loadpy` has gained some flexibility and dropped the requirement of a `.py`
297 296 extension. So it has been renamed simply into %load. You can look at
298 297 `%load`'s docstring for more info.
299 298 """
300 299 self.load(arg_s)
301 300
302 301 @line_magic
303 302 def load(self, arg_s):
304 303 """Load code into the current frontend.
305 304
306 305 Usage:\\
307 306 %load [options] source
308 307
309 308 where source can be a filename, URL, input history range, macro, or
310 309 element in the user namespace
311 310
312 311 Options:
313 312
314 313 -r <lines>: Specify lines or ranges of lines to load from the source.
315 314 Ranges could be specified as x-y (x..y) or in python-style x:y
316 315 (x..(y-1)). Both limits x and y can be left blank (meaning the
317 316 beginning and end of the file, respectively).
318 317
319 318 -s <symbols>: Specify function or classes to load from python source.
320 319
321 320 -y : Don't ask confirmation for loading source above 200 000 characters.
322 321
323 322 -n : Include the user's namespace when searching for source code.
324 323
325 324 This magic command can either take a local filename, a URL, an history
326 325 range (see %history) or a macro as argument, it will prompt for
327 326 confirmation before loading source with more than 200 000 characters, unless
328 327 -y flag is passed or if the frontend does not support raw_input::
329 328
330 329 %load myscript.py
331 330 %load 7-27
332 331 %load myMacro
333 332 %load http://www.example.com/myscript.py
334 333 %load -r 5-10 myscript.py
335 334 %load -r 10-20,30,40: foo.py
336 335 %load -s MyClass,wonder_function myscript.py
337 336 %load -n MyClass
338 337 %load -n my_module.wonder_function
339 338 """
340 339 opts,args = self.parse_options(arg_s,'yns:r:')
341 340
342 341 if not args:
343 342 raise UsageError('Missing filename, URL, input history range, '
344 343 'macro, or element in the user namespace.')
345 344
346 345 search_ns = 'n' in opts
347 346
348 347 contents = self.shell.find_user_code(args, search_ns=search_ns)
349 348
350 349 if 's' in opts:
351 350 try:
352 351 blocks, not_found = extract_symbols(contents, opts['s'])
353 352 except SyntaxError:
354 353 # non python code
355 354 error("Unable to parse the input as valid Python code")
356 355 return
357 356
358 357 if len(not_found) == 1:
359 358 warn('The symbol `%s` was not found' % not_found[0])
360 359 elif len(not_found) > 1:
361 360 warn('The symbols %s were not found' % get_text_list(not_found,
362 361 wrap_item_with='`')
363 362 )
364 363
365 364 contents = '\n'.join(blocks)
366 365
367 366 if 'r' in opts:
368 367 ranges = opts['r'].replace(',', ' ')
369 368 lines = contents.split('\n')
370 369 slices = extract_code_ranges(ranges)
371 370 contents = [lines[slice(*slc)] for slc in slices]
372 371 contents = '\n'.join(strip_initial_indent(chain.from_iterable(contents)))
373 372
374 373 l = len(contents)
375 374
376 375 # 200 000 is ~ 2500 full 80 caracter lines
377 376 # so in average, more than 5000 lines
378 377 if l > 200000 and 'y' not in opts:
379 378 try:
380 379 ans = self.shell.ask_yes_no(("The text you're trying to load seems pretty big"\
381 380 " (%d characters). Continue (y/[N]) ?" % l), default='n' )
382 381 except StdinNotImplementedError:
383 382 #asume yes if raw input not implemented
384 383 ans = True
385 384
386 385 if ans is False :
387 386 print('Operation cancelled.')
388 387 return
389 388
390 389 contents = "# %load {}\n".format(arg_s) + contents
391 390
392 391 self.shell.set_next_input(contents, replace=True)
393 392
394 393 @staticmethod
395 394 def _find_edit_target(shell, args, opts, last_call):
396 395 """Utility method used by magic_edit to find what to edit."""
397 396
398 397 def make_filename(arg):
399 398 "Make a filename from the given args"
400 399 try:
401 400 filename = get_py_filename(arg)
402 401 except IOError:
403 402 # If it ends with .py but doesn't already exist, assume we want
404 403 # a new file.
405 404 if arg.endswith('.py'):
406 405 filename = arg
407 406 else:
408 407 filename = None
409 408 return filename
410 409
411 410 # Set a few locals from the options for convenience:
412 411 opts_prev = 'p' in opts
413 412 opts_raw = 'r' in opts
414 413
415 414 # custom exceptions
416 415 class DataIsObject(Exception): pass
417 416
418 417 # Default line number value
419 418 lineno = opts.get('n',None)
420 419
421 420 if opts_prev:
422 421 args = '_%s' % last_call[0]
423 422 if args not in shell.user_ns:
424 423 args = last_call[1]
425 424
426 425 # by default this is done with temp files, except when the given
427 426 # arg is a filename
428 427 use_temp = True
429 428
430 429 data = ''
431 430
432 431 # First, see if the arguments should be a filename.
433 432 filename = make_filename(args)
434 433 if filename:
435 434 use_temp = False
436 435 elif args:
437 436 # Mode where user specifies ranges of lines, like in %macro.
438 437 data = shell.extract_input_lines(args, opts_raw)
439 438 if not data:
440 439 try:
441 440 # Load the parameter given as a variable. If not a string,
442 441 # process it as an object instead (below)
443 442
444 443 #print '*** args',args,'type',type(args) # dbg
445 444 data = eval(args, shell.user_ns)
446 if not isinstance(data, string_types):
445 if not isinstance(data, str):
447 446 raise DataIsObject
448 447
449 448 except (NameError,SyntaxError):
450 449 # given argument is not a variable, try as a filename
451 450 filename = make_filename(args)
452 451 if filename is None:
453 452 warn("Argument given (%s) can't be found as a variable "
454 453 "or as a filename." % args)
455 454 return (None, None, None)
456 455 use_temp = False
457 456
458 457 except DataIsObject:
459 458 # macros have a special edit function
460 459 if isinstance(data, Macro):
461 460 raise MacroToEdit(data)
462 461
463 462 # For objects, try to edit the file where they are defined
464 463 filename = find_file(data)
465 464 if filename:
466 465 if 'fakemodule' in filename.lower() and \
467 466 inspect.isclass(data):
468 467 # class created by %edit? Try to find source
469 468 # by looking for method definitions instead, the
470 469 # __module__ in those classes is FakeModule.
471 470 attrs = [getattr(data, aname) for aname in dir(data)]
472 471 for attr in attrs:
473 472 if not inspect.ismethod(attr):
474 473 continue
475 474 filename = find_file(attr)
476 475 if filename and \
477 476 'fakemodule' not in filename.lower():
478 477 # change the attribute to be the edit
479 478 # target instead
480 479 data = attr
481 480 break
482 481
483 482 m = ipython_input_pat.match(os.path.basename(filename))
484 483 if m:
485 484 raise InteractivelyDefined(int(m.groups()[0]))
486 485
487 486 datafile = 1
488 487 if filename is None:
489 488 filename = make_filename(args)
490 489 datafile = 1
491 490 if filename is not None:
492 491 # only warn about this if we get a real name
493 492 warn('Could not find file where `%s` is defined.\n'
494 493 'Opening a file named `%s`' % (args, filename))
495 494 # Now, make sure we can actually read the source (if it was
496 495 # in a temp file it's gone by now).
497 496 if datafile:
498 497 if lineno is None:
499 498 lineno = find_source_lines(data)
500 499 if lineno is None:
501 500 filename = make_filename(args)
502 501 if filename is None:
503 502 warn('The file where `%s` was defined '
504 503 'cannot be read or found.' % data)
505 504 return (None, None, None)
506 505 use_temp = False
507 506
508 507 if use_temp:
509 508 filename = shell.mktempfile(data)
510 509 print('IPython will make a temporary file named:',filename)
511 510
512 511 # use last_call to remember the state of the previous call, but don't
513 512 # let it be clobbered by successive '-p' calls.
514 513 try:
515 514 last_call[0] = shell.displayhook.prompt_count
516 515 if not opts_prev:
517 516 last_call[1] = args
518 517 except:
519 518 pass
520 519
521 520
522 521 return filename, lineno, use_temp
523 522
524 523 def _edit_macro(self,mname,macro):
525 524 """open an editor with the macro data in a file"""
526 525 filename = self.shell.mktempfile(macro.value)
527 526 self.shell.hooks.editor(filename)
528 527
529 528 # and make a new macro object, to replace the old one
530 529 with open(filename) as mfile:
531 530 mvalue = mfile.read()
532 531 self.shell.user_ns[mname] = Macro(mvalue)
533 532
534 533 @skip_doctest
535 534 @line_magic
536 535 def edit(self, parameter_s='',last_call=['','']):
537 536 """Bring up an editor and execute the resulting code.
538 537
539 538 Usage:
540 539 %edit [options] [args]
541 540
542 541 %edit runs IPython's editor hook. The default version of this hook is
543 542 set to call the editor specified by your $EDITOR environment variable.
544 543 If this isn't found, it will default to vi under Linux/Unix and to
545 544 notepad under Windows. See the end of this docstring for how to change
546 545 the editor hook.
547 546
548 547 You can also set the value of this editor via the
549 548 ``TerminalInteractiveShell.editor`` option in your configuration file.
550 549 This is useful if you wish to use a different editor from your typical
551 550 default with IPython (and for Windows users who typically don't set
552 551 environment variables).
553 552
554 553 This command allows you to conveniently edit multi-line code right in
555 554 your IPython session.
556 555
557 556 If called without arguments, %edit opens up an empty editor with a
558 557 temporary file and will execute the contents of this file when you
559 558 close it (don't forget to save it!).
560 559
561 560
562 561 Options:
563 562
564 563 -n <number>: open the editor at a specified line number. By default,
565 564 the IPython editor hook uses the unix syntax 'editor +N filename', but
566 565 you can configure this by providing your own modified hook if your
567 566 favorite editor supports line-number specifications with a different
568 567 syntax.
569 568
570 569 -p: this will call the editor with the same data as the previous time
571 570 it was used, regardless of how long ago (in your current session) it
572 571 was.
573 572
574 573 -r: use 'raw' input. This option only applies to input taken from the
575 574 user's history. By default, the 'processed' history is used, so that
576 575 magics are loaded in their transformed version to valid Python. If
577 576 this option is given, the raw input as typed as the command line is
578 577 used instead. When you exit the editor, it will be executed by
579 578 IPython's own processor.
580 579
581 580 -x: do not execute the edited code immediately upon exit. This is
582 581 mainly useful if you are editing programs which need to be called with
583 582 command line arguments, which you can then do using %run.
584 583
585 584
586 585 Arguments:
587 586
588 587 If arguments are given, the following possibilities exist:
589 588
590 589 - If the argument is a filename, IPython will load that into the
591 590 editor. It will execute its contents with execfile() when you exit,
592 591 loading any code in the file into your interactive namespace.
593 592
594 593 - The arguments are ranges of input history, e.g. "7 ~1/4-6".
595 594 The syntax is the same as in the %history magic.
596 595
597 596 - If the argument is a string variable, its contents are loaded
598 597 into the editor. You can thus edit any string which contains
599 598 python code (including the result of previous edits).
600 599
601 600 - If the argument is the name of an object (other than a string),
602 601 IPython will try to locate the file where it was defined and open the
603 602 editor at the point where it is defined. You can use `%edit function`
604 603 to load an editor exactly at the point where 'function' is defined,
605 604 edit it and have the file be executed automatically.
606 605
607 606 - If the object is a macro (see %macro for details), this opens up your
608 607 specified editor with a temporary file containing the macro's data.
609 608 Upon exit, the macro is reloaded with the contents of the file.
610 609
611 610 Note: opening at an exact line is only supported under Unix, and some
612 611 editors (like kedit and gedit up to Gnome 2.8) do not understand the
613 612 '+NUMBER' parameter necessary for this feature. Good editors like
614 613 (X)Emacs, vi, jed, pico and joe all do.
615 614
616 615 After executing your code, %edit will return as output the code you
617 616 typed in the editor (except when it was an existing file). This way
618 617 you can reload the code in further invocations of %edit as a variable,
619 618 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
620 619 the output.
621 620
622 621 Note that %edit is also available through the alias %ed.
623 622
624 623 This is an example of creating a simple function inside the editor and
625 624 then modifying it. First, start up the editor::
626 625
627 626 In [1]: edit
628 627 Editing... done. Executing edited code...
629 628 Out[1]: 'def foo():\\n print "foo() was defined in an editing
630 629 session"\\n'
631 630
632 631 We can then call the function foo()::
633 632
634 633 In [2]: foo()
635 634 foo() was defined in an editing session
636 635
637 636 Now we edit foo. IPython automatically loads the editor with the
638 637 (temporary) file where foo() was previously defined::
639 638
640 639 In [3]: edit foo
641 640 Editing... done. Executing edited code...
642 641
643 642 And if we call foo() again we get the modified version::
644 643
645 644 In [4]: foo()
646 645 foo() has now been changed!
647 646
648 647 Here is an example of how to edit a code snippet successive
649 648 times. First we call the editor::
650 649
651 650 In [5]: edit
652 651 Editing... done. Executing edited code...
653 652 hello
654 653 Out[5]: "print 'hello'\\n"
655 654
656 655 Now we call it again with the previous output (stored in _)::
657 656
658 657 In [6]: edit _
659 658 Editing... done. Executing edited code...
660 659 hello world
661 660 Out[6]: "print 'hello world'\\n"
662 661
663 662 Now we call it with the output #8 (stored in _8, also as Out[8])::
664 663
665 664 In [7]: edit _8
666 665 Editing... done. Executing edited code...
667 666 hello again
668 667 Out[7]: "print 'hello again'\\n"
669 668
670 669
671 670 Changing the default editor hook:
672 671
673 672 If you wish to write your own editor hook, you can put it in a
674 673 configuration file which you load at startup time. The default hook
675 674 is defined in the IPython.core.hooks module, and you can use that as a
676 675 starting example for further modifications. That file also has
677 676 general instructions on how to set a new hook for use once you've
678 677 defined it."""
679 678 opts,args = self.parse_options(parameter_s,'prxn:')
680 679
681 680 try:
682 681 filename, lineno, is_temp = self._find_edit_target(self.shell,
683 682 args, opts, last_call)
684 683 except MacroToEdit as e:
685 684 self._edit_macro(args, e.args[0])
686 685 return
687 686 except InteractivelyDefined as e:
688 687 print("Editing In[%i]" % e.index)
689 688 args = str(e.index)
690 689 filename, lineno, is_temp = self._find_edit_target(self.shell,
691 690 args, opts, last_call)
692 691 if filename is None:
693 692 # nothing was found, warnings have already been issued,
694 693 # just give up.
695 694 return
696 695
697 696 if is_temp:
698 697 self._knowntemps.add(filename)
699 698 elif (filename in self._knowntemps):
700 699 is_temp = True
701 700
702 701
703 702 # do actual editing here
704 703 print('Editing...', end=' ')
705 704 sys.stdout.flush()
706 705 try:
707 706 # Quote filenames that may have spaces in them
708 707 if ' ' in filename:
709 708 filename = "'%s'" % filename
710 709 self.shell.hooks.editor(filename,lineno)
711 710 except TryNext:
712 711 warn('Could not open editor')
713 712 return
714 713
715 714 # XXX TODO: should this be generalized for all string vars?
716 715 # For now, this is special-cased to blocks created by cpaste
717 716 if args.strip() == 'pasted_block':
718 717 with open(filename, 'r') as f:
719 718 self.shell.user_ns['pasted_block'] = f.read()
720 719
721 720 if 'x' in opts: # -x prevents actual execution
722 721 print()
723 722 else:
724 723 print('done. Executing edited code...')
725 724 with preserve_keys(self.shell.user_ns, '__file__'):
726 725 if not is_temp:
727 726 self.shell.user_ns['__file__'] = filename
728 727 if 'r' in opts: # Untranslated IPython code
729 728 with open(filename, 'r') as f:
730 729 source = f.read()
731 730 self.shell.run_cell(source, store_history=False)
732 731 else:
733 732 self.shell.safe_execfile(filename, self.shell.user_ns,
734 733 self.shell.user_ns)
735 734
736 735 if is_temp:
737 736 try:
738 737 return open(filename).read()
739 738 except IOError as msg:
740 739 if msg.filename == filename:
741 740 warn('File not found. Did you forget to save?')
742 741 return
743 742 else:
744 743 self.shell.showtraceback()
@@ -1,1381 +1,1380 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Implementation of execution-related magic functions."""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7
8 8 import ast
9 9 import bdb
10 10 import gc
11 11 import itertools
12 12 import os
13 13 import sys
14 14 import time
15 15 import timeit
16 16 import math
17 17 from pdb import Restart
18 18
19 19 # cProfile was added in Python2.5
20 20 try:
21 21 import cProfile as profile
22 22 import pstats
23 23 except ImportError:
24 24 # profile isn't bundled by default in Debian for license reasons
25 25 try:
26 26 import profile, pstats
27 27 except ImportError:
28 28 profile = pstats = None
29 29
30 30 from IPython.core import oinspect
31 31 from IPython.core import magic_arguments
32 32 from IPython.core import page
33 33 from IPython.core.error import UsageError
34 34 from IPython.core.macro import Macro
35 35 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
36 36 line_cell_magic, on_off, needs_local_scope)
37 37 from IPython.testing.skipdoctest import skip_doctest
38 38 from IPython.utils import py3compat
39 from IPython.utils.py3compat import builtin_mod, iteritems, PY3
39 from IPython.utils.py3compat import builtin_mod, PY3
40 40 from IPython.utils.contexts import preserve_keys
41 41 from IPython.utils.capture import capture_output
42 42 from IPython.utils.ipstruct import Struct
43 43 from IPython.utils.module_paths import find_mod
44 44 from IPython.utils.path import get_py_filename, shellglob
45 45 from IPython.utils.timing import clock, clock2
46 46 from warnings import warn
47 47 from logging import error
48 48
49 49 if PY3:
50 50 from io import StringIO
51 51 else:
52 52 from StringIO import StringIO
53 53
54 54 #-----------------------------------------------------------------------------
55 55 # Magic implementation classes
56 56 #-----------------------------------------------------------------------------
57 57
58 58
59 59 class TimeitResult(object):
60 60 """
61 61 Object returned by the timeit magic with info about the run.
62 62
63 63 Contains the following attributes :
64 64
65 65 loops: (int) number of loops done per measurement
66 66 repeat: (int) number of times the measurement has been repeated
67 67 best: (float) best execution time / number
68 68 all_runs: (list of float) execution time of each run (in s)
69 69 compile_time: (float) time of statement compilation (s)
70 70
71 71 """
72 72 def __init__(self, loops, repeat, best, worst, all_runs, compile_time, precision):
73 73 self.loops = loops
74 74 self.repeat = repeat
75 75 self.best = best
76 76 self.worst = worst
77 77 self.all_runs = all_runs
78 78 self.compile_time = compile_time
79 79 self._precision = precision
80 80 self.timings = [ dt / self.loops for dt in all_runs]
81 81
82 82 @property
83 83 def average(self):
84 84 return math.fsum(self.timings) / len(self.timings)
85 85
86 86 @property
87 87 def stdev(self):
88 88 mean = self.average
89 89 return (math.fsum([(x - mean) ** 2 for x in self.timings]) / len(self.timings)) ** 0.5
90 90
91 91 def __str__(self):
92 92 return (u"%s loop%s, average of %d: %s +- %s per loop (using standard deviation)"
93 93 % (self.loops,"" if self.loops == 1 else "s", self.repeat,
94 94 _format_time(self.average, self._precision),
95 95 _format_time(self.stdev, self._precision)))
96 96
97 97 def _repr_pretty_(self, p , cycle):
98 98 unic = self.__str__()
99 99 p.text(u'<TimeitResult : '+unic+u'>')
100 100
101 101
102 102
103 103 class TimeitTemplateFiller(ast.NodeTransformer):
104 104 """Fill in the AST template for timing execution.
105 105
106 106 This is quite closely tied to the template definition, which is in
107 107 :meth:`ExecutionMagics.timeit`.
108 108 """
109 109 def __init__(self, ast_setup, ast_stmt):
110 110 self.ast_setup = ast_setup
111 111 self.ast_stmt = ast_stmt
112 112
113 113 def visit_FunctionDef(self, node):
114 114 "Fill in the setup statement"
115 115 self.generic_visit(node)
116 116 if node.name == "inner":
117 117 node.body[:1] = self.ast_setup.body
118 118
119 119 return node
120 120
121 121 def visit_For(self, node):
122 122 "Fill in the statement to be timed"
123 123 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
124 124 node.body = self.ast_stmt.body
125 125 return node
126 126
127 127
128 128 class Timer(timeit.Timer):
129 129 """Timer class that explicitly uses self.inner
130 130
131 131 which is an undocumented implementation detail of CPython,
132 132 not shared by PyPy.
133 133 """
134 134 # Timer.timeit copied from CPython 3.4.2
135 135 def timeit(self, number=timeit.default_number):
136 136 """Time 'number' executions of the main statement.
137 137
138 138 To be precise, this executes the setup statement once, and
139 139 then returns the time it takes to execute the main statement
140 140 a number of times, as a float measured in seconds. The
141 141 argument is the number of times through the loop, defaulting
142 142 to one million. The main statement, the setup statement and
143 143 the timer function to be used are passed to the constructor.
144 144 """
145 145 it = itertools.repeat(None, number)
146 146 gcold = gc.isenabled()
147 147 gc.disable()
148 148 try:
149 149 timing = self.inner(it, self.timer)
150 150 finally:
151 151 if gcold:
152 152 gc.enable()
153 153 return timing
154 154
155 155
156 156 @magics_class
157 157 class ExecutionMagics(Magics):
158 158 """Magics related to code execution, debugging, profiling, etc.
159 159
160 160 """
161 161
162 162 def __init__(self, shell):
163 163 super(ExecutionMagics, self).__init__(shell)
164 164 if profile is None:
165 165 self.prun = self.profile_missing_notice
166 166 # Default execution function used to actually run user code.
167 167 self.default_runner = None
168 168
169 169 def profile_missing_notice(self, *args, **kwargs):
170 170 error("""\
171 171 The profile module could not be found. It has been removed from the standard
172 172 python packages because of its non-free license. To use profiling, install the
173 173 python-profiler package from non-free.""")
174 174
175 175 @skip_doctest
176 176 @line_cell_magic
177 177 def prun(self, parameter_s='', cell=None):
178 178
179 179 """Run a statement through the python code profiler.
180 180
181 181 Usage, in line mode:
182 182 %prun [options] statement
183 183
184 184 Usage, in cell mode:
185 185 %%prun [options] [statement]
186 186 code...
187 187 code...
188 188
189 189 In cell mode, the additional code lines are appended to the (possibly
190 190 empty) statement in the first line. Cell mode allows you to easily
191 191 profile multiline blocks without having to put them in a separate
192 192 function.
193 193
194 194 The given statement (which doesn't require quote marks) is run via the
195 195 python profiler in a manner similar to the profile.run() function.
196 196 Namespaces are internally managed to work correctly; profile.run
197 197 cannot be used in IPython because it makes certain assumptions about
198 198 namespaces which do not hold under IPython.
199 199
200 200 Options:
201 201
202 202 -l <limit>
203 203 you can place restrictions on what or how much of the
204 204 profile gets printed. The limit value can be:
205 205
206 206 * A string: only information for function names containing this string
207 207 is printed.
208 208
209 209 * An integer: only these many lines are printed.
210 210
211 211 * A float (between 0 and 1): this fraction of the report is printed
212 212 (for example, use a limit of 0.4 to see the topmost 40% only).
213 213
214 214 You can combine several limits with repeated use of the option. For
215 215 example, ``-l __init__ -l 5`` will print only the topmost 5 lines of
216 216 information about class constructors.
217 217
218 218 -r
219 219 return the pstats.Stats object generated by the profiling. This
220 220 object has all the information about the profile in it, and you can
221 221 later use it for further analysis or in other functions.
222 222
223 223 -s <key>
224 224 sort profile by given key. You can provide more than one key
225 225 by using the option several times: '-s key1 -s key2 -s key3...'. The
226 226 default sorting key is 'time'.
227 227
228 228 The following is copied verbatim from the profile documentation
229 229 referenced below:
230 230
231 231 When more than one key is provided, additional keys are used as
232 232 secondary criteria when the there is equality in all keys selected
233 233 before them.
234 234
235 235 Abbreviations can be used for any key names, as long as the
236 236 abbreviation is unambiguous. The following are the keys currently
237 237 defined:
238 238
239 239 ============ =====================
240 240 Valid Arg Meaning
241 241 ============ =====================
242 242 "calls" call count
243 243 "cumulative" cumulative time
244 244 "file" file name
245 245 "module" file name
246 246 "pcalls" primitive call count
247 247 "line" line number
248 248 "name" function name
249 249 "nfl" name/file/line
250 250 "stdname" standard name
251 251 "time" internal time
252 252 ============ =====================
253 253
254 254 Note that all sorts on statistics are in descending order (placing
255 255 most time consuming items first), where as name, file, and line number
256 256 searches are in ascending order (i.e., alphabetical). The subtle
257 257 distinction between "nfl" and "stdname" is that the standard name is a
258 258 sort of the name as printed, which means that the embedded line
259 259 numbers get compared in an odd way. For example, lines 3, 20, and 40
260 260 would (if the file names were the same) appear in the string order
261 261 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
262 262 line numbers. In fact, sort_stats("nfl") is the same as
263 263 sort_stats("name", "file", "line").
264 264
265 265 -T <filename>
266 266 save profile results as shown on screen to a text
267 267 file. The profile is still shown on screen.
268 268
269 269 -D <filename>
270 270 save (via dump_stats) profile statistics to given
271 271 filename. This data is in a format understood by the pstats module, and
272 272 is generated by a call to the dump_stats() method of profile
273 273 objects. The profile is still shown on screen.
274 274
275 275 -q
276 276 suppress output to the pager. Best used with -T and/or -D above.
277 277
278 278 If you want to run complete programs under the profiler's control, use
279 279 ``%run -p [prof_opts] filename.py [args to program]`` where prof_opts
280 280 contains profiler specific options as described here.
281 281
282 282 You can read the complete documentation for the profile module with::
283 283
284 284 In [1]: import profile; profile.help()
285 285 """
286 286 opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q',
287 287 list_all=True, posix=False)
288 288 if cell is not None:
289 289 arg_str += '\n' + cell
290 290 arg_str = self.shell.input_splitter.transform_cell(arg_str)
291 291 return self._run_with_profiler(arg_str, opts, self.shell.user_ns)
292 292
293 293 def _run_with_profiler(self, code, opts, namespace):
294 294 """
295 295 Run `code` with profiler. Used by ``%prun`` and ``%run -p``.
296 296
297 297 Parameters
298 298 ----------
299 299 code : str
300 300 Code to be executed.
301 301 opts : Struct
302 302 Options parsed by `self.parse_options`.
303 303 namespace : dict
304 304 A dictionary for Python namespace (e.g., `self.shell.user_ns`).
305 305
306 306 """
307 307
308 308 # Fill default values for unspecified options:
309 309 opts.merge(Struct(D=[''], l=[], s=['time'], T=['']))
310 310
311 311 prof = profile.Profile()
312 312 try:
313 313 prof = prof.runctx(code, namespace, namespace)
314 314 sys_exit = ''
315 315 except SystemExit:
316 316 sys_exit = """*** SystemExit exception caught in code being profiled."""
317 317
318 318 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
319 319
320 320 lims = opts.l
321 321 if lims:
322 322 lims = [] # rebuild lims with ints/floats/strings
323 323 for lim in opts.l:
324 324 try:
325 325 lims.append(int(lim))
326 326 except ValueError:
327 327 try:
328 328 lims.append(float(lim))
329 329 except ValueError:
330 330 lims.append(lim)
331 331
332 332 # Trap output.
333 333 stdout_trap = StringIO()
334 334 stats_stream = stats.stream
335 335 try:
336 336 stats.stream = stdout_trap
337 337 stats.print_stats(*lims)
338 338 finally:
339 339 stats.stream = stats_stream
340 340
341 341 output = stdout_trap.getvalue()
342 342 output = output.rstrip()
343 343
344 344 if 'q' not in opts:
345 345 page.page(output)
346 346 print(sys_exit, end=' ')
347 347
348 348 dump_file = opts.D[0]
349 349 text_file = opts.T[0]
350 350 if dump_file:
351 351 prof.dump_stats(dump_file)
352 352 print('\n*** Profile stats marshalled to file',\
353 353 repr(dump_file)+'.',sys_exit)
354 354 if text_file:
355 355 pfile = open(text_file,'w')
356 356 pfile.write(output)
357 357 pfile.close()
358 358 print('\n*** Profile printout saved to text file',\
359 359 repr(text_file)+'.',sys_exit)
360 360
361 361 if 'r' in opts:
362 362 return stats
363 363 else:
364 364 return None
365 365
366 366 @line_magic
367 367 def pdb(self, parameter_s=''):
368 368 """Control the automatic calling of the pdb interactive debugger.
369 369
370 370 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
371 371 argument it works as a toggle.
372 372
373 373 When an exception is triggered, IPython can optionally call the
374 374 interactive pdb debugger after the traceback printout. %pdb toggles
375 375 this feature on and off.
376 376
377 377 The initial state of this feature is set in your configuration
378 378 file (the option is ``InteractiveShell.pdb``).
379 379
380 380 If you want to just activate the debugger AFTER an exception has fired,
381 381 without having to type '%pdb on' and rerunning your code, you can use
382 382 the %debug magic."""
383 383
384 384 par = parameter_s.strip().lower()
385 385
386 386 if par:
387 387 try:
388 388 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
389 389 except KeyError:
390 390 print ('Incorrect argument. Use on/1, off/0, '
391 391 'or nothing for a toggle.')
392 392 return
393 393 else:
394 394 # toggle
395 395 new_pdb = not self.shell.call_pdb
396 396
397 397 # set on the shell
398 398 self.shell.call_pdb = new_pdb
399 399 print('Automatic pdb calling has been turned',on_off(new_pdb))
400 400
401 401 @skip_doctest
402 402 @magic_arguments.magic_arguments()
403 403 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
404 404 help="""
405 405 Set break point at LINE in FILE.
406 406 """
407 407 )
408 408 @magic_arguments.argument('statement', nargs='*',
409 409 help="""
410 410 Code to run in debugger.
411 411 You can omit this in cell magic mode.
412 412 """
413 413 )
414 414 @line_cell_magic
415 415 def debug(self, line='', cell=None):
416 416 """Activate the interactive debugger.
417 417
418 418 This magic command support two ways of activating debugger.
419 419 One is to activate debugger before executing code. This way, you
420 420 can set a break point, to step through the code from the point.
421 421 You can use this mode by giving statements to execute and optionally
422 422 a breakpoint.
423 423
424 424 The other one is to activate debugger in post-mortem mode. You can
425 425 activate this mode simply running %debug without any argument.
426 426 If an exception has just occurred, this lets you inspect its stack
427 427 frames interactively. Note that this will always work only on the last
428 428 traceback that occurred, so you must call this quickly after an
429 429 exception that you wish to inspect has fired, because if another one
430 430 occurs, it clobbers the previous one.
431 431
432 432 If you want IPython to automatically do this on every exception, see
433 433 the %pdb magic for more details.
434 434 """
435 435 args = magic_arguments.parse_argstring(self.debug, line)
436 436
437 437 if not (args.breakpoint or args.statement or cell):
438 438 self._debug_post_mortem()
439 439 else:
440 440 code = "\n".join(args.statement)
441 441 if cell:
442 442 code += "\n" + cell
443 443 self._debug_exec(code, args.breakpoint)
444 444
445 445 def _debug_post_mortem(self):
446 446 self.shell.debugger(force=True)
447 447
448 448 def _debug_exec(self, code, breakpoint):
449 449 if breakpoint:
450 450 (filename, bp_line) = breakpoint.rsplit(':', 1)
451 451 bp_line = int(bp_line)
452 452 else:
453 453 (filename, bp_line) = (None, None)
454 454 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
455 455
456 456 @line_magic
457 457 def tb(self, s):
458 458 """Print the last traceback with the currently active exception mode.
459 459
460 460 See %xmode for changing exception reporting modes."""
461 461 self.shell.showtraceback()
462 462
463 463 @skip_doctest
464 464 @line_magic
465 465 def run(self, parameter_s='', runner=None,
466 466 file_finder=get_py_filename):
467 467 """Run the named file inside IPython as a program.
468 468
469 469 Usage::
470 470
471 471 %run [-n -i -e -G]
472 472 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
473 473 ( -m mod | file ) [args]
474 474
475 475 Parameters after the filename are passed as command-line arguments to
476 476 the program (put in sys.argv). Then, control returns to IPython's
477 477 prompt.
478 478
479 479 This is similar to running at a system prompt ``python file args``,
480 480 but with the advantage of giving you IPython's tracebacks, and of
481 481 loading all variables into your interactive namespace for further use
482 482 (unless -p is used, see below).
483 483
484 484 The file is executed in a namespace initially consisting only of
485 485 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
486 486 sees its environment as if it were being run as a stand-alone program
487 487 (except for sharing global objects such as previously imported
488 488 modules). But after execution, the IPython interactive namespace gets
489 489 updated with all variables defined in the program (except for __name__
490 490 and sys.argv). This allows for very convenient loading of code for
491 491 interactive work, while giving each program a 'clean sheet' to run in.
492 492
493 493 Arguments are expanded using shell-like glob match. Patterns
494 494 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
495 495 tilde '~' will be expanded into user's home directory. Unlike
496 496 real shells, quotation does not suppress expansions. Use
497 497 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
498 498 To completely disable these expansions, you can use -G flag.
499 499
500 500 Options:
501 501
502 502 -n
503 503 __name__ is NOT set to '__main__', but to the running file's name
504 504 without extension (as python does under import). This allows running
505 505 scripts and reloading the definitions in them without calling code
506 506 protected by an ``if __name__ == "__main__"`` clause.
507 507
508 508 -i
509 509 run the file in IPython's namespace instead of an empty one. This
510 510 is useful if you are experimenting with code written in a text editor
511 511 which depends on variables defined interactively.
512 512
513 513 -e
514 514 ignore sys.exit() calls or SystemExit exceptions in the script
515 515 being run. This is particularly useful if IPython is being used to
516 516 run unittests, which always exit with a sys.exit() call. In such
517 517 cases you are interested in the output of the test results, not in
518 518 seeing a traceback of the unittest module.
519 519
520 520 -t
521 521 print timing information at the end of the run. IPython will give
522 522 you an estimated CPU time consumption for your script, which under
523 523 Unix uses the resource module to avoid the wraparound problems of
524 524 time.clock(). Under Unix, an estimate of time spent on system tasks
525 525 is also given (for Windows platforms this is reported as 0.0).
526 526
527 527 If -t is given, an additional ``-N<N>`` option can be given, where <N>
528 528 must be an integer indicating how many times you want the script to
529 529 run. The final timing report will include total and per run results.
530 530
531 531 For example (testing the script uniq_stable.py)::
532 532
533 533 In [1]: run -t uniq_stable
534 534
535 535 IPython CPU timings (estimated):
536 536 User : 0.19597 s.
537 537 System: 0.0 s.
538 538
539 539 In [2]: run -t -N5 uniq_stable
540 540
541 541 IPython CPU timings (estimated):
542 542 Total runs performed: 5
543 543 Times : Total Per run
544 544 User : 0.910862 s, 0.1821724 s.
545 545 System: 0.0 s, 0.0 s.
546 546
547 547 -d
548 548 run your program under the control of pdb, the Python debugger.
549 549 This allows you to execute your program step by step, watch variables,
550 550 etc. Internally, what IPython does is similar to calling::
551 551
552 552 pdb.run('execfile("YOURFILENAME")')
553 553
554 554 with a breakpoint set on line 1 of your file. You can change the line
555 555 number for this automatic breakpoint to be <N> by using the -bN option
556 556 (where N must be an integer). For example::
557 557
558 558 %run -d -b40 myscript
559 559
560 560 will set the first breakpoint at line 40 in myscript.py. Note that
561 561 the first breakpoint must be set on a line which actually does
562 562 something (not a comment or docstring) for it to stop execution.
563 563
564 564 Or you can specify a breakpoint in a different file::
565 565
566 566 %run -d -b myotherfile.py:20 myscript
567 567
568 568 When the pdb debugger starts, you will see a (Pdb) prompt. You must
569 569 first enter 'c' (without quotes) to start execution up to the first
570 570 breakpoint.
571 571
572 572 Entering 'help' gives information about the use of the debugger. You
573 573 can easily see pdb's full documentation with "import pdb;pdb.help()"
574 574 at a prompt.
575 575
576 576 -p
577 577 run program under the control of the Python profiler module (which
578 578 prints a detailed report of execution times, function calls, etc).
579 579
580 580 You can pass other options after -p which affect the behavior of the
581 581 profiler itself. See the docs for %prun for details.
582 582
583 583 In this mode, the program's variables do NOT propagate back to the
584 584 IPython interactive namespace (because they remain in the namespace
585 585 where the profiler executes them).
586 586
587 587 Internally this triggers a call to %prun, see its documentation for
588 588 details on the options available specifically for profiling.
589 589
590 590 There is one special usage for which the text above doesn't apply:
591 591 if the filename ends with .ipy[nb], the file is run as ipython script,
592 592 just as if the commands were written on IPython prompt.
593 593
594 594 -m
595 595 specify module name to load instead of script path. Similar to
596 596 the -m option for the python interpreter. Use this option last if you
597 597 want to combine with other %run options. Unlike the python interpreter
598 598 only source modules are allowed no .pyc or .pyo files.
599 599 For example::
600 600
601 601 %run -m example
602 602
603 603 will run the example module.
604 604
605 605 -G
606 606 disable shell-like glob expansion of arguments.
607 607
608 608 """
609 609
610 610 # get arguments and set sys.argv for program to be run.
611 611 opts, arg_lst = self.parse_options(parameter_s,
612 612 'nidtN:b:pD:l:rs:T:em:G',
613 613 mode='list', list_all=1)
614 614 if "m" in opts:
615 615 modulename = opts["m"][0]
616 616 modpath = find_mod(modulename)
617 617 if modpath is None:
618 618 warn('%r is not a valid modulename on sys.path'%modulename)
619 619 return
620 620 arg_lst = [modpath] + arg_lst
621 621 try:
622 622 filename = file_finder(arg_lst[0])
623 623 except IndexError:
624 624 warn('you must provide at least a filename.')
625 625 print('\n%run:\n', oinspect.getdoc(self.run))
626 626 return
627 627 except IOError as e:
628 628 try:
629 629 msg = str(e)
630 630 except UnicodeError:
631 631 msg = e.message
632 632 error(msg)
633 633 return
634 634
635 635 if filename.lower().endswith(('.ipy', '.ipynb')):
636 636 with preserve_keys(self.shell.user_ns, '__file__'):
637 637 self.shell.user_ns['__file__'] = filename
638 638 self.shell.safe_execfile_ipy(filename)
639 639 return
640 640
641 641 # Control the response to exit() calls made by the script being run
642 642 exit_ignore = 'e' in opts
643 643
644 644 # Make sure that the running script gets a proper sys.argv as if it
645 645 # were run from a system shell.
646 646 save_argv = sys.argv # save it for later restoring
647 647
648 648 if 'G' in opts:
649 649 args = arg_lst[1:]
650 650 else:
651 651 # tilde and glob expansion
652 652 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
653 653
654 654 sys.argv = [filename] + args # put in the proper filename
655 655 # protect sys.argv from potential unicode strings on Python 2:
656 656 if not py3compat.PY3:
657 657 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
658 658
659 659 if 'i' in opts:
660 660 # Run in user's interactive namespace
661 661 prog_ns = self.shell.user_ns
662 662 __name__save = self.shell.user_ns['__name__']
663 663 prog_ns['__name__'] = '__main__'
664 664 main_mod = self.shell.user_module
665 665
666 666 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
667 667 # set the __file__ global in the script's namespace
668 668 # TK: Is this necessary in interactive mode?
669 669 prog_ns['__file__'] = filename
670 670 else:
671 671 # Run in a fresh, empty namespace
672 672 if 'n' in opts:
673 673 name = os.path.splitext(os.path.basename(filename))[0]
674 674 else:
675 675 name = '__main__'
676 676
677 677 # The shell MUST hold a reference to prog_ns so after %run
678 678 # exits, the python deletion mechanism doesn't zero it out
679 679 # (leaving dangling references). See interactiveshell for details
680 680 main_mod = self.shell.new_main_mod(filename, name)
681 681 prog_ns = main_mod.__dict__
682 682
683 683 # pickle fix. See interactiveshell for an explanation. But we need to
684 684 # make sure that, if we overwrite __main__, we replace it at the end
685 685 main_mod_name = prog_ns['__name__']
686 686
687 687 if main_mod_name == '__main__':
688 688 restore_main = sys.modules['__main__']
689 689 else:
690 690 restore_main = False
691 691
692 692 # This needs to be undone at the end to prevent holding references to
693 693 # every single object ever created.
694 694 sys.modules[main_mod_name] = main_mod
695 695
696 696 if 'p' in opts or 'd' in opts:
697 697 if 'm' in opts:
698 698 code = 'run_module(modulename, prog_ns)'
699 699 code_ns = {
700 700 'run_module': self.shell.safe_run_module,
701 701 'prog_ns': prog_ns,
702 702 'modulename': modulename,
703 703 }
704 704 else:
705 705 if 'd' in opts:
706 706 # allow exceptions to raise in debug mode
707 707 code = 'execfile(filename, prog_ns, raise_exceptions=True)'
708 708 else:
709 709 code = 'execfile(filename, prog_ns)'
710 710 code_ns = {
711 711 'execfile': self.shell.safe_execfile,
712 712 'prog_ns': prog_ns,
713 713 'filename': get_py_filename(filename),
714 714 }
715 715
716 716 try:
717 717 stats = None
718 718 if 'p' in opts:
719 719 stats = self._run_with_profiler(code, opts, code_ns)
720 720 else:
721 721 if 'd' in opts:
722 722 bp_file, bp_line = parse_breakpoint(
723 723 opts.get('b', ['1'])[0], filename)
724 724 self._run_with_debugger(
725 725 code, code_ns, filename, bp_line, bp_file)
726 726 else:
727 727 if 'm' in opts:
728 728 def run():
729 729 self.shell.safe_run_module(modulename, prog_ns)
730 730 else:
731 731 if runner is None:
732 732 runner = self.default_runner
733 733 if runner is None:
734 734 runner = self.shell.safe_execfile
735 735
736 736 def run():
737 737 runner(filename, prog_ns, prog_ns,
738 738 exit_ignore=exit_ignore)
739 739
740 740 if 't' in opts:
741 741 # timed execution
742 742 try:
743 743 nruns = int(opts['N'][0])
744 744 if nruns < 1:
745 745 error('Number of runs must be >=1')
746 746 return
747 747 except (KeyError):
748 748 nruns = 1
749 749 self._run_with_timing(run, nruns)
750 750 else:
751 751 # regular execution
752 752 run()
753 753
754 754 if 'i' in opts:
755 755 self.shell.user_ns['__name__'] = __name__save
756 756 else:
757 757 # update IPython interactive namespace
758 758
759 759 # Some forms of read errors on the file may mean the
760 760 # __name__ key was never set; using pop we don't have to
761 761 # worry about a possible KeyError.
762 762 prog_ns.pop('__name__', None)
763 763
764 764 with preserve_keys(self.shell.user_ns, '__file__'):
765 765 self.shell.user_ns.update(prog_ns)
766 766 finally:
767 767 # It's a bit of a mystery why, but __builtins__ can change from
768 768 # being a module to becoming a dict missing some key data after
769 769 # %run. As best I can see, this is NOT something IPython is doing
770 770 # at all, and similar problems have been reported before:
771 771 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
772 772 # Since this seems to be done by the interpreter itself, the best
773 773 # we can do is to at least restore __builtins__ for the user on
774 774 # exit.
775 775 self.shell.user_ns['__builtins__'] = builtin_mod
776 776
777 777 # Ensure key global structures are restored
778 778 sys.argv = save_argv
779 779 if restore_main:
780 780 sys.modules['__main__'] = restore_main
781 781 else:
782 782 # Remove from sys.modules the reference to main_mod we'd
783 783 # added. Otherwise it will trap references to objects
784 784 # contained therein.
785 785 del sys.modules[main_mod_name]
786 786
787 787 return stats
788 788
789 789 def _run_with_debugger(self, code, code_ns, filename=None,
790 790 bp_line=None, bp_file=None):
791 791 """
792 792 Run `code` in debugger with a break point.
793 793
794 794 Parameters
795 795 ----------
796 796 code : str
797 797 Code to execute.
798 798 code_ns : dict
799 799 A namespace in which `code` is executed.
800 800 filename : str
801 801 `code` is ran as if it is in `filename`.
802 802 bp_line : int, optional
803 803 Line number of the break point.
804 804 bp_file : str, optional
805 805 Path to the file in which break point is specified.
806 806 `filename` is used if not given.
807 807
808 808 Raises
809 809 ------
810 810 UsageError
811 811 If the break point given by `bp_line` is not valid.
812 812
813 813 """
814 814 deb = self.shell.InteractiveTB.pdb
815 815 if not deb:
816 816 self.shell.InteractiveTB.pdb = self.shell.InteractiveTB.debugger_cls()
817 817 deb = self.shell.InteractiveTB.pdb
818 818
819 819 # deb.checkline() fails if deb.curframe exists but is None; it can
820 820 # handle it not existing. https://github.com/ipython/ipython/issues/10028
821 821 if hasattr(deb, 'curframe'):
822 822 del deb.curframe
823 823
824 824 # reset Breakpoint state, which is moronically kept
825 825 # in a class
826 826 bdb.Breakpoint.next = 1
827 827 bdb.Breakpoint.bplist = {}
828 828 bdb.Breakpoint.bpbynumber = [None]
829 829 if bp_line is not None:
830 830 # Set an initial breakpoint to stop execution
831 831 maxtries = 10
832 832 bp_file = bp_file or filename
833 833 checkline = deb.checkline(bp_file, bp_line)
834 834 if not checkline:
835 835 for bp in range(bp_line + 1, bp_line + maxtries + 1):
836 836 if deb.checkline(bp_file, bp):
837 837 break
838 838 else:
839 839 msg = ("\nI failed to find a valid line to set "
840 840 "a breakpoint\n"
841 841 "after trying up to line: %s.\n"
842 842 "Please set a valid breakpoint manually "
843 843 "with the -b option." % bp)
844 844 raise UsageError(msg)
845 845 # if we find a good linenumber, set the breakpoint
846 846 deb.do_break('%s:%s' % (bp_file, bp_line))
847 847
848 848 if filename:
849 849 # Mimic Pdb._runscript(...)
850 850 deb._wait_for_mainpyfile = True
851 851 deb.mainpyfile = deb.canonic(filename)
852 852
853 853 # Start file run
854 854 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
855 855 try:
856 856 if filename:
857 857 # save filename so it can be used by methods on the deb object
858 858 deb._exec_filename = filename
859 859 while True:
860 860 try:
861 861 deb.run(code, code_ns)
862 862 except Restart:
863 863 print("Restarting")
864 864 if filename:
865 865 deb._wait_for_mainpyfile = True
866 866 deb.mainpyfile = deb.canonic(filename)
867 867 continue
868 868 else:
869 869 break
870 870
871 871
872 872 except:
873 873 etype, value, tb = sys.exc_info()
874 874 # Skip three frames in the traceback: the %run one,
875 875 # one inside bdb.py, and the command-line typed by the
876 876 # user (run by exec in pdb itself).
877 877 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
878 878
879 879 @staticmethod
880 880 def _run_with_timing(run, nruns):
881 881 """
882 882 Run function `run` and print timing information.
883 883
884 884 Parameters
885 885 ----------
886 886 run : callable
887 887 Any callable object which takes no argument.
888 888 nruns : int
889 889 Number of times to execute `run`.
890 890
891 891 """
892 892 twall0 = time.time()
893 893 if nruns == 1:
894 894 t0 = clock2()
895 895 run()
896 896 t1 = clock2()
897 897 t_usr = t1[0] - t0[0]
898 898 t_sys = t1[1] - t0[1]
899 899 print("\nIPython CPU timings (estimated):")
900 900 print(" User : %10.2f s." % t_usr)
901 901 print(" System : %10.2f s." % t_sys)
902 902 else:
903 903 runs = range(nruns)
904 904 t0 = clock2()
905 905 for nr in runs:
906 906 run()
907 907 t1 = clock2()
908 908 t_usr = t1[0] - t0[0]
909 909 t_sys = t1[1] - t0[1]
910 910 print("\nIPython CPU timings (estimated):")
911 911 print("Total runs performed:", nruns)
912 912 print(" Times : %10s %10s" % ('Total', 'Per run'))
913 913 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
914 914 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
915 915 twall1 = time.time()
916 916 print("Wall time: %10.2f s." % (twall1 - twall0))
917 917
918 918 @skip_doctest
919 919 @line_cell_magic
920 920 def timeit(self, line='', cell=None):
921 921 """Time execution of a Python statement or expression
922 922
923 923 Usage, in line mode:
924 924 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
925 925 or in cell mode:
926 926 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
927 927 code
928 928 code...
929 929
930 930 Time execution of a Python statement or expression using the timeit
931 931 module. This function can be used both as a line and cell magic:
932 932
933 933 - In line mode you can time a single-line statement (though multiple
934 934 ones can be chained with using semicolons).
935 935
936 936 - In cell mode, the statement in the first line is used as setup code
937 937 (executed but not timed) and the body of the cell is timed. The cell
938 938 body has access to any variables created in the setup code.
939 939
940 940 Options:
941 941 -n<N>: execute the given statement <N> times in a loop. If this value
942 942 is not given, a fitting value is chosen.
943 943
944 944 -r<R>: repeat the loop iteration <R> times and take the best result.
945 945 Default: 3
946 946
947 947 -t: use time.time to measure the time, which is the default on Unix.
948 948 This function measures wall time.
949 949
950 950 -c: use time.clock to measure the time, which is the default on
951 951 Windows and measures wall time. On Unix, resource.getrusage is used
952 952 instead and returns the CPU user time.
953 953
954 954 -p<P>: use a precision of <P> digits to display the timing result.
955 955 Default: 3
956 956
957 957 -q: Quiet, do not print result.
958 958
959 959 -o: return a TimeitResult that can be stored in a variable to inspect
960 960 the result in more details.
961 961
962 962
963 963 Examples
964 964 --------
965 965 ::
966 966
967 967 In [1]: %timeit pass
968 968 100000000 loops, average of 7: 5.48 ns +- 0.354 ns per loop (using standard deviation)
969 969
970 970 In [2]: u = None
971 971
972 972 In [3]: %timeit u is None
973 973 10000000 loops, average of 7: 22.7 ns +- 2.33 ns per loop (using standard deviation)
974 974
975 975 In [4]: %timeit -r 4 u == None
976 976 10000000 loops, average of 4: 27.5 ns +- 2.91 ns per loop (using standard deviation)
977 977
978 978 In [5]: import time
979 979
980 980 In [6]: %timeit -n1 time.sleep(2)
981 981 1 loop, average of 7: 2 s +- 4.71 µs per loop (using standard deviation)
982 982
983 983
984 984 The times reported by %timeit will be slightly higher than those
985 985 reported by the timeit.py script when variables are accessed. This is
986 986 due to the fact that %timeit executes the statement in the namespace
987 987 of the shell, compared with timeit.py, which uses a single setup
988 988 statement to import function or create variables. Generally, the bias
989 989 does not matter as long as results from timeit.py are not mixed with
990 990 those from %timeit."""
991 991
992 992 opts, stmt = self.parse_options(line,'n:r:tcp:qo',
993 993 posix=False, strict=False)
994 994 if stmt == "" and cell is None:
995 995 return
996 996
997 997 timefunc = timeit.default_timer
998 998 number = int(getattr(opts, "n", 0))
999 999 default_repeat = 7 if timeit.default_repeat < 7 else timeit.default_repeat
1000 1000 repeat = int(getattr(opts, "r", default_repeat))
1001 1001 precision = int(getattr(opts, "p", 3))
1002 1002 quiet = 'q' in opts
1003 1003 return_result = 'o' in opts
1004 1004 if hasattr(opts, "t"):
1005 1005 timefunc = time.time
1006 1006 if hasattr(opts, "c"):
1007 1007 timefunc = clock
1008 1008
1009 1009 timer = Timer(timer=timefunc)
1010 1010 # this code has tight coupling to the inner workings of timeit.Timer,
1011 1011 # but is there a better way to achieve that the code stmt has access
1012 1012 # to the shell namespace?
1013 1013 transform = self.shell.input_splitter.transform_cell
1014 1014
1015 1015 if cell is None:
1016 1016 # called as line magic
1017 1017 ast_setup = self.shell.compile.ast_parse("pass")
1018 1018 ast_stmt = self.shell.compile.ast_parse(transform(stmt))
1019 1019 else:
1020 1020 ast_setup = self.shell.compile.ast_parse(transform(stmt))
1021 1021 ast_stmt = self.shell.compile.ast_parse(transform(cell))
1022 1022
1023 1023 ast_setup = self.shell.transform_ast(ast_setup)
1024 1024 ast_stmt = self.shell.transform_ast(ast_stmt)
1025 1025
1026 1026 # This codestring is taken from timeit.template - we fill it in as an
1027 1027 # AST, so that we can apply our AST transformations to the user code
1028 1028 # without affecting the timing code.
1029 1029 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
1030 1030 ' setup\n'
1031 1031 ' _t0 = _timer()\n'
1032 1032 ' for _i in _it:\n'
1033 1033 ' stmt\n'
1034 1034 ' _t1 = _timer()\n'
1035 1035 ' return _t1 - _t0\n')
1036 1036
1037 1037 timeit_ast = TimeitTemplateFiller(ast_setup, ast_stmt).visit(timeit_ast_template)
1038 1038 timeit_ast = ast.fix_missing_locations(timeit_ast)
1039 1039
1040 1040 # Track compilation time so it can be reported if too long
1041 1041 # Minimum time above which compilation time will be reported
1042 1042 tc_min = 0.1
1043 1043
1044 1044 t0 = clock()
1045 1045 code = self.shell.compile(timeit_ast, "<magic-timeit>", "exec")
1046 1046 tc = clock()-t0
1047 1047
1048 1048 ns = {}
1049 1049 exec(code, self.shell.user_ns, ns)
1050 1050 timer.inner = ns["inner"]
1051 1051
1052 1052 # This is used to check if there is a huge difference between the
1053 1053 # best and worst timings.
1054 1054 # Issue: https://github.com/ipython/ipython/issues/6471
1055 1055 if number == 0:
1056 1056 # determine number so that 0.2 <= total time < 2.0
1057 1057 for index in range(0, 10):
1058 1058 number = 10 ** index
1059 1059 time_number = timer.timeit(number)
1060 1060 if time_number >= 0.2:
1061 1061 break
1062 1062
1063 1063 all_runs = timer.repeat(repeat, number)
1064 1064 best = min(all_runs) / number
1065 1065 worst = max(all_runs) / number
1066 1066 timeit_result = TimeitResult(number, repeat, best, worst, all_runs, tc, precision)
1067 1067
1068 1068 if not quiet :
1069 1069 # Check best timing is greater than zero to avoid a
1070 1070 # ZeroDivisionError.
1071 1071 # In cases where the slowest timing is lesser than a micosecond
1072 1072 # we assume that it does not really matter if the fastest
1073 1073 # timing is 4 times faster than the slowest timing or not.
1074 1074 if worst > 4 * best and best > 0 and worst > 1e-6:
1075 1075 print("The slowest run took %0.2f times longer than the "
1076 1076 "fastest. This could mean that an intermediate result "
1077 1077 "is being cached." % (worst / best))
1078 1078
1079 1079 print( timeit_result )
1080 1080
1081 1081 if tc > tc_min:
1082 1082 print("Compiler time: %.2f s" % tc)
1083 1083 if return_result:
1084 1084 return timeit_result
1085 1085
1086 1086 @skip_doctest
1087 1087 @needs_local_scope
1088 1088 @line_cell_magic
1089 1089 def time(self,line='', cell=None, local_ns=None):
1090 1090 """Time execution of a Python statement or expression.
1091 1091
1092 1092 The CPU and wall clock times are printed, and the value of the
1093 1093 expression (if any) is returned. Note that under Win32, system time
1094 1094 is always reported as 0, since it can not be measured.
1095 1095
1096 1096 This function can be used both as a line and cell magic:
1097 1097
1098 1098 - In line mode you can time a single-line statement (though multiple
1099 1099 ones can be chained with using semicolons).
1100 1100
1101 1101 - In cell mode, you can time the cell body (a directly
1102 1102 following statement raises an error).
1103 1103
1104 1104 This function provides very basic timing functionality. Use the timeit
1105 1105 magic for more control over the measurement.
1106 1106
1107 1107 Examples
1108 1108 --------
1109 1109 ::
1110 1110
1111 1111 In [1]: %time 2**128
1112 1112 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1113 1113 Wall time: 0.00
1114 1114 Out[1]: 340282366920938463463374607431768211456L
1115 1115
1116 1116 In [2]: n = 1000000
1117 1117
1118 1118 In [3]: %time sum(range(n))
1119 1119 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1120 1120 Wall time: 1.37
1121 1121 Out[3]: 499999500000L
1122 1122
1123 1123 In [4]: %time print 'hello world'
1124 1124 hello world
1125 1125 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1126 1126 Wall time: 0.00
1127 1127
1128 1128 Note that the time needed by Python to compile the given expression
1129 1129 will be reported if it is more than 0.1s. In this example, the
1130 1130 actual exponentiation is done by Python at compilation time, so while
1131 1131 the expression can take a noticeable amount of time to compute, that
1132 1132 time is purely due to the compilation:
1133 1133
1134 1134 In [5]: %time 3**9999;
1135 1135 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1136 1136 Wall time: 0.00 s
1137 1137
1138 1138 In [6]: %time 3**999999;
1139 1139 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1140 1140 Wall time: 0.00 s
1141 1141 Compiler : 0.78 s
1142 1142 """
1143 1143
1144 1144 # fail immediately if the given expression can't be compiled
1145 1145
1146 1146 if line and cell:
1147 1147 raise UsageError("Can't use statement directly after '%%time'!")
1148 1148
1149 1149 if cell:
1150 1150 expr = self.shell.input_transformer_manager.transform_cell(cell)
1151 1151 else:
1152 1152 expr = self.shell.input_transformer_manager.transform_cell(line)
1153 1153
1154 1154 # Minimum time above which parse time will be reported
1155 1155 tp_min = 0.1
1156 1156
1157 1157 t0 = clock()
1158 1158 expr_ast = self.shell.compile.ast_parse(expr)
1159 1159 tp = clock()-t0
1160 1160
1161 1161 # Apply AST transformations
1162 1162 expr_ast = self.shell.transform_ast(expr_ast)
1163 1163
1164 1164 # Minimum time above which compilation time will be reported
1165 1165 tc_min = 0.1
1166 1166
1167 1167 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1168 1168 mode = 'eval'
1169 1169 source = '<timed eval>'
1170 1170 expr_ast = ast.Expression(expr_ast.body[0].value)
1171 1171 else:
1172 1172 mode = 'exec'
1173 1173 source = '<timed exec>'
1174 1174 t0 = clock()
1175 1175 code = self.shell.compile(expr_ast, source, mode)
1176 1176 tc = clock()-t0
1177 1177
1178 1178 # skew measurement as little as possible
1179 1179 glob = self.shell.user_ns
1180 1180 wtime = time.time
1181 1181 # time execution
1182 1182 wall_st = wtime()
1183 1183 if mode=='eval':
1184 1184 st = clock2()
1185 1185 try:
1186 1186 out = eval(code, glob, local_ns)
1187 1187 except:
1188 1188 self.shell.showtraceback()
1189 1189 return
1190 1190 end = clock2()
1191 1191 else:
1192 1192 st = clock2()
1193 1193 try:
1194 1194 exec(code, glob, local_ns)
1195 1195 except:
1196 1196 self.shell.showtraceback()
1197 1197 return
1198 1198 end = clock2()
1199 1199 out = None
1200 1200 wall_end = wtime()
1201 1201 # Compute actual times and report
1202 1202 wall_time = wall_end-wall_st
1203 1203 cpu_user = end[0]-st[0]
1204 1204 cpu_sys = end[1]-st[1]
1205 1205 cpu_tot = cpu_user+cpu_sys
1206 1206 # On windows cpu_sys is always zero, so no new information to the next print
1207 1207 if sys.platform != 'win32':
1208 1208 print("CPU times: user %s, sys: %s, total: %s" % \
1209 1209 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1210 1210 print("Wall time: %s" % _format_time(wall_time))
1211 1211 if tc > tc_min:
1212 1212 print("Compiler : %s" % _format_time(tc))
1213 1213 if tp > tp_min:
1214 1214 print("Parser : %s" % _format_time(tp))
1215 1215 return out
1216 1216
1217 1217 @skip_doctest
1218 1218 @line_magic
1219 1219 def macro(self, parameter_s=''):
1220 1220 """Define a macro for future re-execution. It accepts ranges of history,
1221 1221 filenames or string objects.
1222 1222
1223 1223 Usage:\\
1224 1224 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1225 1225
1226 1226 Options:
1227 1227
1228 1228 -r: use 'raw' input. By default, the 'processed' history is used,
1229 1229 so that magics are loaded in their transformed version to valid
1230 1230 Python. If this option is given, the raw input as typed at the
1231 1231 command line is used instead.
1232 1232
1233 1233 -q: quiet macro definition. By default, a tag line is printed
1234 1234 to indicate the macro has been created, and then the contents of
1235 1235 the macro are printed. If this option is given, then no printout
1236 1236 is produced once the macro is created.
1237 1237
1238 1238 This will define a global variable called `name` which is a string
1239 1239 made of joining the slices and lines you specify (n1,n2,... numbers
1240 1240 above) from your input history into a single string. This variable
1241 1241 acts like an automatic function which re-executes those lines as if
1242 1242 you had typed them. You just type 'name' at the prompt and the code
1243 1243 executes.
1244 1244
1245 1245 The syntax for indicating input ranges is described in %history.
1246 1246
1247 1247 Note: as a 'hidden' feature, you can also use traditional python slice
1248 1248 notation, where N:M means numbers N through M-1.
1249 1249
1250 1250 For example, if your history contains (print using %hist -n )::
1251 1251
1252 1252 44: x=1
1253 1253 45: y=3
1254 1254 46: z=x+y
1255 1255 47: print x
1256 1256 48: a=5
1257 1257 49: print 'x',x,'y',y
1258 1258
1259 1259 you can create a macro with lines 44 through 47 (included) and line 49
1260 1260 called my_macro with::
1261 1261
1262 1262 In [55]: %macro my_macro 44-47 49
1263 1263
1264 1264 Now, typing `my_macro` (without quotes) will re-execute all this code
1265 1265 in one pass.
1266 1266
1267 1267 You don't need to give the line-numbers in order, and any given line
1268 1268 number can appear multiple times. You can assemble macros with any
1269 1269 lines from your input history in any order.
1270 1270
1271 1271 The macro is a simple object which holds its value in an attribute,
1272 1272 but IPython's display system checks for macros and executes them as
1273 1273 code instead of printing them when you type their name.
1274 1274
1275 1275 You can view a macro's contents by explicitly printing it with::
1276 1276
1277 1277 print macro_name
1278 1278
1279 1279 """
1280 1280 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1281 1281 if not args: # List existing macros
1282 return sorted(k for k,v in iteritems(self.shell.user_ns) if\
1283 isinstance(v, Macro))
1282 return sorted(k for k,v in self.shell.user_ns.items() if isinstance(v, Macro))
1284 1283 if len(args) == 1:
1285 1284 raise UsageError(
1286 1285 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1287 1286 name, codefrom = args[0], " ".join(args[1:])
1288 1287
1289 1288 #print 'rng',ranges # dbg
1290 1289 try:
1291 1290 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1292 1291 except (ValueError, TypeError) as e:
1293 1292 print(e.args[0])
1294 1293 return
1295 1294 macro = Macro(lines)
1296 1295 self.shell.define_macro(name, macro)
1297 1296 if not ( 'q' in opts) :
1298 1297 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1299 1298 print('=== Macro contents: ===')
1300 1299 print(macro, end=' ')
1301 1300
1302 1301 @magic_arguments.magic_arguments()
1303 1302 @magic_arguments.argument('output', type=str, default='', nargs='?',
1304 1303 help="""The name of the variable in which to store output.
1305 1304 This is a utils.io.CapturedIO object with stdout/err attributes
1306 1305 for the text of the captured output.
1307 1306
1308 1307 CapturedOutput also has a show() method for displaying the output,
1309 1308 and __call__ as well, so you can use that to quickly display the
1310 1309 output.
1311 1310
1312 1311 If unspecified, captured output is discarded.
1313 1312 """
1314 1313 )
1315 1314 @magic_arguments.argument('--no-stderr', action="store_true",
1316 1315 help="""Don't capture stderr."""
1317 1316 )
1318 1317 @magic_arguments.argument('--no-stdout', action="store_true",
1319 1318 help="""Don't capture stdout."""
1320 1319 )
1321 1320 @magic_arguments.argument('--no-display', action="store_true",
1322 1321 help="""Don't capture IPython's rich display."""
1323 1322 )
1324 1323 @cell_magic
1325 1324 def capture(self, line, cell):
1326 1325 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1327 1326 args = magic_arguments.parse_argstring(self.capture, line)
1328 1327 out = not args.no_stdout
1329 1328 err = not args.no_stderr
1330 1329 disp = not args.no_display
1331 1330 with capture_output(out, err, disp) as io:
1332 1331 self.shell.run_cell(cell)
1333 1332 if args.output:
1334 1333 self.shell.user_ns[args.output] = io
1335 1334
1336 1335 def parse_breakpoint(text, current_file):
1337 1336 '''Returns (file, line) for file:line and (current_file, line) for line'''
1338 1337 colon = text.find(':')
1339 1338 if colon == -1:
1340 1339 return current_file, int(text)
1341 1340 else:
1342 1341 return text[:colon], int(text[colon+1:])
1343 1342
1344 1343 def _format_time(timespan, precision=3):
1345 1344 """Formats the timespan in a human readable form"""
1346 1345
1347 1346 if timespan >= 60.0:
1348 1347 # we have more than a minute, format that in a human readable form
1349 1348 # Idea from http://snipplr.com/view/5713/
1350 1349 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1351 1350 time = []
1352 1351 leftover = timespan
1353 1352 for suffix, length in parts:
1354 1353 value = int(leftover / length)
1355 1354 if value > 0:
1356 1355 leftover = leftover % length
1357 1356 time.append(u'%s%s' % (str(value), suffix))
1358 1357 if leftover < 1:
1359 1358 break
1360 1359 return " ".join(time)
1361 1360
1362 1361
1363 1362 # Unfortunately the unicode 'micro' symbol can cause problems in
1364 1363 # certain terminals.
1365 1364 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1366 1365 # Try to prevent crashes by being more secure than it needs to
1367 1366 # E.g. eclipse is able to print a µ, but has no sys.stdout.encoding set.
1368 1367 units = [u"s", u"ms",u'us',"ns"] # the save value
1369 1368 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1370 1369 try:
1371 1370 u'\xb5'.encode(sys.stdout.encoding)
1372 1371 units = [u"s", u"ms",u'\xb5s',"ns"]
1373 1372 except:
1374 1373 pass
1375 1374 scaling = [1, 1e3, 1e6, 1e9]
1376 1375
1377 1376 if timespan > 0.0:
1378 1377 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1379 1378 else:
1380 1379 order = 3
1381 1380 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
@@ -1,184 +1,183 b''
1 1 """Implementation of magic functions for IPython's own logging.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (c) 2012 The IPython Development Team.
5 5 #
6 6 # Distributed under the terms of the Modified BSD License.
7 7 #
8 8 # The full license is in the file COPYING.txt, distributed with this software.
9 9 #-----------------------------------------------------------------------------
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14
15 15 # Stdlib
16 16 import os
17 17 import sys
18 18
19 19 # Our own packages
20 20 from IPython.core.magic import Magics, magics_class, line_magic
21 21 from warnings import warn
22 from IPython.utils.py3compat import str_to_unicode
23 22
24 23 #-----------------------------------------------------------------------------
25 24 # Magic implementation classes
26 25 #-----------------------------------------------------------------------------
27 26
28 27 @magics_class
29 28 class LoggingMagics(Magics):
30 29 """Magics related to all logging machinery."""
31 30
32 31 @line_magic
33 32 def logstart(self, parameter_s=''):
34 33 """Start logging anywhere in a session.
35 34
36 35 %logstart [-o|-r|-t] [log_name [log_mode]]
37 36
38 37 If no name is given, it defaults to a file named 'ipython_log.py' in your
39 38 current directory, in 'rotate' mode (see below).
40 39
41 40 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
42 41 history up to that point and then continues logging.
43 42
44 43 %logstart takes a second optional parameter: logging mode. This can be one
45 44 of (note that the modes are given unquoted):
46 45
47 46 append
48 47 Keep logging at the end of any existing file.
49 48
50 49 backup
51 50 Rename any existing file to name~ and start name.
52 51
53 52 global
54 53 Append to a single logfile in your home directory.
55 54
56 55 over
57 56 Overwrite any existing log.
58 57
59 58 rotate
60 59 Create rotating logs: name.1~, name.2~, etc.
61 60
62 61 Options:
63 62
64 63 -o
65 64 log also IPython's output. In this mode, all commands which
66 65 generate an Out[NN] prompt are recorded to the logfile, right after
67 66 their corresponding input line. The output lines are always
68 67 prepended with a '#[Out]# ' marker, so that the log remains valid
69 68 Python code.
70 69
71 70 Since this marker is always the same, filtering only the output from
72 71 a log is very easy, using for example a simple awk call::
73 72
74 73 awk -F'#\\[Out\\]# ' '{if($2) {print $2}}' ipython_log.py
75 74
76 75 -r
77 76 log 'raw' input. Normally, IPython's logs contain the processed
78 77 input, so that user lines are logged in their final form, converted
79 78 into valid Python. For example, %Exit is logged as
80 79 _ip.magic("Exit"). If the -r flag is given, all input is logged
81 80 exactly as typed, with no transformations applied.
82 81
83 82 -t
84 83 put timestamps before each input line logged (these are put in
85 84 comments).
86 85 """
87 86
88 87 opts,par = self.parse_options(parameter_s,'ort')
89 88 log_output = 'o' in opts
90 89 log_raw_input = 'r' in opts
91 90 timestamp = 't' in opts
92 91
93 92 logger = self.shell.logger
94 93
95 94 # if no args are given, the defaults set in the logger constructor by
96 95 # ipython remain valid
97 96 if par:
98 97 try:
99 98 logfname,logmode = par.split()
100 99 except:
101 100 logfname = par
102 101 logmode = 'backup'
103 102 else:
104 103 logfname = logger.logfname
105 104 logmode = logger.logmode
106 105 # put logfname into rc struct as if it had been called on the command
107 106 # line, so it ends up saved in the log header Save it in case we need
108 107 # to restore it...
109 108 old_logfile = self.shell.logfile
110 109 if logfname:
111 110 logfname = os.path.expanduser(logfname)
112 111 self.shell.logfile = logfname
113 112
114 113 loghead = u'# IPython log file\n\n'
115 114 try:
116 115 logger.logstart(logfname, loghead, logmode, log_output, timestamp,
117 116 log_raw_input)
118 117 except:
119 118 self.shell.logfile = old_logfile
120 119 warn("Couldn't start log: %s" % sys.exc_info()[1])
121 120 else:
122 121 # log input history up to this point, optionally interleaving
123 122 # output if requested
124 123
125 124 if timestamp:
126 125 # disable timestamping for the previous history, since we've
127 126 # lost those already (no time machine here).
128 127 logger.timestamp = False
129 128
130 129 if log_raw_input:
131 130 input_hist = self.shell.history_manager.input_hist_raw
132 131 else:
133 132 input_hist = self.shell.history_manager.input_hist_parsed
134 133
135 134 if log_output:
136 135 log_write = logger.log_write
137 136 output_hist = self.shell.history_manager.output_hist
138 137 for n in range(1,len(input_hist)-1):
139 138 log_write(input_hist[n].rstrip() + u'\n')
140 139 if n in output_hist:
141 log_write(str_to_unicode(repr(output_hist[n])),'output')
140 log_write(repr(output_hist[n]),'output')
142 141 else:
143 142 logger.log_write(u'\n'.join(input_hist[1:]))
144 143 logger.log_write(u'\n')
145 144 if timestamp:
146 145 # re-enable timestamping
147 146 logger.timestamp = True
148 147
149 148 print ('Activating auto-logging. '
150 149 'Current session state plus future input saved.')
151 150 logger.logstate()
152 151
153 152 @line_magic
154 153 def logstop(self, parameter_s=''):
155 154 """Fully stop logging and close log file.
156 155
157 156 In order to start logging again, a new %logstart call needs to be made,
158 157 possibly (though not necessarily) with a new filename, mode and other
159 158 options."""
160 159 self.shell.logger.logstop()
161 160
162 161 @line_magic
163 162 def logoff(self, parameter_s=''):
164 163 """Temporarily stop logging.
165 164
166 165 You must have previously started logging."""
167 166 self.shell.logger.switch_log(0)
168 167
169 168 @line_magic
170 169 def logon(self, parameter_s=''):
171 170 """Restart logging.
172 171
173 172 This function is for restarting logging which you've temporarily
174 173 stopped with %logoff. For starting logging for the first time, you
175 174 must use the %logstart function, which allows you to specify an
176 175 optional log filename."""
177 176
178 177 self.shell.logger.switch_log(1)
179 178
180 179 @line_magic
181 180 def logstate(self, parameter_s=''):
182 181 """Print the status of the logging system."""
183 182
184 183 self.shell.logger.logstate()
@@ -1,703 +1,702 b''
1 1 """Implementation of namespace-related magic functions.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (c) 2012 The IPython Development Team.
5 5 #
6 6 # Distributed under the terms of the Modified BSD License.
7 7 #
8 8 # The full license is in the file COPYING.txt, distributed with this software.
9 9 #-----------------------------------------------------------------------------
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14
15 15 # Stdlib
16 16 import gc
17 17 import re
18 18 import sys
19 19
20 20 # Our own packages
21 21 from IPython.core import page
22 22 from IPython.core.error import StdinNotImplementedError, UsageError
23 23 from IPython.core.magic import Magics, magics_class, line_magic
24 24 from IPython.testing.skipdoctest import skip_doctest
25 25 from IPython.utils.encoding import DEFAULT_ENCODING
26 26 from IPython.utils.openpy import read_py_file
27 27 from IPython.utils.path import get_py_filename
28 from IPython.utils.py3compat import unicode_type
29 28
30 29 #-----------------------------------------------------------------------------
31 30 # Magic implementation classes
32 31 #-----------------------------------------------------------------------------
33 32
34 33 @magics_class
35 34 class NamespaceMagics(Magics):
36 35 """Magics to manage various aspects of the user's namespace.
37 36
38 37 These include listing variables, introspecting into them, etc.
39 38 """
40 39
41 40 @line_magic
42 41 def pinfo(self, parameter_s='', namespaces=None):
43 42 """Provide detailed information about an object.
44 43
45 44 '%pinfo object' is just a synonym for object? or ?object."""
46 45
47 46 #print 'pinfo par: <%s>' % parameter_s # dbg
48 47 # detail_level: 0 -> obj? , 1 -> obj??
49 48 detail_level = 0
50 49 # We need to detect if we got called as 'pinfo pinfo foo', which can
51 50 # happen if the user types 'pinfo foo?' at the cmd line.
52 51 pinfo,qmark1,oname,qmark2 = \
53 52 re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
54 53 if pinfo or qmark1 or qmark2:
55 54 detail_level = 1
56 55 if "*" in oname:
57 56 self.psearch(oname)
58 57 else:
59 58 self.shell._inspect('pinfo', oname, detail_level=detail_level,
60 59 namespaces=namespaces)
61 60
62 61 @line_magic
63 62 def pinfo2(self, parameter_s='', namespaces=None):
64 63 """Provide extra detailed information about an object.
65 64
66 65 '%pinfo2 object' is just a synonym for object?? or ??object."""
67 66 self.shell._inspect('pinfo', parameter_s, detail_level=1,
68 67 namespaces=namespaces)
69 68
70 69 @skip_doctest
71 70 @line_magic
72 71 def pdef(self, parameter_s='', namespaces=None):
73 72 """Print the call signature for any callable object.
74 73
75 74 If the object is a class, print the constructor information.
76 75
77 76 Examples
78 77 --------
79 78 ::
80 79
81 80 In [3]: %pdef urllib.urlopen
82 81 urllib.urlopen(url, data=None, proxies=None)
83 82 """
84 83 self.shell._inspect('pdef',parameter_s, namespaces)
85 84
86 85 @line_magic
87 86 def pdoc(self, parameter_s='', namespaces=None):
88 87 """Print the docstring for an object.
89 88
90 89 If the given object is a class, it will print both the class and the
91 90 constructor docstrings."""
92 91 self.shell._inspect('pdoc',parameter_s, namespaces)
93 92
94 93 @line_magic
95 94 def psource(self, parameter_s='', namespaces=None):
96 95 """Print (or run through pager) the source code for an object."""
97 96 if not parameter_s:
98 97 raise UsageError('Missing object name.')
99 98 self.shell._inspect('psource',parameter_s, namespaces)
100 99
101 100 @line_magic
102 101 def pfile(self, parameter_s='', namespaces=None):
103 102 """Print (or run through pager) the file where an object is defined.
104 103
105 104 The file opens at the line where the object definition begins. IPython
106 105 will honor the environment variable PAGER if set, and otherwise will
107 106 do its best to print the file in a convenient form.
108 107
109 108 If the given argument is not an object currently defined, IPython will
110 109 try to interpret it as a filename (automatically adding a .py extension
111 110 if needed). You can thus use %pfile as a syntax highlighting code
112 111 viewer."""
113 112
114 113 # first interpret argument as an object name
115 114 out = self.shell._inspect('pfile',parameter_s, namespaces)
116 115 # if not, try the input as a filename
117 116 if out == 'not found':
118 117 try:
119 118 filename = get_py_filename(parameter_s)
120 119 except IOError as msg:
121 120 print(msg)
122 121 return
123 122 page.page(self.shell.pycolorize(read_py_file(filename, skip_encoding_cookie=False)))
124 123
125 124 @line_magic
126 125 def psearch(self, parameter_s=''):
127 126 """Search for object in namespaces by wildcard.
128 127
129 128 %psearch [options] PATTERN [OBJECT TYPE]
130 129
131 130 Note: ? can be used as a synonym for %psearch, at the beginning or at
132 131 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
133 132 rest of the command line must be unchanged (options come first), so
134 133 for example the following forms are equivalent
135 134
136 135 %psearch -i a* function
137 136 -i a* function?
138 137 ?-i a* function
139 138
140 139 Arguments:
141 140
142 141 PATTERN
143 142
144 143 where PATTERN is a string containing * as a wildcard similar to its
145 144 use in a shell. The pattern is matched in all namespaces on the
146 145 search path. By default objects starting with a single _ are not
147 146 matched, many IPython generated objects have a single
148 147 underscore. The default is case insensitive matching. Matching is
149 148 also done on the attributes of objects and not only on the objects
150 149 in a module.
151 150
152 151 [OBJECT TYPE]
153 152
154 153 Is the name of a python type from the types module. The name is
155 154 given in lowercase without the ending type, ex. StringType is
156 155 written string. By adding a type here only objects matching the
157 156 given type are matched. Using all here makes the pattern match all
158 157 types (this is the default).
159 158
160 159 Options:
161 160
162 161 -a: makes the pattern match even objects whose names start with a
163 162 single underscore. These names are normally omitted from the
164 163 search.
165 164
166 165 -i/-c: make the pattern case insensitive/sensitive. If neither of
167 166 these options are given, the default is read from your configuration
168 167 file, with the option ``InteractiveShell.wildcards_case_sensitive``.
169 168 If this option is not specified in your configuration file, IPython's
170 169 internal default is to do a case sensitive search.
171 170
172 171 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
173 172 specify can be searched in any of the following namespaces:
174 173 'builtin', 'user', 'user_global','internal', 'alias', where
175 174 'builtin' and 'user' are the search defaults. Note that you should
176 175 not use quotes when specifying namespaces.
177 176
178 177 'Builtin' contains the python module builtin, 'user' contains all
179 178 user data, 'alias' only contain the shell aliases and no python
180 179 objects, 'internal' contains objects used by IPython. The
181 180 'user_global' namespace is only used by embedded IPython instances,
182 181 and it contains module-level globals. You can add namespaces to the
183 182 search with -s or exclude them with -e (these options can be given
184 183 more than once).
185 184
186 185 Examples
187 186 --------
188 187 ::
189 188
190 189 %psearch a* -> objects beginning with an a
191 190 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
192 191 %psearch a* function -> all functions beginning with an a
193 192 %psearch re.e* -> objects beginning with an e in module re
194 193 %psearch r*.e* -> objects that start with e in modules starting in r
195 194 %psearch r*.* string -> all strings in modules beginning with r
196 195
197 196 Case sensitive search::
198 197
199 198 %psearch -c a* list all object beginning with lower case a
200 199
201 200 Show objects beginning with a single _::
202 201
203 202 %psearch -a _* list objects beginning with a single underscore
204 203 """
205 204 try:
206 205 parameter_s.encode('ascii')
207 206 except UnicodeEncodeError:
208 207 print('Python identifiers can only contain ascii characters.')
209 208 return
210 209
211 210 # default namespaces to be searched
212 211 def_search = ['user_local', 'user_global', 'builtin']
213 212
214 213 # Process options/args
215 214 opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
216 215 opt = opts.get
217 216 shell = self.shell
218 217 psearch = shell.inspector.psearch
219 218
220 219 # select case options
221 220 if 'i' in opts:
222 221 ignore_case = True
223 222 elif 'c' in opts:
224 223 ignore_case = False
225 224 else:
226 225 ignore_case = not shell.wildcards_case_sensitive
227 226
228 227 # Build list of namespaces to search from user options
229 228 def_search.extend(opt('s',[]))
230 229 ns_exclude = ns_exclude=opt('e',[])
231 230 ns_search = [nm for nm in def_search if nm not in ns_exclude]
232 231
233 232 # Call the actual search
234 233 try:
235 234 psearch(args,shell.ns_table,ns_search,
236 235 show_all=opt('a'),ignore_case=ignore_case)
237 236 except:
238 237 shell.showtraceback()
239 238
240 239 @skip_doctest
241 240 @line_magic
242 241 def who_ls(self, parameter_s=''):
243 242 """Return a sorted list of all interactive variables.
244 243
245 244 If arguments are given, only variables of types matching these
246 245 arguments are returned.
247 246
248 247 Examples
249 248 --------
250 249
251 250 Define two variables and list them with who_ls::
252 251
253 252 In [1]: alpha = 123
254 253
255 254 In [2]: beta = 'test'
256 255
257 256 In [3]: %who_ls
258 257 Out[3]: ['alpha', 'beta']
259 258
260 259 In [4]: %who_ls int
261 260 Out[4]: ['alpha']
262 261
263 262 In [5]: %who_ls str
264 263 Out[5]: ['beta']
265 264 """
266 265
267 266 user_ns = self.shell.user_ns
268 267 user_ns_hidden = self.shell.user_ns_hidden
269 268 nonmatching = object() # This can never be in user_ns
270 269 out = [ i for i in user_ns
271 270 if not i.startswith('_') \
272 271 and (user_ns[i] is not user_ns_hidden.get(i, nonmatching)) ]
273 272
274 273 typelist = parameter_s.split()
275 274 if typelist:
276 275 typeset = set(typelist)
277 276 out = [i for i in out if type(user_ns[i]).__name__ in typeset]
278 277
279 278 out.sort()
280 279 return out
281 280
282 281 @skip_doctest
283 282 @line_magic
284 283 def who(self, parameter_s=''):
285 284 """Print all interactive variables, with some minimal formatting.
286 285
287 286 If any arguments are given, only variables whose type matches one of
288 287 these are printed. For example::
289 288
290 289 %who function str
291 290
292 291 will only list functions and strings, excluding all other types of
293 292 variables. To find the proper type names, simply use type(var) at a
294 293 command line to see how python prints type names. For example:
295 294
296 295 ::
297 296
298 297 In [1]: type('hello')\\
299 298 Out[1]: <type 'str'>
300 299
301 300 indicates that the type name for strings is 'str'.
302 301
303 302 ``%who`` always excludes executed names loaded through your configuration
304 303 file and things which are internal to IPython.
305 304
306 305 This is deliberate, as typically you may load many modules and the
307 306 purpose of %who is to show you only what you've manually defined.
308 307
309 308 Examples
310 309 --------
311 310
312 311 Define two variables and list them with who::
313 312
314 313 In [1]: alpha = 123
315 314
316 315 In [2]: beta = 'test'
317 316
318 317 In [3]: %who
319 318 alpha beta
320 319
321 320 In [4]: %who int
322 321 alpha
323 322
324 323 In [5]: %who str
325 324 beta
326 325 """
327 326
328 327 varlist = self.who_ls(parameter_s)
329 328 if not varlist:
330 329 if parameter_s:
331 330 print('No variables match your requested type.')
332 331 else:
333 332 print('Interactive namespace is empty.')
334 333 return
335 334
336 335 # if we have variables, move on...
337 336 count = 0
338 337 for i in varlist:
339 338 print(i+'\t', end=' ')
340 339 count += 1
341 340 if count > 8:
342 341 count = 0
343 342 print()
344 343 print()
345 344
346 345 @skip_doctest
347 346 @line_magic
348 347 def whos(self, parameter_s=''):
349 348 """Like %who, but gives some extra information about each variable.
350 349
351 350 The same type filtering of %who can be applied here.
352 351
353 352 For all variables, the type is printed. Additionally it prints:
354 353
355 354 - For {},[],(): their length.
356 355
357 356 - For numpy arrays, a summary with shape, number of
358 357 elements, typecode and size in memory.
359 358
360 359 - Everything else: a string representation, snipping their middle if
361 360 too long.
362 361
363 362 Examples
364 363 --------
365 364
366 365 Define two variables and list them with whos::
367 366
368 367 In [1]: alpha = 123
369 368
370 369 In [2]: beta = 'test'
371 370
372 371 In [3]: %whos
373 372 Variable Type Data/Info
374 373 --------------------------------
375 374 alpha int 123
376 375 beta str test
377 376 """
378 377
379 378 varnames = self.who_ls(parameter_s)
380 379 if not varnames:
381 380 if parameter_s:
382 381 print('No variables match your requested type.')
383 382 else:
384 383 print('Interactive namespace is empty.')
385 384 return
386 385
387 386 # if we have variables, move on...
388 387
389 388 # for these types, show len() instead of data:
390 389 seq_types = ['dict', 'list', 'tuple']
391 390
392 391 # for numpy arrays, display summary info
393 392 ndarray_type = None
394 393 if 'numpy' in sys.modules:
395 394 try:
396 395 from numpy import ndarray
397 396 except ImportError:
398 397 pass
399 398 else:
400 399 ndarray_type = ndarray.__name__
401 400
402 401 # Find all variable names and types so we can figure out column sizes
403 402
404 403 # some types are well known and can be shorter
405 404 abbrevs = {'IPython.core.macro.Macro' : 'Macro'}
406 405 def type_name(v):
407 406 tn = type(v).__name__
408 407 return abbrevs.get(tn,tn)
409 408
410 409 varlist = [self.shell.user_ns[n] for n in varnames]
411 410
412 411 typelist = []
413 412 for vv in varlist:
414 413 tt = type_name(vv)
415 414
416 415 if tt=='instance':
417 416 typelist.append( abbrevs.get(str(vv.__class__),
418 417 str(vv.__class__)))
419 418 else:
420 419 typelist.append(tt)
421 420
422 421 # column labels and # of spaces as separator
423 422 varlabel = 'Variable'
424 423 typelabel = 'Type'
425 424 datalabel = 'Data/Info'
426 425 colsep = 3
427 426 # variable format strings
428 427 vformat = "{0:<{varwidth}}{1:<{typewidth}}"
429 428 aformat = "%s: %s elems, type `%s`, %s bytes"
430 429 # find the size of the columns to format the output nicely
431 430 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
432 431 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
433 432 # table header
434 433 print(varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
435 434 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1))
436 435 # and the table itself
437 436 kb = 1024
438 437 Mb = 1048576 # kb**2
439 438 for vname,var,vtype in zip(varnames,varlist,typelist):
440 439 print(vformat.format(vname, vtype, varwidth=varwidth, typewidth=typewidth), end=' ')
441 440 if vtype in seq_types:
442 441 print("n="+str(len(var)))
443 442 elif vtype == ndarray_type:
444 443 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
445 444 if vtype==ndarray_type:
446 445 # numpy
447 446 vsize = var.size
448 447 vbytes = vsize*var.itemsize
449 448 vdtype = var.dtype
450 449
451 450 if vbytes < 100000:
452 451 print(aformat % (vshape, vsize, vdtype, vbytes))
453 452 else:
454 453 print(aformat % (vshape, vsize, vdtype, vbytes), end=' ')
455 454 if vbytes < Mb:
456 455 print('(%s kb)' % (vbytes/kb,))
457 456 else:
458 457 print('(%s Mb)' % (vbytes/Mb,))
459 458 else:
460 459 try:
461 460 vstr = str(var)
462 461 except UnicodeEncodeError:
463 vstr = unicode_type(var).encode(DEFAULT_ENCODING,
464 'backslashreplace')
462 vstr = var.encode(DEFAULT_ENCODING,
463 'backslashreplace')
465 464 except:
466 465 vstr = "<object with id %d (str() failed)>" % id(var)
467 466 vstr = vstr.replace('\n', '\\n')
468 467 if len(vstr) < 50:
469 468 print(vstr)
470 469 else:
471 470 print(vstr[:25] + "<...>" + vstr[-25:])
472 471
473 472 @line_magic
474 473 def reset(self, parameter_s=''):
475 474 """Resets the namespace by removing all names defined by the user, if
476 475 called without arguments, or by removing some types of objects, such
477 476 as everything currently in IPython's In[] and Out[] containers (see
478 477 the parameters for details).
479 478
480 479 Parameters
481 480 ----------
482 481 -f : force reset without asking for confirmation.
483 482
484 483 -s : 'Soft' reset: Only clears your namespace, leaving history intact.
485 484 References to objects may be kept. By default (without this option),
486 485 we do a 'hard' reset, giving you a new session and removing all
487 486 references to objects from the current session.
488 487
489 488 in : reset input history
490 489
491 490 out : reset output history
492 491
493 492 dhist : reset directory history
494 493
495 494 array : reset only variables that are NumPy arrays
496 495
497 496 See Also
498 497 --------
499 498 reset_selective : invoked as ``%reset_selective``
500 499
501 500 Examples
502 501 --------
503 502 ::
504 503
505 504 In [6]: a = 1
506 505
507 506 In [7]: a
508 507 Out[7]: 1
509 508
510 509 In [8]: 'a' in _ip.user_ns
511 510 Out[8]: True
512 511
513 512 In [9]: %reset -f
514 513
515 514 In [1]: 'a' in _ip.user_ns
516 515 Out[1]: False
517 516
518 517 In [2]: %reset -f in
519 518 Flushing input history
520 519
521 520 In [3]: %reset -f dhist in
522 521 Flushing directory history
523 522 Flushing input history
524 523
525 524 Notes
526 525 -----
527 526 Calling this magic from clients that do not implement standard input,
528 527 such as the ipython notebook interface, will reset the namespace
529 528 without confirmation.
530 529 """
531 530 opts, args = self.parse_options(parameter_s,'sf', mode='list')
532 531 if 'f' in opts:
533 532 ans = True
534 533 else:
535 534 try:
536 535 ans = self.shell.ask_yes_no(
537 536 "Once deleted, variables cannot be recovered. Proceed (y/[n])?",
538 537 default='n')
539 538 except StdinNotImplementedError:
540 539 ans = True
541 540 if not ans:
542 541 print('Nothing done.')
543 542 return
544 543
545 544 if 's' in opts: # Soft reset
546 545 user_ns = self.shell.user_ns
547 546 for i in self.who_ls():
548 547 del(user_ns[i])
549 548 elif len(args) == 0: # Hard reset
550 549 self.shell.reset(new_session = False)
551 550
552 551 # reset in/out/dhist/array: previously extensinions/clearcmd.py
553 552 ip = self.shell
554 553 user_ns = self.shell.user_ns # local lookup, heavily used
555 554
556 555 for target in args:
557 556 target = target.lower() # make matches case insensitive
558 557 if target == 'out':
559 558 print("Flushing output cache (%d entries)" % len(user_ns['_oh']))
560 559 self.shell.displayhook.flush()
561 560
562 561 elif target == 'in':
563 562 print("Flushing input history")
564 563 pc = self.shell.displayhook.prompt_count + 1
565 564 for n in range(1, pc):
566 565 key = '_i'+repr(n)
567 566 user_ns.pop(key,None)
568 567 user_ns.update(dict(_i=u'',_ii=u'',_iii=u''))
569 568 hm = ip.history_manager
570 569 # don't delete these, as %save and %macro depending on the
571 570 # length of these lists to be preserved
572 571 hm.input_hist_parsed[:] = [''] * pc
573 572 hm.input_hist_raw[:] = [''] * pc
574 573 # hm has internal machinery for _i,_ii,_iii, clear it out
575 574 hm._i = hm._ii = hm._iii = hm._i00 = u''
576 575
577 576 elif target == 'array':
578 577 # Support cleaning up numpy arrays
579 578 try:
580 579 from numpy import ndarray
581 580 # This must be done with items and not iteritems because
582 581 # we're going to modify the dict in-place.
583 582 for x,val in list(user_ns.items()):
584 583 if isinstance(val,ndarray):
585 584 del user_ns[x]
586 585 except ImportError:
587 586 print("reset array only works if Numpy is available.")
588 587
589 588 elif target == 'dhist':
590 589 print("Flushing directory history")
591 590 del user_ns['_dh'][:]
592 591
593 592 else:
594 593 print("Don't know how to reset ", end=' ')
595 594 print(target + ", please run `%reset?` for details")
596 595
597 596 gc.collect()
598 597
599 598 @line_magic
600 599 def reset_selective(self, parameter_s=''):
601 600 """Resets the namespace by removing names defined by the user.
602 601
603 602 Input/Output history are left around in case you need them.
604 603
605 604 %reset_selective [-f] regex
606 605
607 606 No action is taken if regex is not included
608 607
609 608 Options
610 609 -f : force reset without asking for confirmation.
611 610
612 611 See Also
613 612 --------
614 613 reset : invoked as ``%reset``
615 614
616 615 Examples
617 616 --------
618 617
619 618 We first fully reset the namespace so your output looks identical to
620 619 this example for pedagogical reasons; in practice you do not need a
621 620 full reset::
622 621
623 622 In [1]: %reset -f
624 623
625 624 Now, with a clean namespace we can make a few variables and use
626 625 ``%reset_selective`` to only delete names that match our regexp::
627 626
628 627 In [2]: a=1; b=2; c=3; b1m=4; b2m=5; b3m=6; b4m=7; b2s=8
629 628
630 629 In [3]: who_ls
631 630 Out[3]: ['a', 'b', 'b1m', 'b2m', 'b2s', 'b3m', 'b4m', 'c']
632 631
633 632 In [4]: %reset_selective -f b[2-3]m
634 633
635 634 In [5]: who_ls
636 635 Out[5]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
637 636
638 637 In [6]: %reset_selective -f d
639 638
640 639 In [7]: who_ls
641 640 Out[7]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
642 641
643 642 In [8]: %reset_selective -f c
644 643
645 644 In [9]: who_ls
646 645 Out[9]: ['a', 'b', 'b1m', 'b2s', 'b4m']
647 646
648 647 In [10]: %reset_selective -f b
649 648
650 649 In [11]: who_ls
651 650 Out[11]: ['a']
652 651
653 652 Notes
654 653 -----
655 654 Calling this magic from clients that do not implement standard input,
656 655 such as the ipython notebook interface, will reset the namespace
657 656 without confirmation.
658 657 """
659 658
660 659 opts, regex = self.parse_options(parameter_s,'f')
661 660
662 661 if 'f' in opts:
663 662 ans = True
664 663 else:
665 664 try:
666 665 ans = self.shell.ask_yes_no(
667 666 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ",
668 667 default='n')
669 668 except StdinNotImplementedError:
670 669 ans = True
671 670 if not ans:
672 671 print('Nothing done.')
673 672 return
674 673 user_ns = self.shell.user_ns
675 674 if not regex:
676 675 print('No regex pattern specified. Nothing done.')
677 676 return
678 677 else:
679 678 try:
680 679 m = re.compile(regex)
681 680 except TypeError:
682 681 raise TypeError('regex must be a string or compiled pattern')
683 682 for i in self.who_ls():
684 683 if m.search(i):
685 684 del(user_ns[i])
686 685
687 686 @line_magic
688 687 def xdel(self, parameter_s=''):
689 688 """Delete a variable, trying to clear it from anywhere that
690 689 IPython's machinery has references to it. By default, this uses
691 690 the identity of the named object in the user namespace to remove
692 691 references held under other names. The object is also removed
693 692 from the output history.
694 693
695 694 Options
696 695 -n : Delete the specified name from all namespaces, without
697 696 checking their identity.
698 697 """
699 698 opts, varname = self.parse_options(parameter_s,'n')
700 699 try:
701 700 self.shell.del_var(varname, ('n' in opts))
702 701 except (NameError, ValueError) as e:
703 702 print(type(e).__name__ +": "+ str(e))
@@ -1,789 +1,788 b''
1 1 """Implementation of magic functions for interaction with the OS.
2 2
3 3 Note: this module is named 'osm' instead of 'os' to avoid a collision with the
4 4 builtin.
5 5 """
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (c) 2012 The IPython Development Team.
8 8 #
9 9 # Distributed under the terms of the Modified BSD License.
10 10 #
11 11 # The full license is in the file COPYING.txt, distributed with this software.
12 12 #-----------------------------------------------------------------------------
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Imports
16 16 #-----------------------------------------------------------------------------
17 17
18 18 # Stdlib
19 19 import io
20 20 import os
21 21 import re
22 22 import sys
23 23 from pprint import pformat
24 24
25 25 # Our own packages
26 26 from IPython.core import magic_arguments
27 27 from IPython.core import oinspect
28 28 from IPython.core import page
29 29 from IPython.core.alias import AliasError, Alias
30 30 from IPython.core.error import UsageError
31 31 from IPython.core.magic import (
32 32 Magics, compress_dhist, magics_class, line_magic, cell_magic, line_cell_magic
33 33 )
34 34 from IPython.testing.skipdoctest import skip_doctest
35 35 from IPython.utils.openpy import source_to_unicode
36 36 from IPython.utils.process import abbrev_cwd
37 37 from IPython.utils import py3compat
38 from IPython.utils.py3compat import unicode_type
39 38 from IPython.utils.terminal import set_term_title
40 39
41 40 #-----------------------------------------------------------------------------
42 41 # Magic implementation classes
43 42 #-----------------------------------------------------------------------------
44 43 @magics_class
45 44 class OSMagics(Magics):
46 45 """Magics to interact with the underlying OS (shell-type functionality).
47 46 """
48 47
49 48 @skip_doctest
50 49 @line_magic
51 50 def alias(self, parameter_s=''):
52 51 """Define an alias for a system command.
53 52
54 53 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
55 54
56 55 Then, typing 'alias_name params' will execute the system command 'cmd
57 56 params' (from your underlying operating system).
58 57
59 58 Aliases have lower precedence than magic functions and Python normal
60 59 variables, so if 'foo' is both a Python variable and an alias, the
61 60 alias can not be executed until 'del foo' removes the Python variable.
62 61
63 62 You can use the %l specifier in an alias definition to represent the
64 63 whole line when the alias is called. For example::
65 64
66 65 In [2]: alias bracket echo "Input in brackets: <%l>"
67 66 In [3]: bracket hello world
68 67 Input in brackets: <hello world>
69 68
70 69 You can also define aliases with parameters using %s specifiers (one
71 70 per parameter)::
72 71
73 72 In [1]: alias parts echo first %s second %s
74 73 In [2]: %parts A B
75 74 first A second B
76 75 In [3]: %parts A
77 76 Incorrect number of arguments: 2 expected.
78 77 parts is an alias to: 'echo first %s second %s'
79 78
80 79 Note that %l and %s are mutually exclusive. You can only use one or
81 80 the other in your aliases.
82 81
83 82 Aliases expand Python variables just like system calls using ! or !!
84 83 do: all expressions prefixed with '$' get expanded. For details of
85 84 the semantic rules, see PEP-215:
86 85 http://www.python.org/peps/pep-0215.html. This is the library used by
87 86 IPython for variable expansion. If you want to access a true shell
88 87 variable, an extra $ is necessary to prevent its expansion by
89 88 IPython::
90 89
91 90 In [6]: alias show echo
92 91 In [7]: PATH='A Python string'
93 92 In [8]: show $PATH
94 93 A Python string
95 94 In [9]: show $$PATH
96 95 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
97 96
98 97 You can use the alias facility to acess all of $PATH. See the %rehashx
99 98 function, which automatically creates aliases for the contents of your
100 99 $PATH.
101 100
102 101 If called with no parameters, %alias prints the current alias table."""
103 102
104 103 par = parameter_s.strip()
105 104 if not par:
106 105 aliases = sorted(self.shell.alias_manager.aliases)
107 106 # stored = self.shell.db.get('stored_aliases', {} )
108 107 # for k, v in stored:
109 108 # atab.append(k, v[0])
110 109
111 110 print("Total number of aliases:", len(aliases))
112 111 sys.stdout.flush()
113 112 return aliases
114 113
115 114 # Now try to define a new one
116 115 try:
117 116 alias,cmd = par.split(None, 1)
118 117 except TypeError:
119 118 print(oinspect.getdoc(self.alias))
120 119 return
121 120
122 121 try:
123 122 self.shell.alias_manager.define_alias(alias, cmd)
124 123 except AliasError as e:
125 124 print(e)
126 125 # end magic_alias
127 126
128 127 @line_magic
129 128 def unalias(self, parameter_s=''):
130 129 """Remove an alias"""
131 130
132 131 aname = parameter_s.strip()
133 132 try:
134 133 self.shell.alias_manager.undefine_alias(aname)
135 134 except ValueError as e:
136 135 print(e)
137 136 return
138 137
139 138 stored = self.shell.db.get('stored_aliases', {} )
140 139 if aname in stored:
141 140 print("Removing %stored alias",aname)
142 141 del stored[aname]
143 142 self.shell.db['stored_aliases'] = stored
144 143
145 144 @line_magic
146 145 def rehashx(self, parameter_s=''):
147 146 """Update the alias table with all executable files in $PATH.
148 147
149 148 rehashx explicitly checks that every entry in $PATH is a file
150 149 with execute access (os.X_OK).
151 150
152 151 Under Windows, it checks executability as a match against a
153 152 '|'-separated string of extensions, stored in the IPython config
154 153 variable win_exec_ext. This defaults to 'exe|com|bat'.
155 154
156 155 This function also resets the root module cache of module completer,
157 156 used on slow filesystems.
158 157 """
159 158 from IPython.core.alias import InvalidAliasError
160 159
161 160 # for the benefit of module completer in ipy_completers.py
162 161 del self.shell.db['rootmodules_cache']
163 162
164 163 path = [os.path.abspath(os.path.expanduser(p)) for p in
165 164 os.environ.get('PATH','').split(os.pathsep)]
166 165
167 166 syscmdlist = []
168 167 # Now define isexec in a cross platform manner.
169 168 if os.name == 'posix':
170 169 isexec = lambda fname:os.path.isfile(fname) and \
171 170 os.access(fname,os.X_OK)
172 171 else:
173 172 try:
174 173 winext = os.environ['pathext'].replace(';','|').replace('.','')
175 174 except KeyError:
176 175 winext = 'exe|com|bat|py'
177 176 if 'py' not in winext:
178 177 winext += '|py'
179 178 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
180 179 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
181 savedir = py3compat.getcwd()
180 savedir = os.getcwd()
182 181
183 182 # Now walk the paths looking for executables to alias.
184 183 try:
185 184 # write the whole loop for posix/Windows so we don't have an if in
186 185 # the innermost part
187 186 if os.name == 'posix':
188 187 for pdir in path:
189 188 try:
190 189 os.chdir(pdir)
191 190 dirlist = os.listdir(pdir)
192 191 except OSError:
193 192 continue
194 193 for ff in dirlist:
195 194 if isexec(ff):
196 195 try:
197 196 # Removes dots from the name since ipython
198 197 # will assume names with dots to be python.
199 198 if not self.shell.alias_manager.is_alias(ff):
200 199 self.shell.alias_manager.define_alias(
201 200 ff.replace('.',''), ff)
202 201 except InvalidAliasError:
203 202 pass
204 203 else:
205 204 syscmdlist.append(ff)
206 205 else:
207 206 no_alias = Alias.blacklist
208 207 for pdir in path:
209 208 try:
210 209 os.chdir(pdir)
211 210 dirlist = os.listdir(pdir)
212 211 except OSError:
213 212 continue
214 213 for ff in dirlist:
215 214 base, ext = os.path.splitext(ff)
216 215 if isexec(ff) and base.lower() not in no_alias:
217 216 if ext.lower() == '.exe':
218 217 ff = base
219 218 try:
220 219 # Removes dots from the name since ipython
221 220 # will assume names with dots to be python.
222 221 self.shell.alias_manager.define_alias(
223 222 base.lower().replace('.',''), ff)
224 223 except InvalidAliasError:
225 224 pass
226 225 syscmdlist.append(ff)
227 226 self.shell.db['syscmdlist'] = syscmdlist
228 227 finally:
229 228 os.chdir(savedir)
230 229
231 230 @skip_doctest
232 231 @line_magic
233 232 def pwd(self, parameter_s=''):
234 233 """Return the current working directory path.
235 234
236 235 Examples
237 236 --------
238 237 ::
239 238
240 239 In [9]: pwd
241 240 Out[9]: '/home/tsuser/sprint/ipython'
242 241 """
243 return py3compat.getcwd()
242 return os.getcwd()
244 243
245 244 @skip_doctest
246 245 @line_magic
247 246 def cd(self, parameter_s=''):
248 247 """Change the current working directory.
249 248
250 249 This command automatically maintains an internal list of directories
251 250 you visit during your IPython session, in the variable _dh. The
252 251 command %dhist shows this history nicely formatted. You can also
253 252 do 'cd -<tab>' to see directory history conveniently.
254 253
255 254 Usage:
256 255
257 256 cd 'dir': changes to directory 'dir'.
258 257
259 258 cd -: changes to the last visited directory.
260 259
261 260 cd -<n>: changes to the n-th directory in the directory history.
262 261
263 262 cd --foo: change to directory that matches 'foo' in history
264 263
265 264 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
266 265 (note: cd <bookmark_name> is enough if there is no
267 266 directory <bookmark_name>, but a bookmark with the name exists.)
268 267 'cd -b <tab>' allows you to tab-complete bookmark names.
269 268
270 269 Options:
271 270
272 271 -q: quiet. Do not print the working directory after the cd command is
273 272 executed. By default IPython's cd command does print this directory,
274 273 since the default prompts do not display path information.
275 274
276 275 Note that !cd doesn't work for this purpose because the shell where
277 276 !command runs is immediately discarded after executing 'command'.
278 277
279 278 Examples
280 279 --------
281 280 ::
282 281
283 282 In [10]: cd parent/child
284 283 /home/tsuser/parent/child
285 284 """
286 285
287 oldcwd = py3compat.getcwd()
286 oldcwd = os.getcwd()
288 287 numcd = re.match(r'(-)(\d+)$',parameter_s)
289 288 # jump in directory history by number
290 289 if numcd:
291 290 nn = int(numcd.group(2))
292 291 try:
293 292 ps = self.shell.user_ns['_dh'][nn]
294 293 except IndexError:
295 294 print('The requested directory does not exist in history.')
296 295 return
297 296 else:
298 297 opts = {}
299 298 elif parameter_s.startswith('--'):
300 299 ps = None
301 300 fallback = None
302 301 pat = parameter_s[2:]
303 302 dh = self.shell.user_ns['_dh']
304 303 # first search only by basename (last component)
305 304 for ent in reversed(dh):
306 305 if pat in os.path.basename(ent) and os.path.isdir(ent):
307 306 ps = ent
308 307 break
309 308
310 309 if fallback is None and pat in ent and os.path.isdir(ent):
311 310 fallback = ent
312 311
313 312 # if we have no last part match, pick the first full path match
314 313 if ps is None:
315 314 ps = fallback
316 315
317 316 if ps is None:
318 317 print("No matching entry in directory history")
319 318 return
320 319 else:
321 320 opts = {}
322 321
323 322
324 323 else:
325 324 opts, ps = self.parse_options(parameter_s, 'qb', mode='string')
326 325 # jump to previous
327 326 if ps == '-':
328 327 try:
329 328 ps = self.shell.user_ns['_dh'][-2]
330 329 except IndexError:
331 330 raise UsageError('%cd -: No previous directory to change to.')
332 331 # jump to bookmark if needed
333 332 else:
334 333 if not os.path.isdir(ps) or 'b' in opts:
335 334 bkms = self.shell.db.get('bookmarks', {})
336 335
337 336 if ps in bkms:
338 337 target = bkms[ps]
339 338 print('(bookmark:%s) -> %s' % (ps, target))
340 339 ps = target
341 340 else:
342 341 if 'b' in opts:
343 342 raise UsageError("Bookmark '%s' not found. "
344 343 "Use '%%bookmark -l' to see your bookmarks." % ps)
345 344
346 345 # at this point ps should point to the target dir
347 346 if ps:
348 347 try:
349 348 os.chdir(os.path.expanduser(ps))
350 349 if hasattr(self.shell, 'term_title') and self.shell.term_title:
351 350 set_term_title('IPython: ' + abbrev_cwd())
352 351 except OSError:
353 352 print(sys.exc_info()[1])
354 353 else:
355 cwd = py3compat.getcwd()
354 cwd = os.getcwd()
356 355 dhist = self.shell.user_ns['_dh']
357 356 if oldcwd != cwd:
358 357 dhist.append(cwd)
359 358 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
360 359
361 360 else:
362 361 os.chdir(self.shell.home_dir)
363 362 if hasattr(self.shell, 'term_title') and self.shell.term_title:
364 363 set_term_title('IPython: ' + '~')
365 cwd = py3compat.getcwd()
364 cwd = os.getcwd()
366 365 dhist = self.shell.user_ns['_dh']
367 366
368 367 if oldcwd != cwd:
369 368 dhist.append(cwd)
370 369 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
371 370 if not 'q' in opts and self.shell.user_ns['_dh']:
372 371 print(self.shell.user_ns['_dh'][-1])
373 372
374 373 @line_magic
375 374 def env(self, parameter_s=''):
376 375 """Get, set, or list environment variables.
377 376
378 377 Usage:\\
379 378
380 379 %env: lists all environment variables/values
381 380 %env var: get value for var
382 381 %env var val: set value for var
383 382 %env var=val: set value for var
384 383 %env var=$val: set value for var, using python expansion if possible
385 384 """
386 385 if parameter_s.strip():
387 386 split = '=' if '=' in parameter_s else ' '
388 387 bits = parameter_s.split(split)
389 388 if len(bits) == 1:
390 389 key = parameter_s.strip()
391 390 if key in os.environ:
392 391 return os.environ[key]
393 392 else:
394 393 err = "Environment does not have key: {0}".format(key)
395 394 raise UsageError(err)
396 395 if len(bits) > 1:
397 396 return self.set_env(parameter_s)
398 397 return dict(os.environ)
399 398
400 399 @line_magic
401 400 def set_env(self, parameter_s):
402 401 """Set environment variables. Assumptions are that either "val" is a
403 402 name in the user namespace, or val is something that evaluates to a
404 403 string.
405 404
406 405 Usage:\\
407 406 %set_env var val: set value for var
408 407 %set_env var=val: set value for var
409 408 %set_env var=$val: set value for var, using python expansion if possible
410 409 """
411 410 split = '=' if '=' in parameter_s else ' '
412 411 bits = parameter_s.split(split, 1)
413 412 if not parameter_s.strip() or len(bits)<2:
414 413 raise UsageError("usage is 'set_env var=val'")
415 414 var = bits[0].strip()
416 415 val = bits[1].strip()
417 416 if re.match(r'.*\s.*', var):
418 417 # an environment variable with whitespace is almost certainly
419 418 # not what the user intended. what's more likely is the wrong
420 419 # split was chosen, ie for "set_env cmd_args A=B", we chose
421 420 # '=' for the split and should have chosen ' '. to get around
422 421 # this, users should just assign directly to os.environ or use
423 422 # standard magic {var} expansion.
424 423 err = "refusing to set env var with whitespace: '{0}'"
425 424 err = err.format(val)
426 425 raise UsageError(err)
427 426 os.environ[py3compat.cast_bytes_py2(var)] = py3compat.cast_bytes_py2(val)
428 427 print('env: {0}={1}'.format(var,val))
429 428
430 429 @line_magic
431 430 def pushd(self, parameter_s=''):
432 431 """Place the current dir on stack and change directory.
433 432
434 433 Usage:\\
435 434 %pushd ['dirname']
436 435 """
437 436
438 437 dir_s = self.shell.dir_stack
439 438 tgt = os.path.expanduser(parameter_s)
440 cwd = py3compat.getcwd().replace(self.shell.home_dir,'~')
439 cwd = os.getcwd().replace(self.shell.home_dir,'~')
441 440 if tgt:
442 441 self.cd(parameter_s)
443 442 dir_s.insert(0,cwd)
444 443 return self.shell.magic('dirs')
445 444
446 445 @line_magic
447 446 def popd(self, parameter_s=''):
448 447 """Change to directory popped off the top of the stack.
449 448 """
450 449 if not self.shell.dir_stack:
451 450 raise UsageError("%popd on empty stack")
452 451 top = self.shell.dir_stack.pop(0)
453 452 self.cd(top)
454 453 print("popd ->",top)
455 454
456 455 @line_magic
457 456 def dirs(self, parameter_s=''):
458 457 """Return the current directory stack."""
459 458
460 459 return self.shell.dir_stack
461 460
462 461 @line_magic
463 462 def dhist(self, parameter_s=''):
464 463 """Print your history of visited directories.
465 464
466 465 %dhist -> print full history\\
467 466 %dhist n -> print last n entries only\\
468 467 %dhist n1 n2 -> print entries between n1 and n2 (n2 not included)\\
469 468
470 469 This history is automatically maintained by the %cd command, and
471 470 always available as the global list variable _dh. You can use %cd -<n>
472 471 to go to directory number <n>.
473 472
474 473 Note that most of time, you should view directory history by entering
475 474 cd -<TAB>.
476 475
477 476 """
478 477
479 478 dh = self.shell.user_ns['_dh']
480 479 if parameter_s:
481 480 try:
482 481 args = map(int,parameter_s.split())
483 482 except:
484 483 self.arg_err(self.dhist)
485 484 return
486 485 if len(args) == 1:
487 486 ini,fin = max(len(dh)-(args[0]),0),len(dh)
488 487 elif len(args) == 2:
489 488 ini,fin = args
490 489 fin = min(fin, len(dh))
491 490 else:
492 491 self.arg_err(self.dhist)
493 492 return
494 493 else:
495 494 ini,fin = 0,len(dh)
496 495 print('Directory history (kept in _dh)')
497 496 for i in range(ini, fin):
498 497 print("%d: %s" % (i, dh[i]))
499 498
500 499 @skip_doctest
501 500 @line_magic
502 501 def sc(self, parameter_s=''):
503 502 """Shell capture - run shell command and capture output (DEPRECATED use !).
504 503
505 504 DEPRECATED. Suboptimal, retained for backwards compatibility.
506 505
507 506 You should use the form 'var = !command' instead. Example:
508 507
509 508 "%sc -l myfiles = ls ~" should now be written as
510 509
511 510 "myfiles = !ls ~"
512 511
513 512 myfiles.s, myfiles.l and myfiles.n still apply as documented
514 513 below.
515 514
516 515 --
517 516 %sc [options] varname=command
518 517
519 518 IPython will run the given command using commands.getoutput(), and
520 519 will then update the user's interactive namespace with a variable
521 520 called varname, containing the value of the call. Your command can
522 521 contain shell wildcards, pipes, etc.
523 522
524 523 The '=' sign in the syntax is mandatory, and the variable name you
525 524 supply must follow Python's standard conventions for valid names.
526 525
527 526 (A special format without variable name exists for internal use)
528 527
529 528 Options:
530 529
531 530 -l: list output. Split the output on newlines into a list before
532 531 assigning it to the given variable. By default the output is stored
533 532 as a single string.
534 533
535 534 -v: verbose. Print the contents of the variable.
536 535
537 536 In most cases you should not need to split as a list, because the
538 537 returned value is a special type of string which can automatically
539 538 provide its contents either as a list (split on newlines) or as a
540 539 space-separated string. These are convenient, respectively, either
541 540 for sequential processing or to be passed to a shell command.
542 541
543 542 For example::
544 543
545 544 # Capture into variable a
546 545 In [1]: sc a=ls *py
547 546
548 547 # a is a string with embedded newlines
549 548 In [2]: a
550 549 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
551 550
552 551 # which can be seen as a list:
553 552 In [3]: a.l
554 553 Out[3]: ['setup.py', 'win32_manual_post_install.py']
555 554
556 555 # or as a whitespace-separated string:
557 556 In [4]: a.s
558 557 Out[4]: 'setup.py win32_manual_post_install.py'
559 558
560 559 # a.s is useful to pass as a single command line:
561 560 In [5]: !wc -l $a.s
562 561 146 setup.py
563 562 130 win32_manual_post_install.py
564 563 276 total
565 564
566 565 # while the list form is useful to loop over:
567 566 In [6]: for f in a.l:
568 567 ...: !wc -l $f
569 568 ...:
570 569 146 setup.py
571 570 130 win32_manual_post_install.py
572 571
573 572 Similarly, the lists returned by the -l option are also special, in
574 573 the sense that you can equally invoke the .s attribute on them to
575 574 automatically get a whitespace-separated string from their contents::
576 575
577 576 In [7]: sc -l b=ls *py
578 577
579 578 In [8]: b
580 579 Out[8]: ['setup.py', 'win32_manual_post_install.py']
581 580
582 581 In [9]: b.s
583 582 Out[9]: 'setup.py win32_manual_post_install.py'
584 583
585 584 In summary, both the lists and strings used for output capture have
586 585 the following special attributes::
587 586
588 587 .l (or .list) : value as list.
589 588 .n (or .nlstr): value as newline-separated string.
590 589 .s (or .spstr): value as space-separated string.
591 590 """
592 591
593 592 opts,args = self.parse_options(parameter_s, 'lv')
594 593 # Try to get a variable name and command to run
595 594 try:
596 595 # the variable name must be obtained from the parse_options
597 596 # output, which uses shlex.split to strip options out.
598 597 var,_ = args.split('=', 1)
599 598 var = var.strip()
600 599 # But the command has to be extracted from the original input
601 600 # parameter_s, not on what parse_options returns, to avoid the
602 601 # quote stripping which shlex.split performs on it.
603 602 _,cmd = parameter_s.split('=', 1)
604 603 except ValueError:
605 604 var,cmd = '',''
606 605 # If all looks ok, proceed
607 606 split = 'l' in opts
608 607 out = self.shell.getoutput(cmd, split=split)
609 608 if 'v' in opts:
610 609 print('%s ==\n%s' % (var, pformat(out)))
611 610 if var:
612 611 self.shell.user_ns.update({var:out})
613 612 else:
614 613 return out
615 614
616 615 @line_cell_magic
617 616 def sx(self, line='', cell=None):
618 617 """Shell execute - run shell command and capture output (!! is short-hand).
619 618
620 619 %sx command
621 620
622 621 IPython will run the given command using commands.getoutput(), and
623 622 return the result formatted as a list (split on '\\n'). Since the
624 623 output is _returned_, it will be stored in ipython's regular output
625 624 cache Out[N] and in the '_N' automatic variables.
626 625
627 626 Notes:
628 627
629 628 1) If an input line begins with '!!', then %sx is automatically
630 629 invoked. That is, while::
631 630
632 631 !ls
633 632
634 633 causes ipython to simply issue system('ls'), typing::
635 634
636 635 !!ls
637 636
638 637 is a shorthand equivalent to::
639 638
640 639 %sx ls
641 640
642 641 2) %sx differs from %sc in that %sx automatically splits into a list,
643 642 like '%sc -l'. The reason for this is to make it as easy as possible
644 643 to process line-oriented shell output via further python commands.
645 644 %sc is meant to provide much finer control, but requires more
646 645 typing.
647 646
648 647 3) Just like %sc -l, this is a list with special attributes:
649 648 ::
650 649
651 650 .l (or .list) : value as list.
652 651 .n (or .nlstr): value as newline-separated string.
653 652 .s (or .spstr): value as whitespace-separated string.
654 653
655 654 This is very useful when trying to use such lists as arguments to
656 655 system commands."""
657 656
658 657 if cell is None:
659 658 # line magic
660 659 return self.shell.getoutput(line)
661 660 else:
662 661 opts,args = self.parse_options(line, '', 'out=')
663 662 output = self.shell.getoutput(cell)
664 663 out_name = opts.get('out', opts.get('o'))
665 664 if out_name:
666 665 self.shell.user_ns[out_name] = output
667 666 else:
668 667 return output
669 668
670 669 system = line_cell_magic('system')(sx)
671 670 bang = cell_magic('!')(sx)
672 671
673 672 @line_magic
674 673 def bookmark(self, parameter_s=''):
675 674 """Manage IPython's bookmark system.
676 675
677 676 %bookmark <name> - set bookmark to current dir
678 677 %bookmark <name> <dir> - set bookmark to <dir>
679 678 %bookmark -l - list all bookmarks
680 679 %bookmark -d <name> - remove bookmark
681 680 %bookmark -r - remove all bookmarks
682 681
683 682 You can later on access a bookmarked folder with::
684 683
685 684 %cd -b <name>
686 685
687 686 or simply '%cd <name>' if there is no directory called <name> AND
688 687 there is such a bookmark defined.
689 688
690 689 Your bookmarks persist through IPython sessions, but they are
691 690 associated with each profile."""
692 691
693 692 opts,args = self.parse_options(parameter_s,'drl',mode='list')
694 693 if len(args) > 2:
695 694 raise UsageError("%bookmark: too many arguments")
696 695
697 696 bkms = self.shell.db.get('bookmarks',{})
698 697
699 698 if 'd' in opts:
700 699 try:
701 700 todel = args[0]
702 701 except IndexError:
703 702 raise UsageError(
704 703 "%bookmark -d: must provide a bookmark to delete")
705 704 else:
706 705 try:
707 706 del bkms[todel]
708 707 except KeyError:
709 708 raise UsageError(
710 709 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
711 710
712 711 elif 'r' in opts:
713 712 bkms = {}
714 713 elif 'l' in opts:
715 714 bks = sorted(bkms)
716 715 if bks:
717 716 size = max(map(len, bks))
718 717 else:
719 718 size = 0
720 719 fmt = '%-'+str(size)+'s -> %s'
721 720 print('Current bookmarks:')
722 721 for bk in bks:
723 722 print(fmt % (bk, bkms[bk]))
724 723 else:
725 724 if not args:
726 725 raise UsageError("%bookmark: You must specify the bookmark name")
727 726 elif len(args)==1:
728 bkms[args[0]] = py3compat.getcwd()
727 bkms[args[0]] = os.getcwd()
729 728 elif len(args)==2:
730 729 bkms[args[0]] = args[1]
731 730 self.shell.db['bookmarks'] = bkms
732 731
733 732 @line_magic
734 733 def pycat(self, parameter_s=''):
735 734 """Show a syntax-highlighted file through a pager.
736 735
737 736 This magic is similar to the cat utility, but it will assume the file
738 737 to be Python source and will show it with syntax highlighting.
739 738
740 739 This magic command can either take a local filename, an url,
741 740 an history range (see %history) or a macro as argument ::
742 741
743 742 %pycat myscript.py
744 743 %pycat 7-27
745 744 %pycat myMacro
746 745 %pycat http://www.example.com/myscript.py
747 746 """
748 747 if not parameter_s:
749 748 raise UsageError('Missing filename, URL, input history range, '
750 749 'or macro.')
751 750
752 751 try :
753 752 cont = self.shell.find_user_code(parameter_s, skip_encoding_cookie=False)
754 753 except (ValueError, IOError):
755 754 print("Error: no such file, variable, URL, history range or macro")
756 755 return
757 756
758 757 page.page(self.shell.pycolorize(source_to_unicode(cont)))
759 758
760 759 @magic_arguments.magic_arguments()
761 760 @magic_arguments.argument(
762 761 '-a', '--append', action='store_true', default=False,
763 762 help='Append contents of the cell to an existing file. '
764 763 'The file will be created if it does not exist.'
765 764 )
766 765 @magic_arguments.argument(
767 'filename', type=unicode_type,
766 'filename', type=str,
768 767 help='file to write'
769 768 )
770 769 @cell_magic
771 770 def writefile(self, line, cell):
772 771 """Write the contents of the cell to a file.
773 772
774 773 The file will be overwritten unless the -a (--append) flag is specified.
775 774 """
776 775 args = magic_arguments.parse_argstring(self.writefile, line)
777 776 filename = os.path.expanduser(args.filename)
778 777
779 778 if os.path.exists(filename):
780 779 if args.append:
781 780 print("Appending to %s" % filename)
782 781 else:
783 782 print("Overwriting %s" % filename)
784 783 else:
785 784 print("Writing %s" % filename)
786 785
787 786 mode = 'a' if args.append else 'w'
788 787 with io.open(filename, mode, encoding='utf-8') as f:
789 788 f.write(cell)
@@ -1,987 +1,987 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tools for inspecting Python objects.
3 3
4 4 Uses syntax highlighting for presenting the various information elements.
5 5
6 6 Similar in spirit to the inspect module, but all calls take a name argument to
7 7 reference the name under which an object is being read.
8 8 """
9 9
10 10 # Copyright (c) IPython Development Team.
11 11 # Distributed under the terms of the Modified BSD License.
12 12
13 13 __all__ = ['Inspector','InspectColors']
14 14
15 15 # stdlib modules
16 16 import inspect
17 17 from inspect import signature
18 18 import linecache
19 19 import warnings
20 20 import os
21 21 from textwrap import dedent
22 22 import types
23 23 import io as stdlib_io
24 24 from itertools import zip_longest
25 25
26 26 # IPython's own
27 27 from IPython.core import page
28 28 from IPython.lib.pretty import pretty
29 29 from IPython.testing.skipdoctest import skip_doctest
30 30 from IPython.utils import PyColorize
31 31 from IPython.utils import openpy
32 32 from IPython.utils import py3compat
33 33 from IPython.utils.dir2 import safe_hasattr
34 34 from IPython.utils.path import compress_user
35 35 from IPython.utils.text import indent
36 36 from IPython.utils.wildcard import list_namespace
37 37 from IPython.utils.coloransi import TermColors, ColorScheme, ColorSchemeTable
38 from IPython.utils.py3compat import cast_unicode, string_types, PY3
38 from IPython.utils.py3compat import cast_unicode, PY3
39 39 from IPython.utils.colorable import Colorable
40 40 from IPython.utils.decorators import undoc
41 41
42 42 from pygments import highlight
43 43 from pygments.lexers import PythonLexer
44 44 from pygments.formatters import HtmlFormatter
45 45
46 46 def pylight(code):
47 47 return highlight(code, PythonLexer(), HtmlFormatter(noclasses=True))
48 48
49 49 # builtin docstrings to ignore
50 50 _func_call_docstring = types.FunctionType.__call__.__doc__
51 51 _object_init_docstring = object.__init__.__doc__
52 52 _builtin_type_docstrings = {
53 53 inspect.getdoc(t) for t in (types.ModuleType, types.MethodType,
54 54 types.FunctionType, property)
55 55 }
56 56
57 57 _builtin_func_type = type(all)
58 58 _builtin_meth_type = type(str.upper) # Bound methods have the same type as builtin functions
59 59 #****************************************************************************
60 60 # Builtin color schemes
61 61
62 62 Colors = TermColors # just a shorthand
63 63
64 64 InspectColors = PyColorize.ANSICodeColors
65 65
66 66 #****************************************************************************
67 67 # Auxiliary functions and objects
68 68
69 69 # See the messaging spec for the definition of all these fields. This list
70 70 # effectively defines the order of display
71 71 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
72 72 'length', 'file', 'definition', 'docstring', 'source',
73 73 'init_definition', 'class_docstring', 'init_docstring',
74 74 'call_def', 'call_docstring',
75 75 # These won't be printed but will be used to determine how to
76 76 # format the object
77 77 'ismagic', 'isalias', 'isclass', 'argspec', 'found', 'name'
78 78 ]
79 79
80 80
81 81 def object_info(**kw):
82 82 """Make an object info dict with all fields present."""
83 83 infodict = dict(zip_longest(info_fields, [None]))
84 84 infodict.update(kw)
85 85 return infodict
86 86
87 87
88 88 def get_encoding(obj):
89 89 """Get encoding for python source file defining obj
90 90
91 91 Returns None if obj is not defined in a sourcefile.
92 92 """
93 93 ofile = find_file(obj)
94 94 # run contents of file through pager starting at line where the object
95 95 # is defined, as long as the file isn't binary and is actually on the
96 96 # filesystem.
97 97 if ofile is None:
98 98 return None
99 99 elif ofile.endswith(('.so', '.dll', '.pyd')):
100 100 return None
101 101 elif not os.path.isfile(ofile):
102 102 return None
103 103 else:
104 104 # Print only text files, not extension binaries. Note that
105 105 # getsourcelines returns lineno with 1-offset and page() uses
106 106 # 0-offset, so we must adjust.
107 107 with stdlib_io.open(ofile, 'rb') as buffer: # Tweaked to use io.open for Python 2
108 108 encoding, lines = openpy.detect_encoding(buffer.readline)
109 109 return encoding
110 110
111 111 def getdoc(obj):
112 112 """Stable wrapper around inspect.getdoc.
113 113
114 114 This can't crash because of attribute problems.
115 115
116 116 It also attempts to call a getdoc() method on the given object. This
117 117 allows objects which provide their docstrings via non-standard mechanisms
118 118 (like Pyro proxies) to still be inspected by ipython's ? system.
119 119 """
120 120 # Allow objects to offer customized documentation via a getdoc method:
121 121 try:
122 122 ds = obj.getdoc()
123 123 except Exception:
124 124 pass
125 125 else:
126 126 # if we get extra info, we add it to the normal docstring.
127 if isinstance(ds, string_types):
127 if isinstance(ds, str):
128 128 return inspect.cleandoc(ds)
129 129 try:
130 130 docstr = inspect.getdoc(obj)
131 131 encoding = get_encoding(obj)
132 132 return py3compat.cast_unicode(docstr, encoding=encoding)
133 133 except Exception:
134 134 # Harden against an inspect failure, which can occur with
135 135 # extensions modules.
136 136 raise
137 137 return None
138 138
139 139
140 140 def getsource(obj, oname=''):
141 141 """Wrapper around inspect.getsource.
142 142
143 143 This can be modified by other projects to provide customized source
144 144 extraction.
145 145
146 146 Parameters
147 147 ----------
148 148 obj : object
149 149 an object whose source code we will attempt to extract
150 150 oname : str
151 151 (optional) a name under which the object is known
152 152
153 153 Returns
154 154 -------
155 155 src : unicode or None
156 156
157 157 """
158 158
159 159 if isinstance(obj, property):
160 160 sources = []
161 161 for attrname in ['fget', 'fset', 'fdel']:
162 162 fn = getattr(obj, attrname)
163 163 if fn is not None:
164 164 encoding = get_encoding(fn)
165 165 oname_prefix = ('%s.' % oname) if oname else ''
166 166 sources.append(cast_unicode(
167 167 ''.join(('# ', oname_prefix, attrname)),
168 168 encoding=encoding))
169 169 if inspect.isfunction(fn):
170 170 sources.append(dedent(getsource(fn)))
171 171 else:
172 172 # Default str/repr only prints function name,
173 173 # pretty.pretty prints module name too.
174 174 sources.append(cast_unicode(
175 175 '%s%s = %s\n' % (
176 176 oname_prefix, attrname, pretty(fn)),
177 177 encoding=encoding))
178 178 if sources:
179 179 return '\n'.join(sources)
180 180 else:
181 181 return None
182 182
183 183 else:
184 184 # Get source for non-property objects.
185 185
186 186 obj = _get_wrapped(obj)
187 187
188 188 try:
189 189 src = inspect.getsource(obj)
190 190 except TypeError:
191 191 # The object itself provided no meaningful source, try looking for
192 192 # its class definition instead.
193 193 if hasattr(obj, '__class__'):
194 194 try:
195 195 src = inspect.getsource(obj.__class__)
196 196 except TypeError:
197 197 return None
198 198
199 199 encoding = get_encoding(obj)
200 200 return cast_unicode(src, encoding=encoding)
201 201
202 202
203 203 def is_simple_callable(obj):
204 204 """True if obj is a function ()"""
205 205 return (inspect.isfunction(obj) or inspect.ismethod(obj) or \
206 206 isinstance(obj, _builtin_func_type) or isinstance(obj, _builtin_meth_type))
207 207
208 208
209 209 def getargspec(obj):
210 210 """Wrapper around :func:`inspect.getfullargspec` on Python 3, and
211 211 :func:inspect.getargspec` on Python 2.
212 212
213 213 In addition to functions and methods, this can also handle objects with a
214 214 ``__call__`` attribute.
215 215 """
216 216 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
217 217 obj = obj.__call__
218 218
219 219 return inspect.getfullargspec(obj) if PY3 else inspect.getargspec(obj)
220 220
221 221
222 222 def format_argspec(argspec):
223 223 """Format argspect, convenience wrapper around inspect's.
224 224
225 225 This takes a dict instead of ordered arguments and calls
226 226 inspect.format_argspec with the arguments in the necessary order.
227 227 """
228 228 return inspect.formatargspec(argspec['args'], argspec['varargs'],
229 229 argspec['varkw'], argspec['defaults'])
230 230
231 231 @undoc
232 232 def call_tip(oinfo, format_call=True):
233 233 """DEPRECATED. Extract call tip data from an oinfo dict.
234 234 """
235 235 warnings.warn('`call_tip` function is deprecated as of IPython 6.0'
236 236 'and will be removed in future versions.', DeprecationWarning, stacklevel=2)
237 237 # Get call definition
238 238 argspec = oinfo.get('argspec')
239 239 if argspec is None:
240 240 call_line = None
241 241 else:
242 242 # Callable objects will have 'self' as their first argument, prune
243 243 # it out if it's there for clarity (since users do *not* pass an
244 244 # extra first argument explicitly).
245 245 try:
246 246 has_self = argspec['args'][0] == 'self'
247 247 except (KeyError, IndexError):
248 248 pass
249 249 else:
250 250 if has_self:
251 251 argspec['args'] = argspec['args'][1:]
252 252
253 253 call_line = oinfo['name']+format_argspec(argspec)
254 254
255 255 # Now get docstring.
256 256 # The priority is: call docstring, constructor docstring, main one.
257 257 doc = oinfo.get('call_docstring')
258 258 if doc is None:
259 259 doc = oinfo.get('init_docstring')
260 260 if doc is None:
261 261 doc = oinfo.get('docstring','')
262 262
263 263 return call_line, doc
264 264
265 265
266 266 def _get_wrapped(obj):
267 267 """Get the original object if wrapped in one or more @decorators
268 268
269 269 Some objects automatically construct similar objects on any unrecognised
270 270 attribute access (e.g. unittest.mock.call). To protect against infinite loops,
271 271 this will arbitrarily cut off after 100 levels of obj.__wrapped__
272 272 attribute access. --TK, Jan 2016
273 273 """
274 274 orig_obj = obj
275 275 i = 0
276 276 while safe_hasattr(obj, '__wrapped__'):
277 277 obj = obj.__wrapped__
278 278 i += 1
279 279 if i > 100:
280 280 # __wrapped__ is probably a lie, so return the thing we started with
281 281 return orig_obj
282 282 return obj
283 283
284 284 def find_file(obj):
285 285 """Find the absolute path to the file where an object was defined.
286 286
287 287 This is essentially a robust wrapper around `inspect.getabsfile`.
288 288
289 289 Returns None if no file can be found.
290 290
291 291 Parameters
292 292 ----------
293 293 obj : any Python object
294 294
295 295 Returns
296 296 -------
297 297 fname : str
298 298 The absolute path to the file where the object was defined.
299 299 """
300 300 obj = _get_wrapped(obj)
301 301
302 302 fname = None
303 303 try:
304 304 fname = inspect.getabsfile(obj)
305 305 except TypeError:
306 306 # For an instance, the file that matters is where its class was
307 307 # declared.
308 308 if hasattr(obj, '__class__'):
309 309 try:
310 310 fname = inspect.getabsfile(obj.__class__)
311 311 except TypeError:
312 312 # Can happen for builtins
313 313 pass
314 314 except:
315 315 pass
316 316 return cast_unicode(fname)
317 317
318 318
319 319 def find_source_lines(obj):
320 320 """Find the line number in a file where an object was defined.
321 321
322 322 This is essentially a robust wrapper around `inspect.getsourcelines`.
323 323
324 324 Returns None if no file can be found.
325 325
326 326 Parameters
327 327 ----------
328 328 obj : any Python object
329 329
330 330 Returns
331 331 -------
332 332 lineno : int
333 333 The line number where the object definition starts.
334 334 """
335 335 obj = _get_wrapped(obj)
336 336
337 337 try:
338 338 try:
339 339 lineno = inspect.getsourcelines(obj)[1]
340 340 except TypeError:
341 341 # For instances, try the class object like getsource() does
342 342 if hasattr(obj, '__class__'):
343 343 lineno = inspect.getsourcelines(obj.__class__)[1]
344 344 else:
345 345 lineno = None
346 346 except:
347 347 return None
348 348
349 349 return lineno
350 350
351 351 class Inspector(Colorable):
352 352
353 353 def __init__(self, color_table=InspectColors,
354 354 code_color_table=PyColorize.ANSICodeColors,
355 355 scheme='NoColor',
356 356 str_detail_level=0,
357 357 parent=None, config=None):
358 358 super(Inspector, self).__init__(parent=parent, config=config)
359 359 self.color_table = color_table
360 360 self.parser = PyColorize.Parser(out='str', parent=self, style=scheme)
361 361 self.format = self.parser.format
362 362 self.str_detail_level = str_detail_level
363 363 self.set_active_scheme(scheme)
364 364
365 365 def _getdef(self,obj,oname=''):
366 366 """Return the call signature for any callable object.
367 367
368 368 If any exception is generated, None is returned instead and the
369 369 exception is suppressed."""
370 370 try:
371 371 hdef = oname + str(signature(obj))
372 372 return cast_unicode(hdef)
373 373 except:
374 374 return None
375 375
376 376 def __head(self,h):
377 377 """Return a header string with proper colors."""
378 378 return '%s%s%s' % (self.color_table.active_colors.header,h,
379 379 self.color_table.active_colors.normal)
380 380
381 381 def set_active_scheme(self, scheme):
382 382 self.color_table.set_active_scheme(scheme)
383 383 self.parser.color_table.set_active_scheme(scheme)
384 384
385 385 def noinfo(self, msg, oname):
386 386 """Generic message when no information is found."""
387 387 print('No %s found' % msg, end=' ')
388 388 if oname:
389 389 print('for %s' % oname)
390 390 else:
391 391 print()
392 392
393 393 def pdef(self, obj, oname=''):
394 394 """Print the call signature for any callable object.
395 395
396 396 If the object is a class, print the constructor information."""
397 397
398 398 if not callable(obj):
399 399 print('Object is not callable.')
400 400 return
401 401
402 402 header = ''
403 403
404 404 if inspect.isclass(obj):
405 405 header = self.__head('Class constructor information:\n')
406 406 elif (not py3compat.PY3) and type(obj) is types.InstanceType:
407 407 obj = obj.__call__
408 408
409 409 output = self._getdef(obj,oname)
410 410 if output is None:
411 411 self.noinfo('definition header',oname)
412 412 else:
413 413 print(header,self.format(output), end=' ')
414 414
415 415 # In Python 3, all classes are new-style, so they all have __init__.
416 416 @skip_doctest
417 417 def pdoc(self, obj, oname='', formatter=None):
418 418 """Print the docstring for any object.
419 419
420 420 Optional:
421 421 -formatter: a function to run the docstring through for specially
422 422 formatted docstrings.
423 423
424 424 Examples
425 425 --------
426 426
427 427 In [1]: class NoInit:
428 428 ...: pass
429 429
430 430 In [2]: class NoDoc:
431 431 ...: def __init__(self):
432 432 ...: pass
433 433
434 434 In [3]: %pdoc NoDoc
435 435 No documentation found for NoDoc
436 436
437 437 In [4]: %pdoc NoInit
438 438 No documentation found for NoInit
439 439
440 440 In [5]: obj = NoInit()
441 441
442 442 In [6]: %pdoc obj
443 443 No documentation found for obj
444 444
445 445 In [5]: obj2 = NoDoc()
446 446
447 447 In [6]: %pdoc obj2
448 448 No documentation found for obj2
449 449 """
450 450
451 451 head = self.__head # For convenience
452 452 lines = []
453 453 ds = getdoc(obj)
454 454 if formatter:
455 455 ds = formatter(ds).get('plain/text', ds)
456 456 if ds:
457 457 lines.append(head("Class docstring:"))
458 458 lines.append(indent(ds))
459 459 if inspect.isclass(obj) and hasattr(obj, '__init__'):
460 460 init_ds = getdoc(obj.__init__)
461 461 if init_ds is not None:
462 462 lines.append(head("Init docstring:"))
463 463 lines.append(indent(init_ds))
464 464 elif hasattr(obj,'__call__'):
465 465 call_ds = getdoc(obj.__call__)
466 466 if call_ds:
467 467 lines.append(head("Call docstring:"))
468 468 lines.append(indent(call_ds))
469 469
470 470 if not lines:
471 471 self.noinfo('documentation',oname)
472 472 else:
473 473 page.page('\n'.join(lines))
474 474
475 475 def psource(self, obj, oname=''):
476 476 """Print the source code for an object."""
477 477
478 478 # Flush the source cache because inspect can return out-of-date source
479 479 linecache.checkcache()
480 480 try:
481 481 src = getsource(obj, oname=oname)
482 482 except Exception:
483 483 src = None
484 484
485 485 if src is None:
486 486 self.noinfo('source', oname)
487 487 else:
488 488 page.page(self.format(src))
489 489
490 490 def pfile(self, obj, oname=''):
491 491 """Show the whole file where an object was defined."""
492 492
493 493 lineno = find_source_lines(obj)
494 494 if lineno is None:
495 495 self.noinfo('file', oname)
496 496 return
497 497
498 498 ofile = find_file(obj)
499 499 # run contents of file through pager starting at line where the object
500 500 # is defined, as long as the file isn't binary and is actually on the
501 501 # filesystem.
502 502 if ofile.endswith(('.so', '.dll', '.pyd')):
503 503 print('File %r is binary, not printing.' % ofile)
504 504 elif not os.path.isfile(ofile):
505 505 print('File %r does not exist, not printing.' % ofile)
506 506 else:
507 507 # Print only text files, not extension binaries. Note that
508 508 # getsourcelines returns lineno with 1-offset and page() uses
509 509 # 0-offset, so we must adjust.
510 510 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
511 511
512 512 def _format_fields(self, fields, title_width=0):
513 513 """Formats a list of fields for display.
514 514
515 515 Parameters
516 516 ----------
517 517 fields : list
518 518 A list of 2-tuples: (field_title, field_content)
519 519 title_width : int
520 520 How many characters to pad titles to. Default to longest title.
521 521 """
522 522 out = []
523 523 header = self.__head
524 524 if title_width == 0:
525 525 title_width = max(len(title) + 2 for title, _ in fields)
526 526 for title, content in fields:
527 527 if len(content.splitlines()) > 1:
528 528 title = header(title + ':') + '\n'
529 529 else:
530 530 title = header((title + ':').ljust(title_width))
531 531 out.append(cast_unicode(title) + cast_unicode(content))
532 532 return "\n".join(out)
533 533
534 534 def _mime_format(self, text, formatter=None):
535 535 """Return a mime bundle representation of the input text.
536 536
537 537 - if `formatter` is None, the returned mime bundle has
538 538 a `text/plain` field, with the input text.
539 539 a `text/html` field with a `<pre>` tag containing the input text.
540 540
541 541 - if `formatter` is not None, it must be a callable transforming the
542 542 input text into a mime bundle. Default values for `text/plain` and
543 543 `text/html` representations are the ones described above.
544 544
545 545 Note:
546 546
547 547 Formatters returning strings are supported but this behavior is deprecated.
548 548
549 549 """
550 550 text = cast_unicode(text)
551 551 defaults = {
552 552 'text/plain': text,
553 553 'text/html': '<pre>' + text + '</pre>'
554 554 }
555 555
556 556 if formatter is None:
557 557 return defaults
558 558 else:
559 559 formatted = formatter(text)
560 560
561 561 if not isinstance(formatted, dict):
562 562 # Handle the deprecated behavior of a formatter returning
563 563 # a string instead of a mime bundle.
564 564 return {
565 565 'text/plain': formatted,
566 566 'text/html': '<pre>' + formatted + '</pre>'
567 567 }
568 568
569 569 else:
570 570 return dict(defaults, **formatted)
571 571
572 572
573 573 def format_mime(self, bundle):
574 574
575 575 text_plain = bundle['text/plain']
576 576
577 577 text = ''
578 578 heads, bodies = list(zip(*text_plain))
579 579 _len = max(len(h) for h in heads)
580 580
581 581 for head, body in zip(heads, bodies):
582 582 body = body.strip('\n')
583 583 delim = '\n' if '\n' in body else ' '
584 584 text += self.__head(head+':') + (_len - len(head))*' ' +delim + body +'\n'
585 585
586 586 bundle['text/plain'] = text
587 587 return bundle
588 588
589 589 def _get_info(self, obj, oname='', formatter=None, info=None, detail_level=0):
590 590 """Retrieve an info dict and format it."""
591 591
592 592 info = self._info(obj, oname=oname, info=info, detail_level=detail_level)
593 593
594 594 _mime = {
595 595 'text/plain': [],
596 596 'text/html': '',
597 597 }
598 598
599 599 def append_field(bundle, title, key, formatter=None):
600 600 field = info[key]
601 601 if field is not None:
602 602 formatted_field = self._mime_format(field, formatter)
603 603 bundle['text/plain'].append((title, formatted_field['text/plain']))
604 604 bundle['text/html'] += '<h1>' + title + '</h1>\n' + formatted_field['text/html'] + '\n'
605 605
606 606 def code_formatter(text):
607 607 return {
608 608 'text/plain': self.format(text),
609 609 'text/html': pylight(text)
610 610 }
611 611
612 612 if info['isalias']:
613 613 append_field(_mime, 'Repr', 'string_form')
614 614
615 615 elif info['ismagic']:
616 616 if detail_level > 0:
617 617 append_field(_mime, 'Source', 'source', code_formatter)
618 618 else:
619 619 append_field(_mime, 'Docstring', 'docstring', formatter)
620 620 append_field(_mime, 'File', 'file')
621 621
622 622 elif info['isclass'] or is_simple_callable(obj):
623 623 # Functions, methods, classes
624 624 append_field(_mime, 'Signature', 'definition', code_formatter)
625 625 append_field(_mime, 'Init signature', 'init_definition', code_formatter)
626 626 if detail_level > 0 and info['source']:
627 627 append_field(_mime, 'Source', 'source', code_formatter)
628 628 else:
629 629 append_field(_mime, 'Docstring', 'docstring', formatter)
630 630 append_field(_mime, 'Init docstring', 'init_docstring', formatter)
631 631
632 632 append_field(_mime, 'File', 'file')
633 633 append_field(_mime, 'Type', 'type_name')
634 634
635 635 else:
636 636 # General Python objects
637 637 append_field(_mime, 'Signature', 'definition', code_formatter)
638 638 append_field(_mime, 'Call signature', 'call_def', code_formatter)
639 639
640 640 append_field(_mime, 'Type', 'type_name')
641 641
642 642 # Base class for old-style instances
643 643 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
644 644 append_field(_mime, 'Base Class', 'base_class')
645 645
646 646 append_field(_mime, 'String form', 'string_form')
647 647
648 648 # Namespace
649 649 if info['namespace'] != 'Interactive':
650 650 append_field(_mime, 'Namespace', 'namespace')
651 651
652 652 append_field(_mime, 'Length', 'length')
653 653 append_field(_mime, 'File', 'file')
654 654
655 655 # Source or docstring, depending on detail level and whether
656 656 # source found.
657 657 if detail_level > 0:
658 658 append_field(_mime, 'Source', 'source', code_formatter)
659 659 else:
660 660 append_field(_mime, 'Docstring', 'docstring', formatter)
661 661
662 662 append_field(_mime, 'Class docstring', 'class_docstring', formatter)
663 663 append_field(_mime, 'Init docstring', 'init_docstring', formatter)
664 664 append_field(_mime, 'Call docstring', 'call_docstring', formatter)
665 665
666 666
667 667 return self.format_mime(_mime)
668 668
669 669 def pinfo(self, obj, oname='', formatter=None, info=None, detail_level=0, enable_html_pager=True):
670 670 """Show detailed information about an object.
671 671
672 672 Optional arguments:
673 673
674 674 - oname: name of the variable pointing to the object.
675 675
676 676 - formatter: callable (optional)
677 677 A special formatter for docstrings.
678 678
679 679 The formatter is a callable that takes a string as an input
680 680 and returns either a formatted string or a mime type bundle
681 681 in the form of a dictionnary.
682 682
683 683 Although the support of custom formatter returning a string
684 684 instead of a mime type bundle is deprecated.
685 685
686 686 - info: a structure with some information fields which may have been
687 687 precomputed already.
688 688
689 689 - detail_level: if set to 1, more information is given.
690 690 """
691 691 info = self._get_info(obj, oname, formatter, info, detail_level)
692 692 if not enable_html_pager:
693 693 del info['text/html']
694 694 page.page(info)
695 695
696 696 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
697 697 """DEPRECATED. Compute a dict with detailed information about an object.
698 698 """
699 699 if formatter is not None:
700 700 warnings.warn('The `formatter` keyword argument to `Inspector.info`'
701 701 'is deprecated as of IPython 5.0 and will have no effects.',
702 702 DeprecationWarning, stacklevel=2)
703 703 return self._info(obj, oname=oname, info=info, detail_level=detail_level)
704 704
705 705 def _info(self, obj, oname='', info=None, detail_level=0):
706 706 """Compute a dict with detailed information about an object.
707 707
708 708 Optional arguments:
709 709
710 710 - oname: name of the variable pointing to the object.
711 711
712 712 - info: a structure with some information fields which may have been
713 713 precomputed already.
714 714
715 715 - detail_level: if set to 1, more information is given.
716 716 """
717 717
718 718 obj_type = type(obj)
719 719
720 720 if info is None:
721 721 ismagic = 0
722 722 isalias = 0
723 723 ospace = ''
724 724 else:
725 725 ismagic = info.ismagic
726 726 isalias = info.isalias
727 727 ospace = info.namespace
728 728
729 729 # Get docstring, special-casing aliases:
730 730 if isalias:
731 731 if not callable(obj):
732 732 try:
733 733 ds = "Alias to the system command:\n %s" % obj[1]
734 734 except:
735 735 ds = "Alias: " + str(obj)
736 736 else:
737 737 ds = "Alias to " + str(obj)
738 738 if obj.__doc__:
739 739 ds += "\nDocstring:\n" + obj.__doc__
740 740 else:
741 741 ds = getdoc(obj)
742 742 if ds is None:
743 743 ds = '<no docstring>'
744 744
745 745 # store output in a dict, we initialize it here and fill it as we go
746 746 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
747 747
748 748 string_max = 200 # max size of strings to show (snipped if longer)
749 749 shalf = int((string_max - 5) / 2)
750 750
751 751 if ismagic:
752 752 obj_type_name = 'Magic function'
753 753 elif isalias:
754 754 obj_type_name = 'System alias'
755 755 else:
756 756 obj_type_name = obj_type.__name__
757 757 out['type_name'] = obj_type_name
758 758
759 759 try:
760 760 bclass = obj.__class__
761 761 out['base_class'] = str(bclass)
762 762 except: pass
763 763
764 764 # String form, but snip if too long in ? form (full in ??)
765 765 if detail_level >= self.str_detail_level:
766 766 try:
767 767 ostr = str(obj)
768 768 str_head = 'string_form'
769 769 if not detail_level and len(ostr)>string_max:
770 770 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
771 771 ostr = ("\n" + " " * len(str_head.expandtabs())).\
772 772 join(q.strip() for q in ostr.split("\n"))
773 773 out[str_head] = ostr
774 774 except:
775 775 pass
776 776
777 777 if ospace:
778 778 out['namespace'] = ospace
779 779
780 780 # Length (for strings and lists)
781 781 try:
782 782 out['length'] = str(len(obj))
783 783 except: pass
784 784
785 785 # Filename where object was defined
786 786 binary_file = False
787 787 fname = find_file(obj)
788 788 if fname is None:
789 789 # if anything goes wrong, we don't want to show source, so it's as
790 790 # if the file was binary
791 791 binary_file = True
792 792 else:
793 793 if fname.endswith(('.so', '.dll', '.pyd')):
794 794 binary_file = True
795 795 elif fname.endswith('<string>'):
796 796 fname = 'Dynamically generated function. No source code available.'
797 797 out['file'] = compress_user(fname)
798 798
799 799 # Original source code for a callable, class or property.
800 800 if detail_level:
801 801 # Flush the source cache because inspect can return out-of-date
802 802 # source
803 803 linecache.checkcache()
804 804 try:
805 805 if isinstance(obj, property) or not binary_file:
806 806 src = getsource(obj, oname)
807 807 if src is not None:
808 808 src = src.rstrip()
809 809 out['source'] = src
810 810
811 811 except Exception:
812 812 pass
813 813
814 814 # Add docstring only if no source is to be shown (avoid repetitions).
815 815 if ds and out.get('source', None) is None:
816 816 out['docstring'] = ds
817 817
818 818 # Constructor docstring for classes
819 819 if inspect.isclass(obj):
820 820 out['isclass'] = True
821 821
822 822 # get the init signature:
823 823 try:
824 824 init_def = self._getdef(obj, oname)
825 825 except AttributeError:
826 826 init_def = None
827 827
828 828 # get the __init__ docstring
829 829 try:
830 830 obj_init = obj.__init__
831 831 except AttributeError:
832 832 init_ds = None
833 833 else:
834 834 if init_def is None:
835 835 # Get signature from init if top-level sig failed.
836 836 # Can happen for built-in types (list, etc.).
837 837 try:
838 838 init_def = self._getdef(obj_init, oname)
839 839 except AttributeError:
840 840 pass
841 841 init_ds = getdoc(obj_init)
842 842 # Skip Python's auto-generated docstrings
843 843 if init_ds == _object_init_docstring:
844 844 init_ds = None
845 845
846 846 if init_def:
847 847 out['init_definition'] = init_def
848 848
849 849 if init_ds:
850 850 out['init_docstring'] = init_ds
851 851
852 852 # and class docstring for instances:
853 853 else:
854 854 # reconstruct the function definition and print it:
855 855 defln = self._getdef(obj, oname)
856 856 if defln:
857 857 out['definition'] = defln
858 858
859 859 # First, check whether the instance docstring is identical to the
860 860 # class one, and print it separately if they don't coincide. In
861 861 # most cases they will, but it's nice to print all the info for
862 862 # objects which use instance-customized docstrings.
863 863 if ds:
864 864 try:
865 865 cls = getattr(obj,'__class__')
866 866 except:
867 867 class_ds = None
868 868 else:
869 869 class_ds = getdoc(cls)
870 870 # Skip Python's auto-generated docstrings
871 871 if class_ds in _builtin_type_docstrings:
872 872 class_ds = None
873 873 if class_ds and ds != class_ds:
874 874 out['class_docstring'] = class_ds
875 875
876 876 # Next, try to show constructor docstrings
877 877 try:
878 878 init_ds = getdoc(obj.__init__)
879 879 # Skip Python's auto-generated docstrings
880 880 if init_ds == _object_init_docstring:
881 881 init_ds = None
882 882 except AttributeError:
883 883 init_ds = None
884 884 if init_ds:
885 885 out['init_docstring'] = init_ds
886 886
887 887 # Call form docstring for callable instances
888 888 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
889 889 call_def = self._getdef(obj.__call__, oname)
890 890 if call_def and (call_def != out.get('definition')):
891 891 # it may never be the case that call def and definition differ,
892 892 # but don't include the same signature twice
893 893 out['call_def'] = call_def
894 894 call_ds = getdoc(obj.__call__)
895 895 # Skip Python's auto-generated docstrings
896 896 if call_ds == _func_call_docstring:
897 897 call_ds = None
898 898 if call_ds:
899 899 out['call_docstring'] = call_ds
900 900
901 901 # Compute the object's argspec as a callable. The key is to decide
902 902 # whether to pull it from the object itself, from its __init__ or
903 903 # from its __call__ method.
904 904
905 905 if inspect.isclass(obj):
906 906 # Old-style classes need not have an __init__
907 907 callable_obj = getattr(obj, "__init__", None)
908 908 elif callable(obj):
909 909 callable_obj = obj
910 910 else:
911 911 callable_obj = None
912 912
913 913 if callable_obj is not None:
914 914 try:
915 915 argspec = getargspec(callable_obj)
916 916 except (TypeError, AttributeError):
917 917 # For extensions/builtins we can't retrieve the argspec
918 918 pass
919 919 else:
920 920 # named tuples' _asdict() method returns an OrderedDict, but we
921 921 # we want a normal
922 922 out['argspec'] = argspec_dict = dict(argspec._asdict())
923 923 # We called this varkw before argspec became a named tuple.
924 924 # With getfullargspec it's also called varkw.
925 925 if 'varkw' not in argspec_dict:
926 926 argspec_dict['varkw'] = argspec_dict.pop('keywords')
927 927
928 928 return object_info(**out)
929 929
930 930 def psearch(self,pattern,ns_table,ns_search=[],
931 931 ignore_case=False,show_all=False):
932 932 """Search namespaces with wildcards for objects.
933 933
934 934 Arguments:
935 935
936 936 - pattern: string containing shell-like wildcards to use in namespace
937 937 searches and optionally a type specification to narrow the search to
938 938 objects of that type.
939 939
940 940 - ns_table: dict of name->namespaces for search.
941 941
942 942 Optional arguments:
943 943
944 944 - ns_search: list of namespace names to include in search.
945 945
946 946 - ignore_case(False): make the search case-insensitive.
947 947
948 948 - show_all(False): show all names, including those starting with
949 949 underscores.
950 950 """
951 951 #print 'ps pattern:<%r>' % pattern # dbg
952 952
953 953 # defaults
954 954 type_pattern = 'all'
955 955 filter = ''
956 956
957 957 cmds = pattern.split()
958 958 len_cmds = len(cmds)
959 959 if len_cmds == 1:
960 960 # Only filter pattern given
961 961 filter = cmds[0]
962 962 elif len_cmds == 2:
963 963 # Both filter and type specified
964 964 filter,type_pattern = cmds
965 965 else:
966 966 raise ValueError('invalid argument string for psearch: <%s>' %
967 967 pattern)
968 968
969 969 # filter search namespaces
970 970 for name in ns_search:
971 971 if name not in ns_table:
972 972 raise ValueError('invalid namespace <%s>. Valid names: %s' %
973 973 (name,ns_table.keys()))
974 974
975 975 #print 'type_pattern:',type_pattern # dbg
976 976 search_result, namespaces_seen = set(), set()
977 977 for ns_name in ns_search:
978 978 ns = ns_table[ns_name]
979 979 # Normally, locals and globals are the same, so we just check one.
980 980 if id(ns) in namespaces_seen:
981 981 continue
982 982 namespaces_seen.add(id(ns))
983 983 tmp_res = list_namespace(ns, type_pattern, filter,
984 984 ignore_case=ignore_case, show_all=show_all)
985 985 search_result.update(tmp_res)
986 986
987 987 page.page('\n'.join(sorted(search_result)))
@@ -1,313 +1,313 b''
1 1 # encoding: utf-8
2 2 """
3 3 An application for managing IPython profiles.
4 4
5 5 To be invoked as the `ipython profile` subcommand.
6 6
7 7 Authors:
8 8
9 9 * Min RK
10 10
11 11 """
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Copyright (C) 2008 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-----------------------------------------------------------------------------
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Imports
22 22 #-----------------------------------------------------------------------------
23 23
24 24 import os
25 25
26 26 from traitlets.config.application import Application
27 27 from IPython.core.application import (
28 28 BaseIPythonApplication, base_flags
29 29 )
30 30 from IPython.core.profiledir import ProfileDir
31 31 from IPython.utils.importstring import import_item
32 32 from IPython.paths import get_ipython_dir, get_ipython_package_dir
33 33 from IPython.utils import py3compat
34 34 from traitlets import Unicode, Bool, Dict, observe
35 35
36 36 #-----------------------------------------------------------------------------
37 37 # Constants
38 38 #-----------------------------------------------------------------------------
39 39
40 40 create_help = """Create an IPython profile by name
41 41
42 42 Create an ipython profile directory by its name or
43 43 profile directory path. Profile directories contain
44 44 configuration, log and security related files and are named
45 45 using the convention 'profile_<name>'. By default they are
46 46 located in your ipython directory. Once created, you will
47 47 can edit the configuration files in the profile
48 48 directory to configure IPython. Most users will create a
49 49 profile directory by name,
50 50 `ipython profile create myprofile`, which will put the directory
51 51 in `<ipython_dir>/profile_myprofile`.
52 52 """
53 53 list_help = """List available IPython profiles
54 54
55 55 List all available profiles, by profile location, that can
56 56 be found in the current working directly or in the ipython
57 57 directory. Profile directories are named using the convention
58 58 'profile_<profile>'.
59 59 """
60 60 profile_help = """Manage IPython profiles
61 61
62 62 Profile directories contain
63 63 configuration, log and security related files and are named
64 64 using the convention 'profile_<name>'. By default they are
65 65 located in your ipython directory. You can create profiles
66 66 with `ipython profile create <name>`, or see the profiles you
67 67 already have with `ipython profile list`
68 68
69 69 To get started configuring IPython, simply do:
70 70
71 71 $> ipython profile create
72 72
73 73 and IPython will create the default profile in <ipython_dir>/profile_default,
74 74 where you can edit ipython_config.py to start configuring IPython.
75 75
76 76 """
77 77
78 78 _list_examples = "ipython profile list # list all profiles"
79 79
80 80 _create_examples = """
81 81 ipython profile create foo # create profile foo w/ default config files
82 82 ipython profile create foo --reset # restage default config files over current
83 83 ipython profile create foo --parallel # also stage parallel config files
84 84 """
85 85
86 86 _main_examples = """
87 87 ipython profile create -h # show the help string for the create subcommand
88 88 ipython profile list -h # show the help string for the list subcommand
89 89
90 90 ipython locate profile foo # print the path to the directory for profile 'foo'
91 91 """
92 92
93 93 #-----------------------------------------------------------------------------
94 94 # Profile Application Class (for `ipython profile` subcommand)
95 95 #-----------------------------------------------------------------------------
96 96
97 97
98 98 def list_profiles_in(path):
99 99 """list profiles in a given root directory"""
100 100 files = os.listdir(path)
101 101 profiles = []
102 102 for f in files:
103 103 try:
104 104 full_path = os.path.join(path, f)
105 105 except UnicodeError:
106 106 continue
107 107 if os.path.isdir(full_path) and f.startswith('profile_'):
108 108 profiles.append(f.split('_',1)[-1])
109 109 return profiles
110 110
111 111
112 112 def list_bundled_profiles():
113 113 """list profiles that are bundled with IPython."""
114 114 path = os.path.join(get_ipython_package_dir(), u'core', u'profile')
115 115 files = os.listdir(path)
116 116 profiles = []
117 117 for profile in files:
118 118 full_path = os.path.join(path, profile)
119 119 if os.path.isdir(full_path) and profile != "__pycache__":
120 120 profiles.append(profile)
121 121 return profiles
122 122
123 123
124 124 class ProfileLocate(BaseIPythonApplication):
125 125 description = """print the path to an IPython profile dir"""
126 126
127 127 def parse_command_line(self, argv=None):
128 128 super(ProfileLocate, self).parse_command_line(argv)
129 129 if self.extra_args:
130 130 self.profile = self.extra_args[0]
131 131
132 132 def start(self):
133 133 print(self.profile_dir.location)
134 134
135 135
136 136 class ProfileList(Application):
137 137 name = u'ipython-profile'
138 138 description = list_help
139 139 examples = _list_examples
140 140
141 141 aliases = Dict({
142 142 'ipython-dir' : 'ProfileList.ipython_dir',
143 143 'log-level' : 'Application.log_level',
144 144 })
145 145 flags = Dict(dict(
146 146 debug = ({'Application' : {'log_level' : 0}},
147 147 "Set Application.log_level to 0, maximizing log output."
148 148 )
149 149 ))
150 150
151 151 ipython_dir = Unicode(get_ipython_dir(),
152 152 help="""
153 153 The name of the IPython directory. This directory is used for logging
154 154 configuration (through profiles), history storage, etc. The default
155 155 is usually $HOME/.ipython. This options can also be specified through
156 156 the environment variable IPYTHONDIR.
157 157 """
158 158 ).tag(config=True)
159 159
160 160
161 161 def _print_profiles(self, profiles):
162 162 """print list of profiles, indented."""
163 163 for profile in profiles:
164 164 print(' %s' % profile)
165 165
166 166 def list_profile_dirs(self):
167 167 profiles = list_bundled_profiles()
168 168 if profiles:
169 169 print()
170 170 print("Available profiles in IPython:")
171 171 self._print_profiles(profiles)
172 172 print()
173 173 print(" The first request for a bundled profile will copy it")
174 174 print(" into your IPython directory (%s)," % self.ipython_dir)
175 175 print(" where you can customize it.")
176 176
177 177 profiles = list_profiles_in(self.ipython_dir)
178 178 if profiles:
179 179 print()
180 180 print("Available profiles in %s:" % self.ipython_dir)
181 181 self._print_profiles(profiles)
182 182
183 profiles = list_profiles_in(py3compat.getcwd())
183 profiles = list_profiles_in(os.getcwd())
184 184 if profiles:
185 185 print()
186 print("Available profiles in current directory (%s):" % py3compat.getcwd())
186 print("Available profiles in current directory (%s):" % os.getcwd())
187 187 self._print_profiles(profiles)
188 188
189 189 print()
190 190 print("To use any of the above profiles, start IPython with:")
191 191 print(" ipython --profile=<name>")
192 192 print()
193 193
194 194 def start(self):
195 195 self.list_profile_dirs()
196 196
197 197
198 198 create_flags = {}
199 199 create_flags.update(base_flags)
200 200 # don't include '--init' flag, which implies running profile create in other apps
201 201 create_flags.pop('init')
202 202 create_flags['reset'] = ({'ProfileCreate': {'overwrite' : True}},
203 203 "reset config files in this profile to the defaults.")
204 204 create_flags['parallel'] = ({'ProfileCreate': {'parallel' : True}},
205 205 "Include the config files for parallel "
206 206 "computing apps (ipengine, ipcontroller, etc.)")
207 207
208 208
209 209 class ProfileCreate(BaseIPythonApplication):
210 210 name = u'ipython-profile'
211 211 description = create_help
212 212 examples = _create_examples
213 213 auto_create = Bool(True)
214 214 def _log_format_default(self):
215 215 return "[%(name)s] %(message)s"
216 216
217 217 def _copy_config_files_default(self):
218 218 return True
219 219
220 220 parallel = Bool(False,
221 221 help="whether to include parallel computing config files"
222 222 ).tag(config=True)
223 223
224 224 @observe('parallel')
225 225 def _parallel_changed(self, change):
226 226 parallel_files = [ 'ipcontroller_config.py',
227 227 'ipengine_config.py',
228 228 'ipcluster_config.py'
229 229 ]
230 230 if change['new']:
231 231 for cf in parallel_files:
232 232 self.config_files.append(cf)
233 233 else:
234 234 for cf in parallel_files:
235 235 if cf in self.config_files:
236 236 self.config_files.remove(cf)
237 237
238 238 def parse_command_line(self, argv):
239 239 super(ProfileCreate, self).parse_command_line(argv)
240 240 # accept positional arg as profile name
241 241 if self.extra_args:
242 242 self.profile = self.extra_args[0]
243 243
244 244 flags = Dict(create_flags)
245 245
246 246 classes = [ProfileDir]
247 247
248 248 def _import_app(self, app_path):
249 249 """import an app class"""
250 250 app = None
251 251 name = app_path.rsplit('.', 1)[-1]
252 252 try:
253 253 app = import_item(app_path)
254 254 except ImportError:
255 255 self.log.info("Couldn't import %s, config file will be excluded", name)
256 256 except Exception:
257 257 self.log.warning('Unexpected error importing %s', name, exc_info=True)
258 258 return app
259 259
260 260 def init_config_files(self):
261 261 super(ProfileCreate, self).init_config_files()
262 262 # use local imports, since these classes may import from here
263 263 from IPython.terminal.ipapp import TerminalIPythonApp
264 264 apps = [TerminalIPythonApp]
265 265 for app_path in (
266 266 'ipykernel.kernelapp.IPKernelApp',
267 267 ):
268 268 app = self._import_app(app_path)
269 269 if app is not None:
270 270 apps.append(app)
271 271 if self.parallel:
272 272 from ipyparallel.apps.ipcontrollerapp import IPControllerApp
273 273 from ipyparallel.apps.ipengineapp import IPEngineApp
274 274 from ipyparallel.apps.ipclusterapp import IPClusterStart
275 275 apps.extend([
276 276 IPControllerApp,
277 277 IPEngineApp,
278 278 IPClusterStart,
279 279 ])
280 280 for App in apps:
281 281 app = App()
282 282 app.config.update(self.config)
283 283 app.log = self.log
284 284 app.overwrite = self.overwrite
285 285 app.copy_config_files=True
286 286 app.ipython_dir=self.ipython_dir
287 287 app.profile_dir=self.profile_dir
288 288 app.init_config_files()
289 289
290 290 def stage_default_config_file(self):
291 291 pass
292 292
293 293
294 294 class ProfileApp(Application):
295 295 name = u'ipython profile'
296 296 description = profile_help
297 297 examples = _main_examples
298 298
299 299 subcommands = Dict(dict(
300 300 create = (ProfileCreate, ProfileCreate.description.splitlines()[0]),
301 301 list = (ProfileList, ProfileList.description.splitlines()[0]),
302 302 locate = (ProfileLocate, ProfileLocate.description.splitlines()[0]),
303 303 ))
304 304
305 305 def start(self):
306 306 if self.subapp is None:
307 307 print("No subcommand specified. Must specify one of: %s"%(self.subcommands.keys()))
308 308 print()
309 309 self.print_description()
310 310 self.print_subcommands()
311 311 self.exit(1)
312 312 else:
313 313 return self.subapp.start()
@@ -1,224 +1,224 b''
1 1 # encoding: utf-8
2 2 """An object for managing IPython profile directories."""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7 import os
8 8 import shutil
9 9 import errno
10 10
11 11 from traitlets.config.configurable import LoggingConfigurable
12 12 from IPython.paths import get_ipython_package_dir
13 13 from IPython.utils.path import expand_path, ensure_dir_exists
14 14 from IPython.utils import py3compat
15 15 from traitlets import Unicode, Bool, observe
16 16
17 17 #-----------------------------------------------------------------------------
18 18 # Module errors
19 19 #-----------------------------------------------------------------------------
20 20
21 21 class ProfileDirError(Exception):
22 22 pass
23 23
24 24
25 25 #-----------------------------------------------------------------------------
26 26 # Class for managing profile directories
27 27 #-----------------------------------------------------------------------------
28 28
29 29 class ProfileDir(LoggingConfigurable):
30 30 """An object to manage the profile directory and its resources.
31 31
32 32 The profile directory is used by all IPython applications, to manage
33 33 configuration, logging and security.
34 34
35 35 This object knows how to find, create and manage these directories. This
36 36 should be used by any code that wants to handle profiles.
37 37 """
38 38
39 39 security_dir_name = Unicode('security')
40 40 log_dir_name = Unicode('log')
41 41 startup_dir_name = Unicode('startup')
42 42 pid_dir_name = Unicode('pid')
43 43 static_dir_name = Unicode('static')
44 44 security_dir = Unicode(u'')
45 45 log_dir = Unicode(u'')
46 46 startup_dir = Unicode(u'')
47 47 pid_dir = Unicode(u'')
48 48 static_dir = Unicode(u'')
49 49
50 50 location = Unicode(u'',
51 51 help="""Set the profile location directly. This overrides the logic used by the
52 52 `profile` option.""",
53 53 ).tag(config=True)
54 54
55 55 _location_isset = Bool(False) # flag for detecting multiply set location
56 56 @observe('location')
57 57 def _location_changed(self, change):
58 58 if self._location_isset:
59 59 raise RuntimeError("Cannot set profile location more than once.")
60 60 self._location_isset = True
61 61 new = change['new']
62 62 ensure_dir_exists(new)
63 63
64 64 # ensure config files exist:
65 65 self.security_dir = os.path.join(new, self.security_dir_name)
66 66 self.log_dir = os.path.join(new, self.log_dir_name)
67 67 self.startup_dir = os.path.join(new, self.startup_dir_name)
68 68 self.pid_dir = os.path.join(new, self.pid_dir_name)
69 69 self.static_dir = os.path.join(new, self.static_dir_name)
70 70 self.check_dirs()
71 71
72 72 def _mkdir(self, path, mode=None):
73 73 """ensure a directory exists at a given path
74 74
75 75 This is a version of os.mkdir, with the following differences:
76 76
77 77 - returns True if it created the directory, False otherwise
78 78 - ignores EEXIST, protecting against race conditions where
79 79 the dir may have been created in between the check and
80 80 the creation
81 81 - sets permissions if requested and the dir already exists
82 82 """
83 83 if os.path.exists(path):
84 84 if mode and os.stat(path).st_mode != mode:
85 85 try:
86 86 os.chmod(path, mode)
87 87 except OSError:
88 88 self.log.warning(
89 89 "Could not set permissions on %s",
90 90 path
91 91 )
92 92 return False
93 93 try:
94 94 if mode:
95 95 os.mkdir(path, mode)
96 96 else:
97 97 os.mkdir(path)
98 98 except OSError as e:
99 99 if e.errno == errno.EEXIST:
100 100 return False
101 101 else:
102 102 raise
103 103
104 104 return True
105 105
106 106 @observe('log_dir')
107 107 def check_log_dir(self, change=None):
108 108 self._mkdir(self.log_dir)
109 109
110 110 @observe('startup_dir')
111 111 def check_startup_dir(self, change=None):
112 112 self._mkdir(self.startup_dir)
113 113
114 114 readme = os.path.join(self.startup_dir, 'README')
115 115 src = os.path.join(get_ipython_package_dir(), u'core', u'profile', u'README_STARTUP')
116 116
117 117 if not os.path.exists(src):
118 118 self.log.warning("Could not copy README_STARTUP to startup dir. Source file %s does not exist.", src)
119 119
120 120 if os.path.exists(src) and not os.path.exists(readme):
121 121 shutil.copy(src, readme)
122 122
123 123 @observe('security_dir')
124 124 def check_security_dir(self, change=None):
125 125 self._mkdir(self.security_dir, 0o40700)
126 126
127 127 @observe('pid_dir')
128 128 def check_pid_dir(self, change=None):
129 129 self._mkdir(self.pid_dir, 0o40700)
130 130
131 131 def check_dirs(self):
132 132 self.check_security_dir()
133 133 self.check_log_dir()
134 134 self.check_pid_dir()
135 135 self.check_startup_dir()
136 136
137 137 def copy_config_file(self, config_file, path=None, overwrite=False):
138 138 """Copy a default config file into the active profile directory.
139 139
140 140 Default configuration files are kept in :mod:`IPython.core.profile`.
141 141 This function moves these from that location to the working profile
142 142 directory.
143 143 """
144 144 dst = os.path.join(self.location, config_file)
145 145 if os.path.isfile(dst) and not overwrite:
146 146 return False
147 147 if path is None:
148 148 path = os.path.join(get_ipython_package_dir(), u'core', u'profile', u'default')
149 149 src = os.path.join(path, config_file)
150 150 shutil.copy(src, dst)
151 151 return True
152 152
153 153 @classmethod
154 154 def create_profile_dir(cls, profile_dir, config=None):
155 155 """Create a new profile directory given a full path.
156 156
157 157 Parameters
158 158 ----------
159 159 profile_dir : str
160 160 The full path to the profile directory. If it does exist, it will
161 161 be used. If not, it will be created.
162 162 """
163 163 return cls(location=profile_dir, config=config)
164 164
165 165 @classmethod
166 166 def create_profile_dir_by_name(cls, path, name=u'default', config=None):
167 167 """Create a profile dir by profile name and path.
168 168
169 169 Parameters
170 170 ----------
171 171 path : unicode
172 172 The path (directory) to put the profile directory in.
173 173 name : unicode
174 174 The name of the profile. The name of the profile directory will
175 175 be "profile_<profile>".
176 176 """
177 177 if not os.path.isdir(path):
178 178 raise ProfileDirError('Directory not found: %s' % path)
179 179 profile_dir = os.path.join(path, u'profile_' + name)
180 180 return cls(location=profile_dir, config=config)
181 181
182 182 @classmethod
183 183 def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
184 184 """Find an existing profile dir by profile name, return its ProfileDir.
185 185
186 186 This searches through a sequence of paths for a profile dir. If it
187 187 is not found, a :class:`ProfileDirError` exception will be raised.
188 188
189 189 The search path algorithm is:
190 1. ``py3compat.getcwd()``
190 1. ``os.getcwd()``
191 191 2. ``ipython_dir``
192 192
193 193 Parameters
194 194 ----------
195 195 ipython_dir : unicode or str
196 196 The IPython directory to use.
197 197 name : unicode or str
198 198 The name of the profile. The name of the profile directory
199 199 will be "profile_<profile>".
200 200 """
201 201 dirname = u'profile_' + name
202 paths = [py3compat.getcwd(), ipython_dir]
202 paths = [os.getcwd(), ipython_dir]
203 203 for p in paths:
204 204 profile_dir = os.path.join(p, dirname)
205 205 if os.path.isdir(profile_dir):
206 206 return cls(location=profile_dir, config=config)
207 207 else:
208 208 raise ProfileDirError('Profile directory not found in paths: %s' % dirname)
209 209
210 210 @classmethod
211 211 def find_profile_dir(cls, profile_dir, config=None):
212 212 """Find/create a profile dir and return its ProfileDir.
213 213
214 214 This will create the profile directory if it doesn't exist.
215 215
216 216 Parameters
217 217 ----------
218 218 profile_dir : unicode or str
219 219 The path of the profile directory.
220 220 """
221 221 profile_dir = expand_path(profile_dir)
222 222 if not os.path.isdir(profile_dir):
223 223 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
224 224 return cls(location=profile_dir, config=config)
@@ -1,26 +1,23 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Being removed
3 3 """
4 4
5 5 from IPython.utils import py3compat
6 6
7 7 class LazyEvaluate(object):
8 8 """This is used for formatting strings with values that need to be updated
9 9 at that time, such as the current time or working directory."""
10 10 def __init__(self, func, *args, **kwargs):
11 11 self.func = func
12 12 self.args = args
13 13 self.kwargs = kwargs
14 14
15 15 def __call__(self, **kwargs):
16 16 self.kwargs.update(kwargs)
17 17 return self.func(*self.args, **self.kwargs)
18 18
19 19 def __str__(self):
20 20 return str(self())
21
22 def __unicode__(self):
23 return py3compat.unicode_type(self())
24
21
25 22 def __format__(self, format_spec):
26 23 return format(self(), format_spec)
@@ -1,410 +1,410 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Pylab (matplotlib) support utilities."""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7 from io import BytesIO
8 8
9 9 from IPython.core.display import _pngxy
10 10 from IPython.utils.decorators import flag_calls
11 11 from IPython.utils import py3compat
12 12
13 13 # If user specifies a GUI, that dictates the backend, otherwise we read the
14 14 # user's mpl default from the mpl rc structure
15 15 backends = {'tk': 'TkAgg',
16 16 'gtk': 'GTKAgg',
17 17 'gtk3': 'GTK3Agg',
18 18 'wx': 'WXAgg',
19 19 'qt': 'Qt4Agg', # qt3 not supported
20 20 'qt4': 'Qt4Agg',
21 21 'qt5': 'Qt5Agg',
22 22 'osx': 'MacOSX',
23 23 'nbagg': 'nbAgg',
24 24 'notebook': 'nbAgg',
25 25 'agg': 'agg',
26 26 'inline': 'module://ipykernel.pylab.backend_inline',
27 27 'ipympl': 'module://ipympl.backend_nbagg',
28 28 }
29 29
30 30 # We also need a reverse backends2guis mapping that will properly choose which
31 31 # GUI support to activate based on the desired matplotlib backend. For the
32 32 # most part it's just a reverse of the above dict, but we also need to add a
33 33 # few others that map to the same GUI manually:
34 34 backend2gui = dict(zip(backends.values(), backends.keys()))
35 35 # Our tests expect backend2gui to just return 'qt'
36 36 backend2gui['Qt4Agg'] = 'qt'
37 37 # In the reverse mapping, there are a few extra valid matplotlib backends that
38 38 # map to the same GUI support
39 39 backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk'
40 40 backend2gui['GTK3Cairo'] = 'gtk3'
41 41 backend2gui['WX'] = 'wx'
42 42 backend2gui['CocoaAgg'] = 'osx'
43 43 # And some backends that don't need GUI integration
44 44 del backend2gui['nbAgg']
45 45 del backend2gui['agg']
46 46 del backend2gui['module://ipykernel.pylab.backend_inline']
47 47
48 48 #-----------------------------------------------------------------------------
49 49 # Matplotlib utilities
50 50 #-----------------------------------------------------------------------------
51 51
52 52
53 53 def getfigs(*fig_nums):
54 54 """Get a list of matplotlib figures by figure numbers.
55 55
56 56 If no arguments are given, all available figures are returned. If the
57 57 argument list contains references to invalid figures, a warning is printed
58 58 but the function continues pasting further figures.
59 59
60 60 Parameters
61 61 ----------
62 62 figs : tuple
63 63 A tuple of ints giving the figure numbers of the figures to return.
64 64 """
65 65 from matplotlib._pylab_helpers import Gcf
66 66 if not fig_nums:
67 67 fig_managers = Gcf.get_all_fig_managers()
68 68 return [fm.canvas.figure for fm in fig_managers]
69 69 else:
70 70 figs = []
71 71 for num in fig_nums:
72 72 f = Gcf.figs.get(num)
73 73 if f is None:
74 74 print('Warning: figure %s not available.' % num)
75 75 else:
76 76 figs.append(f.canvas.figure)
77 77 return figs
78 78
79 79
80 80 def figsize(sizex, sizey):
81 81 """Set the default figure size to be [sizex, sizey].
82 82
83 83 This is just an easy to remember, convenience wrapper that sets::
84 84
85 85 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
86 86 """
87 87 import matplotlib
88 88 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
89 89
90 90
91 91 def print_figure(fig, fmt='png', bbox_inches='tight', **kwargs):
92 92 """Print a figure to an image, and return the resulting file data
93 93
94 94 Returned data will be bytes unless ``fmt='svg'``,
95 95 in which case it will be unicode.
96 96
97 97 Any keyword args are passed to fig.canvas.print_figure,
98 98 such as ``quality`` or ``bbox_inches``.
99 99 """
100 100 from matplotlib import rcParams
101 101 # When there's an empty figure, we shouldn't return anything, otherwise we
102 102 # get big blank areas in the qt console.
103 103 if not fig.axes and not fig.lines:
104 104 return
105 105
106 106 dpi = fig.dpi
107 107 if fmt == 'retina':
108 108 dpi = dpi * 2
109 109 fmt = 'png'
110 110
111 111 # build keyword args
112 112 kw = dict(
113 113 format=fmt,
114 114 facecolor=fig.get_facecolor(),
115 115 edgecolor=fig.get_edgecolor(),
116 116 dpi=dpi,
117 117 bbox_inches=bbox_inches,
118 118 )
119 119 # **kwargs get higher priority
120 120 kw.update(kwargs)
121 121
122 122 bytes_io = BytesIO()
123 123 fig.canvas.print_figure(bytes_io, **kw)
124 124 data = bytes_io.getvalue()
125 125 if fmt == 'svg':
126 126 data = data.decode('utf-8')
127 127 return data
128 128
129 129 def retina_figure(fig, **kwargs):
130 130 """format a figure as a pixel-doubled (retina) PNG"""
131 131 pngdata = print_figure(fig, fmt='retina', **kwargs)
132 132 # Make sure that retina_figure acts just like print_figure and returns
133 133 # None when the figure is empty.
134 134 if pngdata is None:
135 135 return
136 136 w, h = _pngxy(pngdata)
137 137 metadata = dict(width=w//2, height=h//2)
138 138 return pngdata, metadata
139 139
140 140 # We need a little factory function here to create the closure where
141 141 # safe_execfile can live.
142 142 def mpl_runner(safe_execfile):
143 143 """Factory to return a matplotlib-enabled runner for %run.
144 144
145 145 Parameters
146 146 ----------
147 147 safe_execfile : function
148 148 This must be a function with the same interface as the
149 149 :meth:`safe_execfile` method of IPython.
150 150
151 151 Returns
152 152 -------
153 153 A function suitable for use as the ``runner`` argument of the %run magic
154 154 function.
155 155 """
156 156
157 157 def mpl_execfile(fname,*where,**kw):
158 158 """matplotlib-aware wrapper around safe_execfile.
159 159
160 160 Its interface is identical to that of the :func:`execfile` builtin.
161 161
162 162 This is ultimately a call to execfile(), but wrapped in safeties to
163 163 properly handle interactive rendering."""
164 164
165 165 import matplotlib
166 166 import matplotlib.pyplot as plt
167 167
168 168 #print '*** Matplotlib runner ***' # dbg
169 169 # turn off rendering until end of script
170 170 is_interactive = matplotlib.rcParams['interactive']
171 171 matplotlib.interactive(False)
172 172 safe_execfile(fname,*where,**kw)
173 173 matplotlib.interactive(is_interactive)
174 174 # make rendering call now, if the user tried to do it
175 175 if plt.draw_if_interactive.called:
176 176 plt.draw()
177 177 plt.draw_if_interactive.called = False
178 178
179 179 # re-draw everything that is stale
180 180 try:
181 181 da = plt.draw_all
182 182 except AttributeError:
183 183 pass
184 184 else:
185 185 da()
186 186
187 187 return mpl_execfile
188 188
189 189
190 190 def _reshow_nbagg_figure(fig):
191 191 """reshow an nbagg figure"""
192 192 try:
193 193 reshow = fig.canvas.manager.reshow
194 194 except AttributeError:
195 195 raise NotImplementedError()
196 196 else:
197 197 reshow()
198 198
199 199
200 200 def select_figure_formats(shell, formats, **kwargs):
201 201 """Select figure formats for the inline backend.
202 202
203 203 Parameters
204 204 ==========
205 205 shell : InteractiveShell
206 206 The main IPython instance.
207 207 formats : str or set
208 208 One or a set of figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
209 209 **kwargs : any
210 210 Extra keyword arguments to be passed to fig.canvas.print_figure.
211 211 """
212 212 import matplotlib
213 213 from matplotlib.figure import Figure
214 214
215 215 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
216 216 png_formatter = shell.display_formatter.formatters['image/png']
217 217 jpg_formatter = shell.display_formatter.formatters['image/jpeg']
218 218 pdf_formatter = shell.display_formatter.formatters['application/pdf']
219 219
220 if isinstance(formats, py3compat.string_types):
220 if isinstance(formats, str):
221 221 formats = {formats}
222 222 # cast in case of list / tuple
223 223 formats = set(formats)
224 224
225 225 [ f.pop(Figure, None) for f in shell.display_formatter.formatters.values() ]
226 226 mplbackend = matplotlib.get_backend().lower()
227 227 if mplbackend == 'nbagg' or mplbackend == 'module://ipympl.backend_nbagg':
228 228 formatter = shell.display_formatter.ipython_display_formatter
229 229 formatter.for_type(Figure, _reshow_nbagg_figure)
230 230
231 231 supported = {'png', 'png2x', 'retina', 'jpg', 'jpeg', 'svg', 'pdf'}
232 232 bad = formats.difference(supported)
233 233 if bad:
234 234 bs = "%s" % ','.join([repr(f) for f in bad])
235 235 gs = "%s" % ','.join([repr(f) for f in supported])
236 236 raise ValueError("supported formats are: %s not %s" % (gs, bs))
237 237
238 238 if 'png' in formats:
239 239 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
240 240 if 'retina' in formats or 'png2x' in formats:
241 241 png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs))
242 242 if 'jpg' in formats or 'jpeg' in formats:
243 243 jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', **kwargs))
244 244 if 'svg' in formats:
245 245 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg', **kwargs))
246 246 if 'pdf' in formats:
247 247 pdf_formatter.for_type(Figure, lambda fig: print_figure(fig, 'pdf', **kwargs))
248 248
249 249 #-----------------------------------------------------------------------------
250 250 # Code for initializing matplotlib and importing pylab
251 251 #-----------------------------------------------------------------------------
252 252
253 253
254 254 def find_gui_and_backend(gui=None, gui_select=None):
255 255 """Given a gui string return the gui and mpl backend.
256 256
257 257 Parameters
258 258 ----------
259 259 gui : str
260 260 Can be one of ('tk','gtk','wx','qt','qt4','inline','agg').
261 261 gui_select : str
262 262 Can be one of ('tk','gtk','wx','qt','qt4','inline').
263 263 This is any gui already selected by the shell.
264 264
265 265 Returns
266 266 -------
267 267 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
268 268 'WXAgg','Qt4Agg','module://ipykernel.pylab.backend_inline','agg').
269 269 """
270 270
271 271 import matplotlib
272 272
273 273 if gui and gui != 'auto':
274 274 # select backend based on requested gui
275 275 backend = backends[gui]
276 276 if gui == 'agg':
277 277 gui = None
278 278 else:
279 279 # We need to read the backend from the original data structure, *not*
280 280 # from mpl.rcParams, since a prior invocation of %matplotlib may have
281 281 # overwritten that.
282 282 # WARNING: this assumes matplotlib 1.1 or newer!!
283 283 backend = matplotlib.rcParamsOrig['backend']
284 284 # In this case, we need to find what the appropriate gui selection call
285 285 # should be for IPython, so we can activate inputhook accordingly
286 286 gui = backend2gui.get(backend, None)
287 287
288 288 # If we have already had a gui active, we need it and inline are the
289 289 # ones allowed.
290 290 if gui_select and gui != gui_select:
291 291 gui = gui_select
292 292 backend = backends[gui]
293 293
294 294 return gui, backend
295 295
296 296
297 297 def activate_matplotlib(backend):
298 298 """Activate the given backend and set interactive to True."""
299 299
300 300 import matplotlib
301 301 matplotlib.interactive(True)
302 302
303 303 # Matplotlib had a bug where even switch_backend could not force
304 304 # the rcParam to update. This needs to be set *before* the module
305 305 # magic of switch_backend().
306 306 matplotlib.rcParams['backend'] = backend
307 307
308 308 import matplotlib.pyplot
309 309 matplotlib.pyplot.switch_backend(backend)
310 310
311 311 # This must be imported last in the matplotlib series, after
312 312 # backend/interactivity choices have been made
313 313 import matplotlib.pyplot as plt
314 314
315 315 plt.show._needmain = False
316 316 # We need to detect at runtime whether show() is called by the user.
317 317 # For this, we wrap it into a decorator which adds a 'called' flag.
318 318 plt.draw_if_interactive = flag_calls(plt.draw_if_interactive)
319 319
320 320
321 321 def import_pylab(user_ns, import_all=True):
322 322 """Populate the namespace with pylab-related values.
323 323
324 324 Imports matplotlib, pylab, numpy, and everything from pylab and numpy.
325 325
326 326 Also imports a few names from IPython (figsize, display, getfigs)
327 327
328 328 """
329 329
330 330 # Import numpy as np/pyplot as plt are conventions we're trying to
331 331 # somewhat standardize on. Making them available to users by default
332 332 # will greatly help this.
333 333 s = ("import numpy\n"
334 334 "import matplotlib\n"
335 335 "from matplotlib import pylab, mlab, pyplot\n"
336 336 "np = numpy\n"
337 337 "plt = pyplot\n"
338 338 )
339 339 exec(s, user_ns)
340 340
341 341 if import_all:
342 342 s = ("from matplotlib.pylab import *\n"
343 343 "from numpy import *\n")
344 344 exec(s, user_ns)
345 345
346 346 # IPython symbols to add
347 347 user_ns['figsize'] = figsize
348 348 from IPython.core.display import display
349 349 # Add display and getfigs to the user's namespace
350 350 user_ns['display'] = display
351 351 user_ns['getfigs'] = getfigs
352 352
353 353
354 354 def configure_inline_support(shell, backend):
355 355 """Configure an IPython shell object for matplotlib use.
356 356
357 357 Parameters
358 358 ----------
359 359 shell : InteractiveShell instance
360 360
361 361 backend : matplotlib backend
362 362 """
363 363 # If using our svg payload backend, register the post-execution
364 364 # function that will pick up the results for display. This can only be
365 365 # done with access to the real shell object.
366 366
367 367 # Note: if we can't load the inline backend, then there's no point
368 368 # continuing (such as in terminal-only shells in environments without
369 369 # zeromq available).
370 370 try:
371 371 from ipykernel.pylab.backend_inline import InlineBackend
372 372 except ImportError:
373 373 return
374 374 import matplotlib
375 375
376 376 cfg = InlineBackend.instance(parent=shell)
377 377 cfg.shell = shell
378 378 if cfg not in shell.configurables:
379 379 shell.configurables.append(cfg)
380 380
381 381 if backend == backends['inline']:
382 382 from ipykernel.pylab.backend_inline import flush_figures
383 383 shell.events.register('post_execute', flush_figures)
384 384
385 385 # Save rcParams that will be overwrittern
386 386 shell._saved_rcParams = dict()
387 387 for k in cfg.rc:
388 388 shell._saved_rcParams[k] = matplotlib.rcParams[k]
389 389 # load inline_rc
390 390 matplotlib.rcParams.update(cfg.rc)
391 391 new_backend_name = "inline"
392 392 else:
393 393 from ipykernel.pylab.backend_inline import flush_figures
394 394 try:
395 395 shell.events.unregister('post_execute', flush_figures)
396 396 except ValueError:
397 397 pass
398 398 if hasattr(shell, '_saved_rcParams'):
399 399 matplotlib.rcParams.update(shell._saved_rcParams)
400 400 del shell._saved_rcParams
401 401 new_backend_name = "other"
402 402
403 403 # only enable the formats once -> don't change the enabled formats (which the user may
404 404 # has changed) when getting another "%matplotlib inline" call.
405 405 # See https://github.com/ipython/ipykernel/issues/29
406 406 cur_backend = getattr(configure_inline_support, "current_backend", "unset")
407 407 if new_backend_name != cur_backend:
408 408 # Setup the default figure format
409 409 select_figure_formats(shell, cfg.figure_formats, **cfg.print_figure_kwargs)
410 410 configure_inline_support.current_backend = new_backend_name
@@ -1,74 +1,74 b''
1 1 # coding: utf-8
2 2 """Tests for IPython.core.application"""
3 3
4 4 import os
5 5 import tempfile
6 6
7 7 import nose.tools as nt
8 8
9 9 from traitlets import Unicode
10 10
11 11 from IPython.core.application import BaseIPythonApplication
12 12 from IPython.testing import decorators as dec
13 13 from IPython.utils import py3compat
14 14 from IPython.utils.tempdir import TemporaryDirectory
15 15
16 16
17 17 @dec.onlyif_unicode_paths
18 18 def test_unicode_cwd():
19 19 """Check that IPython starts with non-ascii characters in the path."""
20 20 wd = tempfile.mkdtemp(suffix=u"€")
21 21
22 old_wd = py3compat.getcwd()
22 old_wd = os.getcwd()
23 23 os.chdir(wd)
24 #raise Exception(repr(py3compat.getcwd()))
24 #raise Exception(repr(os.getcwd()))
25 25 try:
26 26 app = BaseIPythonApplication()
27 27 # The lines below are copied from Application.initialize()
28 28 app.init_profile_dir()
29 29 app.init_config_files()
30 30 app.load_config_file(suppress_errors=False)
31 31 finally:
32 32 os.chdir(old_wd)
33 33
34 34 @dec.onlyif_unicode_paths
35 35 def test_unicode_ipdir():
36 36 """Check that IPython starts with non-ascii characters in the IP dir."""
37 37 ipdir = tempfile.mkdtemp(suffix=u"€")
38 38
39 39 # Create the config file, so it tries to load it.
40 40 with open(os.path.join(ipdir, 'ipython_config.py'), "w") as f:
41 41 pass
42 42
43 43 old_ipdir1 = os.environ.pop("IPYTHONDIR", None)
44 44 old_ipdir2 = os.environ.pop("IPYTHON_DIR", None)
45 os.environ["IPYTHONDIR"] = py3compat.unicode_to_str(ipdir, "utf-8")
45 os.environ["IPYTHONDIR"] = ipdir
46 46 try:
47 47 app = BaseIPythonApplication()
48 48 # The lines below are copied from Application.initialize()
49 49 app.init_profile_dir()
50 50 app.init_config_files()
51 51 app.load_config_file(suppress_errors=False)
52 52 finally:
53 53 if old_ipdir1:
54 54 os.environ["IPYTHONDIR"] = old_ipdir1
55 55 if old_ipdir2:
56 56 os.environ["IPYTHONDIR"] = old_ipdir2
57 57
58 58 def test_cli_priority():
59 59 with TemporaryDirectory() as td:
60 60
61 61 class TestApp(BaseIPythonApplication):
62 62 test = Unicode().tag(config=True)
63 63
64 64 # Create the config file, so it tries to load it.
65 65 with open(os.path.join(td, 'ipython_config.py'), "w") as f:
66 66 f.write("c.TestApp.test = 'config file'")
67 67
68 68 app = TestApp()
69 69 app.initialize(['--profile-dir', td])
70 70 nt.assert_equal(app.test, 'config file')
71 71 app = TestApp()
72 72 app.initialize(['--profile-dir', td, '--TestApp.test=cli'])
73 73 nt.assert_equal(app.test, 'cli')
74 74
@@ -1,739 +1,738 b''
1 1 # encoding: utf-8
2 2 """Tests for the IPython tab-completion machinery."""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7 import os
8 8 import sys
9 9 import unittest
10 10
11 11 from contextlib import contextmanager
12 12
13 13 import nose.tools as nt
14 14
15 15 from traitlets.config.loader import Config
16 16 from IPython import get_ipython
17 17 from IPython.core import completer
18 18 from IPython.external.decorators import knownfailureif
19 19 from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
20 20 from IPython.utils.generics import complete_object
21 from IPython.utils.py3compat import string_types, unicode_type
22 21 from IPython.testing import decorators as dec
23 22
24 23 #-----------------------------------------------------------------------------
25 24 # Test functions
26 25 #-----------------------------------------------------------------------------
27 26
28 27 @contextmanager
29 28 def greedy_completion():
30 29 ip = get_ipython()
31 30 greedy_original = ip.Completer.greedy
32 31 try:
33 32 ip.Completer.greedy = True
34 33 yield
35 34 finally:
36 35 ip.Completer.greedy = greedy_original
37 36
38 37 def test_protect_filename():
39 38 if sys.platform == 'win32':
40 39 pairs = [('abc','abc'),
41 40 (' abc','" abc"'),
42 41 ('a bc','"a bc"'),
43 42 ('a bc','"a bc"'),
44 43 (' bc','" bc"'),
45 44 ]
46 45 else:
47 46 pairs = [('abc','abc'),
48 47 (' abc',r'\ abc'),
49 48 ('a bc',r'a\ bc'),
50 49 ('a bc',r'a\ \ bc'),
51 50 (' bc',r'\ \ bc'),
52 51 # On posix, we also protect parens and other special characters.
53 52 ('a(bc',r'a\(bc'),
54 53 ('a)bc',r'a\)bc'),
55 54 ('a( )bc',r'a\(\ \)bc'),
56 55 ('a[1]bc', r'a\[1\]bc'),
57 56 ('a{1}bc', r'a\{1\}bc'),
58 57 ('a#bc', r'a\#bc'),
59 58 ('a?bc', r'a\?bc'),
60 59 ('a=bc', r'a\=bc'),
61 60 ('a\\bc', r'a\\bc'),
62 61 ('a|bc', r'a\|bc'),
63 62 ('a;bc', r'a\;bc'),
64 63 ('a:bc', r'a\:bc'),
65 64 ("a'bc", r"a\'bc"),
66 65 ('a*bc', r'a\*bc'),
67 66 ('a"bc', r'a\"bc'),
68 67 ('a^bc', r'a\^bc'),
69 68 ('a&bc', r'a\&bc'),
70 69 ]
71 70 # run the actual tests
72 71 for s1, s2 in pairs:
73 72 s1p = completer.protect_filename(s1)
74 73 nt.assert_equal(s1p, s2)
75 74
76 75
77 76 def check_line_split(splitter, test_specs):
78 77 for part1, part2, split in test_specs:
79 78 cursor_pos = len(part1)
80 79 line = part1+part2
81 80 out = splitter.split_line(line, cursor_pos)
82 81 nt.assert_equal(out, split)
83 82
84 83
85 84 def test_line_split():
86 85 """Basic line splitter test with default specs."""
87 86 sp = completer.CompletionSplitter()
88 87 # The format of the test specs is: part1, part2, expected answer. Parts 1
89 88 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
90 89 # was at the end of part1. So an empty part2 represents someone hitting
91 90 # tab at the end of the line, the most common case.
92 91 t = [('run some/scrip', '', 'some/scrip'),
93 92 ('run scripts/er', 'ror.py foo', 'scripts/er'),
94 93 ('echo $HOM', '', 'HOM'),
95 94 ('print sys.pa', '', 'sys.pa'),
96 95 ('print(sys.pa', '', 'sys.pa'),
97 96 ("execfile('scripts/er", '', 'scripts/er'),
98 97 ('a[x.', '', 'x.'),
99 98 ('a[x.', 'y', 'x.'),
100 99 ('cd "some_file/', '', 'some_file/'),
101 100 ]
102 101 check_line_split(sp, t)
103 102 # Ensure splitting works OK with unicode by re-running the tests with
104 103 # all inputs turned into unicode
105 check_line_split(sp, [ map(unicode_type, p) for p in t] )
104 check_line_split(sp, [ map(str, p) for p in t] )
106 105
107 106
108 107 def test_custom_completion_error():
109 108 """Test that errors from custom attribute completers are silenced."""
110 109 ip = get_ipython()
111 110 class A(object): pass
112 111 ip.user_ns['a'] = A()
113 112
114 113 @complete_object.when_type(A)
115 114 def complete_A(a, existing_completions):
116 115 raise TypeError("this should be silenced")
117 116
118 117 ip.complete("a.")
119 118
120 119
121 120 def test_unicode_completions():
122 121 ip = get_ipython()
123 122 # Some strings that trigger different types of completion. Check them both
124 123 # in str and unicode forms
125 124 s = ['ru', '%ru', 'cd /', 'floa', 'float(x)/']
126 for t in s + list(map(unicode_type, s)):
125 for t in s + list(map(str, s)):
127 126 # We don't need to check exact completion values (they may change
128 127 # depending on the state of the namespace, but at least no exceptions
129 128 # should be thrown and the return value should be a pair of text, list
130 129 # values.
131 130 text, matches = ip.complete(t)
132 nt.assert_true(isinstance(text, string_types))
131 nt.assert_true(isinstance(text, str))
133 132 nt.assert_true(isinstance(matches, list))
134 133
135 134 def test_latex_completions():
136 135 from IPython.core.latex_symbols import latex_symbols
137 136 import random
138 137 ip = get_ipython()
139 138 # Test some random unicode symbols
140 139 keys = random.sample(latex_symbols.keys(), 10)
141 140 for k in keys:
142 141 text, matches = ip.complete(k)
143 142 nt.assert_equal(len(matches),1)
144 143 nt.assert_equal(text, k)
145 144 nt.assert_equal(matches[0], latex_symbols[k])
146 145 # Test a more complex line
147 146 text, matches = ip.complete(u'print(\\alpha')
148 147 nt.assert_equal(text, u'\\alpha')
149 148 nt.assert_equal(matches[0], latex_symbols['\\alpha'])
150 149 # Test multiple matching latex symbols
151 150 text, matches = ip.complete(u'\\al')
152 151 nt.assert_in('\\alpha', matches)
153 152 nt.assert_in('\\aleph', matches)
154 153
155 154
156 155
157 156
158 157 def test_back_latex_completion():
159 158 ip = get_ipython()
160 159
161 160 # do not return more than 1 matches fro \beta, only the latex one.
162 161 name, matches = ip.complete('\\β')
163 162 nt.assert_equal(len(matches), 1)
164 163 nt.assert_equal(matches[0], '\\beta')
165 164
166 165 def test_back_unicode_completion():
167 166 ip = get_ipython()
168 167
169 168 name, matches = ip.complete('\\â…¤')
170 169 nt.assert_equal(len(matches), 1)
171 170 nt.assert_equal(matches[0], '\\ROMAN NUMERAL FIVE')
172 171
173 172
174 173 def test_forward_unicode_completion():
175 174 ip = get_ipython()
176 175
177 176 name, matches = ip.complete('\\ROMAN NUMERAL FIVE')
178 177 nt.assert_equal(len(matches), 1)
179 178 nt.assert_equal(matches[0], 'â…¤')
180 179
181 180 @dec.knownfailureif(sys.platform == 'win32', 'Fails if there is a C:\\j... path')
182 181 def test_no_ascii_back_completion():
183 182 ip = get_ipython()
184 183 with TemporaryWorkingDirectory(): # Avoid any filename completions
185 184 # single ascii letter that don't have yet completions
186 185 for letter in 'jJ' :
187 186 name, matches = ip.complete('\\'+letter)
188 187 nt.assert_equal(matches, [])
189 188
190 189
191 190
192 191
193 192 class CompletionSplitterTestCase(unittest.TestCase):
194 193 def setUp(self):
195 194 self.sp = completer.CompletionSplitter()
196 195
197 196 def test_delim_setting(self):
198 197 self.sp.delims = ' '
199 198 nt.assert_equal(self.sp.delims, ' ')
200 199 nt.assert_equal(self.sp._delim_expr, '[\ ]')
201 200
202 201 def test_spaces(self):
203 202 """Test with only spaces as split chars."""
204 203 self.sp.delims = ' '
205 204 t = [('foo', '', 'foo'),
206 205 ('run foo', '', 'foo'),
207 206 ('run foo', 'bar', 'foo'),
208 207 ]
209 208 check_line_split(self.sp, t)
210 209
211 210
212 211 def test_has_open_quotes1():
213 212 for s in ["'", "'''", "'hi' '"]:
214 213 nt.assert_equal(completer.has_open_quotes(s), "'")
215 214
216 215
217 216 def test_has_open_quotes2():
218 217 for s in ['"', '"""', '"hi" "']:
219 218 nt.assert_equal(completer.has_open_quotes(s), '"')
220 219
221 220
222 221 def test_has_open_quotes3():
223 222 for s in ["''", "''' '''", "'hi' 'ipython'"]:
224 223 nt.assert_false(completer.has_open_quotes(s))
225 224
226 225
227 226 def test_has_open_quotes4():
228 227 for s in ['""', '""" """', '"hi" "ipython"']:
229 228 nt.assert_false(completer.has_open_quotes(s))
230 229
231 230
232 231 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
233 232 def test_abspath_file_completions():
234 233 ip = get_ipython()
235 234 with TemporaryDirectory() as tmpdir:
236 235 prefix = os.path.join(tmpdir, 'foo')
237 236 suffixes = ['1', '2']
238 237 names = [prefix+s for s in suffixes]
239 238 for n in names:
240 239 open(n, 'w').close()
241 240
242 241 # Check simple completion
243 242 c = ip.complete(prefix)[1]
244 243 nt.assert_equal(c, names)
245 244
246 245 # Now check with a function call
247 246 cmd = 'a = f("%s' % prefix
248 247 c = ip.complete(prefix, cmd)[1]
249 248 comp = [prefix+s for s in suffixes]
250 249 nt.assert_equal(c, comp)
251 250
252 251
253 252 def test_local_file_completions():
254 253 ip = get_ipython()
255 254 with TemporaryWorkingDirectory():
256 255 prefix = './foo'
257 256 suffixes = ['1', '2']
258 257 names = [prefix+s for s in suffixes]
259 258 for n in names:
260 259 open(n, 'w').close()
261 260
262 261 # Check simple completion
263 262 c = ip.complete(prefix)[1]
264 263 nt.assert_equal(c, names)
265 264
266 265 # Now check with a function call
267 266 cmd = 'a = f("%s' % prefix
268 267 c = ip.complete(prefix, cmd)[1]
269 268 comp = set(prefix+s for s in suffixes)
270 269 nt.assert_true(comp.issubset(set(c)))
271 270
272 271
273 272 def test_greedy_completions():
274 273 ip = get_ipython()
275 274 ip.ex('a=list(range(5))')
276 275 _,c = ip.complete('.',line='a[0].')
277 276 nt.assert_false('.real' in c,
278 277 "Shouldn't have completed on a[0]: %s"%c)
279 278 with greedy_completion():
280 279 def _(line, cursor_pos, expect, message):
281 280 _,c = ip.complete('.', line=line, cursor_pos=cursor_pos)
282 281 nt.assert_in(expect, c, message%c)
283 282
284 283 yield _, 'a[0].', 5, 'a[0].real', "Should have completed on a[0].: %s"
285 284 yield _, 'a[0].r', 6, 'a[0].real', "Should have completed on a[0].r: %s"
286 285
287 286 if sys.version_info > (3,4):
288 287 yield _, 'a[0].from_', 10, 'a[0].from_bytes', "Should have completed on a[0].from_: %s"
289 288
290 289
291 290
292 291 def test_omit__names():
293 292 # also happens to test IPCompleter as a configurable
294 293 ip = get_ipython()
295 294 ip._hidden_attr = 1
296 295 ip._x = {}
297 296 c = ip.Completer
298 297 ip.ex('ip=get_ipython()')
299 298 cfg = Config()
300 299 cfg.IPCompleter.omit__names = 0
301 300 c.update_config(cfg)
302 301 s,matches = c.complete('ip.')
303 302 nt.assert_in('ip.__str__', matches)
304 303 nt.assert_in('ip._hidden_attr', matches)
305 304 cfg = Config()
306 305 cfg.IPCompleter.omit__names = 1
307 306 c.update_config(cfg)
308 307 s,matches = c.complete('ip.')
309 308 nt.assert_not_in('ip.__str__', matches)
310 309 nt.assert_in('ip._hidden_attr', matches)
311 310 cfg = Config()
312 311 cfg.IPCompleter.omit__names = 2
313 312 c.update_config(cfg)
314 313 s,matches = c.complete('ip.')
315 314 nt.assert_not_in('ip.__str__', matches)
316 315 nt.assert_not_in('ip._hidden_attr', matches)
317 316 s,matches = c.complete('ip._x.')
318 317 nt.assert_in('ip._x.keys', matches)
319 318 del ip._hidden_attr
320 319
321 320
322 321 def test_limit_to__all__False_ok():
323 322 ip = get_ipython()
324 323 c = ip.Completer
325 324 ip.ex('class D: x=24')
326 325 ip.ex('d=D()')
327 326 cfg = Config()
328 327 cfg.IPCompleter.limit_to__all__ = False
329 328 c.update_config(cfg)
330 329 s, matches = c.complete('d.')
331 330 nt.assert_in('d.x', matches)
332 331
333 332
334 333 def test_get__all__entries_ok():
335 334 class A(object):
336 335 __all__ = ['x', 1]
337 336 words = completer.get__all__entries(A())
338 337 nt.assert_equal(words, ['x'])
339 338
340 339
341 340 def test_get__all__entries_no__all__ok():
342 341 class A(object):
343 342 pass
344 343 words = completer.get__all__entries(A())
345 344 nt.assert_equal(words, [])
346 345
347 346
348 347 def test_func_kw_completions():
349 348 ip = get_ipython()
350 349 c = ip.Completer
351 350 ip.ex('def myfunc(a=1,b=2): return a+b')
352 351 s, matches = c.complete(None, 'myfunc(1,b')
353 352 nt.assert_in('b=', matches)
354 353 # Simulate completing with cursor right after b (pos==10):
355 354 s, matches = c.complete(None, 'myfunc(1,b)', 10)
356 355 nt.assert_in('b=', matches)
357 356 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
358 357 nt.assert_in('b=', matches)
359 358 #builtin function
360 359 s, matches = c.complete(None, 'min(k, k')
361 360 nt.assert_in('key=', matches)
362 361
363 362
364 363 def test_default_arguments_from_docstring():
365 364 ip = get_ipython()
366 365 c = ip.Completer
367 366 kwd = c._default_arguments_from_docstring(
368 367 'min(iterable[, key=func]) -> value')
369 368 nt.assert_equal(kwd, ['key'])
370 369 #with cython type etc
371 370 kwd = c._default_arguments_from_docstring(
372 371 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
373 372 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
374 373 #white spaces
375 374 kwd = c._default_arguments_from_docstring(
376 375 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
377 376 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
378 377
379 378 def test_line_magics():
380 379 ip = get_ipython()
381 380 c = ip.Completer
382 381 s, matches = c.complete(None, 'lsmag')
383 382 nt.assert_in('%lsmagic', matches)
384 383 s, matches = c.complete(None, '%lsmag')
385 384 nt.assert_in('%lsmagic', matches)
386 385
387 386
388 387 def test_cell_magics():
389 388 from IPython.core.magic import register_cell_magic
390 389
391 390 @register_cell_magic
392 391 def _foo_cellm(line, cell):
393 392 pass
394 393
395 394 ip = get_ipython()
396 395 c = ip.Completer
397 396
398 397 s, matches = c.complete(None, '_foo_ce')
399 398 nt.assert_in('%%_foo_cellm', matches)
400 399 s, matches = c.complete(None, '%%_foo_ce')
401 400 nt.assert_in('%%_foo_cellm', matches)
402 401
403 402
404 403 def test_line_cell_magics():
405 404 from IPython.core.magic import register_line_cell_magic
406 405
407 406 @register_line_cell_magic
408 407 def _bar_cellm(line, cell):
409 408 pass
410 409
411 410 ip = get_ipython()
412 411 c = ip.Completer
413 412
414 413 # The policy here is trickier, see comments in completion code. The
415 414 # returned values depend on whether the user passes %% or not explicitly,
416 415 # and this will show a difference if the same name is both a line and cell
417 416 # magic.
418 417 s, matches = c.complete(None, '_bar_ce')
419 418 nt.assert_in('%_bar_cellm', matches)
420 419 nt.assert_in('%%_bar_cellm', matches)
421 420 s, matches = c.complete(None, '%_bar_ce')
422 421 nt.assert_in('%_bar_cellm', matches)
423 422 nt.assert_in('%%_bar_cellm', matches)
424 423 s, matches = c.complete(None, '%%_bar_ce')
425 424 nt.assert_not_in('%_bar_cellm', matches)
426 425 nt.assert_in('%%_bar_cellm', matches)
427 426
428 427
429 428 def test_magic_completion_order():
430 429
431 430 ip = get_ipython()
432 431 c = ip.Completer
433 432
434 433 # Test ordering of magics and non-magics with the same name
435 434 # We want the non-magic first
436 435
437 436 # Before importing matplotlib, there should only be one option:
438 437
439 438 text, matches = c.complete('mat')
440 439 nt.assert_equal(matches, ["%matplotlib"])
441 440
442 441
443 442 ip.run_cell("matplotlib = 1") # introduce name into namespace
444 443
445 444 # After the import, there should be two options, ordered like this:
446 445 text, matches = c.complete('mat')
447 446 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
448 447
449 448
450 449 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
451 450
452 451 # Order of user variable and line and cell magics with same name:
453 452 text, matches = c.complete('timeit')
454 453 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
455 454
456 455
457 456 def test_dict_key_completion_string():
458 457 """Test dictionary key completion for string keys"""
459 458 ip = get_ipython()
460 459 complete = ip.Completer.complete
461 460
462 461 ip.user_ns['d'] = {'abc': None}
463 462
464 463 # check completion at different stages
465 464 _, matches = complete(line_buffer="d[")
466 465 nt.assert_in("'abc'", matches)
467 466 nt.assert_not_in("'abc']", matches)
468 467
469 468 _, matches = complete(line_buffer="d['")
470 469 nt.assert_in("abc", matches)
471 470 nt.assert_not_in("abc']", matches)
472 471
473 472 _, matches = complete(line_buffer="d['a")
474 473 nt.assert_in("abc", matches)
475 474 nt.assert_not_in("abc']", matches)
476 475
477 476 # check use of different quoting
478 477 _, matches = complete(line_buffer="d[\"")
479 478 nt.assert_in("abc", matches)
480 479 nt.assert_not_in('abc\"]', matches)
481 480
482 481 _, matches = complete(line_buffer="d[\"a")
483 482 nt.assert_in("abc", matches)
484 483 nt.assert_not_in('abc\"]', matches)
485 484
486 485 # check sensitivity to following context
487 486 _, matches = complete(line_buffer="d[]", cursor_pos=2)
488 487 nt.assert_in("'abc'", matches)
489 488
490 489 _, matches = complete(line_buffer="d['']", cursor_pos=3)
491 490 nt.assert_in("abc", matches)
492 491 nt.assert_not_in("abc'", matches)
493 492 nt.assert_not_in("abc']", matches)
494 493
495 494 # check multiple solutions are correctly returned and that noise is not
496 495 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
497 496 5: None}
498 497
499 498 _, matches = complete(line_buffer="d['a")
500 499 nt.assert_in("abc", matches)
501 500 nt.assert_in("abd", matches)
502 501 nt.assert_not_in("bad", matches)
503 502 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
504 503
505 504 # check escaping and whitespace
506 505 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
507 506 _, matches = complete(line_buffer="d['a")
508 507 nt.assert_in("a\\nb", matches)
509 508 nt.assert_in("a\\'b", matches)
510 509 nt.assert_in("a\"b", matches)
511 510 nt.assert_in("a word", matches)
512 511 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
513 512
514 513 # - can complete on non-initial word of the string
515 514 _, matches = complete(line_buffer="d['a w")
516 515 nt.assert_in("word", matches)
517 516
518 517 # - understands quote escaping
519 518 _, matches = complete(line_buffer="d['a\\'")
520 519 nt.assert_in("b", matches)
521 520
522 521 # - default quoting should work like repr
523 522 _, matches = complete(line_buffer="d[")
524 523 nt.assert_in("\"a'b\"", matches)
525 524
526 525 # - when opening quote with ", possible to match with unescaped apostrophe
527 526 _, matches = complete(line_buffer="d[\"a'")
528 527 nt.assert_in("b", matches)
529 528
530 529 # need to not split at delims that readline won't split at
531 530 if '-' not in ip.Completer.splitter.delims:
532 531 ip.user_ns['d'] = {'before-after': None}
533 532 _, matches = complete(line_buffer="d['before-af")
534 533 nt.assert_in('before-after', matches)
535 534
536 535 def test_dict_key_completion_contexts():
537 536 """Test expression contexts in which dict key completion occurs"""
538 537 ip = get_ipython()
539 538 complete = ip.Completer.complete
540 539 d = {'abc': None}
541 540 ip.user_ns['d'] = d
542 541
543 542 class C:
544 543 data = d
545 544 ip.user_ns['C'] = C
546 545 ip.user_ns['get'] = lambda: d
547 546
548 547 def assert_no_completion(**kwargs):
549 548 _, matches = complete(**kwargs)
550 549 nt.assert_not_in('abc', matches)
551 550 nt.assert_not_in('abc\'', matches)
552 551 nt.assert_not_in('abc\']', matches)
553 552 nt.assert_not_in('\'abc\'', matches)
554 553 nt.assert_not_in('\'abc\']', matches)
555 554
556 555 def assert_completion(**kwargs):
557 556 _, matches = complete(**kwargs)
558 557 nt.assert_in("'abc'", matches)
559 558 nt.assert_not_in("'abc']", matches)
560 559
561 560 # no completion after string closed, even if reopened
562 561 assert_no_completion(line_buffer="d['a'")
563 562 assert_no_completion(line_buffer="d[\"a\"")
564 563 assert_no_completion(line_buffer="d['a' + ")
565 564 assert_no_completion(line_buffer="d['a' + '")
566 565
567 566 # completion in non-trivial expressions
568 567 assert_completion(line_buffer="+ d[")
569 568 assert_completion(line_buffer="(d[")
570 569 assert_completion(line_buffer="C.data[")
571 570
572 571 # greedy flag
573 572 def assert_completion(**kwargs):
574 573 _, matches = complete(**kwargs)
575 574 nt.assert_in("get()['abc']", matches)
576 575
577 576 assert_no_completion(line_buffer="get()[")
578 577 with greedy_completion():
579 578 assert_completion(line_buffer="get()[")
580 579 assert_completion(line_buffer="get()['")
581 580 assert_completion(line_buffer="get()['a")
582 581 assert_completion(line_buffer="get()['ab")
583 582 assert_completion(line_buffer="get()['abc")
584 583
585 584
586 585
587 586 def test_dict_key_completion_bytes():
588 587 """Test handling of bytes in dict key completion"""
589 588 ip = get_ipython()
590 589 complete = ip.Completer.complete
591 590
592 591 ip.user_ns['d'] = {'abc': None, b'abd': None}
593 592
594 593 _, matches = complete(line_buffer="d[")
595 594 nt.assert_in("'abc'", matches)
596 595 nt.assert_in("b'abd'", matches)
597 596
598 597 if False: # not currently implemented
599 598 _, matches = complete(line_buffer="d[b")
600 599 nt.assert_in("b'abd'", matches)
601 600 nt.assert_not_in("b'abc'", matches)
602 601
603 602 _, matches = complete(line_buffer="d[b'")
604 603 nt.assert_in("abd", matches)
605 604 nt.assert_not_in("abc", matches)
606 605
607 606 _, matches = complete(line_buffer="d[B'")
608 607 nt.assert_in("abd", matches)
609 608 nt.assert_not_in("abc", matches)
610 609
611 610 _, matches = complete(line_buffer="d['")
612 611 nt.assert_in("abc", matches)
613 612 nt.assert_not_in("abd", matches)
614 613
615 614
616 615 def test_dict_key_completion_unicode_py3():
617 616 """Test handling of unicode in dict key completion"""
618 617 ip = get_ipython()
619 618 complete = ip.Completer.complete
620 619
621 620 ip.user_ns['d'] = {u'a\u05d0': None}
622 621
623 622 # query using escape
624 623 if sys.platform != 'win32':
625 624 # Known failure on Windows
626 625 _, matches = complete(line_buffer="d['a\\u05d0")
627 626 nt.assert_in("u05d0", matches) # tokenized after \\
628 627
629 628 # query using character
630 629 _, matches = complete(line_buffer="d['a\u05d0")
631 630 nt.assert_in(u"a\u05d0", matches)
632 631
633 632 with greedy_completion():
634 633 # query using escape
635 634 _, matches = complete(line_buffer="d['a\\u05d0")
636 635 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
637 636
638 637 # query using character
639 638 _, matches = complete(line_buffer="d['a\u05d0")
640 639 nt.assert_in(u"d['a\u05d0']", matches)
641 640
642 641
643 642
644 643 @dec.skip_without('numpy')
645 644 def test_struct_array_key_completion():
646 645 """Test dict key completion applies to numpy struct arrays"""
647 646 import numpy
648 647 ip = get_ipython()
649 648 complete = ip.Completer.complete
650 649 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
651 650 _, matches = complete(line_buffer="d['")
652 651 nt.assert_in("hello", matches)
653 652 nt.assert_in("world", matches)
654 653 # complete on the numpy struct itself
655 654 dt = numpy.dtype([('my_head', [('my_dt', '>u4'), ('my_df', '>u4')]),
656 655 ('my_data', '>f4', 5)])
657 656 x = numpy.zeros(2, dtype=dt)
658 657 ip.user_ns['d'] = x[1]
659 658 _, matches = complete(line_buffer="d['")
660 659 nt.assert_in("my_head", matches)
661 660 nt.assert_in("my_data", matches)
662 661 # complete on a nested level
663 662 with greedy_completion():
664 663 ip.user_ns['d'] = numpy.zeros(2, dtype=dt)
665 664 _, matches = complete(line_buffer="d[1]['my_head']['")
666 665 nt.assert_true(any(["my_dt" in m for m in matches]))
667 666 nt.assert_true(any(["my_df" in m for m in matches]))
668 667
669 668
670 669 @dec.skip_without('pandas')
671 670 def test_dataframe_key_completion():
672 671 """Test dict key completion applies to pandas DataFrames"""
673 672 import pandas
674 673 ip = get_ipython()
675 674 complete = ip.Completer.complete
676 675 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
677 676 _, matches = complete(line_buffer="d['")
678 677 nt.assert_in("hello", matches)
679 678 nt.assert_in("world", matches)
680 679
681 680
682 681 def test_dict_key_completion_invalids():
683 682 """Smoke test cases dict key completion can't handle"""
684 683 ip = get_ipython()
685 684 complete = ip.Completer.complete
686 685
687 686 ip.user_ns['no_getitem'] = None
688 687 ip.user_ns['no_keys'] = []
689 688 ip.user_ns['cant_call_keys'] = dict
690 689 ip.user_ns['empty'] = {}
691 690 ip.user_ns['d'] = {'abc': 5}
692 691
693 692 _, matches = complete(line_buffer="no_getitem['")
694 693 _, matches = complete(line_buffer="no_keys['")
695 694 _, matches = complete(line_buffer="cant_call_keys['")
696 695 _, matches = complete(line_buffer="empty['")
697 696 _, matches = complete(line_buffer="name_error['")
698 697 _, matches = complete(line_buffer="d['\\") # incomplete escape
699 698
700 699 class KeyCompletable(object):
701 700 def __init__(self, things=()):
702 701 self.things = things
703 702
704 703 def _ipython_key_completions_(self):
705 704 return list(self.things)
706 705
707 706 def test_object_key_completion():
708 707 ip = get_ipython()
709 708 ip.user_ns['key_completable'] = KeyCompletable(['qwerty', 'qwick'])
710 709
711 710 _, matches = ip.Completer.complete(line_buffer="key_completable['qw")
712 711 nt.assert_in('qwerty', matches)
713 712 nt.assert_in('qwick', matches)
714 713
715 714
716 715 def test_aimport_module_completer():
717 716 ip = get_ipython()
718 717 _, matches = ip.complete('i', '%aimport i')
719 718 nt.assert_in('io', matches)
720 719 nt.assert_not_in('int', matches)
721 720
722 721 def test_nested_import_module_completer():
723 722 ip = get_ipython()
724 723 _, matches = ip.complete(None, 'import IPython.co', 17)
725 724 nt.assert_in('IPython.core', matches)
726 725 nt.assert_not_in('import IPython.core', matches)
727 726 nt.assert_not_in('IPython.display', matches)
728 727
729 728 def test_import_module_completer():
730 729 ip = get_ipython()
731 730 _, matches = ip.complete('i', 'import i')
732 731 nt.assert_in('io', matches)
733 732 nt.assert_not_in('int', matches)
734 733
735 734 def test_from_module_completer():
736 735 ip = get_ipython()
737 736 _, matches = ip.complete('B', 'from io import B', 16)
738 737 nt.assert_in('BytesIO', matches)
739 738 nt.assert_not_in('BaseException', matches)
@@ -1,162 +1,162 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for completerlib.
3 3
4 4 """
5 5
6 6 #-----------------------------------------------------------------------------
7 7 # Imports
8 8 #-----------------------------------------------------------------------------
9 9
10 10 import os
11 11 import shutil
12 12 import sys
13 13 import tempfile
14 14 import unittest
15 15 from os.path import join
16 16
17 17 import nose.tools as nt
18 18
19 19 from IPython.core.completerlib import magic_run_completer, module_completion
20 20 from IPython.utils import py3compat
21 21 from IPython.utils.tempdir import TemporaryDirectory
22 22 from IPython.testing.decorators import onlyif_unicode_paths
23 23
24 24
25 25 class MockEvent(object):
26 26 def __init__(self, line):
27 27 self.line = line
28 28
29 29 #-----------------------------------------------------------------------------
30 30 # Test functions begin
31 31 #-----------------------------------------------------------------------------
32 32 class Test_magic_run_completer(unittest.TestCase):
33 33 files = [u"aao.py", u"a.py", u"b.py", u"aao.txt"]
34 34 dirs = [u"adir/", "bdir/"]
35 35
36 36 def setUp(self):
37 37 self.BASETESTDIR = tempfile.mkdtemp()
38 38 for fil in self.files:
39 39 with open(join(self.BASETESTDIR, fil), "w") as sfile:
40 40 sfile.write("pass\n")
41 41 for d in self.dirs:
42 42 os.mkdir(join(self.BASETESTDIR, d))
43 43
44 self.oldpath = py3compat.getcwd()
44 self.oldpath = os.getcwd()
45 45 os.chdir(self.BASETESTDIR)
46 46
47 47 def tearDown(self):
48 48 os.chdir(self.oldpath)
49 49 shutil.rmtree(self.BASETESTDIR)
50 50
51 51 def test_1(self):
52 52 """Test magic_run_completer, should match two alterntives
53 53 """
54 54 event = MockEvent(u"%run a")
55 55 mockself = None
56 56 match = set(magic_run_completer(mockself, event))
57 57 self.assertEqual(match, {u"a.py", u"aao.py", u"adir/"})
58 58
59 59 def test_2(self):
60 60 """Test magic_run_completer, should match one alterntive
61 61 """
62 62 event = MockEvent(u"%run aa")
63 63 mockself = None
64 64 match = set(magic_run_completer(mockself, event))
65 65 self.assertEqual(match, {u"aao.py"})
66 66
67 67 def test_3(self):
68 68 """Test magic_run_completer with unterminated " """
69 69 event = MockEvent(u'%run "a')
70 70 mockself = None
71 71 match = set(magic_run_completer(mockself, event))
72 72 self.assertEqual(match, {u"a.py", u"aao.py", u"adir/"})
73 73
74 74 def test_completion_more_args(self):
75 75 event = MockEvent(u'%run a.py ')
76 76 match = set(magic_run_completer(None, event))
77 77 self.assertEqual(match, set(self.files + self.dirs))
78 78
79 79 def test_completion_in_dir(self):
80 80 # Github issue #3459
81 81 event = MockEvent(u'%run a.py {}'.format(join(self.BASETESTDIR, 'a')))
82 82 print(repr(event.line))
83 83 match = set(magic_run_completer(None, event))
84 84 # We specifically use replace here rather than normpath, because
85 85 # at one point there were duplicates 'adir' and 'adir/', and normpath
86 86 # would hide the failure for that.
87 87 self.assertEqual(match, {join(self.BASETESTDIR, f).replace('\\','/')
88 88 for f in (u'a.py', u'aao.py', u'aao.txt', u'adir/')})
89 89
90 90 class Test_magic_run_completer_nonascii(unittest.TestCase):
91 91 @onlyif_unicode_paths
92 92 def setUp(self):
93 93 self.BASETESTDIR = tempfile.mkdtemp()
94 94 for fil in [u"aaø.py", u"a.py", u"b.py"]:
95 95 with open(join(self.BASETESTDIR, fil), "w") as sfile:
96 96 sfile.write("pass\n")
97 self.oldpath = py3compat.getcwd()
97 self.oldpath = os.getcwd()
98 98 os.chdir(self.BASETESTDIR)
99 99
100 100 def tearDown(self):
101 101 os.chdir(self.oldpath)
102 102 shutil.rmtree(self.BASETESTDIR)
103 103
104 104 @onlyif_unicode_paths
105 105 def test_1(self):
106 106 """Test magic_run_completer, should match two alterntives
107 107 """
108 108 event = MockEvent(u"%run a")
109 109 mockself = None
110 110 match = set(magic_run_completer(mockself, event))
111 111 self.assertEqual(match, {u"a.py", u"aaø.py"})
112 112
113 113 @onlyif_unicode_paths
114 114 def test_2(self):
115 115 """Test magic_run_completer, should match one alterntive
116 116 """
117 117 event = MockEvent(u"%run aa")
118 118 mockself = None
119 119 match = set(magic_run_completer(mockself, event))
120 120 self.assertEqual(match, {u"aaø.py"})
121 121
122 122 @onlyif_unicode_paths
123 123 def test_3(self):
124 124 """Test magic_run_completer with unterminated " """
125 125 event = MockEvent(u'%run "a')
126 126 mockself = None
127 127 match = set(magic_run_completer(mockself, event))
128 128 self.assertEqual(match, {u"a.py", u"aaø.py"})
129 129
130 130 # module_completer:
131 131
132 132 def test_import_invalid_module():
133 133 """Testing of issue https://github.com/ipython/ipython/issues/1107"""
134 134 invalid_module_names = {'foo-bar', 'foo:bar', '10foo'}
135 135 valid_module_names = {'foobar'}
136 136 with TemporaryDirectory() as tmpdir:
137 137 sys.path.insert( 0, tmpdir )
138 138 for name in invalid_module_names | valid_module_names:
139 139 filename = os.path.join(tmpdir, name + '.py')
140 140 open(filename, 'w').close()
141 141
142 142 s = set( module_completion('import foo') )
143 143 intersection = s.intersection(invalid_module_names)
144 144 nt.assert_equal(intersection, set())
145 145
146 146 assert valid_module_names.issubset(s), valid_module_names.intersection(s)
147 147
148 148
149 149 def test_bad_module_all():
150 150 """Test module with invalid __all__
151 151
152 152 https://github.com/ipython/ipython/issues/9678
153 153 """
154 154 testsdir = os.path.dirname(__file__)
155 155 sys.path.insert(0, testsdir)
156 156 try:
157 157 results = module_completion('from bad_all import ')
158 158 nt.assert_in('puppies', results)
159 159 for r in results:
160 nt.assert_is_instance(r, py3compat.string_types)
160 nt.assert_is_instance(r, str)
161 161 finally:
162 162 sys.path.remove(testsdir)
@@ -1,614 +1,614 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for the inputsplitter module."""
3 3
4 4
5 5 # Copyright (c) IPython Development Team.
6 6 # Distributed under the terms of the Modified BSD License.
7 7
8 8 import unittest
9 9 import sys
10 10
11 11 import nose.tools as nt
12 12
13 13 from IPython.core import inputsplitter as isp
14 14 from IPython.core.inputtransformer import InputTransformer
15 15 from IPython.core.tests.test_inputtransformer import syntax, syntax_ml
16 16 from IPython.testing import tools as tt
17 17 from IPython.utils import py3compat
18 from IPython.utils.py3compat import string_types, input
18 from IPython.utils.py3compat import input
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Semi-complete examples (also used as tests)
22 22 #-----------------------------------------------------------------------------
23 23
24 24 # Note: at the bottom, there's a slightly more complete version of this that
25 25 # can be useful during development of code here.
26 26
27 27 def mini_interactive_loop(input_func):
28 28 """Minimal example of the logic of an interactive interpreter loop.
29 29
30 30 This serves as an example, and it is used by the test system with a fake
31 31 raw_input that simulates interactive input."""
32 32
33 33 from IPython.core.inputsplitter import InputSplitter
34 34
35 35 isp = InputSplitter()
36 36 # In practice, this input loop would be wrapped in an outside loop to read
37 37 # input indefinitely, until some exit/quit command was issued. Here we
38 38 # only illustrate the basic inner loop.
39 39 while isp.push_accepts_more():
40 40 indent = ' '*isp.indent_spaces
41 41 prompt = '>>> ' + indent
42 42 line = indent + input_func(prompt)
43 43 isp.push(line)
44 44
45 45 # Here we just return input so we can use it in a test suite, but a real
46 46 # interpreter would instead send it for execution somewhere.
47 47 src = isp.source_reset()
48 48 #print 'Input source was:\n', src # dbg
49 49 return src
50 50
51 51 #-----------------------------------------------------------------------------
52 52 # Test utilities, just for local use
53 53 #-----------------------------------------------------------------------------
54 54
55 55 def assemble(block):
56 56 """Assemble a block into multi-line sub-blocks."""
57 57 return ['\n'.join(sub_block)+'\n' for sub_block in block]
58 58
59 59
60 60 def pseudo_input(lines):
61 61 """Return a function that acts like raw_input but feeds the input list."""
62 62 ilines = iter(lines)
63 63 def raw_in(prompt):
64 64 try:
65 65 return next(ilines)
66 66 except StopIteration:
67 67 return ''
68 68 return raw_in
69 69
70 70 #-----------------------------------------------------------------------------
71 71 # Tests
72 72 #-----------------------------------------------------------------------------
73 73 def test_spaces():
74 74 tests = [('', 0),
75 75 (' ', 1),
76 76 ('\n', 0),
77 77 (' \n', 1),
78 78 ('x', 0),
79 79 (' x', 1),
80 80 (' x',2),
81 81 (' x',4),
82 82 # Note: tabs are counted as a single whitespace!
83 83 ('\tx', 1),
84 84 ('\t x', 2),
85 85 ]
86 86 tt.check_pairs(isp.num_ini_spaces, tests)
87 87
88 88
89 89 def test_remove_comments():
90 90 tests = [('text', 'text'),
91 91 ('text # comment', 'text '),
92 92 ('text # comment\n', 'text \n'),
93 93 ('text # comment \n', 'text \n'),
94 94 ('line # c \nline\n','line \nline\n'),
95 95 ('line # c \nline#c2 \nline\nline #c\n\n',
96 96 'line \nline\nline\nline \n\n'),
97 97 ]
98 98 tt.check_pairs(isp.remove_comments, tests)
99 99
100 100
101 101 def test_get_input_encoding():
102 102 encoding = isp.get_input_encoding()
103 nt.assert_true(isinstance(encoding, string_types))
103 nt.assert_true(isinstance(encoding, str))
104 104 # simple-minded check that at least encoding a simple string works with the
105 105 # encoding we got.
106 106 nt.assert_equal(u'test'.encode(encoding), b'test')
107 107
108 108
109 109 class NoInputEncodingTestCase(unittest.TestCase):
110 110 def setUp(self):
111 111 self.old_stdin = sys.stdin
112 112 class X: pass
113 113 fake_stdin = X()
114 114 sys.stdin = fake_stdin
115 115
116 116 def test(self):
117 117 # Verify that if sys.stdin has no 'encoding' attribute we do the right
118 118 # thing
119 119 enc = isp.get_input_encoding()
120 120 self.assertEqual(enc, 'ascii')
121 121
122 122 def tearDown(self):
123 123 sys.stdin = self.old_stdin
124 124
125 125
126 126 class InputSplitterTestCase(unittest.TestCase):
127 127 def setUp(self):
128 128 self.isp = isp.InputSplitter()
129 129
130 130 def test_reset(self):
131 131 isp = self.isp
132 132 isp.push('x=1')
133 133 isp.reset()
134 134 self.assertEqual(isp._buffer, [])
135 135 self.assertEqual(isp.indent_spaces, 0)
136 136 self.assertEqual(isp.source, '')
137 137 self.assertEqual(isp.code, None)
138 138 self.assertEqual(isp._is_complete, False)
139 139
140 140 def test_source(self):
141 141 self.isp._store('1')
142 142 self.isp._store('2')
143 143 self.assertEqual(self.isp.source, '1\n2\n')
144 144 self.assertEqual(len(self.isp._buffer)>0, True)
145 145 self.assertEqual(self.isp.source_reset(), '1\n2\n')
146 146 self.assertEqual(self.isp._buffer, [])
147 147 self.assertEqual(self.isp.source, '')
148 148
149 149 def test_indent(self):
150 150 isp = self.isp # shorthand
151 151 isp.push('x=1')
152 152 self.assertEqual(isp.indent_spaces, 0)
153 153 isp.push('if 1:\n x=1')
154 154 self.assertEqual(isp.indent_spaces, 4)
155 155 isp.push('y=2\n')
156 156 self.assertEqual(isp.indent_spaces, 0)
157 157
158 158 def test_indent2(self):
159 159 isp = self.isp
160 160 isp.push('if 1:')
161 161 self.assertEqual(isp.indent_spaces, 4)
162 162 isp.push(' x=1')
163 163 self.assertEqual(isp.indent_spaces, 4)
164 164 # Blank lines shouldn't change the indent level
165 165 isp.push(' '*2)
166 166 self.assertEqual(isp.indent_spaces, 4)
167 167
168 168 def test_indent3(self):
169 169 isp = self.isp
170 170 # When a multiline statement contains parens or multiline strings, we
171 171 # shouldn't get confused.
172 172 isp.push("if 1:")
173 173 isp.push(" x = (1+\n 2)")
174 174 self.assertEqual(isp.indent_spaces, 4)
175 175
176 176 def test_indent4(self):
177 177 isp = self.isp
178 178 # whitespace after ':' should not screw up indent level
179 179 isp.push('if 1: \n x=1')
180 180 self.assertEqual(isp.indent_spaces, 4)
181 181 isp.push('y=2\n')
182 182 self.assertEqual(isp.indent_spaces, 0)
183 183 isp.push('if 1:\t\n x=1')
184 184 self.assertEqual(isp.indent_spaces, 4)
185 185 isp.push('y=2\n')
186 186 self.assertEqual(isp.indent_spaces, 0)
187 187
188 188 def test_dedent_pass(self):
189 189 isp = self.isp # shorthand
190 190 # should NOT cause dedent
191 191 isp.push('if 1:\n passes = 5')
192 192 self.assertEqual(isp.indent_spaces, 4)
193 193 isp.push('if 1:\n pass')
194 194 self.assertEqual(isp.indent_spaces, 0)
195 195 isp.push('if 1:\n pass ')
196 196 self.assertEqual(isp.indent_spaces, 0)
197 197
198 198 def test_dedent_break(self):
199 199 isp = self.isp # shorthand
200 200 # should NOT cause dedent
201 201 isp.push('while 1:\n breaks = 5')
202 202 self.assertEqual(isp.indent_spaces, 4)
203 203 isp.push('while 1:\n break')
204 204 self.assertEqual(isp.indent_spaces, 0)
205 205 isp.push('while 1:\n break ')
206 206 self.assertEqual(isp.indent_spaces, 0)
207 207
208 208 def test_dedent_continue(self):
209 209 isp = self.isp # shorthand
210 210 # should NOT cause dedent
211 211 isp.push('while 1:\n continues = 5')
212 212 self.assertEqual(isp.indent_spaces, 4)
213 213 isp.push('while 1:\n continue')
214 214 self.assertEqual(isp.indent_spaces, 0)
215 215 isp.push('while 1:\n continue ')
216 216 self.assertEqual(isp.indent_spaces, 0)
217 217
218 218 def test_dedent_raise(self):
219 219 isp = self.isp # shorthand
220 220 # should NOT cause dedent
221 221 isp.push('if 1:\n raised = 4')
222 222 self.assertEqual(isp.indent_spaces, 4)
223 223 isp.push('if 1:\n raise TypeError()')
224 224 self.assertEqual(isp.indent_spaces, 0)
225 225 isp.push('if 1:\n raise')
226 226 self.assertEqual(isp.indent_spaces, 0)
227 227 isp.push('if 1:\n raise ')
228 228 self.assertEqual(isp.indent_spaces, 0)
229 229
230 230 def test_dedent_return(self):
231 231 isp = self.isp # shorthand
232 232 # should NOT cause dedent
233 233 isp.push('if 1:\n returning = 4')
234 234 self.assertEqual(isp.indent_spaces, 4)
235 235 isp.push('if 1:\n return 5 + 493')
236 236 self.assertEqual(isp.indent_spaces, 0)
237 237 isp.push('if 1:\n return')
238 238 self.assertEqual(isp.indent_spaces, 0)
239 239 isp.push('if 1:\n return ')
240 240 self.assertEqual(isp.indent_spaces, 0)
241 241 isp.push('if 1:\n return(0)')
242 242 self.assertEqual(isp.indent_spaces, 0)
243 243
244 244 def test_push(self):
245 245 isp = self.isp
246 246 self.assertEqual(isp.push('x=1'), True)
247 247
248 248 def test_push2(self):
249 249 isp = self.isp
250 250 self.assertEqual(isp.push('if 1:'), False)
251 251 for line in [' x=1', '# a comment', ' y=2']:
252 252 print(line)
253 253 self.assertEqual(isp.push(line), True)
254 254
255 255 def test_push3(self):
256 256 isp = self.isp
257 257 isp.push('if True:')
258 258 isp.push(' a = 1')
259 259 self.assertEqual(isp.push('b = [1,'), False)
260 260
261 261 def test_push_accepts_more(self):
262 262 isp = self.isp
263 263 isp.push('x=1')
264 264 self.assertEqual(isp.push_accepts_more(), False)
265 265
266 266 def test_push_accepts_more2(self):
267 267 isp = self.isp
268 268 isp.push('if 1:')
269 269 self.assertEqual(isp.push_accepts_more(), True)
270 270 isp.push(' x=1')
271 271 self.assertEqual(isp.push_accepts_more(), True)
272 272 isp.push('')
273 273 self.assertEqual(isp.push_accepts_more(), False)
274 274
275 275 def test_push_accepts_more3(self):
276 276 isp = self.isp
277 277 isp.push("x = (2+\n3)")
278 278 self.assertEqual(isp.push_accepts_more(), False)
279 279
280 280 def test_push_accepts_more4(self):
281 281 isp = self.isp
282 282 # When a multiline statement contains parens or multiline strings, we
283 283 # shouldn't get confused.
284 284 # FIXME: we should be able to better handle de-dents in statements like
285 285 # multiline strings and multiline expressions (continued with \ or
286 286 # parens). Right now we aren't handling the indentation tracking quite
287 287 # correctly with this, though in practice it may not be too much of a
288 288 # problem. We'll need to see.
289 289 isp.push("if 1:")
290 290 isp.push(" x = (2+")
291 291 isp.push(" 3)")
292 292 self.assertEqual(isp.push_accepts_more(), True)
293 293 isp.push(" y = 3")
294 294 self.assertEqual(isp.push_accepts_more(), True)
295 295 isp.push('')
296 296 self.assertEqual(isp.push_accepts_more(), False)
297 297
298 298 def test_push_accepts_more5(self):
299 299 isp = self.isp
300 300 isp.push('try:')
301 301 isp.push(' a = 5')
302 302 isp.push('except:')
303 303 isp.push(' raise')
304 304 # We want to be able to add an else: block at this point, so it should
305 305 # wait for a blank line.
306 306 self.assertEqual(isp.push_accepts_more(), True)
307 307
308 308 def test_continuation(self):
309 309 isp = self.isp
310 310 isp.push("import os, \\")
311 311 self.assertEqual(isp.push_accepts_more(), True)
312 312 isp.push("sys")
313 313 self.assertEqual(isp.push_accepts_more(), False)
314 314
315 315 def test_syntax_error(self):
316 316 isp = self.isp
317 317 # Syntax errors immediately produce a 'ready' block, so the invalid
318 318 # Python can be sent to the kernel for evaluation with possible ipython
319 319 # special-syntax conversion.
320 320 isp.push('run foo')
321 321 self.assertEqual(isp.push_accepts_more(), False)
322 322
323 323 def test_unicode(self):
324 324 self.isp.push(u"Pérez")
325 325 self.isp.push(u'\xc3\xa9')
326 326 self.isp.push(u"u'\xc3\xa9'")
327 327
328 328 def test_line_continuation(self):
329 329 """ Test issue #2108."""
330 330 isp = self.isp
331 331 # A blank line after a line continuation should not accept more
332 332 isp.push("1 \\\n\n")
333 333 self.assertEqual(isp.push_accepts_more(), False)
334 334 # Whitespace after a \ is a SyntaxError. The only way to test that
335 335 # here is to test that push doesn't accept more (as with
336 336 # test_syntax_error() above).
337 337 isp.push(r"1 \ ")
338 338 self.assertEqual(isp.push_accepts_more(), False)
339 339 # Even if the line is continuable (c.f. the regular Python
340 340 # interpreter)
341 341 isp.push(r"(1 \ ")
342 342 self.assertEqual(isp.push_accepts_more(), False)
343 343
344 344 def test_check_complete(self):
345 345 isp = self.isp
346 346 self.assertEqual(isp.check_complete("a = 1"), ('complete', None))
347 347 self.assertEqual(isp.check_complete("for a in range(5):"), ('incomplete', 4))
348 348 self.assertEqual(isp.check_complete("raise = 2"), ('invalid', None))
349 349 self.assertEqual(isp.check_complete("a = [1,\n2,"), ('incomplete', 0))
350 350 self.assertEqual(isp.check_complete("def a():\n x=1\n global x"), ('invalid', None))
351 351
352 352 class InteractiveLoopTestCase(unittest.TestCase):
353 353 """Tests for an interactive loop like a python shell.
354 354 """
355 355 def check_ns(self, lines, ns):
356 356 """Validate that the given input lines produce the resulting namespace.
357 357
358 358 Note: the input lines are given exactly as they would be typed in an
359 359 auto-indenting environment, as mini_interactive_loop above already does
360 360 auto-indenting and prepends spaces to the input.
361 361 """
362 362 src = mini_interactive_loop(pseudo_input(lines))
363 363 test_ns = {}
364 364 exec(src, test_ns)
365 365 # We can't check that the provided ns is identical to the test_ns,
366 366 # because Python fills test_ns with extra keys (copyright, etc). But
367 367 # we can check that the given dict is *contained* in test_ns
368 368 for k,v in ns.items():
369 369 self.assertEqual(test_ns[k], v)
370 370
371 371 def test_simple(self):
372 372 self.check_ns(['x=1'], dict(x=1))
373 373
374 374 def test_simple2(self):
375 375 self.check_ns(['if 1:', 'x=2'], dict(x=2))
376 376
377 377 def test_xy(self):
378 378 self.check_ns(['x=1; y=2'], dict(x=1, y=2))
379 379
380 380 def test_abc(self):
381 381 self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
382 382
383 383 def test_multi(self):
384 384 self.check_ns(['x =(1+','1+','2)'], dict(x=4))
385 385
386 386
387 387 class IPythonInputTestCase(InputSplitterTestCase):
388 388 """By just creating a new class whose .isp is a different instance, we
389 389 re-run the same test battery on the new input splitter.
390 390
391 391 In addition, this runs the tests over the syntax and syntax_ml dicts that
392 392 were tested by individual functions, as part of the OO interface.
393 393
394 394 It also makes some checks on the raw buffer storage.
395 395 """
396 396
397 397 def setUp(self):
398 398 self.isp = isp.IPythonInputSplitter()
399 399
400 400 def test_syntax(self):
401 401 """Call all single-line syntax tests from the main object"""
402 402 isp = self.isp
403 403 for example in syntax.values():
404 404 for raw, out_t in example:
405 405 if raw.startswith(' '):
406 406 continue
407 407
408 408 isp.push(raw+'\n')
409 409 out_raw = isp.source_raw
410 410 out = isp.source_reset()
411 411 self.assertEqual(out.rstrip(), out_t,
412 412 tt.pair_fail_msg.format("inputsplitter",raw, out_t, out))
413 413 self.assertEqual(out_raw.rstrip(), raw.rstrip())
414 414
415 415 def test_syntax_multiline(self):
416 416 isp = self.isp
417 417 for example in syntax_ml.values():
418 418 for line_pairs in example:
419 419 out_t_parts = []
420 420 raw_parts = []
421 421 for lraw, out_t_part in line_pairs:
422 422 if out_t_part is not None:
423 423 out_t_parts.append(out_t_part)
424 424
425 425 if lraw is not None:
426 426 isp.push(lraw)
427 427 raw_parts.append(lraw)
428 428
429 429 out_raw = isp.source_raw
430 430 out = isp.source_reset()
431 431 out_t = '\n'.join(out_t_parts).rstrip()
432 432 raw = '\n'.join(raw_parts).rstrip()
433 433 self.assertEqual(out.rstrip(), out_t)
434 434 self.assertEqual(out_raw.rstrip(), raw)
435 435
436 436 def test_syntax_multiline_cell(self):
437 437 isp = self.isp
438 438 for example in syntax_ml.values():
439 439
440 440 out_t_parts = []
441 441 for line_pairs in example:
442 442 raw = '\n'.join(r for r, _ in line_pairs if r is not None)
443 443 out_t = '\n'.join(t for _,t in line_pairs if t is not None)
444 444 out = isp.transform_cell(raw)
445 445 # Match ignoring trailing whitespace
446 446 self.assertEqual(out.rstrip(), out_t.rstrip())
447 447
448 448 def test_cellmagic_preempt(self):
449 449 isp = self.isp
450 450 for raw, name, line, cell in [
451 451 ("%%cellm a\nIn[1]:", u'cellm', u'a', u'In[1]:'),
452 452 ("%%cellm \nline\n>>> hi", u'cellm', u'', u'line\n>>> hi'),
453 453 (">>> %%cellm \nline\n>>> hi", u'cellm', u'', u'line\nhi'),
454 454 ("%%cellm \n>>> hi", u'cellm', u'', u'>>> hi'),
455 455 ("%%cellm \nline1\nline2", u'cellm', u'', u'line1\nline2'),
456 456 ("%%cellm \nline1\\\\\nline2", u'cellm', u'', u'line1\\\\\nline2'),
457 457 ]:
458 458 expected = "get_ipython().run_cell_magic(%r, %r, %r)" % (
459 459 name, line, cell
460 460 )
461 461 out = isp.transform_cell(raw)
462 462 self.assertEqual(out.rstrip(), expected.rstrip())
463 463
464 464 def test_multiline_passthrough(self):
465 465 isp = self.isp
466 466 class CommentTransformer(InputTransformer):
467 467 def __init__(self):
468 468 self._lines = []
469 469
470 470 def push(self, line):
471 471 self._lines.append(line + '#')
472 472
473 473 def reset(self):
474 474 text = '\n'.join(self._lines)
475 475 self._lines = []
476 476 return text
477 477
478 478 isp.physical_line_transforms.insert(0, CommentTransformer())
479 479
480 480 for raw, expected in [
481 481 ("a=5", "a=5#"),
482 482 ("%ls foo", "get_ipython().magic(%r)" % u'ls foo#'),
483 483 ("!ls foo\n%ls bar", "get_ipython().system(%r)\nget_ipython().magic(%r)" % (
484 484 u'ls foo#', u'ls bar#'
485 485 )),
486 486 ("1\n2\n3\n%ls foo\n4\n5", "1#\n2#\n3#\nget_ipython().magic(%r)\n4#\n5#" % u'ls foo#'),
487 487 ]:
488 488 out = isp.transform_cell(raw)
489 489 self.assertEqual(out.rstrip(), expected.rstrip())
490 490
491 491 #-----------------------------------------------------------------------------
492 492 # Main - use as a script, mostly for developer experiments
493 493 #-----------------------------------------------------------------------------
494 494
495 495 if __name__ == '__main__':
496 496 # A simple demo for interactive experimentation. This code will not get
497 497 # picked up by any test suite.
498 498 from IPython.core.inputsplitter import IPythonInputSplitter
499 499
500 500 # configure here the syntax to use, prompt and whether to autoindent
501 501 #isp, start_prompt = InputSplitter(), '>>> '
502 502 isp, start_prompt = IPythonInputSplitter(), 'In> '
503 503
504 504 autoindent = True
505 505 #autoindent = False
506 506
507 507 try:
508 508 while True:
509 509 prompt = start_prompt
510 510 while isp.push_accepts_more():
511 511 indent = ' '*isp.indent_spaces
512 512 if autoindent:
513 513 line = indent + input(prompt+indent)
514 514 else:
515 515 line = input(prompt)
516 516 isp.push(line)
517 517 prompt = '... '
518 518
519 519 # Here we just return input so we can use it in a test suite, but a
520 520 # real interpreter would instead send it for execution somewhere.
521 521 #src = isp.source; raise EOFError # dbg
522 522 raw = isp.source_raw
523 523 src = isp.source_reset()
524 524 print('Input source was:\n', src)
525 525 print('Raw source was:\n', raw)
526 526 except EOFError:
527 527 print('Bye')
528 528
529 529 # Tests for cell magics support
530 530
531 531 def test_last_blank():
532 532 nt.assert_false(isp.last_blank(''))
533 533 nt.assert_false(isp.last_blank('abc'))
534 534 nt.assert_false(isp.last_blank('abc\n'))
535 535 nt.assert_false(isp.last_blank('abc\na'))
536 536
537 537 nt.assert_true(isp.last_blank('\n'))
538 538 nt.assert_true(isp.last_blank('\n '))
539 539 nt.assert_true(isp.last_blank('abc\n '))
540 540 nt.assert_true(isp.last_blank('abc\n\n'))
541 541 nt.assert_true(isp.last_blank('abc\nd\n\n'))
542 542 nt.assert_true(isp.last_blank('abc\nd\ne\n\n'))
543 543 nt.assert_true(isp.last_blank('abc \n \n \n\n'))
544 544
545 545
546 546 def test_last_two_blanks():
547 547 nt.assert_false(isp.last_two_blanks(''))
548 548 nt.assert_false(isp.last_two_blanks('abc'))
549 549 nt.assert_false(isp.last_two_blanks('abc\n'))
550 550 nt.assert_false(isp.last_two_blanks('abc\n\na'))
551 551 nt.assert_false(isp.last_two_blanks('abc\n \n'))
552 552 nt.assert_false(isp.last_two_blanks('abc\n\n'))
553 553
554 554 nt.assert_true(isp.last_two_blanks('\n\n'))
555 555 nt.assert_true(isp.last_two_blanks('\n\n '))
556 556 nt.assert_true(isp.last_two_blanks('\n \n'))
557 557 nt.assert_true(isp.last_two_blanks('abc\n\n '))
558 558 nt.assert_true(isp.last_two_blanks('abc\n\n\n'))
559 559 nt.assert_true(isp.last_two_blanks('abc\n\n \n'))
560 560 nt.assert_true(isp.last_two_blanks('abc\n\n \n '))
561 561 nt.assert_true(isp.last_two_blanks('abc\n\n \n \n'))
562 562 nt.assert_true(isp.last_two_blanks('abc\nd\n\n\n'))
563 563 nt.assert_true(isp.last_two_blanks('abc\nd\ne\nf\n\n\n'))
564 564
565 565
566 566 class CellMagicsCommon(object):
567 567
568 568 def test_whole_cell(self):
569 569 src = "%%cellm line\nbody\n"
570 570 out = self.sp.transform_cell(src)
571 571 ref = u"get_ipython().run_cell_magic({u}'cellm', {u}'line', {u}'body')\n"
572 572 nt.assert_equal(out, py3compat.u_format(ref))
573 573
574 574 def test_cellmagic_help(self):
575 575 self.sp.push('%%cellm?')
576 576 nt.assert_false(self.sp.push_accepts_more())
577 577
578 578 def tearDown(self):
579 579 self.sp.reset()
580 580
581 581
582 582 class CellModeCellMagics(CellMagicsCommon, unittest.TestCase):
583 583 sp = isp.IPythonInputSplitter(line_input_checker=False)
584 584
585 585 def test_incremental(self):
586 586 sp = self.sp
587 587 sp.push('%%cellm firstline\n')
588 588 nt.assert_true(sp.push_accepts_more()) #1
589 589 sp.push('line2\n')
590 590 nt.assert_true(sp.push_accepts_more()) #2
591 591 sp.push('\n')
592 592 # This should accept a blank line and carry on until the cell is reset
593 593 nt.assert_true(sp.push_accepts_more()) #3
594 594
595 595 def test_no_strip_coding(self):
596 596 src = '\n'.join([
597 597 '%%writefile foo.py',
598 598 '# coding: utf-8',
599 599 'print(u"üñîçø∂é")',
600 600 ])
601 601 out = self.sp.transform_cell(src)
602 602 nt.assert_in('# coding: utf-8', out)
603 603
604 604
605 605 class LineModeCellMagics(CellMagicsCommon, unittest.TestCase):
606 606 sp = isp.IPythonInputSplitter(line_input_checker=True)
607 607
608 608 def test_incremental(self):
609 609 sp = self.sp
610 610 sp.push('%%cellm line2\n')
611 611 nt.assert_true(sp.push_accepts_more()) #1
612 612 sp.push('\n')
613 613 # In this case, a blank line should end the cell magic
614 614 nt.assert_false(sp.push_accepts_more()) #2
@@ -1,906 +1,906 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for the key interactiveshell module.
3 3
4 4 Historically the main classes in interactiveshell have been under-tested. This
5 5 module should grow as many single-method tests as possible to trap many of the
6 6 recurring bugs we seem to encounter with high-level interaction.
7 7 """
8 8
9 9 # Copyright (c) IPython Development Team.
10 10 # Distributed under the terms of the Modified BSD License.
11 11
12 12 import ast
13 13 import os
14 14 import signal
15 15 import shutil
16 16 import sys
17 17 import tempfile
18 18 import unittest
19 19 try:
20 20 from unittest import mock
21 21 except ImportError:
22 22 import mock
23 23 from os.path import join
24 24
25 25 import nose.tools as nt
26 26
27 27 from IPython.core.error import InputRejected
28 28 from IPython.core.inputtransformer import InputTransformer
29 29 from IPython.testing.decorators import (
30 30 skipif, skip_win32, onlyif_unicode_paths, onlyif_cmds_exist,
31 31 )
32 32 from IPython.testing import tools as tt
33 33 from IPython.utils.process import find_cmd
34 34 from IPython.utils import py3compat
35 from IPython.utils.py3compat import unicode_type, PY3
35 from IPython.utils.py3compat import PY3
36 36
37 37 if PY3:
38 38 from io import StringIO
39 39 else:
40 40 from StringIO import StringIO
41 41
42 42 #-----------------------------------------------------------------------------
43 43 # Globals
44 44 #-----------------------------------------------------------------------------
45 45 # This is used by every single test, no point repeating it ad nauseam
46 46 ip = get_ipython()
47 47
48 48 #-----------------------------------------------------------------------------
49 49 # Tests
50 50 #-----------------------------------------------------------------------------
51 51
52 52 class DerivedInterrupt(KeyboardInterrupt):
53 53 pass
54 54
55 55 class InteractiveShellTestCase(unittest.TestCase):
56 56 def test_naked_string_cells(self):
57 57 """Test that cells with only naked strings are fully executed"""
58 58 # First, single-line inputs
59 59 ip.run_cell('"a"\n')
60 60 self.assertEqual(ip.user_ns['_'], 'a')
61 61 # And also multi-line cells
62 62 ip.run_cell('"""a\nb"""\n')
63 63 self.assertEqual(ip.user_ns['_'], 'a\nb')
64 64
65 65 def test_run_empty_cell(self):
66 66 """Just make sure we don't get a horrible error with a blank
67 67 cell of input. Yes, I did overlook that."""
68 68 old_xc = ip.execution_count
69 69 res = ip.run_cell('')
70 70 self.assertEqual(ip.execution_count, old_xc)
71 71 self.assertEqual(res.execution_count, None)
72 72
73 73 def test_run_cell_multiline(self):
74 74 """Multi-block, multi-line cells must execute correctly.
75 75 """
76 76 src = '\n'.join(["x=1",
77 77 "y=2",
78 78 "if 1:",
79 79 " x += 1",
80 80 " y += 1",])
81 81 res = ip.run_cell(src)
82 82 self.assertEqual(ip.user_ns['x'], 2)
83 83 self.assertEqual(ip.user_ns['y'], 3)
84 84 self.assertEqual(res.success, True)
85 85 self.assertEqual(res.result, None)
86 86
87 87 def test_multiline_string_cells(self):
88 88 "Code sprinkled with multiline strings should execute (GH-306)"
89 89 ip.run_cell('tmp=0')
90 90 self.assertEqual(ip.user_ns['tmp'], 0)
91 91 res = ip.run_cell('tmp=1;"""a\nb"""\n')
92 92 self.assertEqual(ip.user_ns['tmp'], 1)
93 93 self.assertEqual(res.success, True)
94 94 self.assertEqual(res.result, "a\nb")
95 95
96 96 def test_dont_cache_with_semicolon(self):
97 97 "Ending a line with semicolon should not cache the returned object (GH-307)"
98 98 oldlen = len(ip.user_ns['Out'])
99 99 for cell in ['1;', '1;1;']:
100 100 res = ip.run_cell(cell, store_history=True)
101 101 newlen = len(ip.user_ns['Out'])
102 102 self.assertEqual(oldlen, newlen)
103 103 self.assertIsNone(res.result)
104 104 i = 0
105 105 #also test the default caching behavior
106 106 for cell in ['1', '1;1']:
107 107 ip.run_cell(cell, store_history=True)
108 108 newlen = len(ip.user_ns['Out'])
109 109 i += 1
110 110 self.assertEqual(oldlen+i, newlen)
111 111
112 112 def test_syntax_error(self):
113 113 res = ip.run_cell("raise = 3")
114 114 self.assertIsInstance(res.error_before_exec, SyntaxError)
115 115
116 116 def test_In_variable(self):
117 117 "Verify that In variable grows with user input (GH-284)"
118 118 oldlen = len(ip.user_ns['In'])
119 119 ip.run_cell('1;', store_history=True)
120 120 newlen = len(ip.user_ns['In'])
121 121 self.assertEqual(oldlen+1, newlen)
122 122 self.assertEqual(ip.user_ns['In'][-1],'1;')
123 123
124 124 def test_magic_names_in_string(self):
125 125 ip.run_cell('a = """\n%exit\n"""')
126 126 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
127 127
128 128 def test_trailing_newline(self):
129 129 """test that running !(command) does not raise a SyntaxError"""
130 130 ip.run_cell('!(true)\n', False)
131 131 ip.run_cell('!(true)\n\n\n', False)
132 132
133 133 def test_gh_597(self):
134 134 """Pretty-printing lists of objects with non-ascii reprs may cause
135 135 problems."""
136 136 class Spam(object):
137 137 def __repr__(self):
138 138 return "\xe9"*50
139 139 import IPython.core.formatters
140 140 f = IPython.core.formatters.PlainTextFormatter()
141 141 f([Spam(),Spam()])
142 142
143 143
144 144 def test_future_flags(self):
145 145 """Check that future flags are used for parsing code (gh-777)"""
146 146 ip.run_cell('from __future__ import barry_as_FLUFL')
147 147 try:
148 148 ip.run_cell('prfunc_return_val = 1 <> 2')
149 149 assert 'prfunc_return_val' in ip.user_ns
150 150 finally:
151 151 # Reset compiler flags so we don't mess up other tests.
152 152 ip.compile.reset_compiler_flags()
153 153
154 154 def test_can_pickle(self):
155 155 "Can we pickle objects defined interactively (GH-29)"
156 156 ip = get_ipython()
157 157 ip.reset()
158 158 ip.run_cell(("class Mylist(list):\n"
159 159 " def __init__(self,x=[]):\n"
160 160 " list.__init__(self,x)"))
161 161 ip.run_cell("w=Mylist([1,2,3])")
162 162
163 163 from pickle import dumps
164 164
165 165 # We need to swap in our main module - this is only necessary
166 166 # inside the test framework, because IPython puts the interactive module
167 167 # in place (but the test framework undoes this).
168 168 _main = sys.modules['__main__']
169 169 sys.modules['__main__'] = ip.user_module
170 170 try:
171 171 res = dumps(ip.user_ns["w"])
172 172 finally:
173 173 sys.modules['__main__'] = _main
174 174 self.assertTrue(isinstance(res, bytes))
175 175
176 176 def test_global_ns(self):
177 177 "Code in functions must be able to access variables outside them."
178 178 ip = get_ipython()
179 179 ip.run_cell("a = 10")
180 180 ip.run_cell(("def f(x):\n"
181 181 " return x + a"))
182 182 ip.run_cell("b = f(12)")
183 183 self.assertEqual(ip.user_ns["b"], 22)
184 184
185 185 def test_bad_custom_tb(self):
186 186 """Check that InteractiveShell is protected from bad custom exception handlers"""
187 187 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
188 188 self.assertEqual(ip.custom_exceptions, (IOError,))
189 189 with tt.AssertPrints("Custom TB Handler failed", channel='stderr'):
190 190 ip.run_cell(u'raise IOError("foo")')
191 191 self.assertEqual(ip.custom_exceptions, ())
192 192
193 193 def test_bad_custom_tb_return(self):
194 194 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
195 195 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
196 196 self.assertEqual(ip.custom_exceptions, (NameError,))
197 197 with tt.AssertPrints("Custom TB Handler failed", channel='stderr'):
198 198 ip.run_cell(u'a=abracadabra')
199 199 self.assertEqual(ip.custom_exceptions, ())
200 200
201 201 def test_drop_by_id(self):
202 202 myvars = {"a":object(), "b":object(), "c": object()}
203 203 ip.push(myvars, interactive=False)
204 204 for name in myvars:
205 205 assert name in ip.user_ns, name
206 206 assert name in ip.user_ns_hidden, name
207 207 ip.user_ns['b'] = 12
208 208 ip.drop_by_id(myvars)
209 209 for name in ["a", "c"]:
210 210 assert name not in ip.user_ns, name
211 211 assert name not in ip.user_ns_hidden, name
212 212 assert ip.user_ns['b'] == 12
213 213 ip.reset()
214 214
215 215 def test_var_expand(self):
216 216 ip.user_ns['f'] = u'Ca\xf1o'
217 217 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
218 218 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
219 219 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
220 220 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
221 221
222 222 ip.user_ns['f'] = b'Ca\xc3\xb1o'
223 223 # This should not raise any exception:
224 224 ip.var_expand(u'echo $f')
225 225
226 226 def test_var_expand_local(self):
227 227 """Test local variable expansion in !system and %magic calls"""
228 228 # !system
229 229 ip.run_cell('def test():\n'
230 230 ' lvar = "ttt"\n'
231 231 ' ret = !echo {lvar}\n'
232 232 ' return ret[0]\n')
233 233 res = ip.user_ns['test']()
234 234 nt.assert_in('ttt', res)
235 235
236 236 # %magic
237 237 ip.run_cell('def makemacro():\n'
238 238 ' macroname = "macro_var_expand_locals"\n'
239 239 ' %macro {macroname} codestr\n')
240 240 ip.user_ns['codestr'] = "str(12)"
241 241 ip.run_cell('makemacro()')
242 242 nt.assert_in('macro_var_expand_locals', ip.user_ns)
243 243
244 244 def test_var_expand_self(self):
245 245 """Test variable expansion with the name 'self', which was failing.
246 246
247 247 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
248 248 """
249 249 ip.run_cell('class cTest:\n'
250 250 ' classvar="see me"\n'
251 251 ' def test(self):\n'
252 252 ' res = !echo Variable: {self.classvar}\n'
253 253 ' return res[0]\n')
254 254 nt.assert_in('see me', ip.user_ns['cTest']().test())
255 255
256 256 def test_bad_var_expand(self):
257 257 """var_expand on invalid formats shouldn't raise"""
258 258 # SyntaxError
259 259 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
260 260 # NameError
261 261 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
262 262 # ZeroDivisionError
263 263 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
264 264
265 265 def test_silent_postexec(self):
266 266 """run_cell(silent=True) doesn't invoke pre/post_run_cell callbacks"""
267 267 pre_explicit = mock.Mock()
268 268 pre_always = mock.Mock()
269 269 post_explicit = mock.Mock()
270 270 post_always = mock.Mock()
271 271
272 272 ip.events.register('pre_run_cell', pre_explicit)
273 273 ip.events.register('pre_execute', pre_always)
274 274 ip.events.register('post_run_cell', post_explicit)
275 275 ip.events.register('post_execute', post_always)
276 276
277 277 try:
278 278 ip.run_cell("1", silent=True)
279 279 assert pre_always.called
280 280 assert not pre_explicit.called
281 281 assert post_always.called
282 282 assert not post_explicit.called
283 283 # double-check that non-silent exec did what we expected
284 284 # silent to avoid
285 285 ip.run_cell("1")
286 286 assert pre_explicit.called
287 287 assert post_explicit.called
288 288 finally:
289 289 # remove post-exec
290 290 ip.events.unregister('pre_run_cell', pre_explicit)
291 291 ip.events.unregister('pre_execute', pre_always)
292 292 ip.events.unregister('post_run_cell', post_explicit)
293 293 ip.events.unregister('post_execute', post_always)
294 294
295 295 def test_silent_noadvance(self):
296 296 """run_cell(silent=True) doesn't advance execution_count"""
297 297 ec = ip.execution_count
298 298 # silent should force store_history=False
299 299 ip.run_cell("1", store_history=True, silent=True)
300 300
301 301 self.assertEqual(ec, ip.execution_count)
302 302 # double-check that non-silent exec did what we expected
303 303 # silent to avoid
304 304 ip.run_cell("1", store_history=True)
305 305 self.assertEqual(ec+1, ip.execution_count)
306 306
307 307 def test_silent_nodisplayhook(self):
308 308 """run_cell(silent=True) doesn't trigger displayhook"""
309 309 d = dict(called=False)
310 310
311 311 trap = ip.display_trap
312 312 save_hook = trap.hook
313 313
314 314 def failing_hook(*args, **kwargs):
315 315 d['called'] = True
316 316
317 317 try:
318 318 trap.hook = failing_hook
319 319 res = ip.run_cell("1", silent=True)
320 320 self.assertFalse(d['called'])
321 321 self.assertIsNone(res.result)
322 322 # double-check that non-silent exec did what we expected
323 323 # silent to avoid
324 324 ip.run_cell("1")
325 325 self.assertTrue(d['called'])
326 326 finally:
327 327 trap.hook = save_hook
328 328
329 329 def test_ofind_line_magic(self):
330 330 from IPython.core.magic import register_line_magic
331 331
332 332 @register_line_magic
333 333 def lmagic(line):
334 334 "A line magic"
335 335
336 336 # Get info on line magic
337 337 lfind = ip._ofind('lmagic')
338 338 info = dict(found=True, isalias=False, ismagic=True,
339 339 namespace = 'IPython internal', obj= lmagic.__wrapped__,
340 340 parent = None)
341 341 nt.assert_equal(lfind, info)
342 342
343 343 def test_ofind_cell_magic(self):
344 344 from IPython.core.magic import register_cell_magic
345 345
346 346 @register_cell_magic
347 347 def cmagic(line, cell):
348 348 "A cell magic"
349 349
350 350 # Get info on cell magic
351 351 find = ip._ofind('cmagic')
352 352 info = dict(found=True, isalias=False, ismagic=True,
353 353 namespace = 'IPython internal', obj= cmagic.__wrapped__,
354 354 parent = None)
355 355 nt.assert_equal(find, info)
356 356
357 357 def test_ofind_property_with_error(self):
358 358 class A(object):
359 359 @property
360 360 def foo(self):
361 361 raise NotImplementedError()
362 362 a = A()
363 363
364 364 found = ip._ofind('a.foo', [('locals', locals())])
365 365 info = dict(found=True, isalias=False, ismagic=False,
366 366 namespace='locals', obj=A.foo, parent=a)
367 367 nt.assert_equal(found, info)
368 368
369 369 def test_ofind_multiple_attribute_lookups(self):
370 370 class A(object):
371 371 @property
372 372 def foo(self):
373 373 raise NotImplementedError()
374 374
375 375 a = A()
376 376 a.a = A()
377 377 a.a.a = A()
378 378
379 379 found = ip._ofind('a.a.a.foo', [('locals', locals())])
380 380 info = dict(found=True, isalias=False, ismagic=False,
381 381 namespace='locals', obj=A.foo, parent=a.a.a)
382 382 nt.assert_equal(found, info)
383 383
384 384 def test_ofind_slotted_attributes(self):
385 385 class A(object):
386 386 __slots__ = ['foo']
387 387 def __init__(self):
388 388 self.foo = 'bar'
389 389
390 390 a = A()
391 391 found = ip._ofind('a.foo', [('locals', locals())])
392 392 info = dict(found=True, isalias=False, ismagic=False,
393 393 namespace='locals', obj=a.foo, parent=a)
394 394 nt.assert_equal(found, info)
395 395
396 396 found = ip._ofind('a.bar', [('locals', locals())])
397 397 info = dict(found=False, isalias=False, ismagic=False,
398 398 namespace=None, obj=None, parent=a)
399 399 nt.assert_equal(found, info)
400 400
401 401 def test_ofind_prefers_property_to_instance_level_attribute(self):
402 402 class A(object):
403 403 @property
404 404 def foo(self):
405 405 return 'bar'
406 406 a = A()
407 407 a.__dict__['foo'] = 'baz'
408 408 nt.assert_equal(a.foo, 'bar')
409 409 found = ip._ofind('a.foo', [('locals', locals())])
410 410 nt.assert_is(found['obj'], A.foo)
411 411
412 412 def test_custom_syntaxerror_exception(self):
413 413 called = []
414 414 def my_handler(shell, etype, value, tb, tb_offset=None):
415 415 called.append(etype)
416 416 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
417 417
418 418 ip.set_custom_exc((SyntaxError,), my_handler)
419 419 try:
420 420 ip.run_cell("1f")
421 421 # Check that this was called, and only once.
422 422 self.assertEqual(called, [SyntaxError])
423 423 finally:
424 424 # Reset the custom exception hook
425 425 ip.set_custom_exc((), None)
426 426
427 427 def test_custom_exception(self):
428 428 called = []
429 429 def my_handler(shell, etype, value, tb, tb_offset=None):
430 430 called.append(etype)
431 431 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
432 432
433 433 ip.set_custom_exc((ValueError,), my_handler)
434 434 try:
435 435 res = ip.run_cell("raise ValueError('test')")
436 436 # Check that this was called, and only once.
437 437 self.assertEqual(called, [ValueError])
438 438 # Check that the error is on the result object
439 439 self.assertIsInstance(res.error_in_exec, ValueError)
440 440 finally:
441 441 # Reset the custom exception hook
442 442 ip.set_custom_exc((), None)
443 443
444 444 def test_mktempfile(self):
445 445 filename = ip.mktempfile()
446 446 # Check that we can open the file again on Windows
447 447 with open(filename, 'w') as f:
448 448 f.write('abc')
449 449
450 450 filename = ip.mktempfile(data='blah')
451 451 with open(filename, 'r') as f:
452 452 self.assertEqual(f.read(), 'blah')
453 453
454 454 def test_new_main_mod(self):
455 455 # Smoketest to check that this accepts a unicode module name
456 456 name = u'jiefmw'
457 457 mod = ip.new_main_mod(u'%s.py' % name, name)
458 458 self.assertEqual(mod.__name__, name)
459 459
460 460 def test_get_exception_only(self):
461 461 try:
462 462 raise KeyboardInterrupt
463 463 except KeyboardInterrupt:
464 464 msg = ip.get_exception_only()
465 465 self.assertEqual(msg, 'KeyboardInterrupt\n')
466 466
467 467 try:
468 468 raise DerivedInterrupt("foo")
469 469 except KeyboardInterrupt:
470 470 msg = ip.get_exception_only()
471 471 self.assertEqual(msg, 'IPython.core.tests.test_interactiveshell.DerivedInterrupt: foo\n')
472 472
473 473 def test_inspect_text(self):
474 474 ip.run_cell('a = 5')
475 475 text = ip.object_inspect_text('a')
476 self.assertIsInstance(text, unicode_type)
476 self.assertIsInstance(text, str)
477 477
478 478
479 479 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
480 480
481 481 @onlyif_unicode_paths
482 482 def setUp(self):
483 483 self.BASETESTDIR = tempfile.mkdtemp()
484 484 self.TESTDIR = join(self.BASETESTDIR, u"åäö")
485 485 os.mkdir(self.TESTDIR)
486 486 with open(join(self.TESTDIR, u"åäötestscript.py"), "w") as sfile:
487 487 sfile.write("pass\n")
488 self.oldpath = py3compat.getcwd()
488 self.oldpath = os.getcwd()
489 489 os.chdir(self.TESTDIR)
490 490 self.fname = u"åäötestscript.py"
491 491
492 492 def tearDown(self):
493 493 os.chdir(self.oldpath)
494 494 shutil.rmtree(self.BASETESTDIR)
495 495
496 496 @onlyif_unicode_paths
497 497 def test_1(self):
498 498 """Test safe_execfile with non-ascii path
499 499 """
500 500 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
501 501
502 502 class ExitCodeChecks(tt.TempFileMixin):
503 503 def test_exit_code_ok(self):
504 504 self.system('exit 0')
505 505 self.assertEqual(ip.user_ns['_exit_code'], 0)
506 506
507 507 def test_exit_code_error(self):
508 508 self.system('exit 1')
509 509 self.assertEqual(ip.user_ns['_exit_code'], 1)
510 510
511 511 @skipif(not hasattr(signal, 'SIGALRM'))
512 512 def test_exit_code_signal(self):
513 513 self.mktmp("import signal, time\n"
514 514 "signal.setitimer(signal.ITIMER_REAL, 0.1)\n"
515 515 "time.sleep(1)\n")
516 516 self.system("%s %s" % (sys.executable, self.fname))
517 517 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGALRM)
518 518
519 519 @onlyif_cmds_exist("csh")
520 520 def test_exit_code_signal_csh(self):
521 521 SHELL = os.environ.get('SHELL', None)
522 522 os.environ['SHELL'] = find_cmd("csh")
523 523 try:
524 524 self.test_exit_code_signal()
525 525 finally:
526 526 if SHELL is not None:
527 527 os.environ['SHELL'] = SHELL
528 528 else:
529 529 del os.environ['SHELL']
530 530
531 531 class TestSystemRaw(unittest.TestCase, ExitCodeChecks):
532 532 system = ip.system_raw
533 533
534 534 @onlyif_unicode_paths
535 535 def test_1(self):
536 536 """Test system_raw with non-ascii cmd
537 537 """
538 538 cmd = u'''python -c "'åäö'" '''
539 539 ip.system_raw(cmd)
540 540
541 541 @mock.patch('subprocess.call', side_effect=KeyboardInterrupt)
542 542 @mock.patch('os.system', side_effect=KeyboardInterrupt)
543 543 def test_control_c(self, *mocks):
544 544 try:
545 545 self.system("sleep 1 # wont happen")
546 546 except KeyboardInterrupt:
547 547 self.fail("system call should intercept "
548 548 "keyboard interrupt from subprocess.call")
549 549 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGINT)
550 550
551 551 # TODO: Exit codes are currently ignored on Windows.
552 552 class TestSystemPipedExitCode(unittest.TestCase, ExitCodeChecks):
553 553 system = ip.system_piped
554 554
555 555 @skip_win32
556 556 def test_exit_code_ok(self):
557 557 ExitCodeChecks.test_exit_code_ok(self)
558 558
559 559 @skip_win32
560 560 def test_exit_code_error(self):
561 561 ExitCodeChecks.test_exit_code_error(self)
562 562
563 563 @skip_win32
564 564 def test_exit_code_signal(self):
565 565 ExitCodeChecks.test_exit_code_signal(self)
566 566
567 567 class TestModules(unittest.TestCase, tt.TempFileMixin):
568 568 def test_extraneous_loads(self):
569 569 """Test we're not loading modules on startup that we shouldn't.
570 570 """
571 571 self.mktmp("import sys\n"
572 572 "print('numpy' in sys.modules)\n"
573 573 "print('ipyparallel' in sys.modules)\n"
574 574 "print('ipykernel' in sys.modules)\n"
575 575 )
576 576 out = "False\nFalse\nFalse\n"
577 577 tt.ipexec_validate(self.fname, out)
578 578
579 579 class Negator(ast.NodeTransformer):
580 580 """Negates all number literals in an AST."""
581 581 def visit_Num(self, node):
582 582 node.n = -node.n
583 583 return node
584 584
585 585 class TestAstTransform(unittest.TestCase):
586 586 def setUp(self):
587 587 self.negator = Negator()
588 588 ip.ast_transformers.append(self.negator)
589 589
590 590 def tearDown(self):
591 591 ip.ast_transformers.remove(self.negator)
592 592
593 593 def test_run_cell(self):
594 594 with tt.AssertPrints('-34'):
595 595 ip.run_cell('print (12 + 22)')
596 596
597 597 # A named reference to a number shouldn't be transformed.
598 598 ip.user_ns['n'] = 55
599 599 with tt.AssertNotPrints('-55'):
600 600 ip.run_cell('print (n)')
601 601
602 602 def test_timeit(self):
603 603 called = set()
604 604 def f(x):
605 605 called.add(x)
606 606 ip.push({'f':f})
607 607
608 608 with tt.AssertPrints("average of "):
609 609 ip.run_line_magic("timeit", "-n1 f(1)")
610 610 self.assertEqual(called, {-1})
611 611 called.clear()
612 612
613 613 with tt.AssertPrints("average of "):
614 614 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
615 615 self.assertEqual(called, {-2, -3})
616 616
617 617 def test_time(self):
618 618 called = []
619 619 def f(x):
620 620 called.append(x)
621 621 ip.push({'f':f})
622 622
623 623 # Test with an expression
624 624 with tt.AssertPrints("Wall time: "):
625 625 ip.run_line_magic("time", "f(5+9)")
626 626 self.assertEqual(called, [-14])
627 627 called[:] = []
628 628
629 629 # Test with a statement (different code path)
630 630 with tt.AssertPrints("Wall time: "):
631 631 ip.run_line_magic("time", "a = f(-3 + -2)")
632 632 self.assertEqual(called, [5])
633 633
634 634 def test_macro(self):
635 635 ip.push({'a':10})
636 636 # The AST transformation makes this do a+=-1
637 637 ip.define_macro("amacro", "a+=1\nprint(a)")
638 638
639 639 with tt.AssertPrints("9"):
640 640 ip.run_cell("amacro")
641 641 with tt.AssertPrints("8"):
642 642 ip.run_cell("amacro")
643 643
644 644 class IntegerWrapper(ast.NodeTransformer):
645 645 """Wraps all integers in a call to Integer()"""
646 646 def visit_Num(self, node):
647 647 if isinstance(node.n, int):
648 648 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
649 649 args=[node], keywords=[])
650 650 return node
651 651
652 652 class TestAstTransform2(unittest.TestCase):
653 653 def setUp(self):
654 654 self.intwrapper = IntegerWrapper()
655 655 ip.ast_transformers.append(self.intwrapper)
656 656
657 657 self.calls = []
658 658 def Integer(*args):
659 659 self.calls.append(args)
660 660 return args
661 661 ip.push({"Integer": Integer})
662 662
663 663 def tearDown(self):
664 664 ip.ast_transformers.remove(self.intwrapper)
665 665 del ip.user_ns['Integer']
666 666
667 667 def test_run_cell(self):
668 668 ip.run_cell("n = 2")
669 669 self.assertEqual(self.calls, [(2,)])
670 670
671 671 # This shouldn't throw an error
672 672 ip.run_cell("o = 2.0")
673 673 self.assertEqual(ip.user_ns['o'], 2.0)
674 674
675 675 def test_timeit(self):
676 676 called = set()
677 677 def f(x):
678 678 called.add(x)
679 679 ip.push({'f':f})
680 680
681 681 with tt.AssertPrints("average of "):
682 682 ip.run_line_magic("timeit", "-n1 f(1)")
683 683 self.assertEqual(called, {(1,)})
684 684 called.clear()
685 685
686 686 with tt.AssertPrints("average of "):
687 687 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
688 688 self.assertEqual(called, {(2,), (3,)})
689 689
690 690 class ErrorTransformer(ast.NodeTransformer):
691 691 """Throws an error when it sees a number."""
692 692 def visit_Num(self, node):
693 693 raise ValueError("test")
694 694
695 695 class TestAstTransformError(unittest.TestCase):
696 696 def test_unregistering(self):
697 697 err_transformer = ErrorTransformer()
698 698 ip.ast_transformers.append(err_transformer)
699 699
700 700 with tt.AssertPrints("unregister", channel='stderr'):
701 701 ip.run_cell("1 + 2")
702 702
703 703 # This should have been removed.
704 704 nt.assert_not_in(err_transformer, ip.ast_transformers)
705 705
706 706
707 707 class StringRejector(ast.NodeTransformer):
708 708 """Throws an InputRejected when it sees a string literal.
709 709
710 710 Used to verify that NodeTransformers can signal that a piece of code should
711 711 not be executed by throwing an InputRejected.
712 712 """
713 713
714 714 def visit_Str(self, node):
715 715 raise InputRejected("test")
716 716
717 717
718 718 class TestAstTransformInputRejection(unittest.TestCase):
719 719
720 720 def setUp(self):
721 721 self.transformer = StringRejector()
722 722 ip.ast_transformers.append(self.transformer)
723 723
724 724 def tearDown(self):
725 725 ip.ast_transformers.remove(self.transformer)
726 726
727 727 def test_input_rejection(self):
728 728 """Check that NodeTransformers can reject input."""
729 729
730 730 expect_exception_tb = tt.AssertPrints("InputRejected: test")
731 731 expect_no_cell_output = tt.AssertNotPrints("'unsafe'", suppress=False)
732 732
733 733 # Run the same check twice to verify that the transformer is not
734 734 # disabled after raising.
735 735 with expect_exception_tb, expect_no_cell_output:
736 736 ip.run_cell("'unsafe'")
737 737
738 738 with expect_exception_tb, expect_no_cell_output:
739 739 res = ip.run_cell("'unsafe'")
740 740
741 741 self.assertIsInstance(res.error_before_exec, InputRejected)
742 742
743 743 def test__IPYTHON__():
744 744 # This shouldn't raise a NameError, that's all
745 745 __IPYTHON__
746 746
747 747
748 748 class DummyRepr(object):
749 749 def __repr__(self):
750 750 return "DummyRepr"
751 751
752 752 def _repr_html_(self):
753 753 return "<b>dummy</b>"
754 754
755 755 def _repr_javascript_(self):
756 756 return "console.log('hi');", {'key': 'value'}
757 757
758 758
759 759 def test_user_variables():
760 760 # enable all formatters
761 761 ip.display_formatter.active_types = ip.display_formatter.format_types
762 762
763 763 ip.user_ns['dummy'] = d = DummyRepr()
764 764 keys = {'dummy', 'doesnotexist'}
765 765 r = ip.user_expressions({ key:key for key in keys})
766 766
767 767 nt.assert_equal(keys, set(r.keys()))
768 768 dummy = r['dummy']
769 769 nt.assert_equal({'status', 'data', 'metadata'}, set(dummy.keys()))
770 770 nt.assert_equal(dummy['status'], 'ok')
771 771 data = dummy['data']
772 772 metadata = dummy['metadata']
773 773 nt.assert_equal(data.get('text/html'), d._repr_html_())
774 774 js, jsmd = d._repr_javascript_()
775 775 nt.assert_equal(data.get('application/javascript'), js)
776 776 nt.assert_equal(metadata.get('application/javascript'), jsmd)
777 777
778 778 dne = r['doesnotexist']
779 779 nt.assert_equal(dne['status'], 'error')
780 780 nt.assert_equal(dne['ename'], 'NameError')
781 781
782 782 # back to text only
783 783 ip.display_formatter.active_types = ['text/plain']
784 784
785 785 def test_user_expression():
786 786 # enable all formatters
787 787 ip.display_formatter.active_types = ip.display_formatter.format_types
788 788 query = {
789 789 'a' : '1 + 2',
790 790 'b' : '1/0',
791 791 }
792 792 r = ip.user_expressions(query)
793 793 import pprint
794 794 pprint.pprint(r)
795 795 nt.assert_equal(set(r.keys()), set(query.keys()))
796 796 a = r['a']
797 797 nt.assert_equal({'status', 'data', 'metadata'}, set(a.keys()))
798 798 nt.assert_equal(a['status'], 'ok')
799 799 data = a['data']
800 800 metadata = a['metadata']
801 801 nt.assert_equal(data.get('text/plain'), '3')
802 802
803 803 b = r['b']
804 804 nt.assert_equal(b['status'], 'error')
805 805 nt.assert_equal(b['ename'], 'ZeroDivisionError')
806 806
807 807 # back to text only
808 808 ip.display_formatter.active_types = ['text/plain']
809 809
810 810
811 811
812 812
813 813
814 814 class TestSyntaxErrorTransformer(unittest.TestCase):
815 815 """Check that SyntaxError raised by an input transformer is handled by run_cell()"""
816 816
817 817 class SyntaxErrorTransformer(InputTransformer):
818 818
819 819 def push(self, line):
820 820 pos = line.find('syntaxerror')
821 821 if pos >= 0:
822 822 e = SyntaxError('input contains "syntaxerror"')
823 823 e.text = line
824 824 e.offset = pos + 1
825 825 raise e
826 826 return line
827 827
828 828 def reset(self):
829 829 pass
830 830
831 831 def setUp(self):
832 832 self.transformer = TestSyntaxErrorTransformer.SyntaxErrorTransformer()
833 833 ip.input_splitter.python_line_transforms.append(self.transformer)
834 834 ip.input_transformer_manager.python_line_transforms.append(self.transformer)
835 835
836 836 def tearDown(self):
837 837 ip.input_splitter.python_line_transforms.remove(self.transformer)
838 838 ip.input_transformer_manager.python_line_transforms.remove(self.transformer)
839 839
840 840 def test_syntaxerror_input_transformer(self):
841 841 with tt.AssertPrints('1234'):
842 842 ip.run_cell('1234')
843 843 with tt.AssertPrints('SyntaxError: invalid syntax'):
844 844 ip.run_cell('1 2 3') # plain python syntax error
845 845 with tt.AssertPrints('SyntaxError: input contains "syntaxerror"'):
846 846 ip.run_cell('2345 # syntaxerror') # input transformer syntax error
847 847 with tt.AssertPrints('3456'):
848 848 ip.run_cell('3456')
849 849
850 850
851 851
852 852 def test_warning_suppression():
853 853 ip.run_cell("import warnings")
854 854 try:
855 855 with tt.AssertPrints("UserWarning: asdf", channel="stderr"):
856 856 ip.run_cell("warnings.warn('asdf')")
857 857 # Here's the real test -- if we run that again, we should get the
858 858 # warning again. Traditionally, each warning was only issued once per
859 859 # IPython session (approximately), even if the user typed in new and
860 860 # different code that should have also triggered the warning, leading
861 861 # to much confusion.
862 862 with tt.AssertPrints("UserWarning: asdf", channel="stderr"):
863 863 ip.run_cell("warnings.warn('asdf')")
864 864 finally:
865 865 ip.run_cell("del warnings")
866 866
867 867
868 868 def test_deprecation_warning():
869 869 ip.run_cell("""
870 870 import warnings
871 871 def wrn():
872 872 warnings.warn(
873 873 "I AM A WARNING",
874 874 DeprecationWarning
875 875 )
876 876 """)
877 877 try:
878 878 with tt.AssertPrints("I AM A WARNING", channel="stderr"):
879 879 ip.run_cell("wrn()")
880 880 finally:
881 881 ip.run_cell("del warnings")
882 882 ip.run_cell("del wrn")
883 883
884 884
885 885 class TestImportNoDeprecate(tt.TempFileMixin):
886 886
887 887 def setup(self):
888 888 """Make a valid python temp file."""
889 889 self.mktmp("""
890 890 import warnings
891 891 def wrn():
892 892 warnings.warn(
893 893 "I AM A WARNING",
894 894 DeprecationWarning
895 895 )
896 896 """)
897 897
898 898 def test_no_dep(self):
899 899 """
900 900 No deprecation warning should be raised from imported functions
901 901 """
902 902 ip.run_cell("from {} import wrn".format(self.fname))
903 903
904 904 with tt.AssertNotPrints("I AM A WARNING"):
905 905 ip.run_cell("wrn()")
906 906 ip.run_cell("del wrn")
@@ -1,987 +1,987 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for various magic functions.
3 3
4 4 Needs to be run by nose (to make ipython session available).
5 5 """
6 6
7 7 import io
8 8 import os
9 9 import sys
10 10 import warnings
11 11 from unittest import TestCase
12 12
13 13 try:
14 14 from importlib import invalidate_caches # Required from Python 3.3
15 15 except ImportError:
16 16 def invalidate_caches():
17 17 pass
18 18
19 19 import nose.tools as nt
20 20
21 21 from IPython import get_ipython
22 22 from IPython.core import magic
23 23 from IPython.core.error import UsageError
24 24 from IPython.core.magic import (Magics, magics_class, line_magic,
25 25 cell_magic,
26 26 register_line_magic, register_cell_magic)
27 27 from IPython.core.magics import execution, script, code
28 28 from IPython.testing import decorators as dec
29 29 from IPython.testing import tools as tt
30 30 from IPython.utils import py3compat
31 31 from IPython.utils.io import capture_output
32 32 from IPython.utils.tempdir import TemporaryDirectory
33 33 from IPython.utils.process import find_cmd
34 34
35 35 if py3compat.PY3:
36 36 from io import StringIO
37 37 else:
38 38 from StringIO import StringIO
39 39
40 40
41 41 _ip = get_ipython()
42 42
43 43 @magic.magics_class
44 44 class DummyMagics(magic.Magics): pass
45 45
46 46 def test_extract_code_ranges():
47 47 instr = "1 3 5-6 7-9 10:15 17: :10 10- -13 :"
48 48 expected = [(0, 1),
49 49 (2, 3),
50 50 (4, 6),
51 51 (6, 9),
52 52 (9, 14),
53 53 (16, None),
54 54 (None, 9),
55 55 (9, None),
56 56 (None, 13),
57 57 (None, None)]
58 58 actual = list(code.extract_code_ranges(instr))
59 59 nt.assert_equal(actual, expected)
60 60
61 61 def test_extract_symbols():
62 62 source = """import foo\na = 10\ndef b():\n return 42\n\n\nclass A: pass\n\n\n"""
63 63 symbols_args = ["a", "b", "A", "A,b", "A,a", "z"]
64 64 expected = [([], ['a']),
65 65 (["def b():\n return 42\n"], []),
66 66 (["class A: pass\n"], []),
67 67 (["class A: pass\n", "def b():\n return 42\n"], []),
68 68 (["class A: pass\n"], ['a']),
69 69 ([], ['z'])]
70 70 for symbols, exp in zip(symbols_args, expected):
71 71 nt.assert_equal(code.extract_symbols(source, symbols), exp)
72 72
73 73
74 74 def test_extract_symbols_raises_exception_with_non_python_code():
75 75 source = ("=begin A Ruby program :)=end\n"
76 76 "def hello\n"
77 77 "puts 'Hello world'\n"
78 78 "end")
79 79 with nt.assert_raises(SyntaxError):
80 80 code.extract_symbols(source, "hello")
81 81
82 82 def test_config():
83 83 """ test that config magic does not raise
84 84 can happen if Configurable init is moved too early into
85 85 Magics.__init__ as then a Config object will be registerd as a
86 86 magic.
87 87 """
88 88 ## should not raise.
89 89 _ip.magic('config')
90 90
91 91 def test_rehashx():
92 92 # clear up everything
93 93 _ip.alias_manager.clear_aliases()
94 94 del _ip.db['syscmdlist']
95 95
96 96 _ip.magic('rehashx')
97 97 # Practically ALL ipython development systems will have more than 10 aliases
98 98
99 99 nt.assert_true(len(_ip.alias_manager.aliases) > 10)
100 100 for name, cmd in _ip.alias_manager.aliases:
101 101 # we must strip dots from alias names
102 102 nt.assert_not_in('.', name)
103 103
104 104 # rehashx must fill up syscmdlist
105 105 scoms = _ip.db['syscmdlist']
106 106 nt.assert_true(len(scoms) > 10)
107 107
108 108
109 109 def test_magic_parse_options():
110 110 """Test that we don't mangle paths when parsing magic options."""
111 111 ip = get_ipython()
112 112 path = 'c:\\x'
113 113 m = DummyMagics(ip)
114 114 opts = m.parse_options('-f %s' % path,'f:')[0]
115 115 # argv splitting is os-dependent
116 116 if os.name == 'posix':
117 117 expected = 'c:x'
118 118 else:
119 119 expected = path
120 120 nt.assert_equal(opts['f'], expected)
121 121
122 122 def test_magic_parse_long_options():
123 123 """Magic.parse_options can handle --foo=bar long options"""
124 124 ip = get_ipython()
125 125 m = DummyMagics(ip)
126 126 opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=')
127 127 nt.assert_in('foo', opts)
128 128 nt.assert_in('bar', opts)
129 129 nt.assert_equal(opts['bar'], "bubble")
130 130
131 131
132 132 @dec.skip_without('sqlite3')
133 133 def doctest_hist_f():
134 134 """Test %hist -f with temporary filename.
135 135
136 136 In [9]: import tempfile
137 137
138 138 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
139 139
140 140 In [11]: %hist -nl -f $tfile 3
141 141
142 142 In [13]: import os; os.unlink(tfile)
143 143 """
144 144
145 145
146 146 @dec.skip_without('sqlite3')
147 147 def doctest_hist_r():
148 148 """Test %hist -r
149 149
150 150 XXX - This test is not recording the output correctly. For some reason, in
151 151 testing mode the raw history isn't getting populated. No idea why.
152 152 Disabling the output checking for now, though at least we do run it.
153 153
154 154 In [1]: 'hist' in _ip.lsmagic()
155 155 Out[1]: True
156 156
157 157 In [2]: x=1
158 158
159 159 In [3]: %hist -rl 2
160 160 x=1 # random
161 161 %hist -r 2
162 162 """
163 163
164 164
165 165 @dec.skip_without('sqlite3')
166 166 def doctest_hist_op():
167 167 """Test %hist -op
168 168
169 169 In [1]: class b(float):
170 170 ...: pass
171 171 ...:
172 172
173 173 In [2]: class s(object):
174 174 ...: def __str__(self):
175 175 ...: return 's'
176 176 ...:
177 177
178 178 In [3]:
179 179
180 180 In [4]: class r(b):
181 181 ...: def __repr__(self):
182 182 ...: return 'r'
183 183 ...:
184 184
185 185 In [5]: class sr(s,r): pass
186 186 ...:
187 187
188 188 In [6]:
189 189
190 190 In [7]: bb=b()
191 191
192 192 In [8]: ss=s()
193 193
194 194 In [9]: rr=r()
195 195
196 196 In [10]: ssrr=sr()
197 197
198 198 In [11]: 4.5
199 199 Out[11]: 4.5
200 200
201 201 In [12]: str(ss)
202 202 Out[12]: 's'
203 203
204 204 In [13]:
205 205
206 206 In [14]: %hist -op
207 207 >>> class b:
208 208 ... pass
209 209 ...
210 210 >>> class s(b):
211 211 ... def __str__(self):
212 212 ... return 's'
213 213 ...
214 214 >>>
215 215 >>> class r(b):
216 216 ... def __repr__(self):
217 217 ... return 'r'
218 218 ...
219 219 >>> class sr(s,r): pass
220 220 >>>
221 221 >>> bb=b()
222 222 >>> ss=s()
223 223 >>> rr=r()
224 224 >>> ssrr=sr()
225 225 >>> 4.5
226 226 4.5
227 227 >>> str(ss)
228 228 's'
229 229 >>>
230 230 """
231 231
232 232 def test_hist_pof():
233 233 ip = get_ipython()
234 234 ip.run_cell(u"1+2", store_history=True)
235 235 #raise Exception(ip.history_manager.session_number)
236 236 #raise Exception(list(ip.history_manager._get_range_session()))
237 237 with TemporaryDirectory() as td:
238 238 tf = os.path.join(td, 'hist.py')
239 239 ip.run_line_magic('history', '-pof %s' % tf)
240 240 assert os.path.isfile(tf)
241 241
242 242
243 243 @dec.skip_without('sqlite3')
244 244 def test_macro():
245 245 ip = get_ipython()
246 246 ip.history_manager.reset() # Clear any existing history.
247 247 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
248 248 for i, cmd in enumerate(cmds, start=1):
249 249 ip.history_manager.store_inputs(i, cmd)
250 250 ip.magic("macro test 1-3")
251 251 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
252 252
253 253 # List macros
254 254 nt.assert_in("test", ip.magic("macro"))
255 255
256 256
257 257 @dec.skip_without('sqlite3')
258 258 def test_macro_run():
259 259 """Test that we can run a multi-line macro successfully."""
260 260 ip = get_ipython()
261 261 ip.history_manager.reset()
262 262 cmds = ["a=10", "a+=1", py3compat.doctest_refactor_print("print a"),
263 263 "%macro test 2-3"]
264 264 for cmd in cmds:
265 265 ip.run_cell(cmd, store_history=True)
266 266 nt.assert_equal(ip.user_ns["test"].value,
267 267 py3compat.doctest_refactor_print("a+=1\nprint a\n"))
268 268 with tt.AssertPrints("12"):
269 269 ip.run_cell("test")
270 270 with tt.AssertPrints("13"):
271 271 ip.run_cell("test")
272 272
273 273
274 274 def test_magic_magic():
275 275 """Test %magic"""
276 276 ip = get_ipython()
277 277 with capture_output() as captured:
278 278 ip.magic("magic")
279 279
280 280 stdout = captured.stdout
281 281 nt.assert_in('%magic', stdout)
282 282 nt.assert_in('IPython', stdout)
283 283 nt.assert_in('Available', stdout)
284 284
285 285
286 286 @dec.skipif_not_numpy
287 287 def test_numpy_reset_array_undec():
288 288 "Test '%reset array' functionality"
289 289 _ip.ex('import numpy as np')
290 290 _ip.ex('a = np.empty(2)')
291 291 nt.assert_in('a', _ip.user_ns)
292 292 _ip.magic('reset -f array')
293 293 nt.assert_not_in('a', _ip.user_ns)
294 294
295 295 def test_reset_out():
296 296 "Test '%reset out' magic"
297 297 _ip.run_cell("parrot = 'dead'", store_history=True)
298 298 # test '%reset -f out', make an Out prompt
299 299 _ip.run_cell("parrot", store_history=True)
300 300 nt.assert_true('dead' in [_ip.user_ns[x] for x in ('_','__','___')])
301 301 _ip.magic('reset -f out')
302 302 nt.assert_false('dead' in [_ip.user_ns[x] for x in ('_','__','___')])
303 303 nt.assert_equal(len(_ip.user_ns['Out']), 0)
304 304
305 305 def test_reset_in():
306 306 "Test '%reset in' magic"
307 307 # test '%reset -f in'
308 308 _ip.run_cell("parrot", store_history=True)
309 309 nt.assert_true('parrot' in [_ip.user_ns[x] for x in ('_i','_ii','_iii')])
310 310 _ip.magic('%reset -f in')
311 311 nt.assert_false('parrot' in [_ip.user_ns[x] for x in ('_i','_ii','_iii')])
312 312 nt.assert_equal(len(set(_ip.user_ns['In'])), 1)
313 313
314 314 def test_reset_dhist():
315 315 "Test '%reset dhist' magic"
316 316 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
317 317 _ip.magic('cd ' + os.path.dirname(nt.__file__))
318 318 _ip.magic('cd -')
319 319 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
320 320 _ip.magic('reset -f dhist')
321 321 nt.assert_equal(len(_ip.user_ns['_dh']), 0)
322 322 _ip.run_cell("_dh = [d for d in tmp]") #restore
323 323
324 324 def test_reset_in_length():
325 325 "Test that '%reset in' preserves In[] length"
326 326 _ip.run_cell("print 'foo'")
327 327 _ip.run_cell("reset -f in")
328 328 nt.assert_equal(len(_ip.user_ns['In']), _ip.displayhook.prompt_count+1)
329 329
330 330 def test_tb_syntaxerror():
331 331 """test %tb after a SyntaxError"""
332 332 ip = get_ipython()
333 333 ip.run_cell("for")
334 334
335 335 # trap and validate stdout
336 336 save_stdout = sys.stdout
337 337 try:
338 338 sys.stdout = StringIO()
339 339 ip.run_cell("%tb")
340 340 out = sys.stdout.getvalue()
341 341 finally:
342 342 sys.stdout = save_stdout
343 343 # trim output, and only check the last line
344 344 last_line = out.rstrip().splitlines()[-1].strip()
345 345 nt.assert_equal(last_line, "SyntaxError: invalid syntax")
346 346
347 347
348 348 def test_time():
349 349 ip = get_ipython()
350 350
351 351 with tt.AssertPrints("Wall time: "):
352 352 ip.run_cell("%time None")
353 353
354 354 ip.run_cell("def f(kmjy):\n"
355 355 " %time print (2*kmjy)")
356 356
357 357 with tt.AssertPrints("Wall time: "):
358 358 with tt.AssertPrints("hihi", suppress=False):
359 359 ip.run_cell("f('hi')")
360 360
361 361
362 362 @dec.skip_win32
363 363 def test_time2():
364 364 ip = get_ipython()
365 365
366 366 with tt.AssertPrints("CPU times: user "):
367 367 ip.run_cell("%time None")
368 368
369 369 def test_time3():
370 370 """Erroneous magic function calls, issue gh-3334"""
371 371 ip = get_ipython()
372 372 ip.user_ns.pop('run', None)
373 373
374 374 with tt.AssertNotPrints("not found", channel='stderr'):
375 375 ip.run_cell("%%time\n"
376 376 "run = 0\n"
377 377 "run += 1")
378 378
379 379 def test_doctest_mode():
380 380 "Toggle doctest_mode twice, it should be a no-op and run without error"
381 381 _ip.magic('doctest_mode')
382 382 _ip.magic('doctest_mode')
383 383
384 384
385 385 def test_parse_options():
386 386 """Tests for basic options parsing in magics."""
387 387 # These are only the most minimal of tests, more should be added later. At
388 388 # the very least we check that basic text/unicode calls work OK.
389 389 m = DummyMagics(_ip)
390 390 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
391 391 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
392 392
393 393
394 394 def test_dirops():
395 395 """Test various directory handling operations."""
396 # curpath = lambda :os.path.splitdrive(py3compat.getcwd())[1].replace('\\','/')
397 curpath = py3compat.getcwd
398 startdir = py3compat.getcwd()
396 # curpath = lambda :os.path.splitdrive(os.getcwd())[1].replace('\\','/')
397 curpath = os.getcwd
398 startdir = os.getcwd()
399 399 ipdir = os.path.realpath(_ip.ipython_dir)
400 400 try:
401 401 _ip.magic('cd "%s"' % ipdir)
402 402 nt.assert_equal(curpath(), ipdir)
403 403 _ip.magic('cd -')
404 404 nt.assert_equal(curpath(), startdir)
405 405 _ip.magic('pushd "%s"' % ipdir)
406 406 nt.assert_equal(curpath(), ipdir)
407 407 _ip.magic('popd')
408 408 nt.assert_equal(curpath(), startdir)
409 409 finally:
410 410 os.chdir(startdir)
411 411
412 412
413 413 def test_xmode():
414 414 # Calling xmode three times should be a no-op
415 415 xmode = _ip.InteractiveTB.mode
416 416 for i in range(3):
417 417 _ip.magic("xmode")
418 418 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
419 419
420 420 def test_reset_hard():
421 421 monitor = []
422 422 class A(object):
423 423 def __del__(self):
424 424 monitor.append(1)
425 425 def __repr__(self):
426 426 return "<A instance>"
427 427
428 428 _ip.user_ns["a"] = A()
429 429 _ip.run_cell("a")
430 430
431 431 nt.assert_equal(monitor, [])
432 432 _ip.magic("reset -f")
433 433 nt.assert_equal(monitor, [1])
434 434
435 435 class TestXdel(tt.TempFileMixin):
436 436 def test_xdel(self):
437 437 """Test that references from %run are cleared by xdel."""
438 438 src = ("class A(object):\n"
439 439 " monitor = []\n"
440 440 " def __del__(self):\n"
441 441 " self.monitor.append(1)\n"
442 442 "a = A()\n")
443 443 self.mktmp(src)
444 444 # %run creates some hidden references...
445 445 _ip.magic("run %s" % self.fname)
446 446 # ... as does the displayhook.
447 447 _ip.run_cell("a")
448 448
449 449 monitor = _ip.user_ns["A"].monitor
450 450 nt.assert_equal(monitor, [])
451 451
452 452 _ip.magic("xdel a")
453 453
454 454 # Check that a's __del__ method has been called.
455 455 nt.assert_equal(monitor, [1])
456 456
457 457 def doctest_who():
458 458 """doctest for %who
459 459
460 460 In [1]: %reset -f
461 461
462 462 In [2]: alpha = 123
463 463
464 464 In [3]: beta = 'beta'
465 465
466 466 In [4]: %who int
467 467 alpha
468 468
469 469 In [5]: %who str
470 470 beta
471 471
472 472 In [6]: %whos
473 473 Variable Type Data/Info
474 474 ----------------------------
475 475 alpha int 123
476 476 beta str beta
477 477
478 478 In [7]: %who_ls
479 479 Out[7]: ['alpha', 'beta']
480 480 """
481 481
482 482 def test_whos():
483 483 """Check that whos is protected against objects where repr() fails."""
484 484 class A(object):
485 485 def __repr__(self):
486 486 raise Exception()
487 487 _ip.user_ns['a'] = A()
488 488 _ip.magic("whos")
489 489
490 490 @py3compat.u_format
491 491 def doctest_precision():
492 492 """doctest for %precision
493 493
494 494 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
495 495
496 496 In [2]: %precision 5
497 497 Out[2]: {u}'%.5f'
498 498
499 499 In [3]: f.float_format
500 500 Out[3]: {u}'%.5f'
501 501
502 502 In [4]: %precision %e
503 503 Out[4]: {u}'%e'
504 504
505 505 In [5]: f(3.1415927)
506 506 Out[5]: {u}'3.141593e+00'
507 507 """
508 508
509 509 def test_psearch():
510 510 with tt.AssertPrints("dict.fromkeys"):
511 511 _ip.run_cell("dict.fr*?")
512 512
513 513 def test_timeit_shlex():
514 514 """test shlex issues with timeit (#1109)"""
515 515 _ip.ex("def f(*a,**kw): pass")
516 516 _ip.magic('timeit -n1 "this is a bug".count(" ")')
517 517 _ip.magic('timeit -r1 -n1 f(" ", 1)')
518 518 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
519 519 _ip.magic('timeit -r1 -n1 ("a " + "b")')
520 520 _ip.magic('timeit -r1 -n1 f("a " + "b")')
521 521 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
522 522
523 523
524 524 def test_timeit_arguments():
525 525 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
526 526 _ip.magic("timeit ('#')")
527 527
528 528
529 529 def test_timeit_special_syntax():
530 530 "Test %%timeit with IPython special syntax"
531 531 @register_line_magic
532 532 def lmagic(line):
533 533 ip = get_ipython()
534 534 ip.user_ns['lmagic_out'] = line
535 535
536 536 # line mode test
537 537 _ip.run_line_magic('timeit', '-n1 -r1 %lmagic my line')
538 538 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
539 539 # cell mode test
540 540 _ip.run_cell_magic('timeit', '-n1 -r1', '%lmagic my line2')
541 541 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
542 542
543 543 def test_timeit_return():
544 544 """
545 545 test wether timeit -o return object
546 546 """
547 547
548 548 res = _ip.run_line_magic('timeit','-n10 -r10 -o 1')
549 549 assert(res is not None)
550 550
551 551 def test_timeit_quiet():
552 552 """
553 553 test quiet option of timeit magic
554 554 """
555 555 with tt.AssertNotPrints("loops"):
556 556 _ip.run_cell("%timeit -n1 -r1 -q 1")
557 557
558 558 def test_timeit_return_quiet():
559 559 with tt.AssertNotPrints("loops"):
560 560 res = _ip.run_line_magic('timeit', '-n1 -r1 -q -o 1')
561 561 assert (res is not None)
562 562
563 563 @dec.skipif(execution.profile is None)
564 564 def test_prun_special_syntax():
565 565 "Test %%prun with IPython special syntax"
566 566 @register_line_magic
567 567 def lmagic(line):
568 568 ip = get_ipython()
569 569 ip.user_ns['lmagic_out'] = line
570 570
571 571 # line mode test
572 572 _ip.run_line_magic('prun', '-q %lmagic my line')
573 573 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
574 574 # cell mode test
575 575 _ip.run_cell_magic('prun', '-q', '%lmagic my line2')
576 576 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
577 577
578 578 @dec.skipif(execution.profile is None)
579 579 def test_prun_quotes():
580 580 "Test that prun does not clobber string escapes (GH #1302)"
581 581 _ip.magic(r"prun -q x = '\t'")
582 582 nt.assert_equal(_ip.user_ns['x'], '\t')
583 583
584 584 def test_extension():
585 585 # Debugging information for failures of this test
586 586 print('sys.path:')
587 587 for p in sys.path:
588 588 print(' ', p)
589 589 print('CWD', os.getcwd())
590 590
591 591 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
592 592 daft_path = os.path.join(os.path.dirname(__file__), "daft_extension")
593 593 sys.path.insert(0, daft_path)
594 594 try:
595 595 _ip.user_ns.pop('arq', None)
596 596 invalidate_caches() # Clear import caches
597 597 _ip.magic("load_ext daft_extension")
598 598 nt.assert_equal(_ip.user_ns['arq'], 185)
599 599 _ip.magic("unload_ext daft_extension")
600 600 assert 'arq' not in _ip.user_ns
601 601 finally:
602 602 sys.path.remove(daft_path)
603 603
604 604
605 605 def test_notebook_export_json():
606 606 _ip = get_ipython()
607 607 _ip.history_manager.reset() # Clear any existing history.
608 608 cmds = [u"a=1", u"def b():\n return a**2", u"print('noël, été', b())"]
609 609 for i, cmd in enumerate(cmds, start=1):
610 610 _ip.history_manager.store_inputs(i, cmd)
611 611 with TemporaryDirectory() as td:
612 612 outfile = os.path.join(td, "nb.ipynb")
613 613 _ip.magic("notebook -e %s" % outfile)
614 614
615 615
616 616 class TestEnv(TestCase):
617 617
618 618 def test_env(self):
619 619 env = _ip.magic("env")
620 620 self.assertTrue(isinstance(env, dict))
621 621
622 622 def test_env_get_set_simple(self):
623 623 env = _ip.magic("env var val1")
624 624 self.assertEqual(env, None)
625 625 self.assertEqual(os.environ['var'], 'val1')
626 626 self.assertEqual(_ip.magic("env var"), 'val1')
627 627 env = _ip.magic("env var=val2")
628 628 self.assertEqual(env, None)
629 629 self.assertEqual(os.environ['var'], 'val2')
630 630
631 631 def test_env_get_set_complex(self):
632 632 env = _ip.magic("env var 'val1 '' 'val2")
633 633 self.assertEqual(env, None)
634 634 self.assertEqual(os.environ['var'], "'val1 '' 'val2")
635 635 self.assertEqual(_ip.magic("env var"), "'val1 '' 'val2")
636 636 env = _ip.magic('env var=val2 val3="val4')
637 637 self.assertEqual(env, None)
638 638 self.assertEqual(os.environ['var'], 'val2 val3="val4')
639 639
640 640 def test_env_set_bad_input(self):
641 641 self.assertRaises(UsageError, lambda: _ip.magic("set_env var"))
642 642
643 643 def test_env_set_whitespace(self):
644 644 self.assertRaises(UsageError, lambda: _ip.magic("env var A=B"))
645 645
646 646
647 647 class CellMagicTestCase(TestCase):
648 648
649 649 def check_ident(self, magic):
650 650 # Manually called, we get the result
651 651 out = _ip.run_cell_magic(magic, 'a', 'b')
652 652 nt.assert_equal(out, ('a','b'))
653 653 # Via run_cell, it goes into the user's namespace via displayhook
654 654 _ip.run_cell('%%' + magic +' c\nd')
655 655 nt.assert_equal(_ip.user_ns['_'], ('c','d'))
656 656
657 657 def test_cell_magic_func_deco(self):
658 658 "Cell magic using simple decorator"
659 659 @register_cell_magic
660 660 def cellm(line, cell):
661 661 return line, cell
662 662
663 663 self.check_ident('cellm')
664 664
665 665 def test_cell_magic_reg(self):
666 666 "Cell magic manually registered"
667 667 def cellm(line, cell):
668 668 return line, cell
669 669
670 670 _ip.register_magic_function(cellm, 'cell', 'cellm2')
671 671 self.check_ident('cellm2')
672 672
673 673 def test_cell_magic_class(self):
674 674 "Cell magics declared via a class"
675 675 @magics_class
676 676 class MyMagics(Magics):
677 677
678 678 @cell_magic
679 679 def cellm3(self, line, cell):
680 680 return line, cell
681 681
682 682 _ip.register_magics(MyMagics)
683 683 self.check_ident('cellm3')
684 684
685 685 def test_cell_magic_class2(self):
686 686 "Cell magics declared via a class, #2"
687 687 @magics_class
688 688 class MyMagics2(Magics):
689 689
690 690 @cell_magic('cellm4')
691 691 def cellm33(self, line, cell):
692 692 return line, cell
693 693
694 694 _ip.register_magics(MyMagics2)
695 695 self.check_ident('cellm4')
696 696 # Check that nothing is registered as 'cellm33'
697 697 c33 = _ip.find_cell_magic('cellm33')
698 698 nt.assert_equal(c33, None)
699 699
700 700 def test_file():
701 701 """Basic %%file"""
702 702 ip = get_ipython()
703 703 with TemporaryDirectory() as td:
704 704 fname = os.path.join(td, 'file1')
705 705 ip.run_cell_magic("file", fname, u'\n'.join([
706 706 'line1',
707 707 'line2',
708 708 ]))
709 709 with open(fname) as f:
710 710 s = f.read()
711 711 nt.assert_in('line1\n', s)
712 712 nt.assert_in('line2', s)
713 713
714 714 def test_file_var_expand():
715 715 """%%file $filename"""
716 716 ip = get_ipython()
717 717 with TemporaryDirectory() as td:
718 718 fname = os.path.join(td, 'file1')
719 719 ip.user_ns['filename'] = fname
720 720 ip.run_cell_magic("file", '$filename', u'\n'.join([
721 721 'line1',
722 722 'line2',
723 723 ]))
724 724 with open(fname) as f:
725 725 s = f.read()
726 726 nt.assert_in('line1\n', s)
727 727 nt.assert_in('line2', s)
728 728
729 729 def test_file_unicode():
730 730 """%%file with unicode cell"""
731 731 ip = get_ipython()
732 732 with TemporaryDirectory() as td:
733 733 fname = os.path.join(td, 'file1')
734 734 ip.run_cell_magic("file", fname, u'\n'.join([
735 735 u'liné1',
736 736 u'liné2',
737 737 ]))
738 738 with io.open(fname, encoding='utf-8') as f:
739 739 s = f.read()
740 740 nt.assert_in(u'liné1\n', s)
741 741 nt.assert_in(u'liné2', s)
742 742
743 743 def test_file_amend():
744 744 """%%file -a amends files"""
745 745 ip = get_ipython()
746 746 with TemporaryDirectory() as td:
747 747 fname = os.path.join(td, 'file2')
748 748 ip.run_cell_magic("file", fname, u'\n'.join([
749 749 'line1',
750 750 'line2',
751 751 ]))
752 752 ip.run_cell_magic("file", "-a %s" % fname, u'\n'.join([
753 753 'line3',
754 754 'line4',
755 755 ]))
756 756 with open(fname) as f:
757 757 s = f.read()
758 758 nt.assert_in('line1\n', s)
759 759 nt.assert_in('line3\n', s)
760 760
761 761
762 762 def test_script_config():
763 763 ip = get_ipython()
764 764 ip.config.ScriptMagics.script_magics = ['whoda']
765 765 sm = script.ScriptMagics(shell=ip)
766 766 nt.assert_in('whoda', sm.magics['cell'])
767 767
768 768 @dec.skip_win32
769 769 def test_script_out():
770 770 ip = get_ipython()
771 771 ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
772 772 nt.assert_equal(ip.user_ns['output'], 'hi\n')
773 773
774 774 @dec.skip_win32
775 775 def test_script_err():
776 776 ip = get_ipython()
777 777 ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
778 778 nt.assert_equal(ip.user_ns['error'], 'hello\n')
779 779
780 780 @dec.skip_win32
781 781 def test_script_out_err():
782 782 ip = get_ipython()
783 783 ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
784 784 nt.assert_equal(ip.user_ns['output'], 'hi\n')
785 785 nt.assert_equal(ip.user_ns['error'], 'hello\n')
786 786
787 787 @dec.skip_win32
788 788 def test_script_bg_out():
789 789 ip = get_ipython()
790 790 ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
791 791 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
792 792
793 793 @dec.skip_win32
794 794 def test_script_bg_err():
795 795 ip = get_ipython()
796 796 ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
797 797 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
798 798
799 799 @dec.skip_win32
800 800 def test_script_bg_out_err():
801 801 ip = get_ipython()
802 802 ip.run_cell_magic("script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2")
803 803 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
804 804 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
805 805
806 806 def test_script_defaults():
807 807 ip = get_ipython()
808 808 for cmd in ['sh', 'bash', 'perl', 'ruby']:
809 809 try:
810 810 find_cmd(cmd)
811 811 except Exception:
812 812 pass
813 813 else:
814 814 nt.assert_in(cmd, ip.magics_manager.magics['cell'])
815 815
816 816
817 817 @magics_class
818 818 class FooFoo(Magics):
819 819 """class with both %foo and %%foo magics"""
820 820 @line_magic('foo')
821 821 def line_foo(self, line):
822 822 "I am line foo"
823 823 pass
824 824
825 825 @cell_magic("foo")
826 826 def cell_foo(self, line, cell):
827 827 "I am cell foo, not line foo"
828 828 pass
829 829
830 830 def test_line_cell_info():
831 831 """%%foo and %foo magics are distinguishable to inspect"""
832 832 ip = get_ipython()
833 833 ip.magics_manager.register(FooFoo)
834 834 oinfo = ip.object_inspect('foo')
835 835 nt.assert_true(oinfo['found'])
836 836 nt.assert_true(oinfo['ismagic'])
837 837
838 838 oinfo = ip.object_inspect('%%foo')
839 839 nt.assert_true(oinfo['found'])
840 840 nt.assert_true(oinfo['ismagic'])
841 841 nt.assert_equal(oinfo['docstring'], FooFoo.cell_foo.__doc__)
842 842
843 843 oinfo = ip.object_inspect('%foo')
844 844 nt.assert_true(oinfo['found'])
845 845 nt.assert_true(oinfo['ismagic'])
846 846 nt.assert_equal(oinfo['docstring'], FooFoo.line_foo.__doc__)
847 847
848 848 def test_multiple_magics():
849 849 ip = get_ipython()
850 850 foo1 = FooFoo(ip)
851 851 foo2 = FooFoo(ip)
852 852 mm = ip.magics_manager
853 853 mm.register(foo1)
854 854 nt.assert_true(mm.magics['line']['foo'].__self__ is foo1)
855 855 mm.register(foo2)
856 856 nt.assert_true(mm.magics['line']['foo'].__self__ is foo2)
857 857
858 858 def test_alias_magic():
859 859 """Test %alias_magic."""
860 860 ip = get_ipython()
861 861 mm = ip.magics_manager
862 862
863 863 # Basic operation: both cell and line magics are created, if possible.
864 864 ip.run_line_magic('alias_magic', 'timeit_alias timeit')
865 865 nt.assert_in('timeit_alias', mm.magics['line'])
866 866 nt.assert_in('timeit_alias', mm.magics['cell'])
867 867
868 868 # --cell is specified, line magic not created.
869 869 ip.run_line_magic('alias_magic', '--cell timeit_cell_alias timeit')
870 870 nt.assert_not_in('timeit_cell_alias', mm.magics['line'])
871 871 nt.assert_in('timeit_cell_alias', mm.magics['cell'])
872 872
873 873 # Test that line alias is created successfully.
874 874 ip.run_line_magic('alias_magic', '--line env_alias env')
875 875 nt.assert_equal(ip.run_line_magic('env', ''),
876 876 ip.run_line_magic('env_alias', ''))
877 877
878 878 def test_save():
879 879 """Test %save."""
880 880 ip = get_ipython()
881 881 ip.history_manager.reset() # Clear any existing history.
882 882 cmds = [u"a=1", u"def b():\n return a**2", u"print(a, b())"]
883 883 for i, cmd in enumerate(cmds, start=1):
884 884 ip.history_manager.store_inputs(i, cmd)
885 885 with TemporaryDirectory() as tmpdir:
886 886 file = os.path.join(tmpdir, "testsave.py")
887 887 ip.run_line_magic("save", "%s 1-10" % file)
888 888 with open(file) as f:
889 889 content = f.read()
890 890 nt.assert_equal(content.count(cmds[0]), 1)
891 891 nt.assert_in('coding: utf-8', content)
892 892 ip.run_line_magic("save", "-a %s 1-10" % file)
893 893 with open(file) as f:
894 894 content = f.read()
895 895 nt.assert_equal(content.count(cmds[0]), 2)
896 896 nt.assert_in('coding: utf-8', content)
897 897
898 898
899 899 def test_store():
900 900 """Test %store."""
901 901 ip = get_ipython()
902 902 ip.run_line_magic('load_ext', 'storemagic')
903 903
904 904 # make sure the storage is empty
905 905 ip.run_line_magic('store', '-z')
906 906 ip.user_ns['var'] = 42
907 907 ip.run_line_magic('store', 'var')
908 908 ip.user_ns['var'] = 39
909 909 ip.run_line_magic('store', '-r')
910 910 nt.assert_equal(ip.user_ns['var'], 42)
911 911
912 912 ip.run_line_magic('store', '-d var')
913 913 ip.user_ns['var'] = 39
914 914 ip.run_line_magic('store' , '-r')
915 915 nt.assert_equal(ip.user_ns['var'], 39)
916 916
917 917
918 918 def _run_edit_test(arg_s, exp_filename=None,
919 919 exp_lineno=-1,
920 920 exp_contents=None,
921 921 exp_is_temp=None):
922 922 ip = get_ipython()
923 923 M = code.CodeMagics(ip)
924 924 last_call = ['','']
925 925 opts,args = M.parse_options(arg_s,'prxn:')
926 926 filename, lineno, is_temp = M._find_edit_target(ip, args, opts, last_call)
927 927
928 928 if exp_filename is not None:
929 929 nt.assert_equal(exp_filename, filename)
930 930 if exp_contents is not None:
931 931 with io.open(filename, 'r', encoding='utf-8') as f:
932 932 contents = f.read()
933 933 nt.assert_equal(exp_contents, contents)
934 934 if exp_lineno != -1:
935 935 nt.assert_equal(exp_lineno, lineno)
936 936 if exp_is_temp is not None:
937 937 nt.assert_equal(exp_is_temp, is_temp)
938 938
939 939
940 940 def test_edit_interactive():
941 941 """%edit on interactively defined objects"""
942 942 ip = get_ipython()
943 943 n = ip.execution_count
944 944 ip.run_cell(u"def foo(): return 1", store_history=True)
945 945
946 946 try:
947 947 _run_edit_test("foo")
948 948 except code.InteractivelyDefined as e:
949 949 nt.assert_equal(e.index, n)
950 950 else:
951 951 raise AssertionError("Should have raised InteractivelyDefined")
952 952
953 953
954 954 def test_edit_cell():
955 955 """%edit [cell id]"""
956 956 ip = get_ipython()
957 957
958 958 ip.run_cell(u"def foo(): return 1", store_history=True)
959 959
960 960 # test
961 961 _run_edit_test("1", exp_contents=ip.user_ns['In'][1], exp_is_temp=True)
962 962
963 963 def test_bookmark():
964 964 ip = get_ipython()
965 965 ip.run_line_magic('bookmark', 'bmname')
966 966 with tt.AssertPrints('bmname'):
967 967 ip.run_line_magic('bookmark', '-l')
968 968 ip.run_line_magic('bookmark', '-d bmname')
969 969
970 970 def test_ls_magic():
971 971 ip = get_ipython()
972 972 json_formatter = ip.display_formatter.formatters['application/json']
973 973 json_formatter.enabled = True
974 974 lsmagic = ip.magic('lsmagic')
975 975 with warnings.catch_warnings(record=True) as w:
976 976 j = json_formatter(lsmagic)
977 977 nt.assert_equal(sorted(j), ['cell', 'line'])
978 978 nt.assert_equal(w, []) # no warnings
979 979
980 980 def test_strip_initial_indent():
981 981 def sii(s):
982 982 lines = s.splitlines()
983 983 return '\n'.join(code.strip_initial_indent(lines))
984 984
985 985 nt.assert_equal(sii(" a = 1\nb = 2"), "a = 1\nb = 2")
986 986 nt.assert_equal(sii(" a\n b\nc"), "a\n b\nc")
987 987 nt.assert_equal(sii("a\n b"), "a\n b")
@@ -1,164 +1,163 b''
1 1 # coding: utf-8
2 2 """Tests for profile-related functions.
3 3
4 4 Currently only the startup-dir functionality is tested, but more tests should
5 5 be added for:
6 6
7 7 * ipython profile create
8 8 * ipython profile list
9 9 * ipython profile create --parallel
10 10 * security dir permissions
11 11
12 12 Authors
13 13 -------
14 14
15 15 * MinRK
16 16
17 17 """
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 import os
24 24 import shutil
25 25 import sys
26 26 import tempfile
27 27
28 28 from unittest import TestCase
29 29
30 30 import nose.tools as nt
31 31
32 32 from IPython.core.profileapp import list_profiles_in, list_bundled_profiles
33 33 from IPython.core.profiledir import ProfileDir
34 34
35 35 from IPython.testing import decorators as dec
36 36 from IPython.testing import tools as tt
37 37 from IPython.utils import py3compat
38 38 from IPython.utils.process import getoutput
39 39 from IPython.utils.tempdir import TemporaryDirectory
40 40
41 41 #-----------------------------------------------------------------------------
42 42 # Globals
43 43 #-----------------------------------------------------------------------------
44 44 TMP_TEST_DIR = tempfile.mkdtemp()
45 45 HOME_TEST_DIR = os.path.join(TMP_TEST_DIR, "home_test_dir")
46 46 IP_TEST_DIR = os.path.join(HOME_TEST_DIR,'.ipython')
47 47
48 48 #
49 49 # Setup/teardown functions/decorators
50 50 #
51 51
52 52 def setup():
53 53 """Setup test environment for the module:
54 54
55 55 - Adds dummy home dir tree
56 56 """
57 57 # Do not mask exceptions here. In particular, catching WindowsError is a
58 58 # problem because that exception is only defined on Windows...
59 59 os.makedirs(IP_TEST_DIR)
60 60
61 61
62 62 def teardown():
63 63 """Teardown test environment for the module:
64 64
65 65 - Remove dummy home dir tree
66 66 """
67 67 # Note: we remove the parent test dir, which is the root of all test
68 68 # subdirs we may have created. Use shutil instead of os.removedirs, so
69 69 # that non-empty directories are all recursively removed.
70 70 shutil.rmtree(TMP_TEST_DIR)
71 71
72 72
73 73 #-----------------------------------------------------------------------------
74 74 # Test functions
75 75 #-----------------------------------------------------------------------------
76 76 def win32_without_pywin32():
77 77 if sys.platform == 'win32':
78 78 try:
79 79 import pywin32
80 80 except ImportError:
81 81 return True
82 82 return False
83 83
84 84
85 85 class ProfileStartupTest(TestCase):
86 86 def setUp(self):
87 87 # create profile dir
88 88 self.pd = ProfileDir.create_profile_dir_by_name(IP_TEST_DIR, 'test')
89 89 self.options = ['--ipython-dir', IP_TEST_DIR, '--profile', 'test']
90 90 self.fname = os.path.join(TMP_TEST_DIR, 'test.py')
91 91
92 92 def tearDown(self):
93 93 # We must remove this profile right away so its presence doesn't
94 94 # confuse other tests.
95 95 shutil.rmtree(self.pd.location)
96 96
97 97 def init(self, startup_file, startup, test):
98 98 # write startup python file
99 99 with open(os.path.join(self.pd.startup_dir, startup_file), 'w') as f:
100 100 f.write(startup)
101 101 # write simple test file, to check that the startup file was run
102 102 with open(self.fname, 'w') as f:
103 103 f.write(py3compat.doctest_refactor_print(test))
104 104
105 105 def validate(self, output):
106 106 tt.ipexec_validate(self.fname, output, '', options=self.options)
107 107
108 108 @dec.skipif(win32_without_pywin32(), "Test requires pywin32 on Windows")
109 109 def test_startup_py(self):
110 110 self.init('00-start.py', 'zzz=123\n',
111 111 py3compat.doctest_refactor_print('print zzz\n'))
112 112 self.validate('123')
113 113
114 114 @dec.skipif(win32_without_pywin32(), "Test requires pywin32 on Windows")
115 115 def test_startup_ipy(self):
116 116 self.init('00-start.ipy', '%xmode plain\n', '')
117 117 self.validate('Exception reporting mode: Plain')
118 118
119 119
120 120 def test_list_profiles_in():
121 121 # No need to remove these directories and files, as they will get nuked in
122 122 # the module-level teardown.
123 123 td = tempfile.mkdtemp(dir=TMP_TEST_DIR)
124 td = py3compat.str_to_unicode(td)
125 124 for name in ('profile_foo', 'profile_hello', 'not_a_profile'):
126 125 os.mkdir(os.path.join(td, name))
127 126 if dec.unicode_paths:
128 127 os.mkdir(os.path.join(td, u'profile_ünicode'))
129 128
130 129 with open(os.path.join(td, 'profile_file'), 'w') as f:
131 130 f.write("I am not a profile directory")
132 131 profiles = list_profiles_in(td)
133 132
134 133 # unicode normalization can turn u'ünicode' into u'u\0308nicode',
135 134 # so only check for *nicode, and that creating a ProfileDir from the
136 135 # name remains valid
137 136 found_unicode = False
138 137 for p in list(profiles):
139 138 if p.endswith('nicode'):
140 139 pd = ProfileDir.find_profile_dir_by_name(td, p)
141 140 profiles.remove(p)
142 141 found_unicode = True
143 142 break
144 143 if dec.unicode_paths:
145 144 nt.assert_true(found_unicode)
146 145 nt.assert_equal(set(profiles), {'foo', 'hello'})
147 146
148 147
149 148 def test_list_bundled_profiles():
150 149 # This variable will need to be updated when a new profile gets bundled
151 150 bundled = sorted(list_bundled_profiles())
152 151 nt.assert_equal(bundled, [])
153 152
154 153
155 154 def test_profile_create_ipython_dir():
156 155 """ipython profile create respects --ipython-dir"""
157 156 with TemporaryDirectory() as td:
158 157 getoutput([sys.executable, '-m', 'IPython', 'profile', 'create',
159 158 'foo', '--ipython-dir=%s' % td])
160 159 profile_dir = os.path.join(td, 'profile_foo')
161 160 assert os.path.exists(profile_dir)
162 161 ipython_config = os.path.join(profile_dir, 'ipython_config.py')
163 162 assert os.path.exists(ipython_config)
164 No newline at end of file
163
@@ -1,37 +1,34 b''
1 1 # -*- coding: utf-8
2 2 """Tests for prompt generation."""
3 3
4 4 import unittest
5 5
6 6 from IPython.core.prompts import LazyEvaluate
7 7 from IPython.testing.globalipapp import get_ipython
8 from IPython.utils.py3compat import unicode_type
9 8
10 9 ip = get_ipython()
11 10
12 11
13 12 class PromptTests(unittest.TestCase):
14 13 def test_lazy_eval_unicode(self):
15 14 u = u'ünicødé'
16 15 lz = LazyEvaluate(lambda : u)
17 # str(lz) would fail
18 self.assertEqual(unicode_type(lz), u)
16 self.assertEqual(str(lz), u)
19 17 self.assertEqual(format(lz), u)
20 18
21 19 def test_lazy_eval_nonascii_bytes(self):
22 20 u = u'ünicødé'
23 21 b = u.encode('utf8')
24 22 lz = LazyEvaluate(lambda : b)
25 23 # unicode(lz) would fail
26 24 self.assertEqual(str(lz), str(b))
27 25 self.assertEqual(format(lz), str(b))
28 26
29 27 def test_lazy_eval_float(self):
30 28 f = 0.503
31 29 lz = LazyEvaluate(lambda : f)
32 30
33 31 self.assertEqual(str(lz), str(f))
34 self.assertEqual(unicode_type(lz), unicode_type(f))
35 32 self.assertEqual(format(lz), str(f))
36 33 self.assertEqual(format(lz, '.1'), '0.5')
37 34
@@ -1,514 +1,514 b''
1 1 # encoding: utf-8
2 2 """Tests for code execution (%run and related), which is particularly tricky.
3 3
4 4 Because of how %run manages namespaces, and the fact that we are trying here to
5 5 verify subtle object deletion and reference counting issues, the %run tests
6 6 will be kept in this separate file. This makes it easier to aggregate in one
7 7 place the tricks needed to handle it; most other magics are much easier to test
8 8 and we do so in a common test_magic file.
9 9 """
10 10
11 11 # Copyright (c) IPython Development Team.
12 12 # Distributed under the terms of the Modified BSD License.
13 13
14 14
15 15
16 16 import functools
17 17 import os
18 18 from os.path import join as pjoin
19 19 import random
20 20 import sys
21 21 import textwrap
22 22 import unittest
23 23
24 24 try:
25 25 from unittest.mock import patch
26 26 except ImportError:
27 27 from mock import patch
28 28
29 29 import nose.tools as nt
30 30 from nose import SkipTest
31 31
32 32 from IPython.testing import decorators as dec
33 33 from IPython.testing import tools as tt
34 34 from IPython.utils import py3compat
35 35 from IPython.utils.io import capture_output
36 36 from IPython.utils.tempdir import TemporaryDirectory
37 37 from IPython.core import debugger
38 38
39 39
40 40 def doctest_refbug():
41 41 """Very nasty problem with references held by multiple runs of a script.
42 42 See: https://github.com/ipython/ipython/issues/141
43 43
44 44 In [1]: _ip.clear_main_mod_cache()
45 45 # random
46 46
47 47 In [2]: %run refbug
48 48
49 49 In [3]: call_f()
50 50 lowercased: hello
51 51
52 52 In [4]: %run refbug
53 53
54 54 In [5]: call_f()
55 55 lowercased: hello
56 56 lowercased: hello
57 57 """
58 58
59 59
60 60 def doctest_run_builtins():
61 61 r"""Check that %run doesn't damage __builtins__.
62 62
63 63 In [1]: import tempfile
64 64
65 65 In [2]: bid1 = id(__builtins__)
66 66
67 67 In [3]: fname = tempfile.mkstemp('.py')[1]
68 68
69 69 In [3]: f = open(fname,'w')
70 70
71 71 In [4]: dummy= f.write('pass\n')
72 72
73 73 In [5]: f.flush()
74 74
75 75 In [6]: t1 = type(__builtins__)
76 76
77 77 In [7]: %run $fname
78 78
79 79 In [7]: f.close()
80 80
81 81 In [8]: bid2 = id(__builtins__)
82 82
83 83 In [9]: t2 = type(__builtins__)
84 84
85 85 In [10]: t1 == t2
86 86 Out[10]: True
87 87
88 88 In [10]: bid1 == bid2
89 89 Out[10]: True
90 90
91 91 In [12]: try:
92 92 ....: os.unlink(fname)
93 93 ....: except:
94 94 ....: pass
95 95 ....:
96 96 """
97 97
98 98
99 99 def doctest_run_option_parser():
100 100 r"""Test option parser in %run.
101 101
102 102 In [1]: %run print_argv.py
103 103 []
104 104
105 105 In [2]: %run print_argv.py print*.py
106 106 ['print_argv.py']
107 107
108 108 In [3]: %run -G print_argv.py print*.py
109 109 ['print*.py']
110 110
111 111 """
112 112
113 113
114 114 @dec.skip_win32
115 115 def doctest_run_option_parser_for_posix():
116 116 r"""Test option parser in %run (Linux/OSX specific).
117 117
118 118 You need double quote to escape glob in POSIX systems:
119 119
120 120 In [1]: %run print_argv.py print\\*.py
121 121 ['print*.py']
122 122
123 123 You can't use quote to escape glob in POSIX systems:
124 124
125 125 In [2]: %run print_argv.py 'print*.py'
126 126 ['print_argv.py']
127 127
128 128 """
129 129
130 130
131 131 @dec.skip_if_not_win32
132 132 def doctest_run_option_parser_for_windows():
133 133 r"""Test option parser in %run (Windows specific).
134 134
135 135 In Windows, you can't escape ``*` `by backslash:
136 136
137 137 In [1]: %run print_argv.py print\\*.py
138 138 ['print\\*.py']
139 139
140 140 You can use quote to escape glob:
141 141
142 142 In [2]: %run print_argv.py 'print*.py'
143 143 ['print*.py']
144 144
145 145 """
146 146
147 147
148 148 @py3compat.doctest_refactor_print
149 149 def doctest_reset_del():
150 150 """Test that resetting doesn't cause errors in __del__ methods.
151 151
152 152 In [2]: class A(object):
153 153 ...: def __del__(self):
154 154 ...: print str("Hi")
155 155 ...:
156 156
157 157 In [3]: a = A()
158 158
159 159 In [4]: get_ipython().reset()
160 160 Hi
161 161
162 162 In [5]: 1+1
163 163 Out[5]: 2
164 164 """
165 165
166 166 # For some tests, it will be handy to organize them in a class with a common
167 167 # setup that makes a temp file
168 168
169 169 class TestMagicRunPass(tt.TempFileMixin):
170 170
171 171 def setup(self):
172 172 """Make a valid python temp file."""
173 173 self.mktmp('pass\n')
174 174
175 175 def run_tmpfile(self):
176 176 _ip = get_ipython()
177 177 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
178 178 # See below and ticket https://bugs.launchpad.net/bugs/366353
179 179 _ip.magic('run %s' % self.fname)
180 180
181 181 def run_tmpfile_p(self):
182 182 _ip = get_ipython()
183 183 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
184 184 # See below and ticket https://bugs.launchpad.net/bugs/366353
185 185 _ip.magic('run -p %s' % self.fname)
186 186
187 187 def test_builtins_id(self):
188 188 """Check that %run doesn't damage __builtins__ """
189 189 _ip = get_ipython()
190 190 # Test that the id of __builtins__ is not modified by %run
191 191 bid1 = id(_ip.user_ns['__builtins__'])
192 192 self.run_tmpfile()
193 193 bid2 = id(_ip.user_ns['__builtins__'])
194 194 nt.assert_equal(bid1, bid2)
195 195
196 196 def test_builtins_type(self):
197 197 """Check that the type of __builtins__ doesn't change with %run.
198 198
199 199 However, the above could pass if __builtins__ was already modified to
200 200 be a dict (it should be a module) by a previous use of %run. So we
201 201 also check explicitly that it really is a module:
202 202 """
203 203 _ip = get_ipython()
204 204 self.run_tmpfile()
205 205 nt.assert_equal(type(_ip.user_ns['__builtins__']),type(sys))
206 206
207 207 def test_run_profile( self ):
208 208 """Test that the option -p, which invokes the profiler, do not
209 209 crash by invoking execfile"""
210 210 self.run_tmpfile_p()
211 211
212 212 def test_run_debug_twice(self):
213 213 # https://github.com/ipython/ipython/issues/10028
214 214 _ip = get_ipython()
215 215 with tt.fake_input(['c']):
216 216 _ip.magic('run -d %s' % self.fname)
217 217 with tt.fake_input(['c']):
218 218 _ip.magic('run -d %s' % self.fname)
219 219
220 220
221 221 class TestMagicRunSimple(tt.TempFileMixin):
222 222
223 223 def test_simpledef(self):
224 224 """Test that simple class definitions work."""
225 225 src = ("class foo: pass\n"
226 226 "def f(): return foo()")
227 227 self.mktmp(src)
228 228 _ip.magic('run %s' % self.fname)
229 229 _ip.run_cell('t = isinstance(f(), foo)')
230 230 nt.assert_true(_ip.user_ns['t'])
231 231
232 232 def test_obj_del(self):
233 233 """Test that object's __del__ methods are called on exit."""
234 234 if sys.platform == 'win32':
235 235 try:
236 236 import win32api
237 237 except ImportError:
238 238 raise SkipTest("Test requires pywin32")
239 239 src = ("class A(object):\n"
240 240 " def __del__(self):\n"
241 241 " print 'object A deleted'\n"
242 242 "a = A()\n")
243 243 self.mktmp(py3compat.doctest_refactor_print(src))
244 244 if dec.module_not_available('sqlite3'):
245 245 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
246 246 else:
247 247 err = None
248 248 tt.ipexec_validate(self.fname, 'object A deleted', err)
249 249
250 250 def test_aggressive_namespace_cleanup(self):
251 251 """Test that namespace cleanup is not too aggressive GH-238
252 252
253 253 Returning from another run magic deletes the namespace"""
254 254 # see ticket https://github.com/ipython/ipython/issues/238
255 255
256 256 with tt.TempFileMixin() as empty:
257 257 empty.mktmp('')
258 258 # On Windows, the filename will have \users in it, so we need to use the
259 259 # repr so that the \u becomes \\u.
260 260 src = ("ip = get_ipython()\n"
261 261 "for i in range(5):\n"
262 262 " try:\n"
263 263 " ip.magic(%r)\n"
264 264 " except NameError as e:\n"
265 265 " print(i)\n"
266 266 " break\n" % ('run ' + empty.fname))
267 267 self.mktmp(src)
268 268 _ip.magic('run %s' % self.fname)
269 269 _ip.run_cell('ip == get_ipython()')
270 270 nt.assert_equal(_ip.user_ns['i'], 4)
271 271
272 272 def test_run_second(self):
273 273 """Test that running a second file doesn't clobber the first, gh-3547
274 274 """
275 275 self.mktmp("avar = 1\n"
276 276 "def afunc():\n"
277 277 " return avar\n")
278 278
279 279 with tt.TempFileMixin() as empty:
280 280 empty.mktmp("")
281 281
282 282 _ip.magic('run %s' % self.fname)
283 283 _ip.magic('run %s' % empty.fname)
284 284 nt.assert_equal(_ip.user_ns['afunc'](), 1)
285 285
286 286 @dec.skip_win32
287 287 def test_tclass(self):
288 288 mydir = os.path.dirname(__file__)
289 289 tc = os.path.join(mydir, 'tclass')
290 290 src = ("%%run '%s' C-first\n"
291 291 "%%run '%s' C-second\n"
292 292 "%%run '%s' C-third\n") % (tc, tc, tc)
293 293 self.mktmp(src, '.ipy')
294 294 out = """\
295 295 ARGV 1-: ['C-first']
296 296 ARGV 1-: ['C-second']
297 297 tclass.py: deleting object: C-first
298 298 ARGV 1-: ['C-third']
299 299 tclass.py: deleting object: C-second
300 300 tclass.py: deleting object: C-third
301 301 """
302 302 if dec.module_not_available('sqlite3'):
303 303 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
304 304 else:
305 305 err = None
306 306 tt.ipexec_validate(self.fname, out, err)
307 307
308 308 def test_run_i_after_reset(self):
309 309 """Check that %run -i still works after %reset (gh-693)"""
310 310 src = "yy = zz\n"
311 311 self.mktmp(src)
312 312 _ip.run_cell("zz = 23")
313 313 _ip.magic('run -i %s' % self.fname)
314 314 nt.assert_equal(_ip.user_ns['yy'], 23)
315 315 _ip.magic('reset -f')
316 316 _ip.run_cell("zz = 23")
317 317 _ip.magic('run -i %s' % self.fname)
318 318 nt.assert_equal(_ip.user_ns['yy'], 23)
319 319
320 320 def test_unicode(self):
321 321 """Check that files in odd encodings are accepted."""
322 322 mydir = os.path.dirname(__file__)
323 323 na = os.path.join(mydir, 'nonascii.py')
324 324 _ip.magic('run "%s"' % na)
325 325 nt.assert_equal(_ip.user_ns['u'], u'Ўт№Ф')
326 326
327 327 def test_run_py_file_attribute(self):
328 328 """Test handling of `__file__` attribute in `%run <file>.py`."""
329 329 src = "t = __file__\n"
330 330 self.mktmp(src)
331 331 _missing = object()
332 332 file1 = _ip.user_ns.get('__file__', _missing)
333 333 _ip.magic('run %s' % self.fname)
334 334 file2 = _ip.user_ns.get('__file__', _missing)
335 335
336 336 # Check that __file__ was equal to the filename in the script's
337 337 # namespace.
338 338 nt.assert_equal(_ip.user_ns['t'], self.fname)
339 339
340 340 # Check that __file__ was not leaked back into user_ns.
341 341 nt.assert_equal(file1, file2)
342 342
343 343 def test_run_ipy_file_attribute(self):
344 344 """Test handling of `__file__` attribute in `%run <file.ipy>`."""
345 345 src = "t = __file__\n"
346 346 self.mktmp(src, ext='.ipy')
347 347 _missing = object()
348 348 file1 = _ip.user_ns.get('__file__', _missing)
349 349 _ip.magic('run %s' % self.fname)
350 350 file2 = _ip.user_ns.get('__file__', _missing)
351 351
352 352 # Check that __file__ was equal to the filename in the script's
353 353 # namespace.
354 354 nt.assert_equal(_ip.user_ns['t'], self.fname)
355 355
356 356 # Check that __file__ was not leaked back into user_ns.
357 357 nt.assert_equal(file1, file2)
358 358
359 359 def test_run_formatting(self):
360 360 """ Test that %run -t -N<N> does not raise a TypeError for N > 1."""
361 361 src = "pass"
362 362 self.mktmp(src)
363 363 _ip.magic('run -t -N 1 %s' % self.fname)
364 364 _ip.magic('run -t -N 10 %s' % self.fname)
365 365
366 366 def test_ignore_sys_exit(self):
367 367 """Test the -e option to ignore sys.exit()"""
368 368 src = "import sys; sys.exit(1)"
369 369 self.mktmp(src)
370 370 with tt.AssertPrints('SystemExit'):
371 371 _ip.magic('run %s' % self.fname)
372 372
373 373 with tt.AssertNotPrints('SystemExit'):
374 374 _ip.magic('run -e %s' % self.fname)
375 375
376 376 def test_run_nb(self):
377 377 """Test %run notebook.ipynb"""
378 378 from nbformat import v4, writes
379 379 nb = v4.new_notebook(
380 380 cells=[
381 381 v4.new_markdown_cell("The Ultimate Question of Everything"),
382 382 v4.new_code_cell("answer=42")
383 383 ]
384 384 )
385 385 src = writes(nb, version=4)
386 386 self.mktmp(src, ext='.ipynb')
387 387
388 388 _ip.magic("run %s" % self.fname)
389 389
390 390 nt.assert_equal(_ip.user_ns['answer'], 42)
391 391
392 392
393 393
394 394 class TestMagicRunWithPackage(unittest.TestCase):
395 395
396 396 def writefile(self, name, content):
397 397 path = os.path.join(self.tempdir.name, name)
398 398 d = os.path.dirname(path)
399 399 if not os.path.isdir(d):
400 400 os.makedirs(d)
401 401 with open(path, 'w') as f:
402 402 f.write(textwrap.dedent(content))
403 403
404 404 def setUp(self):
405 405 self.package = package = 'tmp{0}'.format(repr(random.random())[2:])
406 406 """Temporary valid python package name."""
407 407
408 408 self.value = int(random.random() * 10000)
409 409
410 410 self.tempdir = TemporaryDirectory()
411 self.__orig_cwd = py3compat.getcwd()
411 self.__orig_cwd = os.getcwd()
412 412 sys.path.insert(0, self.tempdir.name)
413 413
414 414 self.writefile(os.path.join(package, '__init__.py'), '')
415 415 self.writefile(os.path.join(package, 'sub.py'), """
416 416 x = {0!r}
417 417 """.format(self.value))
418 418 self.writefile(os.path.join(package, 'relative.py'), """
419 419 from .sub import x
420 420 """)
421 421 self.writefile(os.path.join(package, 'absolute.py'), """
422 422 from {0}.sub import x
423 423 """.format(package))
424 424
425 425 def tearDown(self):
426 426 os.chdir(self.__orig_cwd)
427 427 sys.path[:] = [p for p in sys.path if p != self.tempdir.name]
428 428 self.tempdir.cleanup()
429 429
430 430 def check_run_submodule(self, submodule, opts=''):
431 431 _ip.user_ns.pop('x', None)
432 432 _ip.magic('run {2} -m {0}.{1}'.format(self.package, submodule, opts))
433 433 self.assertEqual(_ip.user_ns['x'], self.value,
434 434 'Variable `x` is not loaded from module `{0}`.'
435 435 .format(submodule))
436 436
437 437 def test_run_submodule_with_absolute_import(self):
438 438 self.check_run_submodule('absolute')
439 439
440 440 def test_run_submodule_with_relative_import(self):
441 441 """Run submodule that has a relative import statement (#2727)."""
442 442 self.check_run_submodule('relative')
443 443
444 444 def test_prun_submodule_with_absolute_import(self):
445 445 self.check_run_submodule('absolute', '-p')
446 446
447 447 def test_prun_submodule_with_relative_import(self):
448 448 self.check_run_submodule('relative', '-p')
449 449
450 450 def with_fake_debugger(func):
451 451 @functools.wraps(func)
452 452 def wrapper(*args, **kwds):
453 453 with patch.object(debugger.Pdb, 'run', staticmethod(eval)):
454 454 return func(*args, **kwds)
455 455 return wrapper
456 456
457 457 @with_fake_debugger
458 458 def test_debug_run_submodule_with_absolute_import(self):
459 459 self.check_run_submodule('absolute', '-d')
460 460
461 461 @with_fake_debugger
462 462 def test_debug_run_submodule_with_relative_import(self):
463 463 self.check_run_submodule('relative', '-d')
464 464
465 465 def test_run__name__():
466 466 with TemporaryDirectory() as td:
467 467 path = pjoin(td, 'foo.py')
468 468 with open(path, 'w') as f:
469 469 f.write("q = __name__")
470 470
471 471 _ip.user_ns.pop('q', None)
472 472 _ip.magic('run {}'.format(path))
473 473 nt.assert_equal(_ip.user_ns.pop('q'), '__main__')
474 474
475 475 _ip.magic('run -n {}'.format(path))
476 476 nt.assert_equal(_ip.user_ns.pop('q'), 'foo')
477 477
478 478 def test_run_tb():
479 479 """Test traceback offset in %run"""
480 480 with TemporaryDirectory() as td:
481 481 path = pjoin(td, 'foo.py')
482 482 with open(path, 'w') as f:
483 483 f.write('\n'.join([
484 484 "def foo():",
485 485 " return bar()",
486 486 "def bar():",
487 487 " raise RuntimeError('hello!')",
488 488 "foo()",
489 489 ]))
490 490 with capture_output() as io:
491 491 _ip.magic('run {}'.format(path))
492 492 out = io.stdout
493 493 nt.assert_not_in("execfile", out)
494 494 nt.assert_in("RuntimeError", out)
495 495 nt.assert_equal(out.count("---->"), 3)
496 496
497 497 @dec.knownfailureif(sys.platform == 'win32', "writes to io.stdout aren't captured on Windows")
498 498 def test_script_tb():
499 499 """Test traceback offset in `ipython script.py`"""
500 500 with TemporaryDirectory() as td:
501 501 path = pjoin(td, 'foo.py')
502 502 with open(path, 'w') as f:
503 503 f.write('\n'.join([
504 504 "def foo():",
505 505 " return bar()",
506 506 "def bar():",
507 507 " raise RuntimeError('hello!')",
508 508 "foo()",
509 509 ]))
510 510 out, err = tt.ipexec(path)
511 511 nt.assert_not_in("execfile", out)
512 512 nt.assert_in("RuntimeError", out)
513 513 nt.assert_equal(out.count("---->"), 3)
514 514
@@ -1,1488 +1,1488 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Verbose and colourful traceback formatting.
4 4
5 5 **ColorTB**
6 6
7 7 I've always found it a bit hard to visually parse tracebacks in Python. The
8 8 ColorTB class is a solution to that problem. It colors the different parts of a
9 9 traceback in a manner similar to what you would expect from a syntax-highlighting
10 10 text editor.
11 11
12 12 Installation instructions for ColorTB::
13 13
14 14 import sys,ultratb
15 15 sys.excepthook = ultratb.ColorTB()
16 16
17 17 **VerboseTB**
18 18
19 19 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
20 20 of useful info when a traceback occurs. Ping originally had it spit out HTML
21 21 and intended it for CGI programmers, but why should they have all the fun? I
22 22 altered it to spit out colored text to the terminal. It's a bit overwhelming,
23 23 but kind of neat, and maybe useful for long-running programs that you believe
24 24 are bug-free. If a crash *does* occur in that type of program you want details.
25 25 Give it a shot--you'll love it or you'll hate it.
26 26
27 27 .. note::
28 28
29 29 The Verbose mode prints the variables currently visible where the exception
30 30 happened (shortening their strings if too long). This can potentially be
31 31 very slow, if you happen to have a huge data structure whose string
32 32 representation is complex to compute. Your computer may appear to freeze for
33 33 a while with cpu usage at 100%. If this occurs, you can cancel the traceback
34 34 with Ctrl-C (maybe hitting it more than once).
35 35
36 36 If you encounter this kind of situation often, you may want to use the
37 37 Verbose_novars mode instead of the regular Verbose, which avoids formatting
38 38 variables (but otherwise includes the information and context given by
39 39 Verbose).
40 40
41 41 .. note::
42 42
43 43 The verbose mode print all variables in the stack, which means it can
44 44 potentially leak sensitive information like access keys, or unencryted
45 45 password.
46 46
47 47 Installation instructions for VerboseTB::
48 48
49 49 import sys,ultratb
50 50 sys.excepthook = ultratb.VerboseTB()
51 51
52 52 Note: Much of the code in this module was lifted verbatim from the standard
53 53 library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'.
54 54
55 55 Color schemes
56 56 -------------
57 57
58 58 The colors are defined in the class TBTools through the use of the
59 59 ColorSchemeTable class. Currently the following exist:
60 60
61 61 - NoColor: allows all of this module to be used in any terminal (the color
62 62 escapes are just dummy blank strings).
63 63
64 64 - Linux: is meant to look good in a terminal like the Linux console (black
65 65 or very dark background).
66 66
67 67 - LightBG: similar to Linux but swaps dark/light colors to be more readable
68 68 in light background terminals.
69 69
70 70 - Neutral: a neutral color scheme that should be readable on both light and
71 71 dark background
72 72
73 73 You can implement other color schemes easily, the syntax is fairly
74 74 self-explanatory. Please send back new schemes you develop to the author for
75 75 possible inclusion in future releases.
76 76
77 77 Inheritance diagram:
78 78
79 79 .. inheritance-diagram:: IPython.core.ultratb
80 80 :parts: 3
81 81 """
82 82
83 83 #*****************************************************************************
84 84 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
85 85 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
86 86 #
87 87 # Distributed under the terms of the BSD License. The full license is in
88 88 # the file COPYING, distributed as part of this software.
89 89 #*****************************************************************************
90 90
91 91
92 92 import dis
93 93 import inspect
94 94 import keyword
95 95 import linecache
96 96 import os
97 97 import pydoc
98 98 import re
99 99 import sys
100 100 import time
101 101 import tokenize
102 102 import traceback
103 103 import types
104 104
105 105 try: # Python 2
106 106 generate_tokens = tokenize.generate_tokens
107 107 except AttributeError: # Python 3
108 108 generate_tokens = tokenize.tokenize
109 109
110 110 # For purposes of monkeypatching inspect to fix a bug in it.
111 111 from inspect import getsourcefile, getfile, getmodule, \
112 112 ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode
113 113
114 114 # IPython's own modules
115 115 from IPython import get_ipython
116 116 from IPython.core import debugger
117 117 from IPython.core.display_trap import DisplayTrap
118 118 from IPython.core.excolors import exception_colors
119 119 from IPython.utils import PyColorize
120 120 from IPython.utils import openpy
121 121 from IPython.utils import path as util_path
122 122 from IPython.utils import py3compat
123 123 from IPython.utils import ulinecache
124 124 from IPython.utils.data import uniq_stable
125 125 from IPython.utils.terminal import get_terminal_size
126 126 from logging import info, error
127 127
128 128 import IPython.utils.colorable as colorable
129 129
130 130 # Globals
131 131 # amount of space to put line numbers before verbose tracebacks
132 132 INDENT_SIZE = 8
133 133
134 134 # Default color scheme. This is used, for example, by the traceback
135 135 # formatter. When running in an actual IPython instance, the user's rc.colors
136 136 # value is used, but having a module global makes this functionality available
137 137 # to users of ultratb who are NOT running inside ipython.
138 138 DEFAULT_SCHEME = 'NoColor'
139 139
140 140 # ---------------------------------------------------------------------------
141 141 # Code begins
142 142
143 143 # Utility functions
144 144 def inspect_error():
145 145 """Print a message about internal inspect errors.
146 146
147 147 These are unfortunately quite common."""
148 148
149 149 error('Internal Python error in the inspect module.\n'
150 150 'Below is the traceback from this internal error.\n')
151 151
152 152
153 153 # This function is a monkeypatch we apply to the Python inspect module. We have
154 154 # now found when it's needed (see discussion on issue gh-1456), and we have a
155 155 # test case (IPython.core.tests.test_ultratb.ChangedPyFileTest) that fails if
156 156 # the monkeypatch is not applied. TK, Aug 2012.
157 157 def findsource(object):
158 158 """Return the entire source file and starting line number for an object.
159 159
160 160 The argument may be a module, class, method, function, traceback, frame,
161 161 or code object. The source code is returned as a list of all the lines
162 162 in the file and the line number indexes a line in that list. An IOError
163 163 is raised if the source code cannot be retrieved.
164 164
165 165 FIXED version with which we monkeypatch the stdlib to work around a bug."""
166 166
167 167 file = getsourcefile(object) or getfile(object)
168 168 # If the object is a frame, then trying to get the globals dict from its
169 169 # module won't work. Instead, the frame object itself has the globals
170 170 # dictionary.
171 171 globals_dict = None
172 172 if inspect.isframe(object):
173 173 # XXX: can this ever be false?
174 174 globals_dict = object.f_globals
175 175 else:
176 176 module = getmodule(object, file)
177 177 if module:
178 178 globals_dict = module.__dict__
179 179 lines = linecache.getlines(file, globals_dict)
180 180 if not lines:
181 181 raise IOError('could not get source code')
182 182
183 183 if ismodule(object):
184 184 return lines, 0
185 185
186 186 if isclass(object):
187 187 name = object.__name__
188 188 pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
189 189 # make some effort to find the best matching class definition:
190 190 # use the one with the least indentation, which is the one
191 191 # that's most probably not inside a function definition.
192 192 candidates = []
193 193 for i in range(len(lines)):
194 194 match = pat.match(lines[i])
195 195 if match:
196 196 # if it's at toplevel, it's already the best one
197 197 if lines[i][0] == 'c':
198 198 return lines, i
199 199 # else add whitespace to candidate list
200 200 candidates.append((match.group(1), i))
201 201 if candidates:
202 202 # this will sort by whitespace, and by line number,
203 203 # less whitespace first
204 204 candidates.sort()
205 205 return lines, candidates[0][1]
206 206 else:
207 207 raise IOError('could not find class definition')
208 208
209 209 if ismethod(object):
210 210 object = object.__func__
211 211 if isfunction(object):
212 212 object = object.__code__
213 213 if istraceback(object):
214 214 object = object.tb_frame
215 215 if isframe(object):
216 216 object = object.f_code
217 217 if iscode(object):
218 218 if not hasattr(object, 'co_firstlineno'):
219 219 raise IOError('could not find function definition')
220 220 pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
221 221 pmatch = pat.match
222 222 # fperez - fix: sometimes, co_firstlineno can give a number larger than
223 223 # the length of lines, which causes an error. Safeguard against that.
224 224 lnum = min(object.co_firstlineno, len(lines)) - 1
225 225 while lnum > 0:
226 226 if pmatch(lines[lnum]):
227 227 break
228 228 lnum -= 1
229 229
230 230 return lines, lnum
231 231 raise IOError('could not find code object')
232 232
233 233
234 234 # This is a patched version of inspect.getargs that applies the (unmerged)
235 235 # patch for http://bugs.python.org/issue14611 by Stefano Taschini. This fixes
236 236 # https://github.com/ipython/ipython/issues/8205 and
237 237 # https://github.com/ipython/ipython/issues/8293
238 238 def getargs(co):
239 239 """Get information about the arguments accepted by a code object.
240 240
241 241 Three things are returned: (args, varargs, varkw), where 'args' is
242 242 a list of argument names (possibly containing nested lists), and
243 243 'varargs' and 'varkw' are the names of the * and ** arguments or None."""
244 244 if not iscode(co):
245 245 raise TypeError('{!r} is not a code object'.format(co))
246 246
247 247 nargs = co.co_argcount
248 248 names = co.co_varnames
249 249 args = list(names[:nargs])
250 250 step = 0
251 251
252 252 # The following acrobatics are for anonymous (tuple) arguments.
253 253 for i in range(nargs):
254 254 if args[i][:1] in ('', '.'):
255 255 stack, remain, count = [], [], []
256 256 while step < len(co.co_code):
257 257 op = ord(co.co_code[step])
258 258 step = step + 1
259 259 if op >= dis.HAVE_ARGUMENT:
260 260 opname = dis.opname[op]
261 261 value = ord(co.co_code[step]) + ord(co.co_code[step+1])*256
262 262 step = step + 2
263 263 if opname in ('UNPACK_TUPLE', 'UNPACK_SEQUENCE'):
264 264 remain.append(value)
265 265 count.append(value)
266 266 elif opname in ('STORE_FAST', 'STORE_DEREF'):
267 267 if op in dis.haslocal:
268 268 stack.append(co.co_varnames[value])
269 269 elif op in dis.hasfree:
270 270 stack.append((co.co_cellvars + co.co_freevars)[value])
271 271 # Special case for sublists of length 1: def foo((bar))
272 272 # doesn't generate the UNPACK_TUPLE bytecode, so if
273 273 # `remain` is empty here, we have such a sublist.
274 274 if not remain:
275 275 stack[0] = [stack[0]]
276 276 break
277 277 else:
278 278 remain[-1] = remain[-1] - 1
279 279 while remain[-1] == 0:
280 280 remain.pop()
281 281 size = count.pop()
282 282 stack[-size:] = [stack[-size:]]
283 283 if not remain:
284 284 break
285 285 remain[-1] = remain[-1] - 1
286 286 if not remain:
287 287 break
288 288 args[i] = stack[0]
289 289
290 290 varargs = None
291 291 if co.co_flags & inspect.CO_VARARGS:
292 292 varargs = co.co_varnames[nargs]
293 293 nargs = nargs + 1
294 294 varkw = None
295 295 if co.co_flags & inspect.CO_VARKEYWORDS:
296 296 varkw = co.co_varnames[nargs]
297 297 return inspect.Arguments(args, varargs, varkw)
298 298
299 299
300 300 # Monkeypatch inspect to apply our bugfix.
301 301 def with_patch_inspect(f):
302 302 """decorator for monkeypatching inspect.findsource"""
303 303
304 304 def wrapped(*args, **kwargs):
305 305 save_findsource = inspect.findsource
306 306 save_getargs = inspect.getargs
307 307 inspect.findsource = findsource
308 308 inspect.getargs = getargs
309 309 try:
310 310 return f(*args, **kwargs)
311 311 finally:
312 312 inspect.findsource = save_findsource
313 313 inspect.getargs = save_getargs
314 314
315 315 return wrapped
316 316
317 317
318 318 if py3compat.PY3:
319 319 fixed_getargvalues = inspect.getargvalues
320 320 else:
321 321 # Fixes for https://github.com/ipython/ipython/issues/8293
322 322 # and https://github.com/ipython/ipython/issues/8205.
323 323 # The relevant bug is caused by failure to correctly handle anonymous tuple
324 324 # unpacking, which only exists in Python 2.
325 325 fixed_getargvalues = with_patch_inspect(inspect.getargvalues)
326 326
327 327
328 328 def fix_frame_records_filenames(records):
329 329 """Try to fix the filenames in each record from inspect.getinnerframes().
330 330
331 331 Particularly, modules loaded from within zip files have useless filenames
332 332 attached to their code object, and inspect.getinnerframes() just uses it.
333 333 """
334 334 fixed_records = []
335 335 for frame, filename, line_no, func_name, lines, index in records:
336 336 # Look inside the frame's globals dictionary for __file__,
337 337 # which should be better. However, keep Cython filenames since
338 338 # we prefer the source filenames over the compiled .so file.
339 339 filename = py3compat.cast_unicode_py2(filename, "utf-8")
340 340 if not filename.endswith(('.pyx', '.pxd', '.pxi')):
341 341 better_fn = frame.f_globals.get('__file__', None)
342 342 if isinstance(better_fn, str):
343 343 # Check the type just in case someone did something weird with
344 344 # __file__. It might also be None if the error occurred during
345 345 # import.
346 346 filename = better_fn
347 347 fixed_records.append((frame, filename, line_no, func_name, lines, index))
348 348 return fixed_records
349 349
350 350
351 351 @with_patch_inspect
352 352 def _fixed_getinnerframes(etb, context=1, tb_offset=0):
353 353 LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5
354 354
355 355 records = fix_frame_records_filenames(inspect.getinnerframes(etb, context))
356 356 # If the error is at the console, don't build any context, since it would
357 357 # otherwise produce 5 blank lines printed out (there is no file at the
358 358 # console)
359 359 rec_check = records[tb_offset:]
360 360 try:
361 361 rname = rec_check[0][1]
362 362 if rname == '<ipython console>' or rname.endswith('<string>'):
363 363 return rec_check
364 364 except IndexError:
365 365 pass
366 366
367 367 aux = traceback.extract_tb(etb)
368 368 assert len(records) == len(aux)
369 369 for i, (file, lnum, _, _) in zip(range(len(records)), aux):
370 370 maybeStart = lnum - 1 - context // 2
371 371 start = max(maybeStart, 0)
372 372 end = start + context
373 373 lines = ulinecache.getlines(file)[start:end]
374 374 buf = list(records[i])
375 375 buf[LNUM_POS] = lnum
376 376 buf[INDEX_POS] = lnum - 1 - start
377 377 buf[LINES_POS] = lines
378 378 records[i] = tuple(buf)
379 379 return records[tb_offset:]
380 380
381 381 # Helper function -- largely belongs to VerboseTB, but we need the same
382 382 # functionality to produce a pseudo verbose TB for SyntaxErrors, so that they
383 383 # can be recognized properly by ipython.el's py-traceback-line-re
384 384 # (SyntaxErrors have to be treated specially because they have no traceback)
385 385
386 386
387 387 def _format_traceback_lines(lnum, index, lines, Colors, lvals=None, _line_format=(lambda x,_:x,None)):
388 388 numbers_width = INDENT_SIZE - 1
389 389 res = []
390 390 i = lnum - index
391 391
392 392 for line in lines:
393 393 line = py3compat.cast_unicode(line)
394 394
395 395 new_line, err = _line_format(line, 'str')
396 396 if not err: line = new_line
397 397
398 398 if i == lnum:
399 399 # This is the line with the error
400 400 pad = numbers_width - len(str(i))
401 401 num = '%s%s' % (debugger.make_arrow(pad), str(lnum))
402 402 line = '%s%s%s %s%s' % (Colors.linenoEm, num,
403 403 Colors.line, line, Colors.Normal)
404 404 else:
405 405 num = '%*s' % (numbers_width, i)
406 406 line = '%s%s%s %s' % (Colors.lineno, num,
407 407 Colors.Normal, line)
408 408
409 409 res.append(line)
410 410 if lvals and i == lnum:
411 411 res.append(lvals + '\n')
412 412 i = i + 1
413 413 return res
414 414
415 415 def is_recursion_error(etype, value, records):
416 416 try:
417 417 # RecursionError is new in Python 3.5
418 418 recursion_error_type = RecursionError
419 419 except NameError:
420 420 recursion_error_type = RuntimeError
421 421
422 422 # The default recursion limit is 1000, but some of that will be taken up
423 423 # by stack frames in IPython itself. >500 frames probably indicates
424 424 # a recursion error.
425 425 return (etype is recursion_error_type) \
426 426 and "recursion" in str(value).lower() \
427 427 and len(records) > 500
428 428
429 429 def find_recursion(etype, value, records):
430 430 """Identify the repeating stack frames from a RecursionError traceback
431 431
432 432 'records' is a list as returned by VerboseTB.get_records()
433 433
434 434 Returns (last_unique, repeat_length)
435 435 """
436 436 # This involves a bit of guesswork - we want to show enough of the traceback
437 437 # to indicate where the recursion is occurring. We guess that the innermost
438 438 # quarter of the traceback (250 frames by default) is repeats, and find the
439 439 # first frame (from in to out) that looks different.
440 440 if not is_recursion_error(etype, value, records):
441 441 return len(records), 0
442 442
443 443 # Select filename, lineno, func_name to track frames with
444 444 records = [r[1:4] for r in records]
445 445 inner_frames = records[-(len(records)//4):]
446 446 frames_repeated = set(inner_frames)
447 447
448 448 last_seen_at = {}
449 449 longest_repeat = 0
450 450 i = len(records)
451 451 for frame in reversed(records):
452 452 i -= 1
453 453 if frame not in frames_repeated:
454 454 last_unique = i
455 455 break
456 456
457 457 if frame in last_seen_at:
458 458 distance = last_seen_at[frame] - i
459 459 longest_repeat = max(longest_repeat, distance)
460 460
461 461 last_seen_at[frame] = i
462 462 else:
463 463 last_unique = 0 # The whole traceback was recursion
464 464
465 465 return last_unique, longest_repeat
466 466
467 467 #---------------------------------------------------------------------------
468 468 # Module classes
469 469 class TBTools(colorable.Colorable):
470 470 """Basic tools used by all traceback printer classes."""
471 471
472 472 # Number of frames to skip when reporting tracebacks
473 473 tb_offset = 0
474 474
475 475 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None, parent=None, config=None):
476 476 # Whether to call the interactive pdb debugger after printing
477 477 # tracebacks or not
478 478 super(TBTools, self).__init__(parent=parent, config=config)
479 479 self.call_pdb = call_pdb
480 480
481 481 # Output stream to write to. Note that we store the original value in
482 482 # a private attribute and then make the public ostream a property, so
483 483 # that we can delay accessing sys.stdout until runtime. The way
484 484 # things are written now, the sys.stdout object is dynamically managed
485 485 # so a reference to it should NEVER be stored statically. This
486 486 # property approach confines this detail to a single location, and all
487 487 # subclasses can simply access self.ostream for writing.
488 488 self._ostream = ostream
489 489
490 490 # Create color table
491 491 self.color_scheme_table = exception_colors()
492 492
493 493 self.set_colors(color_scheme)
494 494 self.old_scheme = color_scheme # save initial value for toggles
495 495
496 496 if call_pdb:
497 497 self.pdb = debugger.Pdb()
498 498 else:
499 499 self.pdb = None
500 500
501 501 def _get_ostream(self):
502 502 """Output stream that exceptions are written to.
503 503
504 504 Valid values are:
505 505
506 506 - None: the default, which means that IPython will dynamically resolve
507 507 to sys.stdout. This ensures compatibility with most tools, including
508 508 Windows (where plain stdout doesn't recognize ANSI escapes).
509 509
510 510 - Any object with 'write' and 'flush' attributes.
511 511 """
512 512 return sys.stdout if self._ostream is None else self._ostream
513 513
514 514 def _set_ostream(self, val):
515 515 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
516 516 self._ostream = val
517 517
518 518 ostream = property(_get_ostream, _set_ostream)
519 519
520 520 def set_colors(self, *args, **kw):
521 521 """Shorthand access to the color table scheme selector method."""
522 522
523 523 # Set own color table
524 524 self.color_scheme_table.set_active_scheme(*args, **kw)
525 525 # for convenience, set Colors to the active scheme
526 526 self.Colors = self.color_scheme_table.active_colors
527 527 # Also set colors of debugger
528 528 if hasattr(self, 'pdb') and self.pdb is not None:
529 529 self.pdb.set_colors(*args, **kw)
530 530
531 531 def color_toggle(self):
532 532 """Toggle between the currently active color scheme and NoColor."""
533 533
534 534 if self.color_scheme_table.active_scheme_name == 'NoColor':
535 535 self.color_scheme_table.set_active_scheme(self.old_scheme)
536 536 self.Colors = self.color_scheme_table.active_colors
537 537 else:
538 538 self.old_scheme = self.color_scheme_table.active_scheme_name
539 539 self.color_scheme_table.set_active_scheme('NoColor')
540 540 self.Colors = self.color_scheme_table.active_colors
541 541
542 542 def stb2text(self, stb):
543 543 """Convert a structured traceback (a list) to a string."""
544 544 return '\n'.join(stb)
545 545
546 546 def text(self, etype, value, tb, tb_offset=None, context=5):
547 547 """Return formatted traceback.
548 548
549 549 Subclasses may override this if they add extra arguments.
550 550 """
551 551 tb_list = self.structured_traceback(etype, value, tb,
552 552 tb_offset, context)
553 553 return self.stb2text(tb_list)
554 554
555 555 def structured_traceback(self, etype, evalue, tb, tb_offset=None,
556 556 context=5, mode=None):
557 557 """Return a list of traceback frames.
558 558
559 559 Must be implemented by each class.
560 560 """
561 561 raise NotImplementedError()
562 562
563 563
564 564 #---------------------------------------------------------------------------
565 565 class ListTB(TBTools):
566 566 """Print traceback information from a traceback list, with optional color.
567 567
568 568 Calling requires 3 arguments: (etype, evalue, elist)
569 569 as would be obtained by::
570 570
571 571 etype, evalue, tb = sys.exc_info()
572 572 if tb:
573 573 elist = traceback.extract_tb(tb)
574 574 else:
575 575 elist = None
576 576
577 577 It can thus be used by programs which need to process the traceback before
578 578 printing (such as console replacements based on the code module from the
579 579 standard library).
580 580
581 581 Because they are meant to be called without a full traceback (only a
582 582 list), instances of this class can't call the interactive pdb debugger."""
583 583
584 584 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None, parent=None, config=None):
585 585 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
586 586 ostream=ostream, parent=parent,config=config)
587 587
588 588 def __call__(self, etype, value, elist):
589 589 self.ostream.flush()
590 590 self.ostream.write(self.text(etype, value, elist))
591 591 self.ostream.write('\n')
592 592
593 593 def structured_traceback(self, etype, value, elist, tb_offset=None,
594 594 context=5):
595 595 """Return a color formatted string with the traceback info.
596 596
597 597 Parameters
598 598 ----------
599 599 etype : exception type
600 600 Type of the exception raised.
601 601
602 602 value : object
603 603 Data stored in the exception
604 604
605 605 elist : list
606 606 List of frames, see class docstring for details.
607 607
608 608 tb_offset : int, optional
609 609 Number of frames in the traceback to skip. If not given, the
610 610 instance value is used (set in constructor).
611 611
612 612 context : int, optional
613 613 Number of lines of context information to print.
614 614
615 615 Returns
616 616 -------
617 617 String with formatted exception.
618 618 """
619 619 tb_offset = self.tb_offset if tb_offset is None else tb_offset
620 620 Colors = self.Colors
621 621 out_list = []
622 622 if elist:
623 623
624 624 if tb_offset and len(elist) > tb_offset:
625 625 elist = elist[tb_offset:]
626 626
627 627 out_list.append('Traceback %s(most recent call last)%s:' %
628 628 (Colors.normalEm, Colors.Normal) + '\n')
629 629 out_list.extend(self._format_list(elist))
630 630 # The exception info should be a single entry in the list.
631 631 lines = ''.join(self._format_exception_only(etype, value))
632 632 out_list.append(lines)
633 633
634 634 # Note: this code originally read:
635 635
636 636 ## for line in lines[:-1]:
637 637 ## out_list.append(" "+line)
638 638 ## out_list.append(lines[-1])
639 639
640 640 # This means it was indenting everything but the last line by a little
641 641 # bit. I've disabled this for now, but if we see ugliness somewhere we
642 642 # can restore it.
643 643
644 644 return out_list
645 645
646 646 def _format_list(self, extracted_list):
647 647 """Format a list of traceback entry tuples for printing.
648 648
649 649 Given a list of tuples as returned by extract_tb() or
650 650 extract_stack(), return a list of strings ready for printing.
651 651 Each string in the resulting list corresponds to the item with the
652 652 same index in the argument list. Each string ends in a newline;
653 653 the strings may contain internal newlines as well, for those items
654 654 whose source text line is not None.
655 655
656 656 Lifted almost verbatim from traceback.py
657 657 """
658 658
659 659 Colors = self.Colors
660 660 list = []
661 661 for filename, lineno, name, line in extracted_list[:-1]:
662 662 item = ' File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \
663 663 (Colors.filename, py3compat.cast_unicode_py2(filename, "utf-8"), Colors.Normal,
664 664 Colors.lineno, lineno, Colors.Normal,
665 665 Colors.name, py3compat.cast_unicode_py2(name, "utf-8"), Colors.Normal)
666 666 if line:
667 667 item += ' %s\n' % line.strip()
668 668 list.append(item)
669 669 # Emphasize the last entry
670 670 filename, lineno, name, line = extracted_list[-1]
671 671 item = '%s File %s"%s"%s, line %s%d%s, in %s%s%s%s\n' % \
672 672 (Colors.normalEm,
673 673 Colors.filenameEm, py3compat.cast_unicode_py2(filename, "utf-8"), Colors.normalEm,
674 674 Colors.linenoEm, lineno, Colors.normalEm,
675 675 Colors.nameEm, py3compat.cast_unicode_py2(name, "utf-8"), Colors.normalEm,
676 676 Colors.Normal)
677 677 if line:
678 678 item += '%s %s%s\n' % (Colors.line, line.strip(),
679 679 Colors.Normal)
680 680 list.append(item)
681 681 return list
682 682
683 683 def _format_exception_only(self, etype, value):
684 684 """Format the exception part of a traceback.
685 685
686 686 The arguments are the exception type and value such as given by
687 687 sys.exc_info()[:2]. The return value is a list of strings, each ending
688 688 in a newline. Normally, the list contains a single string; however,
689 689 for SyntaxError exceptions, it contains several lines that (when
690 690 printed) display detailed information about where the syntax error
691 691 occurred. The message indicating which exception occurred is the
692 692 always last string in the list.
693 693
694 694 Also lifted nearly verbatim from traceback.py
695 695 """
696 696 have_filedata = False
697 697 Colors = self.Colors
698 698 list = []
699 699 stype = py3compat.cast_unicode(Colors.excName + etype.__name__ + Colors.Normal)
700 700 if value is None:
701 701 # Not sure if this can still happen in Python 2.6 and above
702 702 list.append(stype + '\n')
703 703 else:
704 704 if issubclass(etype, SyntaxError):
705 705 have_filedata = True
706 706 if not value.filename: value.filename = "<string>"
707 707 if value.lineno:
708 708 lineno = value.lineno
709 709 textline = ulinecache.getline(value.filename, value.lineno)
710 710 else:
711 711 lineno = 'unknown'
712 712 textline = ''
713 713 list.append('%s File %s"%s"%s, line %s%s%s\n' % \
714 714 (Colors.normalEm,
715 715 Colors.filenameEm, py3compat.cast_unicode(value.filename), Colors.normalEm,
716 716 Colors.linenoEm, lineno, Colors.Normal ))
717 717 if textline == '':
718 718 textline = py3compat.cast_unicode(value.text, "utf-8")
719 719
720 720 if textline is not None:
721 721 i = 0
722 722 while i < len(textline) and textline[i].isspace():
723 723 i += 1
724 724 list.append('%s %s%s\n' % (Colors.line,
725 725 textline.strip(),
726 726 Colors.Normal))
727 727 if value.offset is not None:
728 728 s = ' '
729 729 for c in textline[i:value.offset - 1]:
730 730 if c.isspace():
731 731 s += c
732 732 else:
733 733 s += ' '
734 734 list.append('%s%s^%s\n' % (Colors.caret, s,
735 735 Colors.Normal))
736 736
737 737 try:
738 738 s = value.msg
739 739 except Exception:
740 740 s = self._some_str(value)
741 741 if s:
742 742 list.append('%s%s:%s %s\n' % (stype, Colors.excName,
743 743 Colors.Normal, s))
744 744 else:
745 745 list.append('%s\n' % stype)
746 746
747 747 # sync with user hooks
748 748 if have_filedata:
749 749 ipinst = get_ipython()
750 750 if ipinst is not None:
751 751 ipinst.hooks.synchronize_with_editor(value.filename, value.lineno, 0)
752 752
753 753 return list
754 754
755 755 def get_exception_only(self, etype, value):
756 756 """Only print the exception type and message, without a traceback.
757 757
758 758 Parameters
759 759 ----------
760 760 etype : exception type
761 761 value : exception value
762 762 """
763 763 return ListTB.structured_traceback(self, etype, value, [])
764 764
765 765 def show_exception_only(self, etype, evalue):
766 766 """Only print the exception type and message, without a traceback.
767 767
768 768 Parameters
769 769 ----------
770 770 etype : exception type
771 771 value : exception value
772 772 """
773 773 # This method needs to use __call__ from *this* class, not the one from
774 774 # a subclass whose signature or behavior may be different
775 775 ostream = self.ostream
776 776 ostream.flush()
777 777 ostream.write('\n'.join(self.get_exception_only(etype, evalue)))
778 778 ostream.flush()
779 779
780 780 def _some_str(self, value):
781 781 # Lifted from traceback.py
782 782 try:
783 783 return py3compat.cast_unicode(str(value))
784 784 except:
785 785 return u'<unprintable %s object>' % type(value).__name__
786 786
787 787
788 788 #----------------------------------------------------------------------------
789 789 class VerboseTB(TBTools):
790 790 """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
791 791 of HTML. Requires inspect and pydoc. Crazy, man.
792 792
793 793 Modified version which optionally strips the topmost entries from the
794 794 traceback, to be used with alternate interpreters (because their own code
795 795 would appear in the traceback)."""
796 796
797 797 def __init__(self, color_scheme='Linux', call_pdb=False, ostream=None,
798 798 tb_offset=0, long_header=False, include_vars=True,
799 799 check_cache=None, debugger_cls = None,
800 800 parent=None, config=None):
801 801 """Specify traceback offset, headers and color scheme.
802 802
803 803 Define how many frames to drop from the tracebacks. Calling it with
804 804 tb_offset=1 allows use of this handler in interpreters which will have
805 805 their own code at the top of the traceback (VerboseTB will first
806 806 remove that frame before printing the traceback info)."""
807 807 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
808 808 ostream=ostream, parent=parent, config=config)
809 809 self.tb_offset = tb_offset
810 810 self.long_header = long_header
811 811 self.include_vars = include_vars
812 812 # By default we use linecache.checkcache, but the user can provide a
813 813 # different check_cache implementation. This is used by the IPython
814 814 # kernel to provide tracebacks for interactive code that is cached,
815 815 # by a compiler instance that flushes the linecache but preserves its
816 816 # own code cache.
817 817 if check_cache is None:
818 818 check_cache = linecache.checkcache
819 819 self.check_cache = check_cache
820 820
821 821 self.debugger_cls = debugger_cls or debugger.Pdb
822 822
823 823 def format_records(self, records, last_unique, recursion_repeat):
824 824 """Format the stack frames of the traceback"""
825 825 frames = []
826 826 for r in records[:last_unique+recursion_repeat+1]:
827 827 #print '*** record:',file,lnum,func,lines,index # dbg
828 828 frames.append(self.format_record(*r))
829 829
830 830 if recursion_repeat:
831 831 frames.append('... last %d frames repeated, from the frame below ...\n' % recursion_repeat)
832 832 frames.append(self.format_record(*records[last_unique+recursion_repeat+1]))
833 833
834 834 return frames
835 835
836 836 def format_record(self, frame, file, lnum, func, lines, index):
837 837 """Format a single stack frame"""
838 838 Colors = self.Colors # just a shorthand + quicker name lookup
839 839 ColorsNormal = Colors.Normal # used a lot
840 840 col_scheme = self.color_scheme_table.active_scheme_name
841 841 indent = ' ' * INDENT_SIZE
842 842 em_normal = '%s\n%s%s' % (Colors.valEm, indent, ColorsNormal)
843 843 undefined = '%sundefined%s' % (Colors.em, ColorsNormal)
844 844 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
845 845 tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm,
846 846 ColorsNormal)
847 847 tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \
848 848 (Colors.vName, Colors.valEm, ColorsNormal)
849 849 tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal)
850 850 tpl_global_var = '%sglobal%s %s%%s%s' % (Colors.em, ColorsNormal,
851 851 Colors.vName, ColorsNormal)
852 852 tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal)
853 853
854 854 tpl_line = '%s%%s%s %%s' % (Colors.lineno, ColorsNormal)
855 855 tpl_line_em = '%s%%s%s %%s%s' % (Colors.linenoEm, Colors.line,
856 856 ColorsNormal)
857 857
858 858 abspath = os.path.abspath
859 859
860 860
861 861 if not file:
862 862 file = '?'
863 863 elif file.startswith(str("<")) and file.endswith(str(">")):
864 864 # Not a real filename, no problem...
865 865 pass
866 866 elif not os.path.isabs(file):
867 867 # Try to make the filename absolute by trying all
868 868 # sys.path entries (which is also what linecache does)
869 869 for dirname in sys.path:
870 870 try:
871 871 fullname = os.path.join(dirname, file)
872 872 if os.path.isfile(fullname):
873 873 file = os.path.abspath(fullname)
874 874 break
875 875 except Exception:
876 876 # Just in case that sys.path contains very
877 877 # strange entries...
878 878 pass
879 879
880 880 file = py3compat.cast_unicode(file, util_path.fs_encoding)
881 881 link = tpl_link % file
882 882 args, varargs, varkw, locals = fixed_getargvalues(frame)
883 883
884 884 if func == '?':
885 885 call = ''
886 886 else:
887 887 # Decide whether to include variable details or not
888 888 var_repr = self.include_vars and eqrepr or nullrepr
889 889 try:
890 890 call = tpl_call % (func, inspect.formatargvalues(args,
891 891 varargs, varkw,
892 892 locals, formatvalue=var_repr))
893 893 except KeyError:
894 894 # This happens in situations like errors inside generator
895 895 # expressions, where local variables are listed in the
896 896 # line, but can't be extracted from the frame. I'm not
897 897 # 100% sure this isn't actually a bug in inspect itself,
898 898 # but since there's no info for us to compute with, the
899 899 # best we can do is report the failure and move on. Here
900 900 # we must *not* call any traceback construction again,
901 901 # because that would mess up use of %debug later on. So we
902 902 # simply report the failure and move on. The only
903 903 # limitation will be that this frame won't have locals
904 904 # listed in the call signature. Quite subtle problem...
905 905 # I can't think of a good way to validate this in a unit
906 906 # test, but running a script consisting of:
907 907 # dict( (k,v.strip()) for (k,v) in range(10) )
908 908 # will illustrate the error, if this exception catch is
909 909 # disabled.
910 910 call = tpl_call_fail % func
911 911
912 912 # Don't attempt to tokenize binary files.
913 913 if file.endswith(('.so', '.pyd', '.dll')):
914 914 return '%s %s\n' % (link, call)
915 915
916 916 elif file.endswith(('.pyc', '.pyo')):
917 917 # Look up the corresponding source file.
918 918 try:
919 919 file = openpy.source_from_cache(file)
920 920 except ValueError:
921 921 # Failed to get the source file for some reason
922 922 # E.g. https://github.com/ipython/ipython/issues/9486
923 923 return '%s %s\n' % (link, call)
924 924
925 925 def linereader(file=file, lnum=[lnum], getline=ulinecache.getline):
926 926 line = getline(file, lnum[0])
927 927 lnum[0] += 1
928 928 return line
929 929
930 930 # Build the list of names on this line of code where the exception
931 931 # occurred.
932 932 try:
933 933 names = []
934 934 name_cont = False
935 935
936 936 for token_type, token, start, end, line in generate_tokens(linereader):
937 937 # build composite names
938 938 if token_type == tokenize.NAME and token not in keyword.kwlist:
939 939 if name_cont:
940 940 # Continuation of a dotted name
941 941 try:
942 942 names[-1].append(token)
943 943 except IndexError:
944 944 names.append([token])
945 945 name_cont = False
946 946 else:
947 947 # Regular new names. We append everything, the caller
948 948 # will be responsible for pruning the list later. It's
949 949 # very tricky to try to prune as we go, b/c composite
950 950 # names can fool us. The pruning at the end is easy
951 951 # to do (or the caller can print a list with repeated
952 952 # names if so desired.
953 953 names.append([token])
954 954 elif token == '.':
955 955 name_cont = True
956 956 elif token_type == tokenize.NEWLINE:
957 957 break
958 958
959 959 except (IndexError, UnicodeDecodeError, SyntaxError):
960 960 # signals exit of tokenizer
961 961 # SyntaxError can occur if the file is not actually Python
962 962 # - see gh-6300
963 963 pass
964 964 except tokenize.TokenError as msg:
965 965 _m = ("An unexpected error occurred while tokenizing input\n"
966 966 "The following traceback may be corrupted or invalid\n"
967 967 "The error message is: %s\n" % msg)
968 968 error(_m)
969 969
970 970 # Join composite names (e.g. "dict.fromkeys")
971 971 names = ['.'.join(n) for n in names]
972 972 # prune names list of duplicates, but keep the right order
973 973 unique_names = uniq_stable(names)
974 974
975 975 # Start loop over vars
976 976 lvals = []
977 977 if self.include_vars:
978 978 for name_full in unique_names:
979 979 name_base = name_full.split('.', 1)[0]
980 980 if name_base in frame.f_code.co_varnames:
981 981 if name_base in locals:
982 982 try:
983 983 value = repr(eval(name_full, locals))
984 984 except:
985 985 value = undefined
986 986 else:
987 987 value = undefined
988 988 name = tpl_local_var % name_full
989 989 else:
990 990 if name_base in frame.f_globals:
991 991 try:
992 992 value = repr(eval(name_full, frame.f_globals))
993 993 except:
994 994 value = undefined
995 995 else:
996 996 value = undefined
997 997 name = tpl_global_var % name_full
998 998 lvals.append(tpl_name_val % (name, value))
999 999 if lvals:
1000 1000 lvals = '%s%s' % (indent, em_normal.join(lvals))
1001 1001 else:
1002 1002 lvals = ''
1003 1003
1004 1004 level = '%s %s\n' % (link, call)
1005 1005
1006 1006 if index is None:
1007 1007 return level
1008 1008 else:
1009 1009 _line_format = PyColorize.Parser(style=col_scheme, parent=self).format2
1010 1010 return '%s%s' % (level, ''.join(
1011 1011 _format_traceback_lines(lnum, index, lines, Colors, lvals,
1012 1012 _line_format)))
1013 1013
1014 1014 def prepare_chained_exception_message(self, cause):
1015 1015 direct_cause = "\nThe above exception was the direct cause of the following exception:\n"
1016 1016 exception_during_handling = "\nDuring handling of the above exception, another exception occurred:\n"
1017 1017
1018 1018 if cause:
1019 1019 message = [[direct_cause]]
1020 1020 else:
1021 1021 message = [[exception_during_handling]]
1022 1022 return message
1023 1023
1024 1024 def prepare_header(self, etype, long_version=False):
1025 1025 colors = self.Colors # just a shorthand + quicker name lookup
1026 1026 colorsnormal = colors.Normal # used a lot
1027 1027 exc = '%s%s%s' % (colors.excName, etype, colorsnormal)
1028 1028 width = min(75, get_terminal_size()[0])
1029 1029 if long_version:
1030 1030 # Header with the exception type, python version, and date
1031 1031 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
1032 1032 date = time.ctime(time.time())
1033 1033
1034 1034 head = '%s%s%s\n%s%s%s\n%s' % (colors.topline, '-' * width, colorsnormal,
1035 1035 exc, ' ' * (width - len(str(etype)) - len(pyver)),
1036 1036 pyver, date.rjust(width) )
1037 1037 head += "\nA problem occurred executing Python code. Here is the sequence of function" \
1038 1038 "\ncalls leading up to the error, with the most recent (innermost) call last."
1039 1039 else:
1040 1040 # Simplified header
1041 1041 head = '%s%s' % (exc, 'Traceback (most recent call last)'. \
1042 1042 rjust(width - len(str(etype))) )
1043 1043
1044 1044 return head
1045 1045
1046 1046 def format_exception(self, etype, evalue):
1047 1047 colors = self.Colors # just a shorthand + quicker name lookup
1048 1048 colorsnormal = colors.Normal # used a lot
1049 1049 indent = ' ' * INDENT_SIZE
1050 1050 # Get (safely) a string form of the exception info
1051 1051 try:
1052 1052 etype_str, evalue_str = map(str, (etype, evalue))
1053 1053 except:
1054 1054 # User exception is improperly defined.
1055 1055 etype, evalue = str, sys.exc_info()[:2]
1056 1056 etype_str, evalue_str = map(str, (etype, evalue))
1057 1057 # ... and format it
1058 1058 exception = ['%s%s%s: %s' % (colors.excName, etype_str,
1059 1059 colorsnormal, py3compat.cast_unicode(evalue_str))]
1060 1060
1061 1061 if (not py3compat.PY3) and type(evalue) is types.InstanceType:
1062 1062 try:
1063 names = [w for w in dir(evalue) if isinstance(w, py3compat.string_types)]
1063 names = [w for w in dir(evalue) if isinstance(w, str)]
1064 1064 except:
1065 1065 # Every now and then, an object with funny internals blows up
1066 1066 # when dir() is called on it. We do the best we can to report
1067 1067 # the problem and continue
1068 1068 _m = '%sException reporting error (object with broken dir())%s:'
1069 1069 exception.append(_m % (colors.excName, colorsnormal))
1070 1070 etype_str, evalue_str = map(str, sys.exc_info()[:2])
1071 1071 exception.append('%s%s%s: %s' % (colors.excName, etype_str,
1072 1072 colorsnormal, py3compat.cast_unicode(evalue_str)))
1073 1073 names = []
1074 1074 for name in names:
1075 1075 value = text_repr(getattr(evalue, name))
1076 1076 exception.append('\n%s%s = %s' % (indent, name, value))
1077 1077
1078 1078 return exception
1079 1079
1080 1080 def format_exception_as_a_whole(self, etype, evalue, etb, number_of_lines_of_context, tb_offset):
1081 1081 """Formats the header, traceback and exception message for a single exception.
1082 1082
1083 1083 This may be called multiple times by Python 3 exception chaining
1084 1084 (PEP 3134).
1085 1085 """
1086 1086 # some locals
1087 1087 orig_etype = etype
1088 1088 try:
1089 1089 etype = etype.__name__
1090 1090 except AttributeError:
1091 1091 pass
1092 1092
1093 1093 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1094 1094 head = self.prepare_header(etype, self.long_header)
1095 1095 records = self.get_records(etb, number_of_lines_of_context, tb_offset)
1096 1096
1097 1097 if records is None:
1098 1098 return ""
1099 1099
1100 1100 last_unique, recursion_repeat = find_recursion(orig_etype, evalue, records)
1101 1101
1102 1102 frames = self.format_records(records, last_unique, recursion_repeat)
1103 1103
1104 1104 formatted_exception = self.format_exception(etype, evalue)
1105 1105 if records:
1106 1106 filepath, lnum = records[-1][1:3]
1107 1107 filepath = os.path.abspath(filepath)
1108 1108 ipinst = get_ipython()
1109 1109 if ipinst is not None:
1110 1110 ipinst.hooks.synchronize_with_editor(filepath, lnum, 0)
1111 1111
1112 1112 return [[head] + frames + [''.join(formatted_exception[0])]]
1113 1113
1114 1114 def get_records(self, etb, number_of_lines_of_context, tb_offset):
1115 1115 try:
1116 1116 # Try the default getinnerframes and Alex's: Alex's fixes some
1117 1117 # problems, but it generates empty tracebacks for console errors
1118 1118 # (5 blanks lines) where none should be returned.
1119 1119 return _fixed_getinnerframes(etb, number_of_lines_of_context, tb_offset)
1120 1120 except UnicodeDecodeError:
1121 1121 # This can occur if a file's encoding magic comment is wrong.
1122 1122 # I can't see a way to recover without duplicating a bunch of code
1123 1123 # from the stdlib traceback module. --TK
1124 1124 error('\nUnicodeDecodeError while processing traceback.\n')
1125 1125 return None
1126 1126 except:
1127 1127 # FIXME: I've been getting many crash reports from python 2.3
1128 1128 # users, traceable to inspect.py. If I can find a small test-case
1129 1129 # to reproduce this, I should either write a better workaround or
1130 1130 # file a bug report against inspect (if that's the real problem).
1131 1131 # So far, I haven't been able to find an isolated example to
1132 1132 # reproduce the problem.
1133 1133 inspect_error()
1134 1134 traceback.print_exc(file=self.ostream)
1135 1135 info('\nUnfortunately, your original traceback can not be constructed.\n')
1136 1136 return None
1137 1137
1138 1138 def get_parts_of_chained_exception(self, evalue):
1139 1139 def get_chained_exception(exception_value):
1140 1140 cause = getattr(exception_value, '__cause__', None)
1141 1141 if cause:
1142 1142 return cause
1143 1143 if getattr(exception_value, '__suppress_context__', False):
1144 1144 return None
1145 1145 return getattr(exception_value, '__context__', None)
1146 1146
1147 1147 chained_evalue = get_chained_exception(evalue)
1148 1148
1149 1149 if chained_evalue:
1150 1150 return chained_evalue.__class__, chained_evalue, chained_evalue.__traceback__
1151 1151
1152 1152 def structured_traceback(self, etype, evalue, etb, tb_offset=None,
1153 1153 number_of_lines_of_context=5):
1154 1154 """Return a nice text document describing the traceback."""
1155 1155
1156 1156 formatted_exception = self.format_exception_as_a_whole(etype, evalue, etb, number_of_lines_of_context,
1157 1157 tb_offset)
1158 1158
1159 1159 colors = self.Colors # just a shorthand + quicker name lookup
1160 1160 colorsnormal = colors.Normal # used a lot
1161 1161 head = '%s%s%s' % (colors.topline, '-' * min(75, get_terminal_size()[0]), colorsnormal)
1162 1162 structured_traceback_parts = [head]
1163 1163 if py3compat.PY3:
1164 1164 chained_exceptions_tb_offset = 0
1165 1165 lines_of_context = 3
1166 1166 formatted_exceptions = formatted_exception
1167 1167 exception = self.get_parts_of_chained_exception(evalue)
1168 1168 if exception:
1169 1169 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1170 1170 etype, evalue, etb = exception
1171 1171 else:
1172 1172 evalue = None
1173 1173 chained_exc_ids = set()
1174 1174 while evalue:
1175 1175 formatted_exceptions += self.format_exception_as_a_whole(etype, evalue, etb, lines_of_context,
1176 1176 chained_exceptions_tb_offset)
1177 1177 exception = self.get_parts_of_chained_exception(evalue)
1178 1178
1179 1179 if exception and not id(exception[1]) in chained_exc_ids:
1180 1180 chained_exc_ids.add(id(exception[1])) # trace exception to avoid infinite 'cause' loop
1181 1181 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1182 1182 etype, evalue, etb = exception
1183 1183 else:
1184 1184 evalue = None
1185 1185
1186 1186 # we want to see exceptions in a reversed order:
1187 1187 # the first exception should be on top
1188 1188 for formatted_exception in reversed(formatted_exceptions):
1189 1189 structured_traceback_parts += formatted_exception
1190 1190 else:
1191 1191 structured_traceback_parts += formatted_exception[0]
1192 1192
1193 1193 return structured_traceback_parts
1194 1194
1195 1195 def debugger(self, force=False):
1196 1196 """Call up the pdb debugger if desired, always clean up the tb
1197 1197 reference.
1198 1198
1199 1199 Keywords:
1200 1200
1201 1201 - force(False): by default, this routine checks the instance call_pdb
1202 1202 flag and does not actually invoke the debugger if the flag is false.
1203 1203 The 'force' option forces the debugger to activate even if the flag
1204 1204 is false.
1205 1205
1206 1206 If the call_pdb flag is set, the pdb interactive debugger is
1207 1207 invoked. In all cases, the self.tb reference to the current traceback
1208 1208 is deleted to prevent lingering references which hamper memory
1209 1209 management.
1210 1210
1211 1211 Note that each call to pdb() does an 'import readline', so if your app
1212 1212 requires a special setup for the readline completers, you'll have to
1213 1213 fix that by hand after invoking the exception handler."""
1214 1214
1215 1215 if force or self.call_pdb:
1216 1216 if self.pdb is None:
1217 1217 self.pdb = self.debugger_cls()
1218 1218 # the system displayhook may have changed, restore the original
1219 1219 # for pdb
1220 1220 display_trap = DisplayTrap(hook=sys.__displayhook__)
1221 1221 with display_trap:
1222 1222 self.pdb.reset()
1223 1223 # Find the right frame so we don't pop up inside ipython itself
1224 1224 if hasattr(self, 'tb') and self.tb is not None:
1225 1225 etb = self.tb
1226 1226 else:
1227 1227 etb = self.tb = sys.last_traceback
1228 1228 while self.tb is not None and self.tb.tb_next is not None:
1229 1229 self.tb = self.tb.tb_next
1230 1230 if etb and etb.tb_next:
1231 1231 etb = etb.tb_next
1232 1232 self.pdb.botframe = etb.tb_frame
1233 1233 self.pdb.interaction(self.tb.tb_frame, self.tb)
1234 1234
1235 1235 if hasattr(self, 'tb'):
1236 1236 del self.tb
1237 1237
1238 1238 def handler(self, info=None):
1239 1239 (etype, evalue, etb) = info or sys.exc_info()
1240 1240 self.tb = etb
1241 1241 ostream = self.ostream
1242 1242 ostream.flush()
1243 1243 ostream.write(self.text(etype, evalue, etb))
1244 1244 ostream.write('\n')
1245 1245 ostream.flush()
1246 1246
1247 1247 # Changed so an instance can just be called as VerboseTB_inst() and print
1248 1248 # out the right info on its own.
1249 1249 def __call__(self, etype=None, evalue=None, etb=None):
1250 1250 """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
1251 1251 if etb is None:
1252 1252 self.handler()
1253 1253 else:
1254 1254 self.handler((etype, evalue, etb))
1255 1255 try:
1256 1256 self.debugger()
1257 1257 except KeyboardInterrupt:
1258 1258 print("\nKeyboardInterrupt")
1259 1259
1260 1260
1261 1261 #----------------------------------------------------------------------------
1262 1262 class FormattedTB(VerboseTB, ListTB):
1263 1263 """Subclass ListTB but allow calling with a traceback.
1264 1264
1265 1265 It can thus be used as a sys.excepthook for Python > 2.1.
1266 1266
1267 1267 Also adds 'Context' and 'Verbose' modes, not available in ListTB.
1268 1268
1269 1269 Allows a tb_offset to be specified. This is useful for situations where
1270 1270 one needs to remove a number of topmost frames from the traceback (such as
1271 1271 occurs with python programs that themselves execute other python code,
1272 1272 like Python shells). """
1273 1273
1274 1274 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
1275 1275 ostream=None,
1276 1276 tb_offset=0, long_header=False, include_vars=False,
1277 1277 check_cache=None, debugger_cls=None,
1278 1278 parent=None, config=None):
1279 1279
1280 1280 # NEVER change the order of this list. Put new modes at the end:
1281 1281 self.valid_modes = ['Plain', 'Context', 'Verbose']
1282 1282 self.verbose_modes = self.valid_modes[1:3]
1283 1283
1284 1284 VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
1285 1285 ostream=ostream, tb_offset=tb_offset,
1286 1286 long_header=long_header, include_vars=include_vars,
1287 1287 check_cache=check_cache, debugger_cls=debugger_cls,
1288 1288 parent=parent, config=config)
1289 1289
1290 1290 # Different types of tracebacks are joined with different separators to
1291 1291 # form a single string. They are taken from this dict
1292 1292 self._join_chars = dict(Plain='', Context='\n', Verbose='\n')
1293 1293 # set_mode also sets the tb_join_char attribute
1294 1294 self.set_mode(mode)
1295 1295
1296 1296 def _extract_tb(self, tb):
1297 1297 if tb:
1298 1298 return traceback.extract_tb(tb)
1299 1299 else:
1300 1300 return None
1301 1301
1302 1302 def structured_traceback(self, etype, value, tb, tb_offset=None, number_of_lines_of_context=5):
1303 1303 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1304 1304 mode = self.mode
1305 1305 if mode in self.verbose_modes:
1306 1306 # Verbose modes need a full traceback
1307 1307 return VerboseTB.structured_traceback(
1308 1308 self, etype, value, tb, tb_offset, number_of_lines_of_context
1309 1309 )
1310 1310 else:
1311 1311 # We must check the source cache because otherwise we can print
1312 1312 # out-of-date source code.
1313 1313 self.check_cache()
1314 1314 # Now we can extract and format the exception
1315 1315 elist = self._extract_tb(tb)
1316 1316 return ListTB.structured_traceback(
1317 1317 self, etype, value, elist, tb_offset, number_of_lines_of_context
1318 1318 )
1319 1319
1320 1320 def stb2text(self, stb):
1321 1321 """Convert a structured traceback (a list) to a string."""
1322 1322 return self.tb_join_char.join(stb)
1323 1323
1324 1324
1325 1325 def set_mode(self, mode=None):
1326 1326 """Switch to the desired mode.
1327 1327
1328 1328 If mode is not specified, cycles through the available modes."""
1329 1329
1330 1330 if not mode:
1331 1331 new_idx = (self.valid_modes.index(self.mode) + 1 ) % \
1332 1332 len(self.valid_modes)
1333 1333 self.mode = self.valid_modes[new_idx]
1334 1334 elif mode not in self.valid_modes:
1335 1335 raise ValueError('Unrecognized mode in FormattedTB: <' + mode + '>\n'
1336 1336 'Valid modes: ' + str(self.valid_modes))
1337 1337 else:
1338 1338 self.mode = mode
1339 1339 # include variable details only in 'Verbose' mode
1340 1340 self.include_vars = (self.mode == self.valid_modes[2])
1341 1341 # Set the join character for generating text tracebacks
1342 1342 self.tb_join_char = self._join_chars[self.mode]
1343 1343
1344 1344 # some convenient shortcuts
1345 1345 def plain(self):
1346 1346 self.set_mode(self.valid_modes[0])
1347 1347
1348 1348 def context(self):
1349 1349 self.set_mode(self.valid_modes[1])
1350 1350
1351 1351 def verbose(self):
1352 1352 self.set_mode(self.valid_modes[2])
1353 1353
1354 1354
1355 1355 #----------------------------------------------------------------------------
1356 1356 class AutoFormattedTB(FormattedTB):
1357 1357 """A traceback printer which can be called on the fly.
1358 1358
1359 1359 It will find out about exceptions by itself.
1360 1360
1361 1361 A brief example::
1362 1362
1363 1363 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1364 1364 try:
1365 1365 ...
1366 1366 except:
1367 1367 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1368 1368 """
1369 1369
1370 1370 def __call__(self, etype=None, evalue=None, etb=None,
1371 1371 out=None, tb_offset=None):
1372 1372 """Print out a formatted exception traceback.
1373 1373
1374 1374 Optional arguments:
1375 1375 - out: an open file-like object to direct output to.
1376 1376
1377 1377 - tb_offset: the number of frames to skip over in the stack, on a
1378 1378 per-call basis (this overrides temporarily the instance's tb_offset
1379 1379 given at initialization time. """
1380 1380
1381 1381 if out is None:
1382 1382 out = self.ostream
1383 1383 out.flush()
1384 1384 out.write(self.text(etype, evalue, etb, tb_offset))
1385 1385 out.write('\n')
1386 1386 out.flush()
1387 1387 # FIXME: we should remove the auto pdb behavior from here and leave
1388 1388 # that to the clients.
1389 1389 try:
1390 1390 self.debugger()
1391 1391 except KeyboardInterrupt:
1392 1392 print("\nKeyboardInterrupt")
1393 1393
1394 1394 def structured_traceback(self, etype=None, value=None, tb=None,
1395 1395 tb_offset=None, number_of_lines_of_context=5):
1396 1396 if etype is None:
1397 1397 etype, value, tb = sys.exc_info()
1398 1398 self.tb = tb
1399 1399 return FormattedTB.structured_traceback(
1400 1400 self, etype, value, tb, tb_offset, number_of_lines_of_context)
1401 1401
1402 1402
1403 1403 #---------------------------------------------------------------------------
1404 1404
1405 1405 # A simple class to preserve Nathan's original functionality.
1406 1406 class ColorTB(FormattedTB):
1407 1407 """Shorthand to initialize a FormattedTB in Linux colors mode."""
1408 1408
1409 1409 def __init__(self, color_scheme='Linux', call_pdb=0, **kwargs):
1410 1410 FormattedTB.__init__(self, color_scheme=color_scheme,
1411 1411 call_pdb=call_pdb, **kwargs)
1412 1412
1413 1413
1414 1414 class SyntaxTB(ListTB):
1415 1415 """Extension which holds some state: the last exception value"""
1416 1416
1417 1417 def __init__(self, color_scheme='NoColor', parent=None, config=None):
1418 1418 ListTB.__init__(self, color_scheme, parent=parent, config=config)
1419 1419 self.last_syntax_error = None
1420 1420
1421 1421 def __call__(self, etype, value, elist):
1422 1422 self.last_syntax_error = value
1423 1423
1424 1424 ListTB.__call__(self, etype, value, elist)
1425 1425
1426 1426 def structured_traceback(self, etype, value, elist, tb_offset=None,
1427 1427 context=5):
1428 1428 # If the source file has been edited, the line in the syntax error can
1429 1429 # be wrong (retrieved from an outdated cache). This replaces it with
1430 1430 # the current value.
1431 1431 if isinstance(value, SyntaxError) \
1432 and isinstance(value.filename, py3compat.string_types) \
1432 and isinstance(value.filename, str) \
1433 1433 and isinstance(value.lineno, int):
1434 1434 linecache.checkcache(value.filename)
1435 1435 newtext = ulinecache.getline(value.filename, value.lineno)
1436 1436 if newtext:
1437 1437 value.text = newtext
1438 1438 self.last_syntax_error = value
1439 1439 return super(SyntaxTB, self).structured_traceback(etype, value, elist,
1440 1440 tb_offset=tb_offset, context=context)
1441 1441
1442 1442 def clear_err_state(self):
1443 1443 """Return the current error state and clear it"""
1444 1444 e = self.last_syntax_error
1445 1445 self.last_syntax_error = None
1446 1446 return e
1447 1447
1448 1448 def stb2text(self, stb):
1449 1449 """Convert a structured traceback (a list) to a string."""
1450 1450 return ''.join(stb)
1451 1451
1452 1452
1453 1453 # some internal-use functions
1454 1454 def text_repr(value):
1455 1455 """Hopefully pretty robust repr equivalent."""
1456 1456 # this is pretty horrible but should always return *something*
1457 1457 try:
1458 1458 return pydoc.text.repr(value)
1459 1459 except KeyboardInterrupt:
1460 1460 raise
1461 1461 except:
1462 1462 try:
1463 1463 return repr(value)
1464 1464 except KeyboardInterrupt:
1465 1465 raise
1466 1466 except:
1467 1467 try:
1468 1468 # all still in an except block so we catch
1469 1469 # getattr raising
1470 1470 name = getattr(value, '__name__', None)
1471 1471 if name:
1472 1472 # ick, recursion
1473 1473 return text_repr(name)
1474 1474 klass = getattr(value, '__class__', None)
1475 1475 if klass:
1476 1476 return '%s instance' % text_repr(klass)
1477 1477 except KeyboardInterrupt:
1478 1478 raise
1479 1479 except:
1480 1480 return 'UNRECOVERABLE REPR FAILURE'
1481 1481
1482 1482
1483 1483 def eqrepr(value, repr=text_repr):
1484 1484 return '=%s' % repr(value)
1485 1485
1486 1486
1487 1487 def nullrepr(value, repr=text_repr):
1488 1488 return ''
@@ -1,227 +1,226 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 %store magic for lightweight persistence.
4 4
5 5 Stores variables, aliases and macros in IPython's database.
6 6
7 7 To automatically restore stored variables at startup, add this to your
8 8 :file:`ipython_config.py` file::
9 9
10 10 c.StoreMagics.autorestore = True
11 11 """
12 12
13 13 # Copyright (c) IPython Development Team.
14 14 # Distributed under the terms of the Modified BSD License.
15 15
16 16 import inspect, os, sys, textwrap
17 17
18 18 from IPython.core.error import UsageError
19 19 from IPython.core.magic import Magics, magics_class, line_magic
20 20 from traitlets import Bool
21 from IPython.utils.py3compat import string_types
22 21
23 22
24 23 def restore_aliases(ip):
25 24 staliases = ip.db.get('stored_aliases', {})
26 25 for k,v in staliases.items():
27 26 #print "restore alias",k,v # dbg
28 27 #self.alias_table[k] = v
29 28 ip.alias_manager.define_alias(k,v)
30 29
31 30
32 31 def refresh_variables(ip):
33 32 db = ip.db
34 33 for key in db.keys('autorestore/*'):
35 34 # strip autorestore
36 35 justkey = os.path.basename(key)
37 36 try:
38 37 obj = db[key]
39 38 except KeyError:
40 39 print("Unable to restore variable '%s', ignoring (use %%store -d to forget!)" % justkey)
41 40 print("The error was:", sys.exc_info()[0])
42 41 else:
43 42 #print "restored",justkey,"=",obj #dbg
44 43 ip.user_ns[justkey] = obj
45 44
46 45
47 46 def restore_dhist(ip):
48 47 ip.user_ns['_dh'] = ip.db.get('dhist',[])
49 48
50 49
51 50 def restore_data(ip):
52 51 refresh_variables(ip)
53 52 restore_aliases(ip)
54 53 restore_dhist(ip)
55 54
56 55
57 56 @magics_class
58 57 class StoreMagics(Magics):
59 58 """Lightweight persistence for python variables.
60 59
61 60 Provides the %store magic."""
62 61
63 62 autorestore = Bool(False, help=
64 63 """If True, any %store-d variables will be automatically restored
65 64 when IPython starts.
66 65 """
67 66 ).tag(config=True)
68 67
69 68 def __init__(self, shell):
70 69 super(StoreMagics, self).__init__(shell=shell)
71 70 self.shell.configurables.append(self)
72 71 if self.autorestore:
73 72 restore_data(self.shell)
74 73
75 74 @line_magic
76 75 def store(self, parameter_s=''):
77 76 """Lightweight persistence for python variables.
78 77
79 78 Example::
80 79
81 80 In [1]: l = ['hello',10,'world']
82 81 In [2]: %store l
83 82 In [3]: exit
84 83
85 84 (IPython session is closed and started again...)
86 85
87 86 ville@badger:~$ ipython
88 87 In [1]: l
89 88 NameError: name 'l' is not defined
90 89 In [2]: %store -r
91 90 In [3]: l
92 91 Out[3]: ['hello', 10, 'world']
93 92
94 93 Usage:
95 94
96 95 * ``%store`` - Show list of all variables and their current
97 96 values
98 97 * ``%store spam`` - Store the *current* value of the variable spam
99 98 to disk
100 99 * ``%store -d spam`` - Remove the variable and its value from storage
101 100 * ``%store -z`` - Remove all variables from storage
102 101 * ``%store -r`` - Refresh all variables from store (overwrite
103 102 current vals)
104 103 * ``%store -r spam bar`` - Refresh specified variables from store
105 104 (delete current val)
106 105 * ``%store foo >a.txt`` - Store value of foo to new file a.txt
107 106 * ``%store foo >>a.txt`` - Append value of foo to file a.txt
108 107
109 108 It should be noted that if you change the value of a variable, you
110 109 need to %store it again if you want to persist the new value.
111 110
112 111 Note also that the variables will need to be pickleable; most basic
113 112 python types can be safely %store'd.
114 113
115 114 Also aliases can be %store'd across sessions.
116 115 """
117 116
118 117 opts,argsl = self.parse_options(parameter_s,'drz',mode='string')
119 118 args = argsl.split(None,1)
120 119 ip = self.shell
121 120 db = ip.db
122 121 # delete
123 122 if 'd' in opts:
124 123 try:
125 124 todel = args[0]
126 125 except IndexError:
127 126 raise UsageError('You must provide the variable to forget')
128 127 else:
129 128 try:
130 129 del db['autorestore/' + todel]
131 130 except:
132 131 raise UsageError("Can't delete variable '%s'" % todel)
133 132 # reset
134 133 elif 'z' in opts:
135 134 for k in db.keys('autorestore/*'):
136 135 del db[k]
137 136
138 137 elif 'r' in opts:
139 138 if args:
140 139 for arg in args:
141 140 try:
142 141 obj = db['autorestore/' + arg]
143 142 except KeyError:
144 143 print("no stored variable %s" % arg)
145 144 else:
146 145 ip.user_ns[arg] = obj
147 146 else:
148 147 restore_data(ip)
149 148
150 149 # run without arguments -> list variables & values
151 150 elif not args:
152 151 vars = db.keys('autorestore/*')
153 152 vars.sort()
154 153 if vars:
155 154 size = max(map(len, vars))
156 155 else:
157 156 size = 0
158 157
159 158 print('Stored variables and their in-db values:')
160 159 fmt = '%-'+str(size)+'s -> %s'
161 160 get = db.get
162 161 for var in vars:
163 162 justkey = os.path.basename(var)
164 163 # print 30 first characters from every var
165 164 print(fmt % (justkey, repr(get(var, '<unavailable>'))[:50]))
166 165
167 166 # default action - store the variable
168 167 else:
169 168 # %store foo >file.txt or >>file.txt
170 169 if len(args) > 1 and args[1].startswith('>'):
171 170 fnam = os.path.expanduser(args[1].lstrip('>').lstrip())
172 171 if args[1].startswith('>>'):
173 172 fil = open(fnam, 'a')
174 173 else:
175 174 fil = open(fnam, 'w')
176 175 obj = ip.ev(args[0])
177 176 print("Writing '%s' (%s) to file '%s'." % (args[0],
178 177 obj.__class__.__name__, fnam))
179 178
180 179
181 if not isinstance (obj, string_types):
180 if not isinstance (obj, str):
182 181 from pprint import pprint
183 182 pprint(obj, fil)
184 183 else:
185 184 fil.write(obj)
186 185 if not obj.endswith('\n'):
187 186 fil.write('\n')
188 187
189 188 fil.close()
190 189 return
191 190
192 191 # %store foo
193 192 try:
194 193 obj = ip.user_ns[args[0]]
195 194 except KeyError:
196 195 # it might be an alias
197 196 name = args[0]
198 197 try:
199 198 cmd = ip.alias_manager.retrieve_alias(name)
200 199 except ValueError:
201 200 raise UsageError("Unknown variable '%s'" % name)
202 201
203 202 staliases = db.get('stored_aliases',{})
204 203 staliases[name] = cmd
205 204 db['stored_aliases'] = staliases
206 205 print("Alias stored: %s (%s)" % (name, cmd))
207 206 return
208 207
209 208 else:
210 209 modname = getattr(inspect.getmodule(obj), '__name__', '')
211 210 if modname == '__main__':
212 211 print(textwrap.dedent("""\
213 212 Warning:%s is %s
214 213 Proper storage of interactively declared classes (or instances
215 214 of those classes) is not possible! Only instances
216 215 of classes in real modules on file system can be %%store'd.
217 216 """ % (args[0], obj) ))
218 217 return
219 218 #pickled = pickle.dumps(obj)
220 219 db[ 'autorestore/' + args[0] ] = obj
221 220 print("Stored '%s' (%s)" % (args[0], obj.__class__.__name__))
222 221
223 222
224 223 def load_ipython_extension(ip):
225 224 """Load the extension in IPython."""
226 225 ip.register_magics(StoreMagics)
227 226
@@ -1,490 +1,489 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Manage background (threaded) jobs conveniently from an interactive shell.
3 3
4 4 This module provides a BackgroundJobManager class. This is the main class
5 5 meant for public usage, it implements an object which can create and manage
6 6 new background jobs.
7 7
8 8 It also provides the actual job classes managed by these BackgroundJobManager
9 9 objects, see their docstrings below.
10 10
11 11
12 12 This system was inspired by discussions with B. Granger and the
13 13 BackgroundCommand class described in the book Python Scripting for
14 14 Computational Science, by H. P. Langtangen:
15 15
16 16 http://folk.uio.no/hpl/scripting
17 17
18 18 (although ultimately no code from this text was used, as IPython's system is a
19 19 separate implementation).
20 20
21 21 An example notebook is provided in our documentation illustrating interactive
22 22 use of the system.
23 23 """
24 24
25 25 #*****************************************************************************
26 26 # Copyright (C) 2005-2006 Fernando Perez <fperez@colorado.edu>
27 27 #
28 28 # Distributed under the terms of the BSD License. The full license is in
29 29 # the file COPYING, distributed as part of this software.
30 30 #*****************************************************************************
31 31
32 32 # Code begins
33 33 import sys
34 34 import threading
35 35
36 36 from IPython import get_ipython
37 37 from IPython.core.ultratb import AutoFormattedTB
38 38 from logging import error
39 from IPython.utils.py3compat import string_types
40 39
41 40
42 41 class BackgroundJobManager(object):
43 42 """Class to manage a pool of backgrounded threaded jobs.
44 43
45 44 Below, we assume that 'jobs' is a BackgroundJobManager instance.
46 45
47 46 Usage summary (see the method docstrings for details):
48 47
49 48 jobs.new(...) -> start a new job
50 49
51 50 jobs() or jobs.status() -> print status summary of all jobs
52 51
53 52 jobs[N] -> returns job number N.
54 53
55 54 foo = jobs[N].result -> assign to variable foo the result of job N
56 55
57 56 jobs[N].traceback() -> print the traceback of dead job N
58 57
59 58 jobs.remove(N) -> remove (finished) job N
60 59
61 60 jobs.flush() -> remove all finished jobs
62 61
63 62 As a convenience feature, BackgroundJobManager instances provide the
64 63 utility result and traceback methods which retrieve the corresponding
65 64 information from the jobs list:
66 65
67 66 jobs.result(N) <--> jobs[N].result
68 67 jobs.traceback(N) <--> jobs[N].traceback()
69 68
70 69 While this appears minor, it allows you to use tab completion
71 70 interactively on the job manager instance.
72 71 """
73 72
74 73 def __init__(self):
75 74 # Lists for job management, accessed via a property to ensure they're
76 75 # up to date.x
77 76 self._running = []
78 77 self._completed = []
79 78 self._dead = []
80 79 # A dict of all jobs, so users can easily access any of them
81 80 self.all = {}
82 81 # For reporting
83 82 self._comp_report = []
84 83 self._dead_report = []
85 84 # Store status codes locally for fast lookups
86 85 self._s_created = BackgroundJobBase.stat_created_c
87 86 self._s_running = BackgroundJobBase.stat_running_c
88 87 self._s_completed = BackgroundJobBase.stat_completed_c
89 88 self._s_dead = BackgroundJobBase.stat_dead_c
90 89
91 90 @property
92 91 def running(self):
93 92 self._update_status()
94 93 return self._running
95 94
96 95 @property
97 96 def dead(self):
98 97 self._update_status()
99 98 return self._dead
100 99
101 100 @property
102 101 def completed(self):
103 102 self._update_status()
104 103 return self._completed
105 104
106 105 def new(self, func_or_exp, *args, **kwargs):
107 106 """Add a new background job and start it in a separate thread.
108 107
109 108 There are two types of jobs which can be created:
110 109
111 110 1. Jobs based on expressions which can be passed to an eval() call.
112 111 The expression must be given as a string. For example:
113 112
114 113 job_manager.new('myfunc(x,y,z=1)'[,glob[,loc]])
115 114
116 115 The given expression is passed to eval(), along with the optional
117 116 global/local dicts provided. If no dicts are given, they are
118 117 extracted automatically from the caller's frame.
119 118
120 119 A Python statement is NOT a valid eval() expression. Basically, you
121 120 can only use as an eval() argument something which can go on the right
122 121 of an '=' sign and be assigned to a variable.
123 122
124 123 For example,"print 'hello'" is not valid, but '2+3' is.
125 124
126 125 2. Jobs given a function object, optionally passing additional
127 126 positional arguments:
128 127
129 128 job_manager.new(myfunc, x, y)
130 129
131 130 The function is called with the given arguments.
132 131
133 132 If you need to pass keyword arguments to your function, you must
134 133 supply them as a dict named kw:
135 134
136 135 job_manager.new(myfunc, x, y, kw=dict(z=1))
137 136
138 137 The reason for this assymmetry is that the new() method needs to
139 138 maintain access to its own keywords, and this prevents name collisions
140 139 between arguments to new() and arguments to your own functions.
141 140
142 141 In both cases, the result is stored in the job.result field of the
143 142 background job object.
144 143
145 144 You can set `daemon` attribute of the thread by giving the keyword
146 145 argument `daemon`.
147 146
148 147 Notes and caveats:
149 148
150 149 1. All threads running share the same standard output. Thus, if your
151 150 background jobs generate output, it will come out on top of whatever
152 151 you are currently writing. For this reason, background jobs are best
153 152 used with silent functions which simply return their output.
154 153
155 154 2. Threads also all work within the same global namespace, and this
156 155 system does not lock interactive variables. So if you send job to the
157 156 background which operates on a mutable object for a long time, and
158 157 start modifying that same mutable object interactively (or in another
159 158 backgrounded job), all sorts of bizarre behaviour will occur.
160 159
161 160 3. If a background job is spending a lot of time inside a C extension
162 161 module which does not release the Python Global Interpreter Lock
163 162 (GIL), this will block the IPython prompt. This is simply because the
164 163 Python interpreter can only switch between threads at Python
165 164 bytecodes. While the execution is inside C code, the interpreter must
166 165 simply wait unless the extension module releases the GIL.
167 166
168 167 4. There is no way, due to limitations in the Python threads library,
169 168 to kill a thread once it has started."""
170 169
171 170 if callable(func_or_exp):
172 171 kw = kwargs.get('kw',{})
173 172 job = BackgroundJobFunc(func_or_exp,*args,**kw)
174 elif isinstance(func_or_exp, string_types):
173 elif isinstance(func_or_exp, str):
175 174 if not args:
176 175 frame = sys._getframe(1)
177 176 glob, loc = frame.f_globals, frame.f_locals
178 177 elif len(args)==1:
179 178 glob = loc = args[0]
180 179 elif len(args)==2:
181 180 glob,loc = args
182 181 else:
183 182 raise ValueError(
184 183 'Expression jobs take at most 2 args (globals,locals)')
185 184 job = BackgroundJobExpr(func_or_exp, glob, loc)
186 185 else:
187 186 raise TypeError('invalid args for new job')
188 187
189 188 if kwargs.get('daemon', False):
190 189 job.daemon = True
191 190 job.num = len(self.all)+1 if self.all else 0
192 191 self.running.append(job)
193 192 self.all[job.num] = job
194 193 print('Starting job # %s in a separate thread.' % job.num)
195 194 job.start()
196 195 return job
197 196
198 197 def __getitem__(self, job_key):
199 198 num = job_key if isinstance(job_key, int) else job_key.num
200 199 return self.all[num]
201 200
202 201 def __call__(self):
203 202 """An alias to self.status(),
204 203
205 204 This allows you to simply call a job manager instance much like the
206 205 Unix `jobs` shell command."""
207 206
208 207 return self.status()
209 208
210 209 def _update_status(self):
211 210 """Update the status of the job lists.
212 211
213 212 This method moves finished jobs to one of two lists:
214 213 - self.completed: jobs which completed successfully
215 214 - self.dead: jobs which finished but died.
216 215
217 216 It also copies those jobs to corresponding _report lists. These lists
218 217 are used to report jobs completed/dead since the last update, and are
219 218 then cleared by the reporting function after each call."""
220 219
221 220 # Status codes
222 221 srun, scomp, sdead = self._s_running, self._s_completed, self._s_dead
223 222 # State lists, use the actual lists b/c the public names are properties
224 223 # that call this very function on access
225 224 running, completed, dead = self._running, self._completed, self._dead
226 225
227 226 # Now, update all state lists
228 227 for num, job in enumerate(running):
229 228 stat = job.stat_code
230 229 if stat == srun:
231 230 continue
232 231 elif stat == scomp:
233 232 completed.append(job)
234 233 self._comp_report.append(job)
235 234 running[num] = False
236 235 elif stat == sdead:
237 236 dead.append(job)
238 237 self._dead_report.append(job)
239 238 running[num] = False
240 239 # Remove dead/completed jobs from running list
241 240 running[:] = filter(None, running)
242 241
243 242 def _group_report(self,group,name):
244 243 """Report summary for a given job group.
245 244
246 245 Return True if the group had any elements."""
247 246
248 247 if group:
249 248 print('%s jobs:' % name)
250 249 for job in group:
251 250 print('%s : %s' % (job.num,job))
252 251 print()
253 252 return True
254 253
255 254 def _group_flush(self,group,name):
256 255 """Flush a given job group
257 256
258 257 Return True if the group had any elements."""
259 258
260 259 njobs = len(group)
261 260 if njobs:
262 261 plural = {1:''}.setdefault(njobs,'s')
263 262 print('Flushing %s %s job%s.' % (njobs,name,plural))
264 263 group[:] = []
265 264 return True
266 265
267 266 def _status_new(self):
268 267 """Print the status of newly finished jobs.
269 268
270 269 Return True if any new jobs are reported.
271 270
272 271 This call resets its own state every time, so it only reports jobs
273 272 which have finished since the last time it was called."""
274 273
275 274 self._update_status()
276 275 new_comp = self._group_report(self._comp_report, 'Completed')
277 276 new_dead = self._group_report(self._dead_report,
278 277 'Dead, call jobs.traceback() for details')
279 278 self._comp_report[:] = []
280 279 self._dead_report[:] = []
281 280 return new_comp or new_dead
282 281
283 282 def status(self,verbose=0):
284 283 """Print a status of all jobs currently being managed."""
285 284
286 285 self._update_status()
287 286 self._group_report(self.running,'Running')
288 287 self._group_report(self.completed,'Completed')
289 288 self._group_report(self.dead,'Dead')
290 289 # Also flush the report queues
291 290 self._comp_report[:] = []
292 291 self._dead_report[:] = []
293 292
294 293 def remove(self,num):
295 294 """Remove a finished (completed or dead) job."""
296 295
297 296 try:
298 297 job = self.all[num]
299 298 except KeyError:
300 299 error('Job #%s not found' % num)
301 300 else:
302 301 stat_code = job.stat_code
303 302 if stat_code == self._s_running:
304 303 error('Job #%s is still running, it can not be removed.' % num)
305 304 return
306 305 elif stat_code == self._s_completed:
307 306 self.completed.remove(job)
308 307 elif stat_code == self._s_dead:
309 308 self.dead.remove(job)
310 309
311 310 def flush(self):
312 311 """Flush all finished jobs (completed and dead) from lists.
313 312
314 313 Running jobs are never flushed.
315 314
316 315 It first calls _status_new(), to update info. If any jobs have
317 316 completed since the last _status_new() call, the flush operation
318 317 aborts."""
319 318
320 319 # Remove the finished jobs from the master dict
321 320 alljobs = self.all
322 321 for job in self.completed+self.dead:
323 322 del(alljobs[job.num])
324 323
325 324 # Now flush these lists completely
326 325 fl_comp = self._group_flush(self.completed, 'Completed')
327 326 fl_dead = self._group_flush(self.dead, 'Dead')
328 327 if not (fl_comp or fl_dead):
329 328 print('No jobs to flush.')
330 329
331 330 def result(self,num):
332 331 """result(N) -> return the result of job N."""
333 332 try:
334 333 return self.all[num].result
335 334 except KeyError:
336 335 error('Job #%s not found' % num)
337 336
338 337 def _traceback(self, job):
339 338 num = job if isinstance(job, int) else job.num
340 339 try:
341 340 self.all[num].traceback()
342 341 except KeyError:
343 342 error('Job #%s not found' % num)
344 343
345 344 def traceback(self, job=None):
346 345 if job is None:
347 346 self._update_status()
348 347 for deadjob in self.dead:
349 348 print("Traceback for: %r" % deadjob)
350 349 self._traceback(deadjob)
351 350 print()
352 351 else:
353 352 self._traceback(job)
354 353
355 354
356 355 class BackgroundJobBase(threading.Thread):
357 356 """Base class to build BackgroundJob classes.
358 357
359 358 The derived classes must implement:
360 359
361 360 - Their own __init__, since the one here raises NotImplementedError. The
362 361 derived constructor must call self._init() at the end, to provide common
363 362 initialization.
364 363
365 364 - A strform attribute used in calls to __str__.
366 365
367 366 - A call() method, which will make the actual execution call and must
368 367 return a value to be held in the 'result' field of the job object.
369 368 """
370 369
371 370 # Class constants for status, in string and as numerical codes (when
372 371 # updating jobs lists, we don't want to do string comparisons). This will
373 372 # be done at every user prompt, so it has to be as fast as possible
374 373 stat_created = 'Created'; stat_created_c = 0
375 374 stat_running = 'Running'; stat_running_c = 1
376 375 stat_completed = 'Completed'; stat_completed_c = 2
377 376 stat_dead = 'Dead (Exception), call jobs.traceback() for details'
378 377 stat_dead_c = -1
379 378
380 379 def __init__(self):
381 380 """Must be implemented in subclasses.
382 381
383 382 Subclasses must call :meth:`_init` for standard initialisation.
384 383 """
385 384 raise NotImplementedError("This class can not be instantiated directly.")
386 385
387 386 def _init(self):
388 387 """Common initialization for all BackgroundJob objects"""
389 388
390 389 for attr in ['call','strform']:
391 390 assert hasattr(self,attr), "Missing attribute <%s>" % attr
392 391
393 392 # The num tag can be set by an external job manager
394 393 self.num = None
395 394
396 395 self.status = BackgroundJobBase.stat_created
397 396 self.stat_code = BackgroundJobBase.stat_created_c
398 397 self.finished = False
399 398 self.result = '<BackgroundJob has not completed>'
400 399
401 400 # reuse the ipython traceback handler if we can get to it, otherwise
402 401 # make a new one
403 402 try:
404 403 make_tb = get_ipython().InteractiveTB.text
405 404 except:
406 405 make_tb = AutoFormattedTB(mode = 'Context',
407 406 color_scheme='NoColor',
408 407 tb_offset = 1).text
409 408 # Note that the actual API for text() requires the three args to be
410 409 # passed in, so we wrap it in a simple lambda.
411 410 self._make_tb = lambda : make_tb(None, None, None)
412 411
413 412 # Hold a formatted traceback if one is generated.
414 413 self._tb = None
415 414
416 415 threading.Thread.__init__(self)
417 416
418 417 def __str__(self):
419 418 return self.strform
420 419
421 420 def __repr__(self):
422 421 return '<BackgroundJob #%d: %s>' % (self.num, self.strform)
423 422
424 423 def traceback(self):
425 424 print(self._tb)
426 425
427 426 def run(self):
428 427 try:
429 428 self.status = BackgroundJobBase.stat_running
430 429 self.stat_code = BackgroundJobBase.stat_running_c
431 430 self.result = self.call()
432 431 except:
433 432 self.status = BackgroundJobBase.stat_dead
434 433 self.stat_code = BackgroundJobBase.stat_dead_c
435 434 self.finished = None
436 435 self.result = ('<BackgroundJob died, call jobs.traceback() for details>')
437 436 self._tb = self._make_tb()
438 437 else:
439 438 self.status = BackgroundJobBase.stat_completed
440 439 self.stat_code = BackgroundJobBase.stat_completed_c
441 440 self.finished = True
442 441
443 442
444 443 class BackgroundJobExpr(BackgroundJobBase):
445 444 """Evaluate an expression as a background job (uses a separate thread)."""
446 445
447 446 def __init__(self, expression, glob=None, loc=None):
448 447 """Create a new job from a string which can be fed to eval().
449 448
450 449 global/locals dicts can be provided, which will be passed to the eval
451 450 call."""
452 451
453 452 # fail immediately if the given expression can't be compiled
454 453 self.code = compile(expression,'<BackgroundJob compilation>','eval')
455 454
456 455 glob = {} if glob is None else glob
457 456 loc = {} if loc is None else loc
458 457 self.expression = self.strform = expression
459 458 self.glob = glob
460 459 self.loc = loc
461 460 self._init()
462 461
463 462 def call(self):
464 463 return eval(self.code,self.glob,self.loc)
465 464
466 465
467 466 class BackgroundJobFunc(BackgroundJobBase):
468 467 """Run a function call as a background job (uses a separate thread)."""
469 468
470 469 def __init__(self, func, *args, **kwargs):
471 470 """Create a new job from a callable object.
472 471
473 472 Any positional arguments and keyword args given to this constructor
474 473 after the initial callable are passed directly to it."""
475 474
476 475 if not callable(func):
477 476 raise TypeError(
478 477 'first argument to BackgroundJobFunc must be callable')
479 478
480 479 self.func = func
481 480 self.args = args
482 481 self.kwargs = kwargs
483 482 # The string form will only include the function passed, because
484 483 # generating string representations of the arguments is a potentially
485 484 # _very_ expensive operation (e.g. with large arrays).
486 485 self.strform = str(func)
487 486 self._init()
488 487
489 488 def call(self):
490 489 return self.func(*self.args, **self.kwargs)
@@ -1,867 +1,866 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Python advanced pretty printer. This pretty printer is intended to
4 4 replace the old `pprint` python module which does not allow developers
5 5 to provide their own pretty print callbacks.
6 6
7 7 This module is based on ruby's `prettyprint.rb` library by `Tanaka Akira`.
8 8
9 9
10 10 Example Usage
11 11 -------------
12 12
13 13 To directly print the representation of an object use `pprint`::
14 14
15 15 from pretty import pprint
16 16 pprint(complex_object)
17 17
18 18 To get a string of the output use `pretty`::
19 19
20 20 from pretty import pretty
21 21 string = pretty(complex_object)
22 22
23 23
24 24 Extending
25 25 ---------
26 26
27 27 The pretty library allows developers to add pretty printing rules for their
28 28 own objects. This process is straightforward. All you have to do is to
29 29 add a `_repr_pretty_` method to your object and call the methods on the
30 30 pretty printer passed::
31 31
32 32 class MyObject(object):
33 33
34 34 def _repr_pretty_(self, p, cycle):
35 35 ...
36 36
37 37 Here is an example implementation of a `_repr_pretty_` method for a list
38 38 subclass::
39 39
40 40 class MyList(list):
41 41
42 42 def _repr_pretty_(self, p, cycle):
43 43 if cycle:
44 44 p.text('MyList(...)')
45 45 else:
46 46 with p.group(8, 'MyList([', '])'):
47 47 for idx, item in enumerate(self):
48 48 if idx:
49 49 p.text(',')
50 50 p.breakable()
51 51 p.pretty(item)
52 52
53 53 The `cycle` parameter is `True` if pretty detected a cycle. You *have* to
54 54 react to that or the result is an infinite loop. `p.text()` just adds
55 55 non breaking text to the output, `p.breakable()` either adds a whitespace
56 56 or breaks here. If you pass it an argument it's used instead of the
57 57 default space. `p.pretty` prettyprints another object using the pretty print
58 58 method.
59 59
60 60 The first parameter to the `group` function specifies the extra indentation
61 61 of the next line. In this example the next item will either be on the same
62 62 line (if the items are short enough) or aligned with the right edge of the
63 63 opening bracket of `MyList`.
64 64
65 65 If you just want to indent something you can use the group function
66 66 without open / close parameters. You can also use this code::
67 67
68 68 with p.indent(2):
69 69 ...
70 70
71 71 Inheritance diagram:
72 72
73 73 .. inheritance-diagram:: IPython.lib.pretty
74 74 :parts: 3
75 75
76 76 :copyright: 2007 by Armin Ronacher.
77 77 Portions (c) 2009 by Robert Kern.
78 78 :license: BSD License.
79 79 """
80 80 from contextlib import contextmanager
81 81 import sys
82 82 import types
83 83 import re
84 84 import datetime
85 85 from collections import deque
86 86
87 from IPython.utils.py3compat import PY3, PYPY, cast_unicode, string_types
87 from IPython.utils.py3compat import PY3, PYPY, cast_unicode
88 88 from IPython.utils.encoding import get_stream_enc
89 89
90 90 from io import StringIO
91 91
92 92
93 93 __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter',
94 94 'for_type', 'for_type_by_name']
95 95
96 96
97 97 MAX_SEQ_LENGTH = 1000
98 98 _re_pattern_type = type(re.compile(''))
99 99
100 100 def _safe_getattr(obj, attr, default=None):
101 101 """Safe version of getattr.
102 102
103 103 Same as getattr, but will return ``default`` on any Exception,
104 104 rather than raising.
105 105 """
106 106 try:
107 107 return getattr(obj, attr, default)
108 108 except Exception:
109 109 return default
110 110
111 111 if PY3:
112 112 CUnicodeIO = StringIO
113 113 else:
114 114 class CUnicodeIO(StringIO):
115 115 """StringIO that casts str to unicode on Python 2"""
116 116 def write(self, text):
117 117 return super(CUnicodeIO, self).write(
118 118 cast_unicode(text, encoding=get_stream_enc(sys.stdout)))
119 119
120 120
121 121 def pretty(obj, verbose=False, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
122 122 """
123 123 Pretty print the object's representation.
124 124 """
125 125 stream = CUnicodeIO()
126 126 printer = RepresentationPrinter(stream, verbose, max_width, newline, max_seq_length=max_seq_length)
127 127 printer.pretty(obj)
128 128 printer.flush()
129 129 return stream.getvalue()
130 130
131 131
132 132 def pprint(obj, verbose=False, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
133 133 """
134 134 Like `pretty` but print to stdout.
135 135 """
136 136 printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline, max_seq_length=max_seq_length)
137 137 printer.pretty(obj)
138 138 printer.flush()
139 139 sys.stdout.write(newline)
140 140 sys.stdout.flush()
141 141
142 142 class _PrettyPrinterBase(object):
143 143
144 144 @contextmanager
145 145 def indent(self, indent):
146 146 """with statement support for indenting/dedenting."""
147 147 self.indentation += indent
148 148 try:
149 149 yield
150 150 finally:
151 151 self.indentation -= indent
152 152
153 153 @contextmanager
154 154 def group(self, indent=0, open='', close=''):
155 155 """like begin_group / end_group but for the with statement."""
156 156 self.begin_group(indent, open)
157 157 try:
158 158 yield
159 159 finally:
160 160 self.end_group(indent, close)
161 161
162 162 class PrettyPrinter(_PrettyPrinterBase):
163 163 """
164 164 Baseclass for the `RepresentationPrinter` prettyprinter that is used to
165 165 generate pretty reprs of objects. Contrary to the `RepresentationPrinter`
166 166 this printer knows nothing about the default pprinters or the `_repr_pretty_`
167 167 callback method.
168 168 """
169 169
170 170 def __init__(self, output, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
171 171 self.output = output
172 172 self.max_width = max_width
173 173 self.newline = newline
174 174 self.max_seq_length = max_seq_length
175 175 self.output_width = 0
176 176 self.buffer_width = 0
177 177 self.buffer = deque()
178 178
179 179 root_group = Group(0)
180 180 self.group_stack = [root_group]
181 181 self.group_queue = GroupQueue(root_group)
182 182 self.indentation = 0
183 183
184 184 def _break_outer_groups(self):
185 185 while self.max_width < self.output_width + self.buffer_width:
186 186 group = self.group_queue.deq()
187 187 if not group:
188 188 return
189 189 while group.breakables:
190 190 x = self.buffer.popleft()
191 191 self.output_width = x.output(self.output, self.output_width)
192 192 self.buffer_width -= x.width
193 193 while self.buffer and isinstance(self.buffer[0], Text):
194 194 x = self.buffer.popleft()
195 195 self.output_width = x.output(self.output, self.output_width)
196 196 self.buffer_width -= x.width
197 197
198 198 def text(self, obj):
199 199 """Add literal text to the output."""
200 200 width = len(obj)
201 201 if self.buffer:
202 202 text = self.buffer[-1]
203 203 if not isinstance(text, Text):
204 204 text = Text()
205 205 self.buffer.append(text)
206 206 text.add(obj, width)
207 207 self.buffer_width += width
208 208 self._break_outer_groups()
209 209 else:
210 210 self.output.write(obj)
211 211 self.output_width += width
212 212
213 213 def breakable(self, sep=' '):
214 214 """
215 215 Add a breakable separator to the output. This does not mean that it
216 216 will automatically break here. If no breaking on this position takes
217 217 place the `sep` is inserted which default to one space.
218 218 """
219 219 width = len(sep)
220 220 group = self.group_stack[-1]
221 221 if group.want_break:
222 222 self.flush()
223 223 self.output.write(self.newline)
224 224 self.output.write(' ' * self.indentation)
225 225 self.output_width = self.indentation
226 226 self.buffer_width = 0
227 227 else:
228 228 self.buffer.append(Breakable(sep, width, self))
229 229 self.buffer_width += width
230 230 self._break_outer_groups()
231 231
232 232 def break_(self):
233 233 """
234 234 Explicitly insert a newline into the output, maintaining correct indentation.
235 235 """
236 236 self.flush()
237 237 self.output.write(self.newline)
238 238 self.output.write(' ' * self.indentation)
239 239 self.output_width = self.indentation
240 240 self.buffer_width = 0
241 241
242 242
243 243 def begin_group(self, indent=0, open=''):
244 244 """
245 245 Begin a group. If you want support for python < 2.5 which doesn't has
246 246 the with statement this is the preferred way:
247 247
248 248 p.begin_group(1, '{')
249 249 ...
250 250 p.end_group(1, '}')
251 251
252 252 The python 2.5 expression would be this:
253 253
254 254 with p.group(1, '{', '}'):
255 255 ...
256 256
257 257 The first parameter specifies the indentation for the next line (usually
258 258 the width of the opening text), the second the opening text. All
259 259 parameters are optional.
260 260 """
261 261 if open:
262 262 self.text(open)
263 263 group = Group(self.group_stack[-1].depth + 1)
264 264 self.group_stack.append(group)
265 265 self.group_queue.enq(group)
266 266 self.indentation += indent
267 267
268 268 def _enumerate(self, seq):
269 269 """like enumerate, but with an upper limit on the number of items"""
270 270 for idx, x in enumerate(seq):
271 271 if self.max_seq_length and idx >= self.max_seq_length:
272 272 self.text(',')
273 273 self.breakable()
274 274 self.text('...')
275 275 return
276 276 yield idx, x
277 277
278 278 def end_group(self, dedent=0, close=''):
279 279 """End a group. See `begin_group` for more details."""
280 280 self.indentation -= dedent
281 281 group = self.group_stack.pop()
282 282 if not group.breakables:
283 283 self.group_queue.remove(group)
284 284 if close:
285 285 self.text(close)
286 286
287 287 def flush(self):
288 288 """Flush data that is left in the buffer."""
289 289 for data in self.buffer:
290 290 self.output_width += data.output(self.output, self.output_width)
291 291 self.buffer.clear()
292 292 self.buffer_width = 0
293 293
294 294
295 295 def _get_mro(obj_class):
296 296 """ Get a reasonable method resolution order of a class and its superclasses
297 297 for both old-style and new-style classes.
298 298 """
299 299 if not hasattr(obj_class, '__mro__'):
300 300 # Old-style class. Mix in object to make a fake new-style class.
301 301 try:
302 302 obj_class = type(obj_class.__name__, (obj_class, object), {})
303 303 except TypeError:
304 304 # Old-style extension type that does not descend from object.
305 305 # FIXME: try to construct a more thorough MRO.
306 306 mro = [obj_class]
307 307 else:
308 308 mro = obj_class.__mro__[1:-1]
309 309 else:
310 310 mro = obj_class.__mro__
311 311 return mro
312 312
313 313
314 314 class RepresentationPrinter(PrettyPrinter):
315 315 """
316 316 Special pretty printer that has a `pretty` method that calls the pretty
317 317 printer for a python object.
318 318
319 319 This class stores processing data on `self` so you must *never* use
320 320 this class in a threaded environment. Always lock it or reinstanciate
321 321 it.
322 322
323 323 Instances also have a verbose flag callbacks can access to control their
324 324 output. For example the default instance repr prints all attributes and
325 325 methods that are not prefixed by an underscore if the printer is in
326 326 verbose mode.
327 327 """
328 328
329 329 def __init__(self, output, verbose=False, max_width=79, newline='\n',
330 330 singleton_pprinters=None, type_pprinters=None, deferred_pprinters=None,
331 331 max_seq_length=MAX_SEQ_LENGTH):
332 332
333 333 PrettyPrinter.__init__(self, output, max_width, newline, max_seq_length=max_seq_length)
334 334 self.verbose = verbose
335 335 self.stack = []
336 336 if singleton_pprinters is None:
337 337 singleton_pprinters = _singleton_pprinters.copy()
338 338 self.singleton_pprinters = singleton_pprinters
339 339 if type_pprinters is None:
340 340 type_pprinters = _type_pprinters.copy()
341 341 self.type_pprinters = type_pprinters
342 342 if deferred_pprinters is None:
343 343 deferred_pprinters = _deferred_type_pprinters.copy()
344 344 self.deferred_pprinters = deferred_pprinters
345 345
346 346 def pretty(self, obj):
347 347 """Pretty print the given object."""
348 348 obj_id = id(obj)
349 349 cycle = obj_id in self.stack
350 350 self.stack.append(obj_id)
351 351 self.begin_group()
352 352 try:
353 353 obj_class = _safe_getattr(obj, '__class__', None) or type(obj)
354 354 # First try to find registered singleton printers for the type.
355 355 try:
356 356 printer = self.singleton_pprinters[obj_id]
357 357 except (TypeError, KeyError):
358 358 pass
359 359 else:
360 360 return printer(obj, self, cycle)
361 361 # Next walk the mro and check for either:
362 362 # 1) a registered printer
363 363 # 2) a _repr_pretty_ method
364 364 for cls in _get_mro(obj_class):
365 365 if cls in self.type_pprinters:
366 366 # printer registered in self.type_pprinters
367 367 return self.type_pprinters[cls](obj, self, cycle)
368 368 else:
369 369 # deferred printer
370 370 printer = self._in_deferred_types(cls)
371 371 if printer is not None:
372 372 return printer(obj, self, cycle)
373 373 else:
374 374 # Finally look for special method names.
375 375 # Some objects automatically create any requested
376 376 # attribute. Try to ignore most of them by checking for
377 377 # callability.
378 378 if '_repr_pretty_' in cls.__dict__:
379 379 meth = cls._repr_pretty_
380 380 if callable(meth):
381 381 return meth(obj, self, cycle)
382 382 return _default_pprint(obj, self, cycle)
383 383 finally:
384 384 self.end_group()
385 385 self.stack.pop()
386 386
387 387 def _in_deferred_types(self, cls):
388 388 """
389 389 Check if the given class is specified in the deferred type registry.
390 390
391 391 Returns the printer from the registry if it exists, and None if the
392 392 class is not in the registry. Successful matches will be moved to the
393 393 regular type registry for future use.
394 394 """
395 395 mod = _safe_getattr(cls, '__module__', None)
396 396 name = _safe_getattr(cls, '__name__', None)
397 397 key = (mod, name)
398 398 printer = None
399 399 if key in self.deferred_pprinters:
400 400 # Move the printer over to the regular registry.
401 401 printer = self.deferred_pprinters.pop(key)
402 402 self.type_pprinters[cls] = printer
403 403 return printer
404 404
405 405
406 406 class Printable(object):
407 407
408 408 def output(self, stream, output_width):
409 409 return output_width
410 410
411 411
412 412 class Text(Printable):
413 413
414 414 def __init__(self):
415 415 self.objs = []
416 416 self.width = 0
417 417
418 418 def output(self, stream, output_width):
419 419 for obj in self.objs:
420 420 stream.write(obj)
421 421 return output_width + self.width
422 422
423 423 def add(self, obj, width):
424 424 self.objs.append(obj)
425 425 self.width += width
426 426
427 427
428 428 class Breakable(Printable):
429 429
430 430 def __init__(self, seq, width, pretty):
431 431 self.obj = seq
432 432 self.width = width
433 433 self.pretty = pretty
434 434 self.indentation = pretty.indentation
435 435 self.group = pretty.group_stack[-1]
436 436 self.group.breakables.append(self)
437 437
438 438 def output(self, stream, output_width):
439 439 self.group.breakables.popleft()
440 440 if self.group.want_break:
441 441 stream.write(self.pretty.newline)
442 442 stream.write(' ' * self.indentation)
443 443 return self.indentation
444 444 if not self.group.breakables:
445 445 self.pretty.group_queue.remove(self.group)
446 446 stream.write(self.obj)
447 447 return output_width + self.width
448 448
449 449
450 450 class Group(Printable):
451 451
452 452 def __init__(self, depth):
453 453 self.depth = depth
454 454 self.breakables = deque()
455 455 self.want_break = False
456 456
457 457
458 458 class GroupQueue(object):
459 459
460 460 def __init__(self, *groups):
461 461 self.queue = []
462 462 for group in groups:
463 463 self.enq(group)
464 464
465 465 def enq(self, group):
466 466 depth = group.depth
467 467 while depth > len(self.queue) - 1:
468 468 self.queue.append([])
469 469 self.queue[depth].append(group)
470 470
471 471 def deq(self):
472 472 for stack in self.queue:
473 473 for idx, group in enumerate(reversed(stack)):
474 474 if group.breakables:
475 475 del stack[idx]
476 476 group.want_break = True
477 477 return group
478 478 for group in stack:
479 479 group.want_break = True
480 480 del stack[:]
481 481
482 482 def remove(self, group):
483 483 try:
484 484 self.queue[group.depth].remove(group)
485 485 except ValueError:
486 486 pass
487 487
488 488 try:
489 489 _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
490 490 except AttributeError: # Python 3
491 491 _baseclass_reprs = (object.__repr__,)
492 492
493 493
494 494 def _default_pprint(obj, p, cycle):
495 495 """
496 496 The default print function. Used if an object does not provide one and
497 497 it's none of the builtin objects.
498 498 """
499 499 klass = _safe_getattr(obj, '__class__', None) or type(obj)
500 500 if _safe_getattr(klass, '__repr__', None) not in _baseclass_reprs:
501 501 # A user-provided repr. Find newlines and replace them with p.break_()
502 502 _repr_pprint(obj, p, cycle)
503 503 return
504 504 p.begin_group(1, '<')
505 505 p.pretty(klass)
506 506 p.text(' at 0x%x' % id(obj))
507 507 if cycle:
508 508 p.text(' ...')
509 509 elif p.verbose:
510 510 first = True
511 511 for key in dir(obj):
512 512 if not key.startswith('_'):
513 513 try:
514 514 value = getattr(obj, key)
515 515 except AttributeError:
516 516 continue
517 517 if isinstance(value, types.MethodType):
518 518 continue
519 519 if not first:
520 520 p.text(',')
521 521 p.breakable()
522 522 p.text(key)
523 523 p.text('=')
524 524 step = len(key) + 1
525 525 p.indentation += step
526 526 p.pretty(value)
527 527 p.indentation -= step
528 528 first = False
529 529 p.end_group(1, '>')
530 530
531 531
532 532 def _seq_pprinter_factory(start, end, basetype):
533 533 """
534 534 Factory that returns a pprint function useful for sequences. Used by
535 535 the default pprint for tuples, dicts, and lists.
536 536 """
537 537 def inner(obj, p, cycle):
538 538 typ = type(obj)
539 539 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
540 540 # If the subclass provides its own repr, use it instead.
541 541 return p.text(typ.__repr__(obj))
542 542
543 543 if cycle:
544 544 return p.text(start + '...' + end)
545 545 step = len(start)
546 546 p.begin_group(step, start)
547 547 for idx, x in p._enumerate(obj):
548 548 if idx:
549 549 p.text(',')
550 550 p.breakable()
551 551 p.pretty(x)
552 552 if len(obj) == 1 and type(obj) is tuple:
553 553 # Special case for 1-item tuples.
554 554 p.text(',')
555 555 p.end_group(step, end)
556 556 return inner
557 557
558 558
559 559 def _set_pprinter_factory(start, end, basetype):
560 560 """
561 561 Factory that returns a pprint function useful for sets and frozensets.
562 562 """
563 563 def inner(obj, p, cycle):
564 564 typ = type(obj)
565 565 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
566 566 # If the subclass provides its own repr, use it instead.
567 567 return p.text(typ.__repr__(obj))
568 568
569 569 if cycle:
570 570 return p.text(start + '...' + end)
571 571 if len(obj) == 0:
572 572 # Special case.
573 573 p.text(basetype.__name__ + '()')
574 574 else:
575 575 step = len(start)
576 576 p.begin_group(step, start)
577 577 # Like dictionary keys, we will try to sort the items if there aren't too many
578 578 items = obj
579 579 if not (p.max_seq_length and len(obj) >= p.max_seq_length):
580 580 try:
581 581 items = sorted(obj)
582 582 except Exception:
583 583 # Sometimes the items don't sort.
584 584 pass
585 585 for idx, x in p._enumerate(items):
586 586 if idx:
587 587 p.text(',')
588 588 p.breakable()
589 589 p.pretty(x)
590 590 p.end_group(step, end)
591 591 return inner
592 592
593 593
594 594 def _dict_pprinter_factory(start, end, basetype=None):
595 595 """
596 596 Factory that returns a pprint function used by the default pprint of
597 597 dicts and dict proxies.
598 598 """
599 599 def inner(obj, p, cycle):
600 600 typ = type(obj)
601 601 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
602 602 # If the subclass provides its own repr, use it instead.
603 603 return p.text(typ.__repr__(obj))
604 604
605 605 if cycle:
606 606 return p.text('{...}')
607 607 step = len(start)
608 608 p.begin_group(step, start)
609 609 keys = obj.keys()
610 610 # if dict isn't large enough to be truncated, sort keys before displaying
611 611 if not (p.max_seq_length and len(obj) >= p.max_seq_length):
612 612 try:
613 613 keys = sorted(keys)
614 614 except Exception:
615 615 # Sometimes the keys don't sort.
616 616 pass
617 617 for idx, key in p._enumerate(keys):
618 618 if idx:
619 619 p.text(',')
620 620 p.breakable()
621 621 p.pretty(key)
622 622 p.text(': ')
623 623 p.pretty(obj[key])
624 624 p.end_group(step, end)
625 625 return inner
626 626
627 627
628 628 def _super_pprint(obj, p, cycle):
629 629 """The pprint for the super type."""
630 630 p.begin_group(8, '<super: ')
631 631 p.pretty(obj.__thisclass__)
632 632 p.text(',')
633 633 p.breakable()
634 634 if PYPY: # In PyPy, super() objects don't have __self__ attributes
635 635 dself = obj.__repr__.__self__
636 636 p.pretty(None if dself is obj else dself)
637 637 else:
638 638 p.pretty(obj.__self__)
639 639 p.end_group(8, '>')
640 640
641 641
642 642 def _re_pattern_pprint(obj, p, cycle):
643 643 """The pprint function for regular expression patterns."""
644 644 p.text('re.compile(')
645 645 pattern = repr(obj.pattern)
646 646 if pattern[:1] in 'uU':
647 647 pattern = pattern[1:]
648 648 prefix = 'ur'
649 649 else:
650 650 prefix = 'r'
651 651 pattern = prefix + pattern.replace('\\\\', '\\')
652 652 p.text(pattern)
653 653 if obj.flags:
654 654 p.text(',')
655 655 p.breakable()
656 656 done_one = False
657 657 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
658 658 'UNICODE', 'VERBOSE', 'DEBUG'):
659 659 if obj.flags & getattr(re, flag):
660 660 if done_one:
661 661 p.text('|')
662 662 p.text('re.' + flag)
663 663 done_one = True
664 664 p.text(')')
665 665
666 666
667 667 def _type_pprint(obj, p, cycle):
668 668 """The pprint for classes and types."""
669 669 # Heap allocated types might not have the module attribute,
670 670 # and others may set it to None.
671 671
672 672 # Checks for a __repr__ override in the metaclass. Can't compare the
673 673 # type(obj).__repr__ directly because in PyPy the representation function
674 674 # inherited from type isn't the same type.__repr__
675 675 if [m for m in _get_mro(type(obj)) if "__repr__" in vars(m)][:1] != [type]:
676 676 _repr_pprint(obj, p, cycle)
677 677 return
678 678
679 679 mod = _safe_getattr(obj, '__module__', None)
680 680 try:
681 681 name = obj.__qualname__
682 if not isinstance(name, string_types):
682 if not isinstance(name, str):
683 683 # This can happen if the type implements __qualname__ as a property
684 684 # or other descriptor in Python 2.
685 685 raise Exception("Try __name__")
686 686 except Exception:
687 687 name = obj.__name__
688 if not isinstance(name, string_types):
688 if not isinstance(name, str):
689 689 name = '<unknown type>'
690 690
691 691 if mod in (None, '__builtin__', 'builtins', 'exceptions'):
692 692 p.text(name)
693 693 else:
694 694 p.text(mod + '.' + name)
695 695
696 696
697 697 def _repr_pprint(obj, p, cycle):
698 698 """A pprint that just redirects to the normal repr function."""
699 699 # Find newlines and replace them with p.break_()
700 700 output = repr(obj)
701 701 for idx,output_line in enumerate(output.splitlines()):
702 702 if idx:
703 703 p.break_()
704 704 p.text(output_line)
705 705
706 706
707 707 def _function_pprint(obj, p, cycle):
708 708 """Base pprint for all functions and builtin functions."""
709 709 name = _safe_getattr(obj, '__qualname__', obj.__name__)
710 710 mod = obj.__module__
711 711 if mod and mod not in ('__builtin__', 'builtins', 'exceptions'):
712 712 name = mod + '.' + name
713 713 p.text('<function %s>' % name)
714 714
715 715
716 716 def _exception_pprint(obj, p, cycle):
717 717 """Base pprint for all exceptions."""
718 718 name = getattr(obj.__class__, '__qualname__', obj.__class__.__name__)
719 719 if obj.__class__.__module__ not in ('exceptions', 'builtins'):
720 720 name = '%s.%s' % (obj.__class__.__module__, name)
721 721 step = len(name) + 1
722 722 p.begin_group(step, name + '(')
723 723 for idx, arg in enumerate(getattr(obj, 'args', ())):
724 724 if idx:
725 725 p.text(',')
726 726 p.breakable()
727 727 p.pretty(arg)
728 728 p.end_group(step, ')')
729 729
730 730
731 731 #: the exception base
732 732 try:
733 733 _exception_base = BaseException
734 734 except NameError:
735 735 _exception_base = Exception
736 736
737 737
738 738 #: printers for builtin types
739 739 _type_pprinters = {
740 740 int: _repr_pprint,
741 741 float: _repr_pprint,
742 742 str: _repr_pprint,
743 743 tuple: _seq_pprinter_factory('(', ')', tuple),
744 744 list: _seq_pprinter_factory('[', ']', list),
745 745 dict: _dict_pprinter_factory('{', '}', dict),
746 746
747 747 set: _set_pprinter_factory('{', '}', set),
748 748 frozenset: _set_pprinter_factory('frozenset({', '})', frozenset),
749 749 super: _super_pprint,
750 750 _re_pattern_type: _re_pattern_pprint,
751 751 type: _type_pprint,
752 752 types.FunctionType: _function_pprint,
753 753 types.BuiltinFunctionType: _function_pprint,
754 754 types.MethodType: _repr_pprint,
755 755
756 756 datetime.datetime: _repr_pprint,
757 757 datetime.timedelta: _repr_pprint,
758 758 _exception_base: _exception_pprint
759 759 }
760 760
761 761 try:
762 762 # In PyPy, types.DictProxyType is dict, setting the dictproxy printer
763 763 # using dict.setdefault avoids overwritting the dict printer
764 764 _type_pprinters.setdefault(types.DictProxyType,
765 765 _dict_pprinter_factory('dict_proxy({', '})'))
766 766 _type_pprinters[types.ClassType] = _type_pprint
767 767 _type_pprinters[types.SliceType] = _repr_pprint
768 768 except AttributeError: # Python 3
769 769 _type_pprinters[types.MappingProxyType] = \
770 770 _dict_pprinter_factory('mappingproxy({', '})')
771 771 _type_pprinters[slice] = _repr_pprint
772 772
773 773 try:
774 _type_pprinters[xrange] = _repr_pprint
775 774 _type_pprinters[long] = _repr_pprint
776 775 _type_pprinters[unicode] = _repr_pprint
777 776 except NameError:
778 777 _type_pprinters[range] = _repr_pprint
779 778 _type_pprinters[bytes] = _repr_pprint
780 779
781 780 #: printers for types specified by name
782 781 _deferred_type_pprinters = {
783 782 }
784 783
785 784 def for_type(typ, func):
786 785 """
787 786 Add a pretty printer for a given type.
788 787 """
789 788 oldfunc = _type_pprinters.get(typ, None)
790 789 if func is not None:
791 790 # To support easy restoration of old pprinters, we need to ignore Nones.
792 791 _type_pprinters[typ] = func
793 792 return oldfunc
794 793
795 794 def for_type_by_name(type_module, type_name, func):
796 795 """
797 796 Add a pretty printer for a type specified by the module and name of a type
798 797 rather than the type object itself.
799 798 """
800 799 key = (type_module, type_name)
801 800 oldfunc = _deferred_type_pprinters.get(key, None)
802 801 if func is not None:
803 802 # To support easy restoration of old pprinters, we need to ignore Nones.
804 803 _deferred_type_pprinters[key] = func
805 804 return oldfunc
806 805
807 806
808 807 #: printers for the default singletons
809 808 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
810 809 NotImplemented]), _repr_pprint)
811 810
812 811
813 812 def _defaultdict_pprint(obj, p, cycle):
814 813 name = obj.__class__.__name__
815 814 with p.group(len(name) + 1, name + '(', ')'):
816 815 if cycle:
817 816 p.text('...')
818 817 else:
819 818 p.pretty(obj.default_factory)
820 819 p.text(',')
821 820 p.breakable()
822 821 p.pretty(dict(obj))
823 822
824 823 def _ordereddict_pprint(obj, p, cycle):
825 824 name = obj.__class__.__name__
826 825 with p.group(len(name) + 1, name + '(', ')'):
827 826 if cycle:
828 827 p.text('...')
829 828 elif len(obj):
830 829 p.pretty(list(obj.items()))
831 830
832 831 def _deque_pprint(obj, p, cycle):
833 832 name = obj.__class__.__name__
834 833 with p.group(len(name) + 1, name + '(', ')'):
835 834 if cycle:
836 835 p.text('...')
837 836 else:
838 837 p.pretty(list(obj))
839 838
840 839
841 840 def _counter_pprint(obj, p, cycle):
842 841 name = obj.__class__.__name__
843 842 with p.group(len(name) + 1, name + '(', ')'):
844 843 if cycle:
845 844 p.text('...')
846 845 elif len(obj):
847 846 p.pretty(dict(obj))
848 847
849 848 for_type_by_name('collections', 'defaultdict', _defaultdict_pprint)
850 849 for_type_by_name('collections', 'OrderedDict', _ordereddict_pprint)
851 850 for_type_by_name('collections', 'deque', _deque_pprint)
852 851 for_type_by_name('collections', 'Counter', _counter_pprint)
853 852
854 853 if __name__ == '__main__':
855 854 from random import randrange
856 855 class Foo(object):
857 856 def __init__(self):
858 857 self.foo = 1
859 858 self.bar = re.compile(r'\s+')
860 859 self.blub = dict.fromkeys(range(30), randrange(1, 40))
861 860 self.hehe = 23424.234234
862 861 self.list = ["blub", "blah", self]
863 862
864 863 def get_foo(self):
865 864 print("foo")
866 865
867 866 pprint(Foo(), verbose=True)
@@ -1,22 +1,21 b''
1 1 import nose.tools as nt
2 2
3 3 from IPython.core.error import TryNext
4 4 from IPython.lib.clipboard import ClipboardEmpty
5 5 from IPython.testing.decorators import skip_if_no_x11
6 from IPython.utils.py3compat import unicode_type
7 6
8 7 @skip_if_no_x11
9 8 def test_clipboard_get():
10 9 # Smoketest for clipboard access - we can't easily guarantee that the
11 10 # clipboard is accessible and has something on it, but this tries to
12 11 # exercise the relevant code anyway.
13 12 try:
14 13 a = get_ipython().hooks.clipboard_get()
15 14 except ClipboardEmpty:
16 15 # Nothing in clipboard to get
17 16 pass
18 17 except TryNext:
19 18 # No clipboard access API available
20 19 pass
21 20 else:
22 nt.assert_is_instance(a, unicode_type)
21 nt.assert_is_instance(a, str)
@@ -1,500 +1,500 b''
1 1 """IPython terminal interface using prompt_toolkit"""
2 2
3 3 import os
4 4 import sys
5 5 import warnings
6 6 from warnings import warn
7 7
8 8 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
9 9 from IPython.utils import io
10 from IPython.utils.py3compat import PY3, cast_unicode_py2, input, string_types
10 from IPython.utils.py3compat import PY3, cast_unicode_py2, input
11 11 from IPython.utils.terminal import toggle_set_term_title, set_term_title
12 12 from IPython.utils.process import abbrev_cwd
13 13 from traitlets import Bool, Unicode, Dict, Integer, observe, Instance, Type, default, Enum, Union
14 14
15 15 from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
16 16 from prompt_toolkit.filters import (HasFocus, Condition, IsDone)
17 17 from prompt_toolkit.history import InMemoryHistory
18 18 from prompt_toolkit.shortcuts import create_prompt_application, create_eventloop, create_prompt_layout, create_output
19 19 from prompt_toolkit.interface import CommandLineInterface
20 20 from prompt_toolkit.key_binding.manager import KeyBindingManager
21 21 from prompt_toolkit.layout.processors import ConditionalProcessor, HighlightMatchingBracketProcessor
22 22 from prompt_toolkit.styles import PygmentsStyle, DynamicStyle
23 23
24 24 from pygments.styles import get_style_by_name, get_all_styles
25 25 from pygments.style import Style
26 26 from pygments.token import Token
27 27
28 28 from .debugger import TerminalPdb, Pdb
29 29 from .magics import TerminalMagics
30 30 from .pt_inputhooks import get_inputhook_name_and_func
31 31 from .prompts import Prompts, ClassicPrompts, RichPromptDisplayHook
32 32 from .ptutils import IPythonPTCompleter, IPythonPTLexer
33 33 from .shortcuts import register_ipython_shortcuts
34 34
35 35 DISPLAY_BANNER_DEPRECATED = object()
36 36
37 37
38 38 from pygments.style import Style
39 39
40 40 class _NoStyle(Style): pass
41 41
42 42
43 43
44 44 _style_overrides_light_bg = {
45 45 Token.Prompt: '#0000ff',
46 46 Token.PromptNum: '#0000ee bold',
47 47 Token.OutPrompt: '#cc0000',
48 48 Token.OutPromptNum: '#bb0000 bold',
49 49 }
50 50
51 51 _style_overrides_linux = {
52 52 Token.Prompt: '#00cc00',
53 53 Token.PromptNum: '#00bb00 bold',
54 54 Token.OutPrompt: '#cc0000',
55 55 Token.OutPromptNum: '#bb0000 bold',
56 56 }
57 57
58 58
59 59
60 60 def get_default_editor():
61 61 try:
62 62 ed = os.environ['EDITOR']
63 63 if not PY3:
64 64 ed = ed.decode()
65 65 return ed
66 66 except KeyError:
67 67 pass
68 68 except UnicodeError:
69 69 warn("$EDITOR environment variable is not pure ASCII. Using platform "
70 70 "default editor.")
71 71
72 72 if os.name == 'posix':
73 73 return 'vi' # the only one guaranteed to be there!
74 74 else:
75 75 return 'notepad' # same in Windows!
76 76
77 77 # conservatively check for tty
78 78 # overridden streams can result in things like:
79 79 # - sys.stdin = None
80 80 # - no isatty method
81 81 for _name in ('stdin', 'stdout', 'stderr'):
82 82 _stream = getattr(sys, _name)
83 83 if not _stream or not hasattr(_stream, 'isatty') or not _stream.isatty():
84 84 _is_tty = False
85 85 break
86 86 else:
87 87 _is_tty = True
88 88
89 89
90 90 _use_simple_prompt = ('IPY_TEST_SIMPLE_PROMPT' in os.environ) or (not _is_tty)
91 91
92 92 class TerminalInteractiveShell(InteractiveShell):
93 93 space_for_menu = Integer(6, help='Number of line at the bottom of the screen '
94 94 'to reserve for the completion menu'
95 95 ).tag(config=True)
96 96
97 97 def _space_for_menu_changed(self, old, new):
98 98 self._update_layout()
99 99
100 100 pt_cli = None
101 101 debugger_history = None
102 102 _pt_app = None
103 103
104 104 simple_prompt = Bool(_use_simple_prompt,
105 105 help="""Use `raw_input` for the REPL, without completion, multiline input, and prompt colors.
106 106
107 107 Useful when controlling IPython as a subprocess, and piping STDIN/OUT/ERR. Known usage are:
108 108 IPython own testing machinery, and emacs inferior-shell integration through elpy.
109 109
110 110 This mode default to `True` if the `IPY_TEST_SIMPLE_PROMPT`
111 111 environment variable is set, or the current terminal is not a tty.
112 112
113 113 """
114 114 ).tag(config=True)
115 115
116 116 @property
117 117 def debugger_cls(self):
118 118 return Pdb if self.simple_prompt else TerminalPdb
119 119
120 120 confirm_exit = Bool(True,
121 121 help="""
122 122 Set to confirm when you try to exit IPython with an EOF (Control-D
123 123 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
124 124 you can force a direct exit without any confirmation.""",
125 125 ).tag(config=True)
126 126
127 127 editing_mode = Unicode('emacs',
128 128 help="Shortcut style to use at the prompt. 'vi' or 'emacs'.",
129 129 ).tag(config=True)
130 130
131 131 mouse_support = Bool(False,
132 132 help="Enable mouse support in the prompt"
133 133 ).tag(config=True)
134 134
135 135 highlighting_style = Union([Unicode('legacy'), Type(klass=Style)],
136 136 help="""The name or class of a Pygments style to use for syntax
137 137 highlighting: \n %s""" % ', '.join(get_all_styles())
138 138 ).tag(config=True)
139 139
140 140
141 141 @observe('highlighting_style')
142 142 @observe('colors')
143 143 def _highlighting_style_changed(self, change):
144 144 self.refresh_style()
145 145
146 146 def refresh_style(self):
147 147 self._style = self._make_style_from_name_or_cls(self.highlighting_style)
148 148
149 149
150 150 highlighting_style_overrides = Dict(
151 151 help="Override highlighting format for specific tokens"
152 152 ).tag(config=True)
153 153
154 154 true_color = Bool(False,
155 155 help=("Use 24bit colors instead of 256 colors in prompt highlighting. "
156 156 "If your terminal supports true color, the following command "
157 157 "should print 'TRUECOLOR' in orange: "
158 158 "printf \"\\x1b[38;2;255;100;0mTRUECOLOR\\x1b[0m\\n\"")
159 159 ).tag(config=True)
160 160
161 161 editor = Unicode(get_default_editor(),
162 162 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
163 163 ).tag(config=True)
164 164
165 165 prompts_class = Type(Prompts, help='Class used to generate Prompt token for prompt_toolkit').tag(config=True)
166 166
167 167 prompts = Instance(Prompts)
168 168
169 169 @default('prompts')
170 170 def _prompts_default(self):
171 171 return self.prompts_class(self)
172 172
173 173 @observe('prompts')
174 174 def _(self, change):
175 175 self._update_layout()
176 176
177 177 @default('displayhook_class')
178 178 def _displayhook_class_default(self):
179 179 return RichPromptDisplayHook
180 180
181 181 term_title = Bool(True,
182 182 help="Automatically set the terminal title"
183 183 ).tag(config=True)
184 184
185 185 display_completions = Enum(('column', 'multicolumn','readlinelike'),
186 186 help= ( "Options for displaying tab completions, 'column', 'multicolumn', and "
187 187 "'readlinelike'. These options are for `prompt_toolkit`, see "
188 188 "`prompt_toolkit` documentation for more information."
189 189 ),
190 190 default_value='multicolumn').tag(config=True)
191 191
192 192 highlight_matching_brackets = Bool(True,
193 193 help="Highlight matching brackets .",
194 194 ).tag(config=True)
195 195
196 196 @observe('term_title')
197 197 def init_term_title(self, change=None):
198 198 # Enable or disable the terminal title.
199 199 if self.term_title:
200 200 toggle_set_term_title(True)
201 201 set_term_title('IPython: ' + abbrev_cwd())
202 202 else:
203 203 toggle_set_term_title(False)
204 204
205 205 def init_display_formatter(self):
206 206 super(TerminalInteractiveShell, self).init_display_formatter()
207 207 # terminal only supports plain text
208 208 self.display_formatter.active_types = ['text/plain']
209 209
210 210 def init_prompt_toolkit_cli(self):
211 211 if self.simple_prompt:
212 212 # Fall back to plain non-interactive output for tests.
213 213 # This is very limited, and only accepts a single line.
214 214 def prompt():
215 215 return cast_unicode_py2(input('In [%d]: ' % self.execution_count))
216 216 self.prompt_for_code = prompt
217 217 return
218 218
219 219 # Set up keyboard shortcuts
220 220 kbmanager = KeyBindingManager.for_prompt()
221 221 register_ipython_shortcuts(kbmanager.registry, self)
222 222
223 223 # Pre-populate history from IPython's history database
224 224 history = InMemoryHistory()
225 225 last_cell = u""
226 226 for __, ___, cell in self.history_manager.get_tail(self.history_load_length,
227 227 include_latest=True):
228 228 # Ignore blank lines and consecutive duplicates
229 229 cell = cell.rstrip()
230 230 if cell and (cell != last_cell):
231 231 history.append(cell)
232 232 last_cell = cell
233 233
234 234 self._style = self._make_style_from_name_or_cls(self.highlighting_style)
235 235 style = DynamicStyle(lambda: self._style)
236 236
237 237 editing_mode = getattr(EditingMode, self.editing_mode.upper())
238 238
239 239 self._pt_app = create_prompt_application(
240 240 editing_mode=editing_mode,
241 241 key_bindings_registry=kbmanager.registry,
242 242 history=history,
243 243 completer=IPythonPTCompleter(shell=self),
244 244 enable_history_search=True,
245 245 style=style,
246 246 mouse_support=self.mouse_support,
247 247 **self._layout_options()
248 248 )
249 249 self._eventloop = create_eventloop(self.inputhook)
250 250 self.pt_cli = CommandLineInterface(
251 251 self._pt_app, eventloop=self._eventloop,
252 252 output=create_output(true_color=self.true_color))
253 253
254 254 def _make_style_from_name_or_cls(self, name_or_cls):
255 255 """
256 256 Small wrapper that make an IPython compatible style from a style name
257 257
258 258 We need that to add style for prompt ... etc.
259 259 """
260 260 style_overrides = {}
261 261 if name_or_cls == 'legacy':
262 262 legacy = self.colors.lower()
263 263 if legacy == 'linux':
264 264 style_cls = get_style_by_name('monokai')
265 265 style_overrides = _style_overrides_linux
266 266 elif legacy == 'lightbg':
267 267 style_overrides = _style_overrides_light_bg
268 268 style_cls = get_style_by_name('pastie')
269 269 elif legacy == 'neutral':
270 270 # The default theme needs to be visible on both a dark background
271 271 # and a light background, because we can't tell what the terminal
272 272 # looks like. These tweaks to the default theme help with that.
273 273 style_cls = get_style_by_name('default')
274 274 style_overrides.update({
275 275 Token.Number: '#007700',
276 276 Token.Operator: 'noinherit',
277 277 Token.String: '#BB6622',
278 278 Token.Name.Function: '#2080D0',
279 279 Token.Name.Class: 'bold #2080D0',
280 280 Token.Name.Namespace: 'bold #2080D0',
281 281 Token.Prompt: '#009900',
282 282 Token.PromptNum: '#00ff00 bold',
283 283 Token.OutPrompt: '#990000',
284 284 Token.OutPromptNum: '#ff0000 bold',
285 285 })
286 286 elif legacy =='nocolor':
287 287 style_cls=_NoStyle
288 288 style_overrides = {}
289 289 else :
290 290 raise ValueError('Got unknown colors: ', legacy)
291 291 else :
292 if isinstance(name_or_cls, string_types):
292 if isinstance(name_or_cls, str):
293 293 style_cls = get_style_by_name(name_or_cls)
294 294 else:
295 295 style_cls = name_or_cls
296 296 style_overrides = {
297 297 Token.Prompt: '#009900',
298 298 Token.PromptNum: '#00ff00 bold',
299 299 Token.OutPrompt: '#990000',
300 300 Token.OutPromptNum: '#ff0000 bold',
301 301 }
302 302 style_overrides.update(self.highlighting_style_overrides)
303 303 style = PygmentsStyle.from_defaults(pygments_style_cls=style_cls,
304 304 style_dict=style_overrides)
305 305
306 306 return style
307 307
308 308 def _layout_options(self):
309 309 """
310 310 Return the current layout option for the current Terminal InteractiveShell
311 311 """
312 312 return {
313 313 'lexer':IPythonPTLexer(),
314 314 'reserve_space_for_menu':self.space_for_menu,
315 315 'get_prompt_tokens':self.prompts.in_prompt_tokens,
316 316 'get_continuation_tokens':self.prompts.continuation_prompt_tokens,
317 317 'multiline':True,
318 318 'display_completions_in_columns': (self.display_completions == 'multicolumn'),
319 319
320 320 # Highlight matching brackets, but only when this setting is
321 321 # enabled, and only when the DEFAULT_BUFFER has the focus.
322 322 'extra_input_processors': [ConditionalProcessor(
323 323 processor=HighlightMatchingBracketProcessor(chars='[](){}'),
324 324 filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() &
325 325 Condition(lambda cli: self.highlight_matching_brackets))],
326 326 }
327 327
328 328 def _update_layout(self):
329 329 """
330 330 Ask for a re computation of the application layout, if for example ,
331 331 some configuration options have changed.
332 332 """
333 333 if self._pt_app:
334 334 self._pt_app.layout = create_prompt_layout(**self._layout_options())
335 335
336 336 def prompt_for_code(self):
337 337 document = self.pt_cli.run(
338 338 pre_run=self.pre_prompt, reset_current_buffer=True)
339 339 return document.text
340 340
341 341 def enable_win_unicode_console(self):
342 342 if sys.version_info >= (3, 6):
343 343 # Since PEP 528, Python uses the unicode APIs for the Windows
344 344 # console by default, so WUC shouldn't be needed.
345 345 return
346 346
347 347 import win_unicode_console
348 348
349 349 if PY3:
350 350 win_unicode_console.enable()
351 351 else:
352 352 # https://github.com/ipython/ipython/issues/9768
353 353 from win_unicode_console.streams import (TextStreamWrapper,
354 354 stdout_text_transcoded, stderr_text_transcoded)
355 355
356 356 class LenientStrStreamWrapper(TextStreamWrapper):
357 357 def write(self, s):
358 358 if isinstance(s, bytes):
359 359 s = s.decode(self.encoding, 'replace')
360 360
361 361 self.base.write(s)
362 362
363 363 stdout_text_str = LenientStrStreamWrapper(stdout_text_transcoded)
364 364 stderr_text_str = LenientStrStreamWrapper(stderr_text_transcoded)
365 365
366 366 win_unicode_console.enable(stdout=stdout_text_str,
367 367 stderr=stderr_text_str)
368 368
369 369 def init_io(self):
370 370 if sys.platform not in {'win32', 'cli'}:
371 371 return
372 372
373 373 self.enable_win_unicode_console()
374 374
375 375 import colorama
376 376 colorama.init()
377 377
378 378 # For some reason we make these wrappers around stdout/stderr.
379 379 # For now, we need to reset them so all output gets coloured.
380 380 # https://github.com/ipython/ipython/issues/8669
381 381 # io.std* are deprecated, but don't show our own deprecation warnings
382 382 # during initialization of the deprecated API.
383 383 with warnings.catch_warnings():
384 384 warnings.simplefilter('ignore', DeprecationWarning)
385 385 io.stdout = io.IOStream(sys.stdout)
386 386 io.stderr = io.IOStream(sys.stderr)
387 387
388 388 def init_magics(self):
389 389 super(TerminalInteractiveShell, self).init_magics()
390 390 self.register_magics(TerminalMagics)
391 391
392 392 def init_alias(self):
393 393 # The parent class defines aliases that can be safely used with any
394 394 # frontend.
395 395 super(TerminalInteractiveShell, self).init_alias()
396 396
397 397 # Now define aliases that only make sense on the terminal, because they
398 398 # need direct access to the console in a way that we can't emulate in
399 399 # GUI or web frontend
400 400 if os.name == 'posix':
401 401 for cmd in ['clear', 'more', 'less', 'man']:
402 402 self.alias_manager.soft_define_alias(cmd, cmd)
403 403
404 404
405 405 def __init__(self, *args, **kwargs):
406 406 super(TerminalInteractiveShell, self).__init__(*args, **kwargs)
407 407 self.init_prompt_toolkit_cli()
408 408 self.init_term_title()
409 409 self.keep_running = True
410 410
411 411 self.debugger_history = InMemoryHistory()
412 412
413 413 def ask_exit(self):
414 414 self.keep_running = False
415 415
416 416 rl_next_input = None
417 417
418 418 def pre_prompt(self):
419 419 if self.rl_next_input:
420 420 self.pt_cli.application.buffer.text = cast_unicode_py2(self.rl_next_input)
421 421 self.rl_next_input = None
422 422
423 423 def interact(self, display_banner=DISPLAY_BANNER_DEPRECATED):
424 424
425 425 if display_banner is not DISPLAY_BANNER_DEPRECATED:
426 426 warn('interact `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
427 427
428 428 self.keep_running = True
429 429 while self.keep_running:
430 430 print(self.separate_in, end='')
431 431
432 432 try:
433 433 code = self.prompt_for_code()
434 434 except EOFError:
435 435 if (not self.confirm_exit) \
436 436 or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
437 437 self.ask_exit()
438 438
439 439 else:
440 440 if code:
441 441 self.run_cell(code, store_history=True)
442 442
443 443 def mainloop(self, display_banner=DISPLAY_BANNER_DEPRECATED):
444 444 # An extra layer of protection in case someone mashing Ctrl-C breaks
445 445 # out of our internal code.
446 446 if display_banner is not DISPLAY_BANNER_DEPRECATED:
447 447 warn('mainloop `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
448 448 while True:
449 449 try:
450 450 self.interact()
451 451 break
452 452 except KeyboardInterrupt:
453 453 print("\nKeyboardInterrupt escaped interact()\n")
454 454
455 455 _inputhook = None
456 456 def inputhook(self, context):
457 457 if self._inputhook is not None:
458 458 self._inputhook(context)
459 459
460 460 active_eventloop = None
461 461 def enable_gui(self, gui=None):
462 462 if gui:
463 463 self.active_eventloop, self._inputhook =\
464 464 get_inputhook_name_and_func(gui)
465 465 else:
466 466 self.active_eventloop = self._inputhook = None
467 467
468 468 # Run !system commands directly, not through pipes, so terminal programs
469 469 # work correctly.
470 470 system = InteractiveShell.system_raw
471 471
472 472 def auto_rewrite_input(self, cmd):
473 473 """Overridden from the parent class to use fancy rewriting prompt"""
474 474 if not self.show_rewritten_input:
475 475 return
476 476
477 477 tokens = self.prompts.rewrite_prompt_tokens()
478 478 if self.pt_cli:
479 479 self.pt_cli.print_tokens(tokens)
480 480 print(cmd)
481 481 else:
482 482 prompt = ''.join(s for t, s in tokens)
483 483 print(prompt, cmd, sep='')
484 484
485 485 _prompts_before = None
486 486 def switch_doctest_mode(self, mode):
487 487 """Switch prompts to classic for %doctest_mode"""
488 488 if mode:
489 489 self._prompts_before = self.prompts
490 490 self.prompts = ClassicPrompts(self)
491 491 elif self._prompts_before:
492 492 self.prompts = self._prompts_before
493 493 self._prompts_before = None
494 494 self._update_layout()
495 495
496 496
497 497 InteractiveShellABC.register(TerminalInteractiveShell)
498 498
499 499 if __name__ == '__main__':
500 500 TerminalInteractiveShell.instance().interact()
@@ -1,206 +1,206 b''
1 1 """Extra magics for terminal use."""
2 2
3 3 # Copyright (c) IPython Development Team.
4 4 # Distributed under the terms of the Modified BSD License.
5 5
6 6
7 7 from logging import error
8 8 import os
9 9 import sys
10 10
11 11 from IPython.core.error import TryNext, UsageError
12 12 from IPython.core.inputsplitter import IPythonInputSplitter
13 13 from IPython.core.magic import Magics, magics_class, line_magic
14 14 from IPython.lib.clipboard import ClipboardEmpty
15 15 from IPython.utils.text import SList, strip_email_quotes
16 16 from IPython.utils import py3compat
17 17
18 18 def get_pasted_lines(sentinel, l_input=py3compat.input, quiet=False):
19 19 """ Yield pasted lines until the user enters the given sentinel value.
20 20 """
21 21 if not quiet:
22 22 print("Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
23 23 % sentinel)
24 24 prompt = ":"
25 25 else:
26 26 prompt = ""
27 27 while True:
28 28 try:
29 l = py3compat.str_to_unicode(l_input(prompt))
29 l = l_input(prompt)
30 30 if l == sentinel:
31 31 return
32 32 else:
33 33 yield l
34 34 except EOFError:
35 35 print('<EOF>')
36 36 return
37 37
38 38
39 39 @magics_class
40 40 class TerminalMagics(Magics):
41 41 def __init__(self, shell):
42 42 super(TerminalMagics, self).__init__(shell)
43 43 self.input_splitter = IPythonInputSplitter()
44 44
45 45 def store_or_execute(self, block, name):
46 46 """ Execute a block, or store it in a variable, per the user's request.
47 47 """
48 48 if name:
49 49 # If storing it for further editing
50 50 self.shell.user_ns[name] = SList(block.splitlines())
51 51 print("Block assigned to '%s'" % name)
52 52 else:
53 53 b = self.preclean_input(block)
54 54 self.shell.user_ns['pasted_block'] = b
55 55 self.shell.using_paste_magics = True
56 56 try:
57 57 self.shell.run_cell(b)
58 58 finally:
59 59 self.shell.using_paste_magics = False
60 60
61 61 def preclean_input(self, block):
62 62 lines = block.splitlines()
63 63 while lines and not lines[0].strip():
64 64 lines = lines[1:]
65 65 return strip_email_quotes('\n'.join(lines))
66 66
67 67 def rerun_pasted(self, name='pasted_block'):
68 68 """ Rerun a previously pasted command.
69 69 """
70 70 b = self.shell.user_ns.get(name)
71 71
72 72 # Sanity checks
73 73 if b is None:
74 74 raise UsageError('No previous pasted block available')
75 if not isinstance(b, py3compat.string_types):
75 if not isinstance(b, str):
76 76 raise UsageError(
77 77 "Variable 'pasted_block' is not a string, can't execute")
78 78
79 79 print("Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)))
80 80 self.shell.run_cell(b)
81 81
82 82 @line_magic
83 83 def autoindent(self, parameter_s = ''):
84 84 """Toggle autoindent on/off (if available)."""
85 85
86 86 self.shell.set_autoindent()
87 87 print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
88 88
89 89 @line_magic
90 90 def cpaste(self, parameter_s=''):
91 91 """Paste & execute a pre-formatted code block from clipboard.
92 92
93 93 You must terminate the block with '--' (two minus-signs) or Ctrl-D
94 94 alone on the line. You can also provide your own sentinel with '%paste
95 95 -s %%' ('%%' is the new sentinel for this operation).
96 96
97 97 The block is dedented prior to execution to enable execution of method
98 98 definitions. '>' and '+' characters at the beginning of a line are
99 99 ignored, to allow pasting directly from e-mails, diff files and
100 100 doctests (the '...' continuation prompt is also stripped). The
101 101 executed block is also assigned to variable named 'pasted_block' for
102 102 later editing with '%edit pasted_block'.
103 103
104 104 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
105 105 This assigns the pasted block to variable 'foo' as string, without
106 106 dedenting or executing it (preceding >>> and + is still stripped)
107 107
108 108 '%cpaste -r' re-executes the block previously entered by cpaste.
109 109 '%cpaste -q' suppresses any additional output messages.
110 110
111 111 Do not be alarmed by garbled output on Windows (it's a readline bug).
112 112 Just press enter and type -- (and press enter again) and the block
113 113 will be what was just pasted.
114 114
115 115 IPython statements (magics, shell escapes) are not supported (yet).
116 116
117 117 See also
118 118 --------
119 119 paste: automatically pull code from clipboard.
120 120
121 121 Examples
122 122 --------
123 123 ::
124 124
125 125 In [8]: %cpaste
126 126 Pasting code; enter '--' alone on the line to stop.
127 127 :>>> a = ["world!", "Hello"]
128 128 :>>> print " ".join(sorted(a))
129 129 :--
130 130 Hello world!
131 131 """
132 132 opts, name = self.parse_options(parameter_s, 'rqs:', mode='string')
133 133 if 'r' in opts:
134 134 self.rerun_pasted()
135 135 return
136 136
137 137 quiet = ('q' in opts)
138 138
139 139 sentinel = opts.get('s', u'--')
140 140 block = '\n'.join(get_pasted_lines(sentinel, quiet=quiet))
141 141 self.store_or_execute(block, name)
142 142
143 143 @line_magic
144 144 def paste(self, parameter_s=''):
145 145 """Paste & execute a pre-formatted code block from clipboard.
146 146
147 147 The text is pulled directly from the clipboard without user
148 148 intervention and printed back on the screen before execution (unless
149 149 the -q flag is given to force quiet mode).
150 150
151 151 The block is dedented prior to execution to enable execution of method
152 152 definitions. '>' and '+' characters at the beginning of a line are
153 153 ignored, to allow pasting directly from e-mails, diff files and
154 154 doctests (the '...' continuation prompt is also stripped). The
155 155 executed block is also assigned to variable named 'pasted_block' for
156 156 later editing with '%edit pasted_block'.
157 157
158 158 You can also pass a variable name as an argument, e.g. '%paste foo'.
159 159 This assigns the pasted block to variable 'foo' as string, without
160 160 executing it (preceding >>> and + is still stripped).
161 161
162 162 Options:
163 163
164 164 -r: re-executes the block previously entered by cpaste.
165 165
166 166 -q: quiet mode: do not echo the pasted text back to the terminal.
167 167
168 168 IPython statements (magics, shell escapes) are not supported (yet).
169 169
170 170 See also
171 171 --------
172 172 cpaste: manually paste code into terminal until you mark its end.
173 173 """
174 174 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
175 175 if 'r' in opts:
176 176 self.rerun_pasted()
177 177 return
178 178 try:
179 179 block = self.shell.hooks.clipboard_get()
180 180 except TryNext as clipboard_exc:
181 181 message = getattr(clipboard_exc, 'args')
182 182 if message:
183 183 error(message[0])
184 184 else:
185 185 error('Could not get text from the clipboard.')
186 186 return
187 187 except ClipboardEmpty:
188 188 raise UsageError("The clipboard appears to be empty")
189 189
190 190 # By default, echo back to terminal unless quiet mode is requested
191 191 if 'q' not in opts:
192 192 write = self.shell.write
193 193 write(self.shell.pycolorize(block))
194 194 if not block.endswith('\n'):
195 195 write('\n')
196 196 write("## -- End pasted text --\n")
197 197
198 198 self.store_or_execute(block, name)
199 199
200 200 # Class-level: add a '%cls' magic only on Windows
201 201 if sys.platform == 'win32':
202 202 @line_magic
203 203 def cls(self, s):
204 204 """Clear screen.
205 205 """
206 206 os.system("cls")
@@ -1,378 +1,378 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Decorators for labeling test objects.
3 3
4 4 Decorators that merely return a modified version of the original function
5 5 object are straightforward. Decorators that return a new function object need
6 6 to use nose.tools.make_decorator(original_function)(decorator) in returning the
7 7 decorator, in order to preserve metadata such as function name, setup and
8 8 teardown functions and so on - see nose.tools for more information.
9 9
10 10 This module provides a set of useful decorators meant to be ready to use in
11 11 your own tests. See the bottom of the file for the ready-made ones, and if you
12 12 find yourself writing a new one that may be of generic use, add it here.
13 13
14 14 Included decorators:
15 15
16 16
17 17 Lightweight testing that remains unittest-compatible.
18 18
19 19 - An @as_unittest decorator can be used to tag any normal parameter-less
20 20 function as a unittest TestCase. Then, both nose and normal unittest will
21 21 recognize it as such. This will make it easier to migrate away from Nose if
22 22 we ever need/want to while maintaining very lightweight tests.
23 23
24 24 NOTE: This file contains IPython-specific decorators. Using the machinery in
25 25 IPython.external.decorators, we import either numpy.testing.decorators if numpy is
26 26 available, OR use equivalent code in IPython.external._decorators, which
27 27 we've copied verbatim from numpy.
28 28
29 29 """
30 30
31 31 # Copyright (c) IPython Development Team.
32 32 # Distributed under the terms of the Modified BSD License.
33 33
34 34 import sys
35 35 import os
36 36 import tempfile
37 37 import unittest
38 38 import warnings
39 39 from importlib import import_module
40 40
41 41 from decorator import decorator
42 42
43 43 # Expose the unittest-driven decorators
44 44 from .ipunittest import ipdoctest, ipdocstring
45 45
46 46 # Grab the numpy-specific decorators which we keep in a file that we
47 47 # occasionally update from upstream: decorators.py is a copy of
48 48 # numpy.testing.decorators, we expose all of it here.
49 49 from IPython.external.decorators import *
50 50
51 51 # For onlyif_cmd_exists decorator
52 from IPython.utils.py3compat import string_types, which, PY2, PY3, PYPY
52 from IPython.utils.py3compat import which, PY2, PY3, PYPY
53 53
54 54 #-----------------------------------------------------------------------------
55 55 # Classes and functions
56 56 #-----------------------------------------------------------------------------
57 57
58 58 # Simple example of the basic idea
59 59 def as_unittest(func):
60 60 """Decorator to make a simple function into a normal test via unittest."""
61 61 class Tester(unittest.TestCase):
62 62 def test(self):
63 63 func()
64 64
65 65 Tester.__name__ = func.__name__
66 66
67 67 return Tester
68 68
69 69 # Utility functions
70 70
71 71 def apply_wrapper(wrapper, func):
72 72 """Apply a wrapper to a function for decoration.
73 73
74 74 This mixes Michele Simionato's decorator tool with nose's make_decorator,
75 75 to apply a wrapper in a decorator so that all nose attributes, as well as
76 76 function signature and other properties, survive the decoration cleanly.
77 77 This will ensure that wrapped functions can still be well introspected via
78 78 IPython, for example.
79 79 """
80 80 warnings.warn("The function `apply_wrapper` is deprecated since IPython 4.0",
81 81 DeprecationWarning, stacklevel=2)
82 82 import nose.tools
83 83
84 84 return decorator(wrapper,nose.tools.make_decorator(func)(wrapper))
85 85
86 86
87 87 def make_label_dec(label, ds=None):
88 88 """Factory function to create a decorator that applies one or more labels.
89 89
90 90 Parameters
91 91 ----------
92 92 label : string or sequence
93 93 One or more labels that will be applied by the decorator to the functions
94 94 it decorates. Labels are attributes of the decorated function with their
95 95 value set to True.
96 96
97 97 ds : string
98 98 An optional docstring for the resulting decorator. If not given, a
99 99 default docstring is auto-generated.
100 100
101 101 Returns
102 102 -------
103 103 A decorator.
104 104
105 105 Examples
106 106 --------
107 107
108 108 A simple labeling decorator:
109 109
110 110 >>> slow = make_label_dec('slow')
111 111 >>> slow.__doc__
112 112 "Labels a test as 'slow'."
113 113
114 114 And one that uses multiple labels and a custom docstring:
115 115
116 116 >>> rare = make_label_dec(['slow','hard'],
117 117 ... "Mix labels 'slow' and 'hard' for rare tests.")
118 118 >>> rare.__doc__
119 119 "Mix labels 'slow' and 'hard' for rare tests."
120 120
121 121 Now, let's test using this one:
122 122 >>> @rare
123 123 ... def f(): pass
124 124 ...
125 125 >>>
126 126 >>> f.slow
127 127 True
128 128 >>> f.hard
129 129 True
130 130 """
131 131
132 132 warnings.warn("The function `make_label_dec` is deprecated since IPython 4.0",
133 133 DeprecationWarning, stacklevel=2)
134 if isinstance(label, string_types):
134 if isinstance(label, str):
135 135 labels = [label]
136 136 else:
137 137 labels = label
138 138
139 139 # Validate that the given label(s) are OK for use in setattr() by doing a
140 140 # dry run on a dummy function.
141 141 tmp = lambda : None
142 142 for label in labels:
143 143 setattr(tmp,label,True)
144 144
145 145 # This is the actual decorator we'll return
146 146 def decor(f):
147 147 for label in labels:
148 148 setattr(f,label,True)
149 149 return f
150 150
151 151 # Apply the user's docstring, or autogenerate a basic one
152 152 if ds is None:
153 153 ds = "Labels a test as %r." % label
154 154 decor.__doc__ = ds
155 155
156 156 return decor
157 157
158 158
159 159 # Inspired by numpy's skipif, but uses the full apply_wrapper utility to
160 160 # preserve function metadata better and allows the skip condition to be a
161 161 # callable.
162 162 def skipif(skip_condition, msg=None):
163 163 ''' Make function raise SkipTest exception if skip_condition is true
164 164
165 165 Parameters
166 166 ----------
167 167
168 168 skip_condition : bool or callable
169 169 Flag to determine whether to skip test. If the condition is a
170 170 callable, it is used at runtime to dynamically make the decision. This
171 171 is useful for tests that may require costly imports, to delay the cost
172 172 until the test suite is actually executed.
173 173 msg : string
174 174 Message to give on raising a SkipTest exception.
175 175
176 176 Returns
177 177 -------
178 178 decorator : function
179 179 Decorator, which, when applied to a function, causes SkipTest
180 180 to be raised when the skip_condition was True, and the function
181 181 to be called normally otherwise.
182 182
183 183 Notes
184 184 -----
185 185 You will see from the code that we had to further decorate the
186 186 decorator with the nose.tools.make_decorator function in order to
187 187 transmit function name, and various other metadata.
188 188 '''
189 189
190 190 def skip_decorator(f):
191 191 # Local import to avoid a hard nose dependency and only incur the
192 192 # import time overhead at actual test-time.
193 193 import nose
194 194
195 195 # Allow for both boolean or callable skip conditions.
196 196 if callable(skip_condition):
197 197 skip_val = skip_condition
198 198 else:
199 199 skip_val = lambda : skip_condition
200 200
201 201 def get_msg(func,msg=None):
202 202 """Skip message with information about function being skipped."""
203 203 if msg is None: out = 'Test skipped due to test condition.'
204 204 else: out = msg
205 205 return "Skipping test: %s. %s" % (func.__name__,out)
206 206
207 207 # We need to define *two* skippers because Python doesn't allow both
208 208 # return with value and yield inside the same function.
209 209 def skipper_func(*args, **kwargs):
210 210 """Skipper for normal test functions."""
211 211 if skip_val():
212 212 raise nose.SkipTest(get_msg(f,msg))
213 213 else:
214 214 return f(*args, **kwargs)
215 215
216 216 def skipper_gen(*args, **kwargs):
217 217 """Skipper for test generators."""
218 218 if skip_val():
219 219 raise nose.SkipTest(get_msg(f,msg))
220 220 else:
221 221 for x in f(*args, **kwargs):
222 222 yield x
223 223
224 224 # Choose the right skipper to use when building the actual generator.
225 225 if nose.util.isgenerator(f):
226 226 skipper = skipper_gen
227 227 else:
228 228 skipper = skipper_func
229 229
230 230 return nose.tools.make_decorator(f)(skipper)
231 231
232 232 return skip_decorator
233 233
234 234 # A version with the condition set to true, common case just to attach a message
235 235 # to a skip decorator
236 236 def skip(msg=None):
237 237 """Decorator factory - mark a test function for skipping from test suite.
238 238
239 239 Parameters
240 240 ----------
241 241 msg : string
242 242 Optional message to be added.
243 243
244 244 Returns
245 245 -------
246 246 decorator : function
247 247 Decorator, which, when applied to a function, causes SkipTest
248 248 to be raised, with the optional message added.
249 249 """
250 250
251 251 return skipif(True,msg)
252 252
253 253
254 254 def onlyif(condition, msg):
255 255 """The reverse from skipif, see skipif for details."""
256 256
257 257 if callable(condition):
258 258 skip_condition = lambda : not condition()
259 259 else:
260 260 skip_condition = lambda : not condition
261 261
262 262 return skipif(skip_condition, msg)
263 263
264 264 #-----------------------------------------------------------------------------
265 265 # Utility functions for decorators
266 266 def module_not_available(module):
267 267 """Can module be imported? Returns true if module does NOT import.
268 268
269 269 This is used to make a decorator to skip tests that require module to be
270 270 available, but delay the 'import numpy' to test execution time.
271 271 """
272 272 try:
273 273 mod = import_module(module)
274 274 mod_not_avail = False
275 275 except ImportError:
276 276 mod_not_avail = True
277 277
278 278 return mod_not_avail
279 279
280 280
281 281 def decorated_dummy(dec, name):
282 282 """Return a dummy function decorated with dec, with the given name.
283 283
284 284 Examples
285 285 --------
286 286 import IPython.testing.decorators as dec
287 287 setup = dec.decorated_dummy(dec.skip_if_no_x11, __name__)
288 288 """
289 289 warnings.warn("The function `decorated_dummy` is deprecated since IPython 4.0",
290 290 DeprecationWarning, stacklevel=2)
291 291 dummy = lambda: None
292 292 dummy.__name__ = name
293 293 return dec(dummy)
294 294
295 295 #-----------------------------------------------------------------------------
296 296 # Decorators for public use
297 297
298 298 # Decorators to skip certain tests on specific platforms.
299 299 skip_win32 = skipif(sys.platform == 'win32',
300 300 "This test does not run under Windows")
301 301 skip_linux = skipif(sys.platform.startswith('linux'),
302 302 "This test does not run under Linux")
303 303 skip_osx = skipif(sys.platform == 'darwin',"This test does not run under OS X")
304 304
305 305
306 306 # Decorators to skip tests if not on specific platforms.
307 307 skip_if_not_win32 = skipif(sys.platform != 'win32',
308 308 "This test only runs under Windows")
309 309 skip_if_not_linux = skipif(not sys.platform.startswith('linux'),
310 310 "This test only runs under Linux")
311 311 skip_if_not_osx = skipif(sys.platform != 'darwin',
312 312 "This test only runs under OSX")
313 313
314 314
315 315 _x11_skip_cond = (sys.platform not in ('darwin', 'win32') and
316 316 os.environ.get('DISPLAY', '') == '')
317 317 _x11_skip_msg = "Skipped under *nix when X11/XOrg not available"
318 318
319 319 skip_if_no_x11 = skipif(_x11_skip_cond, _x11_skip_msg)
320 320
321 321 # not a decorator itself, returns a dummy function to be used as setup
322 322 def skip_file_no_x11(name):
323 323 warnings.warn("The function `skip_file_no_x11` is deprecated since IPython 4.0",
324 324 DeprecationWarning, stacklevel=2)
325 325 return decorated_dummy(skip_if_no_x11, name) if _x11_skip_cond else None
326 326
327 327 # Other skip decorators
328 328
329 329 # generic skip without module
330 330 skip_without = lambda mod: skipif(module_not_available(mod), "This test requires %s" % mod)
331 331
332 332 skipif_not_numpy = skip_without('numpy')
333 333
334 334 skipif_not_matplotlib = skip_without('matplotlib')
335 335
336 336 skipif_not_sympy = skip_without('sympy')
337 337
338 338 skip_known_failure = knownfailureif(True,'This test is known to fail')
339 339
340 340 # A null 'decorator', useful to make more readable code that needs to pick
341 341 # between different decorators based on OS or other conditions
342 342 null_deco = lambda f: f
343 343
344 344 # Some tests only run where we can use unicode paths. Note that we can't just
345 345 # check os.path.supports_unicode_filenames, which is always False on Linux.
346 346 try:
347 347 f = tempfile.NamedTemporaryFile(prefix=u"tmp€")
348 348 except UnicodeEncodeError:
349 349 unicode_paths = False
350 350 else:
351 351 unicode_paths = True
352 352 f.close()
353 353
354 354 onlyif_unicode_paths = onlyif(unicode_paths, ("This test is only applicable "
355 355 "where we can use unicode in filenames."))
356 356
357 357
358 358 def onlyif_cmds_exist(*commands):
359 359 """
360 360 Decorator to skip test when at least one of `commands` is not found.
361 361 """
362 362 for cmd in commands:
363 363 if not which(cmd):
364 364 return skip("This test runs only if command '{0}' "
365 365 "is installed".format(cmd))
366 366 return null_deco
367 367
368 368 def onlyif_any_cmd_exists(*commands):
369 369 """
370 370 Decorator to skip test unless at least one of `commands` is found.
371 371 """
372 372 warnings.warn("The function `onlyif_any_cmd_exists` is deprecated since IPython 4.0",
373 373 DeprecationWarning, stacklevel=2)
374 374 for cmd in commands:
375 375 if which(cmd):
376 376 return null_deco
377 377 return skip("This test runs only if one of the commands {0} "
378 378 "is installed".format(commands))
@@ -1,770 +1,770 b''
1 1 """Nose Plugin that supports IPython doctests.
2 2
3 3 Limitations:
4 4
5 5 - When generating examples for use as doctests, make sure that you have
6 6 pretty-printing OFF. This can be done either by setting the
7 7 ``PlainTextFormatter.pprint`` option in your configuration file to False, or
8 8 by interactively disabling it with %Pprint. This is required so that IPython
9 9 output matches that of normal Python, which is used by doctest for internal
10 10 execution.
11 11
12 12 - Do not rely on specific prompt numbers for results (such as using
13 13 '_34==True', for example). For IPython tests run via an external process the
14 14 prompt numbers may be different, and IPython tests run as normal python code
15 15 won't even have these special _NN variables set at all.
16 16 """
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Module imports
20 20
21 21 # From the standard library
22 22 import doctest
23 23 import inspect
24 24 import logging
25 25 import os
26 26 import re
27 27 import sys
28 28 from importlib import import_module
29 29
30 30 from testpath import modified_env
31 31
32 32 from inspect import getmodule
33 33
34 34 # We are overriding the default doctest runner, so we need to import a few
35 35 # things from doctest directly
36 36 from doctest import (REPORTING_FLAGS, REPORT_ONLY_FIRST_FAILURE,
37 37 _unittest_reportflags, DocTestRunner,
38 38 _extract_future_flags, pdb, _OutputRedirectingPdb,
39 39 _exception_traceback,
40 40 linecache)
41 41
42 42 # Third-party modules
43 43
44 44 from nose.plugins import doctests, Plugin
45 45 from nose.util import anyp, tolist
46 46
47 47 # Our own imports
48 from IPython.utils.py3compat import builtin_mod, PY3, getcwd
48 from IPython.utils.py3compat import builtin_mod, PY3
49 49
50 50 if PY3:
51 51 from io import StringIO
52 52 else:
53 53 from StringIO import StringIO
54 54
55 55 #-----------------------------------------------------------------------------
56 56 # Module globals and other constants
57 57 #-----------------------------------------------------------------------------
58 58
59 59 log = logging.getLogger(__name__)
60 60
61 61
62 62 #-----------------------------------------------------------------------------
63 63 # Classes and functions
64 64 #-----------------------------------------------------------------------------
65 65
66 66 def is_extension_module(filename):
67 67 """Return whether the given filename is an extension module.
68 68
69 69 This simply checks that the extension is either .so or .pyd.
70 70 """
71 71 return os.path.splitext(filename)[1].lower() in ('.so','.pyd')
72 72
73 73
74 74 class DocTestSkip(object):
75 75 """Object wrapper for doctests to be skipped."""
76 76
77 77 ds_skip = """Doctest to skip.
78 78 >>> 1 #doctest: +SKIP
79 79 """
80 80
81 81 def __init__(self,obj):
82 82 self.obj = obj
83 83
84 84 def __getattribute__(self,key):
85 85 if key == '__doc__':
86 86 return DocTestSkip.ds_skip
87 87 else:
88 88 return getattr(object.__getattribute__(self,'obj'),key)
89 89
90 90 # Modified version of the one in the stdlib, that fixes a python bug (doctests
91 91 # not found in extension modules, http://bugs.python.org/issue3158)
92 92 class DocTestFinder(doctest.DocTestFinder):
93 93
94 94 def _from_module(self, module, object):
95 95 """
96 96 Return true if the given object is defined in the given
97 97 module.
98 98 """
99 99 if module is None:
100 100 return True
101 101 elif inspect.isfunction(object):
102 102 return module.__dict__ is object.__globals__
103 103 elif inspect.isbuiltin(object):
104 104 return module.__name__ == object.__module__
105 105 elif inspect.isclass(object):
106 106 return module.__name__ == object.__module__
107 107 elif inspect.ismethod(object):
108 108 # This one may be a bug in cython that fails to correctly set the
109 109 # __module__ attribute of methods, but since the same error is easy
110 110 # to make by extension code writers, having this safety in place
111 111 # isn't such a bad idea
112 112 return module.__name__ == object.__self__.__class__.__module__
113 113 elif inspect.getmodule(object) is not None:
114 114 return module is inspect.getmodule(object)
115 115 elif hasattr(object, '__module__'):
116 116 return module.__name__ == object.__module__
117 117 elif isinstance(object, property):
118 118 return True # [XX] no way not be sure.
119 119 elif inspect.ismethoddescriptor(object):
120 120 # Unbound PyQt signals reach this point in Python 3.4b3, and we want
121 121 # to avoid throwing an error. See also http://bugs.python.org/issue3158
122 122 return False
123 123 else:
124 124 raise ValueError("object must be a class or function, got %r" % object)
125 125
126 126 def _find(self, tests, obj, name, module, source_lines, globs, seen):
127 127 """
128 128 Find tests for the given object and any contained objects, and
129 129 add them to `tests`.
130 130 """
131 131 print('_find for:', obj, name, module) # dbg
132 132 if hasattr(obj,"skip_doctest"):
133 133 #print 'SKIPPING DOCTEST FOR:',obj # dbg
134 134 obj = DocTestSkip(obj)
135 135
136 136 doctest.DocTestFinder._find(self,tests, obj, name, module,
137 137 source_lines, globs, seen)
138 138
139 139 # Below we re-run pieces of the above method with manual modifications,
140 140 # because the original code is buggy and fails to correctly identify
141 141 # doctests in extension modules.
142 142
143 143 # Local shorthands
144 144 from inspect import isroutine, isclass
145 145
146 146 # Look for tests in a module's contained objects.
147 147 if inspect.ismodule(obj) and self._recurse:
148 148 for valname, val in obj.__dict__.items():
149 149 valname1 = '%s.%s' % (name, valname)
150 150 if ( (isroutine(val) or isclass(val))
151 151 and self._from_module(module, val) ):
152 152
153 153 self._find(tests, val, valname1, module, source_lines,
154 154 globs, seen)
155 155
156 156 # Look for tests in a class's contained objects.
157 157 if inspect.isclass(obj) and self._recurse:
158 158 #print 'RECURSE into class:',obj # dbg
159 159 for valname, val in obj.__dict__.items():
160 160 # Special handling for staticmethod/classmethod.
161 161 if isinstance(val, staticmethod):
162 162 val = getattr(obj, valname)
163 163 if isinstance(val, classmethod):
164 164 val = getattr(obj, valname).__func__
165 165
166 166 # Recurse to methods, properties, and nested classes.
167 167 if ((inspect.isfunction(val) or inspect.isclass(val) or
168 168 inspect.ismethod(val) or
169 169 isinstance(val, property)) and
170 170 self._from_module(module, val)):
171 171 valname = '%s.%s' % (name, valname)
172 172 self._find(tests, val, valname, module, source_lines,
173 173 globs, seen)
174 174
175 175
176 176 class IPDoctestOutputChecker(doctest.OutputChecker):
177 177 """Second-chance checker with support for random tests.
178 178
179 179 If the default comparison doesn't pass, this checker looks in the expected
180 180 output string for flags that tell us to ignore the output.
181 181 """
182 182
183 183 random_re = re.compile(r'#\s*random\s+')
184 184
185 185 def check_output(self, want, got, optionflags):
186 186 """Check output, accepting special markers embedded in the output.
187 187
188 188 If the output didn't pass the default validation but the special string
189 189 '#random' is included, we accept it."""
190 190
191 191 # Let the original tester verify first, in case people have valid tests
192 192 # that happen to have a comment saying '#random' embedded in.
193 193 ret = doctest.OutputChecker.check_output(self, want, got,
194 194 optionflags)
195 195 if not ret and self.random_re.search(want):
196 196 #print >> sys.stderr, 'RANDOM OK:',want # dbg
197 197 return True
198 198
199 199 return ret
200 200
201 201
202 202 class DocTestCase(doctests.DocTestCase):
203 203 """Proxy for DocTestCase: provides an address() method that
204 204 returns the correct address for the doctest case. Otherwise
205 205 acts as a proxy to the test case. To provide hints for address(),
206 206 an obj may also be passed -- this will be used as the test object
207 207 for purposes of determining the test address, if it is provided.
208 208 """
209 209
210 210 # Note: this method was taken from numpy's nosetester module.
211 211
212 212 # Subclass nose.plugins.doctests.DocTestCase to work around a bug in
213 213 # its constructor that blocks non-default arguments from being passed
214 214 # down into doctest.DocTestCase
215 215
216 216 def __init__(self, test, optionflags=0, setUp=None, tearDown=None,
217 217 checker=None, obj=None, result_var='_'):
218 218 self._result_var = result_var
219 219 doctests.DocTestCase.__init__(self, test,
220 220 optionflags=optionflags,
221 221 setUp=setUp, tearDown=tearDown,
222 222 checker=checker)
223 223 # Now we must actually copy the original constructor from the stdlib
224 224 # doctest class, because we can't call it directly and a bug in nose
225 225 # means it never gets passed the right arguments.
226 226
227 227 self._dt_optionflags = optionflags
228 228 self._dt_checker = checker
229 229 self._dt_test = test
230 230 self._dt_test_globs_ori = test.globs
231 231 self._dt_setUp = setUp
232 232 self._dt_tearDown = tearDown
233 233
234 234 # XXX - store this runner once in the object!
235 235 runner = IPDocTestRunner(optionflags=optionflags,
236 236 checker=checker, verbose=False)
237 237 self._dt_runner = runner
238 238
239 239
240 240 # Each doctest should remember the directory it was loaded from, so
241 241 # things like %run work without too many contortions
242 242 self._ori_dir = os.path.dirname(test.filename)
243 243
244 244 # Modified runTest from the default stdlib
245 245 def runTest(self):
246 246 test = self._dt_test
247 247 runner = self._dt_runner
248 248
249 249 old = sys.stdout
250 250 new = StringIO()
251 251 optionflags = self._dt_optionflags
252 252
253 253 if not (optionflags & REPORTING_FLAGS):
254 254 # The option flags don't include any reporting flags,
255 255 # so add the default reporting flags
256 256 optionflags |= _unittest_reportflags
257 257
258 258 try:
259 259 # Save our current directory and switch out to the one where the
260 260 # test was originally created, in case another doctest did a
261 261 # directory change. We'll restore this in the finally clause.
262 curdir = getcwd()
262 curdir = os.getcwd()
263 263 #print 'runTest in dir:', self._ori_dir # dbg
264 264 os.chdir(self._ori_dir)
265 265
266 266 runner.DIVIDER = "-"*70
267 267 failures, tries = runner.run(test,out=new.write,
268 268 clear_globs=False)
269 269 finally:
270 270 sys.stdout = old
271 271 os.chdir(curdir)
272 272
273 273 if failures:
274 274 raise self.failureException(self.format_failure(new.getvalue()))
275 275
276 276 def setUp(self):
277 277 """Modified test setup that syncs with ipython namespace"""
278 278 #print "setUp test", self._dt_test.examples # dbg
279 279 if isinstance(self._dt_test.examples[0], IPExample):
280 280 # for IPython examples *only*, we swap the globals with the ipython
281 281 # namespace, after updating it with the globals (which doctest
282 282 # fills with the necessary info from the module being tested).
283 283 self.user_ns_orig = {}
284 284 self.user_ns_orig.update(_ip.user_ns)
285 285 _ip.user_ns.update(self._dt_test.globs)
286 286 # We must remove the _ key in the namespace, so that Python's
287 287 # doctest code sets it naturally
288 288 _ip.user_ns.pop('_', None)
289 289 _ip.user_ns['__builtins__'] = builtin_mod
290 290 self._dt_test.globs = _ip.user_ns
291 291
292 292 super(DocTestCase, self).setUp()
293 293
294 294 def tearDown(self):
295 295
296 296 # Undo the test.globs reassignment we made, so that the parent class
297 297 # teardown doesn't destroy the ipython namespace
298 298 if isinstance(self._dt_test.examples[0], IPExample):
299 299 self._dt_test.globs = self._dt_test_globs_ori
300 300 _ip.user_ns.clear()
301 301 _ip.user_ns.update(self.user_ns_orig)
302 302
303 303 # XXX - fperez: I am not sure if this is truly a bug in nose 0.11, but
304 304 # it does look like one to me: its tearDown method tries to run
305 305 #
306 306 # delattr(builtin_mod, self._result_var)
307 307 #
308 308 # without checking that the attribute really is there; it implicitly
309 309 # assumes it should have been set via displayhook. But if the
310 310 # displayhook was never called, this doesn't necessarily happen. I
311 311 # haven't been able to find a little self-contained example outside of
312 312 # ipython that would show the problem so I can report it to the nose
313 313 # team, but it does happen a lot in our code.
314 314 #
315 315 # So here, we just protect as narrowly as possible by trapping an
316 316 # attribute error whose message would be the name of self._result_var,
317 317 # and letting any other error propagate.
318 318 try:
319 319 super(DocTestCase, self).tearDown()
320 320 except AttributeError as exc:
321 321 if exc.args[0] != self._result_var:
322 322 raise
323 323
324 324
325 325 # A simple subclassing of the original with a different class name, so we can
326 326 # distinguish and treat differently IPython examples from pure python ones.
327 327 class IPExample(doctest.Example): pass
328 328
329 329
330 330 class IPExternalExample(doctest.Example):
331 331 """Doctest examples to be run in an external process."""
332 332
333 333 def __init__(self, source, want, exc_msg=None, lineno=0, indent=0,
334 334 options=None):
335 335 # Parent constructor
336 336 doctest.Example.__init__(self,source,want,exc_msg,lineno,indent,options)
337 337
338 338 # An EXTRA newline is needed to prevent pexpect hangs
339 339 self.source += '\n'
340 340
341 341
342 342 class IPDocTestParser(doctest.DocTestParser):
343 343 """
344 344 A class used to parse strings containing doctest examples.
345 345
346 346 Note: This is a version modified to properly recognize IPython input and
347 347 convert any IPython examples into valid Python ones.
348 348 """
349 349 # This regular expression is used to find doctest examples in a
350 350 # string. It defines three groups: `source` is the source code
351 351 # (including leading indentation and prompts); `indent` is the
352 352 # indentation of the first (PS1) line of the source code; and
353 353 # `want` is the expected output (including leading indentation).
354 354
355 355 # Classic Python prompts or default IPython ones
356 356 _PS1_PY = r'>>>'
357 357 _PS2_PY = r'\.\.\.'
358 358
359 359 _PS1_IP = r'In\ \[\d+\]:'
360 360 _PS2_IP = r'\ \ \ \.\.\.+:'
361 361
362 362 _RE_TPL = r'''
363 363 # Source consists of a PS1 line followed by zero or more PS2 lines.
364 364 (?P<source>
365 365 (?:^(?P<indent> [ ]*) (?P<ps1> %s) .*) # PS1 line
366 366 (?:\n [ ]* (?P<ps2> %s) .*)*) # PS2 lines
367 367 \n? # a newline
368 368 # Want consists of any non-blank lines that do not start with PS1.
369 369 (?P<want> (?:(?![ ]*$) # Not a blank line
370 370 (?![ ]*%s) # Not a line starting with PS1
371 371 (?![ ]*%s) # Not a line starting with PS2
372 372 .*$\n? # But any other line
373 373 )*)
374 374 '''
375 375
376 376 _EXAMPLE_RE_PY = re.compile( _RE_TPL % (_PS1_PY,_PS2_PY,_PS1_PY,_PS2_PY),
377 377 re.MULTILINE | re.VERBOSE)
378 378
379 379 _EXAMPLE_RE_IP = re.compile( _RE_TPL % (_PS1_IP,_PS2_IP,_PS1_IP,_PS2_IP),
380 380 re.MULTILINE | re.VERBOSE)
381 381
382 382 # Mark a test as being fully random. In this case, we simply append the
383 383 # random marker ('#random') to each individual example's output. This way
384 384 # we don't need to modify any other code.
385 385 _RANDOM_TEST = re.compile(r'#\s*all-random\s+')
386 386
387 387 # Mark tests to be executed in an external process - currently unsupported.
388 388 _EXTERNAL_IP = re.compile(r'#\s*ipdoctest:\s*EXTERNAL')
389 389
390 390 def ip2py(self,source):
391 391 """Convert input IPython source into valid Python."""
392 392 block = _ip.input_transformer_manager.transform_cell(source)
393 393 if len(block.splitlines()) == 1:
394 394 return _ip.prefilter(block)
395 395 else:
396 396 return block
397 397
398 398 def parse(self, string, name='<string>'):
399 399 """
400 400 Divide the given string into examples and intervening text,
401 401 and return them as a list of alternating Examples and strings.
402 402 Line numbers for the Examples are 0-based. The optional
403 403 argument `name` is a name identifying this string, and is only
404 404 used for error messages.
405 405 """
406 406
407 407 #print 'Parse string:\n',string # dbg
408 408
409 409 string = string.expandtabs()
410 410 # If all lines begin with the same indentation, then strip it.
411 411 min_indent = self._min_indent(string)
412 412 if min_indent > 0:
413 413 string = '\n'.join([l[min_indent:] for l in string.split('\n')])
414 414
415 415 output = []
416 416 charno, lineno = 0, 0
417 417
418 418 # We make 'all random' tests by adding the '# random' mark to every
419 419 # block of output in the test.
420 420 if self._RANDOM_TEST.search(string):
421 421 random_marker = '\n# random'
422 422 else:
423 423 random_marker = ''
424 424
425 425 # Whether to convert the input from ipython to python syntax
426 426 ip2py = False
427 427 # Find all doctest examples in the string. First, try them as Python
428 428 # examples, then as IPython ones
429 429 terms = list(self._EXAMPLE_RE_PY.finditer(string))
430 430 if terms:
431 431 # Normal Python example
432 432 #print '-'*70 # dbg
433 433 #print 'PyExample, Source:\n',string # dbg
434 434 #print '-'*70 # dbg
435 435 Example = doctest.Example
436 436 else:
437 437 # It's an ipython example. Note that IPExamples are run
438 438 # in-process, so their syntax must be turned into valid python.
439 439 # IPExternalExamples are run out-of-process (via pexpect) so they
440 440 # don't need any filtering (a real ipython will be executing them).
441 441 terms = list(self._EXAMPLE_RE_IP.finditer(string))
442 442 if self._EXTERNAL_IP.search(string):
443 443 #print '-'*70 # dbg
444 444 #print 'IPExternalExample, Source:\n',string # dbg
445 445 #print '-'*70 # dbg
446 446 Example = IPExternalExample
447 447 else:
448 448 #print '-'*70 # dbg
449 449 #print 'IPExample, Source:\n',string # dbg
450 450 #print '-'*70 # dbg
451 451 Example = IPExample
452 452 ip2py = True
453 453
454 454 for m in terms:
455 455 # Add the pre-example text to `output`.
456 456 output.append(string[charno:m.start()])
457 457 # Update lineno (lines before this example)
458 458 lineno += string.count('\n', charno, m.start())
459 459 # Extract info from the regexp match.
460 460 (source, options, want, exc_msg) = \
461 461 self._parse_example(m, name, lineno,ip2py)
462 462
463 463 # Append the random-output marker (it defaults to empty in most
464 464 # cases, it's only non-empty for 'all-random' tests):
465 465 want += random_marker
466 466
467 467 if Example is IPExternalExample:
468 468 options[doctest.NORMALIZE_WHITESPACE] = True
469 469 want += '\n'
470 470
471 471 # Create an Example, and add it to the list.
472 472 if not self._IS_BLANK_OR_COMMENT(source):
473 473 output.append(Example(source, want, exc_msg,
474 474 lineno=lineno,
475 475 indent=min_indent+len(m.group('indent')),
476 476 options=options))
477 477 # Update lineno (lines inside this example)
478 478 lineno += string.count('\n', m.start(), m.end())
479 479 # Update charno.
480 480 charno = m.end()
481 481 # Add any remaining post-example text to `output`.
482 482 output.append(string[charno:])
483 483 return output
484 484
485 485 def _parse_example(self, m, name, lineno,ip2py=False):
486 486 """
487 487 Given a regular expression match from `_EXAMPLE_RE` (`m`),
488 488 return a pair `(source, want)`, where `source` is the matched
489 489 example's source code (with prompts and indentation stripped);
490 490 and `want` is the example's expected output (with indentation
491 491 stripped).
492 492
493 493 `name` is the string's name, and `lineno` is the line number
494 494 where the example starts; both are used for error messages.
495 495
496 496 Optional:
497 497 `ip2py`: if true, filter the input via IPython to convert the syntax
498 498 into valid python.
499 499 """
500 500
501 501 # Get the example's indentation level.
502 502 indent = len(m.group('indent'))
503 503
504 504 # Divide source into lines; check that they're properly
505 505 # indented; and then strip their indentation & prompts.
506 506 source_lines = m.group('source').split('\n')
507 507
508 508 # We're using variable-length input prompts
509 509 ps1 = m.group('ps1')
510 510 ps2 = m.group('ps2')
511 511 ps1_len = len(ps1)
512 512
513 513 self._check_prompt_blank(source_lines, indent, name, lineno,ps1_len)
514 514 if ps2:
515 515 self._check_prefix(source_lines[1:], ' '*indent + ps2, name, lineno)
516 516
517 517 source = '\n'.join([sl[indent+ps1_len+1:] for sl in source_lines])
518 518
519 519 if ip2py:
520 520 # Convert source input from IPython into valid Python syntax
521 521 source = self.ip2py(source)
522 522
523 523 # Divide want into lines; check that it's properly indented; and
524 524 # then strip the indentation. Spaces before the last newline should
525 525 # be preserved, so plain rstrip() isn't good enough.
526 526 want = m.group('want')
527 527 want_lines = want.split('\n')
528 528 if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]):
529 529 del want_lines[-1] # forget final newline & spaces after it
530 530 self._check_prefix(want_lines, ' '*indent, name,
531 531 lineno + len(source_lines))
532 532
533 533 # Remove ipython output prompt that might be present in the first line
534 534 want_lines[0] = re.sub(r'Out\[\d+\]: \s*?\n?','',want_lines[0])
535 535
536 536 want = '\n'.join([wl[indent:] for wl in want_lines])
537 537
538 538 # If `want` contains a traceback message, then extract it.
539 539 m = self._EXCEPTION_RE.match(want)
540 540 if m:
541 541 exc_msg = m.group('msg')
542 542 else:
543 543 exc_msg = None
544 544
545 545 # Extract options from the source.
546 546 options = self._find_options(source, name, lineno)
547 547
548 548 return source, options, want, exc_msg
549 549
550 550 def _check_prompt_blank(self, lines, indent, name, lineno, ps1_len):
551 551 """
552 552 Given the lines of a source string (including prompts and
553 553 leading indentation), check to make sure that every prompt is
554 554 followed by a space character. If any line is not followed by
555 555 a space character, then raise ValueError.
556 556
557 557 Note: IPython-modified version which takes the input prompt length as a
558 558 parameter, so that prompts of variable length can be dealt with.
559 559 """
560 560 space_idx = indent+ps1_len
561 561 min_len = space_idx+1
562 562 for i, line in enumerate(lines):
563 563 if len(line) >= min_len and line[space_idx] != ' ':
564 564 raise ValueError('line %r of the docstring for %s '
565 565 'lacks blank after %s: %r' %
566 566 (lineno+i+1, name,
567 567 line[indent:space_idx], line))
568 568
569 569
570 570 SKIP = doctest.register_optionflag('SKIP')
571 571
572 572
573 573 class IPDocTestRunner(doctest.DocTestRunner,object):
574 574 """Test runner that synchronizes the IPython namespace with test globals.
575 575 """
576 576
577 577 def run(self, test, compileflags=None, out=None, clear_globs=True):
578 578
579 579 # Hack: ipython needs access to the execution context of the example,
580 580 # so that it can propagate user variables loaded by %run into
581 581 # test.globs. We put them here into our modified %run as a function
582 582 # attribute. Our new %run will then only make the namespace update
583 583 # when called (rather than unconconditionally updating test.globs here
584 584 # for all examples, most of which won't be calling %run anyway).
585 585 #_ip._ipdoctest_test_globs = test.globs
586 586 #_ip._ipdoctest_test_filename = test.filename
587 587
588 588 test.globs.update(_ip.user_ns)
589 589
590 590 # Override terminal size to standardise traceback format
591 591 with modified_env({'COLUMNS': '80', 'LINES': '24'}):
592 592 return super(IPDocTestRunner,self).run(test,
593 593 compileflags,out,clear_globs)
594 594
595 595
596 596 class DocFileCase(doctest.DocFileCase):
597 597 """Overrides to provide filename
598 598 """
599 599 def address(self):
600 600 return (self._dt_test.filename, None, None)
601 601
602 602
603 603 class ExtensionDoctest(doctests.Doctest):
604 604 """Nose Plugin that supports doctests in extension modules.
605 605 """
606 606 name = 'extdoctest' # call nosetests with --with-extdoctest
607 607 enabled = True
608 608
609 609 def options(self, parser, env=os.environ):
610 610 Plugin.options(self, parser, env)
611 611 parser.add_option('--doctest-tests', action='store_true',
612 612 dest='doctest_tests',
613 613 default=env.get('NOSE_DOCTEST_TESTS',True),
614 614 help="Also look for doctests in test modules. "
615 615 "Note that classes, methods and functions should "
616 616 "have either doctests or non-doctest tests, "
617 617 "not both. [NOSE_DOCTEST_TESTS]")
618 618 parser.add_option('--doctest-extension', action="append",
619 619 dest="doctestExtension",
620 620 help="Also look for doctests in files with "
621 621 "this extension [NOSE_DOCTEST_EXTENSION]")
622 622 # Set the default as a list, if given in env; otherwise
623 623 # an additional value set on the command line will cause
624 624 # an error.
625 625 env_setting = env.get('NOSE_DOCTEST_EXTENSION')
626 626 if env_setting is not None:
627 627 parser.set_defaults(doctestExtension=tolist(env_setting))
628 628
629 629
630 630 def configure(self, options, config):
631 631 Plugin.configure(self, options, config)
632 632 # Pull standard doctest plugin out of config; we will do doctesting
633 633 config.plugins.plugins = [p for p in config.plugins.plugins
634 634 if p.name != 'doctest']
635 635 self.doctest_tests = options.doctest_tests
636 636 self.extension = tolist(options.doctestExtension)
637 637
638 638 self.parser = doctest.DocTestParser()
639 639 self.finder = DocTestFinder()
640 640 self.checker = IPDoctestOutputChecker()
641 641 self.globs = None
642 642 self.extraglobs = None
643 643
644 644
645 645 def loadTestsFromExtensionModule(self,filename):
646 646 bpath,mod = os.path.split(filename)
647 647 modname = os.path.splitext(mod)[0]
648 648 try:
649 649 sys.path.append(bpath)
650 650 module = import_module(modname)
651 651 tests = list(self.loadTestsFromModule(module))
652 652 finally:
653 653 sys.path.pop()
654 654 return tests
655 655
656 656 # NOTE: the method below is almost a copy of the original one in nose, with
657 657 # a few modifications to control output checking.
658 658
659 659 def loadTestsFromModule(self, module):
660 660 #print '*** ipdoctest - lTM',module # dbg
661 661
662 662 if not self.matches(module.__name__):
663 663 log.debug("Doctest doesn't want module %s", module)
664 664 return
665 665
666 666 tests = self.finder.find(module,globs=self.globs,
667 667 extraglobs=self.extraglobs)
668 668 if not tests:
669 669 return
670 670
671 671 # always use whitespace and ellipsis options
672 672 optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
673 673
674 674 tests.sort()
675 675 module_file = module.__file__
676 676 if module_file[-4:] in ('.pyc', '.pyo'):
677 677 module_file = module_file[:-1]
678 678 for test in tests:
679 679 if not test.examples:
680 680 continue
681 681 if not test.filename:
682 682 test.filename = module_file
683 683
684 684 yield DocTestCase(test,
685 685 optionflags=optionflags,
686 686 checker=self.checker)
687 687
688 688
689 689 def loadTestsFromFile(self, filename):
690 690 #print "ipdoctest - from file", filename # dbg
691 691 if is_extension_module(filename):
692 692 for t in self.loadTestsFromExtensionModule(filename):
693 693 yield t
694 694 else:
695 695 if self.extension and anyp(filename.endswith, self.extension):
696 696 name = os.path.basename(filename)
697 697 dh = open(filename)
698 698 try:
699 699 doc = dh.read()
700 700 finally:
701 701 dh.close()
702 702 test = self.parser.get_doctest(
703 703 doc, globs={'__file__': filename}, name=name,
704 704 filename=filename, lineno=0)
705 705 if test.examples:
706 706 #print 'FileCase:',test.examples # dbg
707 707 yield DocFileCase(test)
708 708 else:
709 709 yield False # no tests to load
710 710
711 711
712 712 class IPythonDoctest(ExtensionDoctest):
713 713 """Nose Plugin that supports doctests in extension modules.
714 714 """
715 715 name = 'ipdoctest' # call nosetests with --with-ipdoctest
716 716 enabled = True
717 717
718 718 def makeTest(self, obj, parent):
719 719 """Look for doctests in the given object, which will be a
720 720 function, method or class.
721 721 """
722 722 #print 'Plugin analyzing:', obj, parent # dbg
723 723 # always use whitespace and ellipsis options
724 724 optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
725 725
726 726 doctests = self.finder.find(obj, module=getmodule(parent))
727 727 if doctests:
728 728 for test in doctests:
729 729 if len(test.examples) == 0:
730 730 continue
731 731
732 732 yield DocTestCase(test, obj=obj,
733 733 optionflags=optionflags,
734 734 checker=self.checker)
735 735
736 736 def options(self, parser, env=os.environ):
737 737 #print "Options for nose plugin:", self.name # dbg
738 738 Plugin.options(self, parser, env)
739 739 parser.add_option('--ipdoctest-tests', action='store_true',
740 740 dest='ipdoctest_tests',
741 741 default=env.get('NOSE_IPDOCTEST_TESTS',True),
742 742 help="Also look for doctests in test modules. "
743 743 "Note that classes, methods and functions should "
744 744 "have either doctests or non-doctest tests, "
745 745 "not both. [NOSE_IPDOCTEST_TESTS]")
746 746 parser.add_option('--ipdoctest-extension', action="append",
747 747 dest="ipdoctest_extension",
748 748 help="Also look for doctests in files with "
749 749 "this extension [NOSE_IPDOCTEST_EXTENSION]")
750 750 # Set the default as a list, if given in env; otherwise
751 751 # an additional value set on the command line will cause
752 752 # an error.
753 753 env_setting = env.get('NOSE_IPDOCTEST_EXTENSION')
754 754 if env_setting is not None:
755 755 parser.set_defaults(ipdoctest_extension=tolist(env_setting))
756 756
757 757 def configure(self, options, config):
758 758 #print "Configuring nose plugin:", self.name # dbg
759 759 Plugin.configure(self, options, config)
760 760 # Pull standard doctest plugin out of config; we will do doctesting
761 761 config.plugins.plugins = [p for p in config.plugins.plugins
762 762 if p.name != 'doctest']
763 763 self.doctest_tests = options.ipdoctest_tests
764 764 self.extension = tolist(options.ipdoctest_extension)
765 765
766 766 self.parser = IPDocTestParser()
767 767 self.finder = DocTestFinder(parser=self.parser)
768 768 self.checker = IPDoctestOutputChecker()
769 769 self.globs = None
770 770 self.extraglobs = None
@@ -1,476 +1,476 b''
1 1 """Generic testing tools.
2 2
3 3 Authors
4 4 -------
5 5 - Fernando Perez <Fernando.Perez@berkeley.edu>
6 6 """
7 7
8 8
9 9 # Copyright (c) IPython Development Team.
10 10 # Distributed under the terms of the Modified BSD License.
11 11
12 12 import os
13 13 import re
14 14 import sys
15 15 import tempfile
16 16
17 17 from contextlib import contextmanager
18 18 from io import StringIO
19 19 from subprocess import Popen, PIPE
20 20 from unittest.mock import patch
21 21
22 22 try:
23 23 # These tools are used by parts of the runtime, so we make the nose
24 24 # dependency optional at this point. Nose is a hard dependency to run the
25 25 # test suite, but NOT to use ipython itself.
26 26 import nose.tools as nt
27 27 has_nose = True
28 28 except ImportError:
29 29 has_nose = False
30 30
31 31 from traitlets.config.loader import Config
32 32 from IPython.utils.process import get_output_error_code
33 33 from IPython.utils.text import list_strings
34 34 from IPython.utils.io import temp_pyfile, Tee
35 35 from IPython.utils import py3compat
36 36 from IPython.utils.encoding import DEFAULT_ENCODING
37 37
38 38 from . import decorators as dec
39 39 from . import skipdoctest
40 40
41 41
42 42 # The docstring for full_path doctests differently on win32 (different path
43 43 # separator) so just skip the doctest there. The example remains informative.
44 44 doctest_deco = skipdoctest.skip_doctest if sys.platform == 'win32' else dec.null_deco
45 45
46 46 @doctest_deco
47 47 def full_path(startPath,files):
48 48 """Make full paths for all the listed files, based on startPath.
49 49
50 50 Only the base part of startPath is kept, since this routine is typically
51 51 used with a script's ``__file__`` variable as startPath. The base of startPath
52 52 is then prepended to all the listed files, forming the output list.
53 53
54 54 Parameters
55 55 ----------
56 56 startPath : string
57 57 Initial path to use as the base for the results. This path is split
58 58 using os.path.split() and only its first component is kept.
59 59
60 60 files : string or list
61 61 One or more files.
62 62
63 63 Examples
64 64 --------
65 65
66 66 >>> full_path('/foo/bar.py',['a.txt','b.txt'])
67 67 ['/foo/a.txt', '/foo/b.txt']
68 68
69 69 >>> full_path('/foo',['a.txt','b.txt'])
70 70 ['/a.txt', '/b.txt']
71 71
72 72 If a single file is given, the output is still a list::
73 73
74 74 >>> full_path('/foo','a.txt')
75 75 ['/a.txt']
76 76 """
77 77
78 78 files = list_strings(files)
79 79 base = os.path.split(startPath)[0]
80 80 return [ os.path.join(base,f) for f in files ]
81 81
82 82
83 83 def parse_test_output(txt):
84 84 """Parse the output of a test run and return errors, failures.
85 85
86 86 Parameters
87 87 ----------
88 88 txt : str
89 89 Text output of a test run, assumed to contain a line of one of the
90 90 following forms::
91 91
92 92 'FAILED (errors=1)'
93 93 'FAILED (failures=1)'
94 94 'FAILED (errors=1, failures=1)'
95 95
96 96 Returns
97 97 -------
98 98 nerr, nfail
99 99 number of errors and failures.
100 100 """
101 101
102 102 err_m = re.search(r'^FAILED \(errors=(\d+)\)', txt, re.MULTILINE)
103 103 if err_m:
104 104 nerr = int(err_m.group(1))
105 105 nfail = 0
106 106 return nerr, nfail
107 107
108 108 fail_m = re.search(r'^FAILED \(failures=(\d+)\)', txt, re.MULTILINE)
109 109 if fail_m:
110 110 nerr = 0
111 111 nfail = int(fail_m.group(1))
112 112 return nerr, nfail
113 113
114 114 both_m = re.search(r'^FAILED \(errors=(\d+), failures=(\d+)\)', txt,
115 115 re.MULTILINE)
116 116 if both_m:
117 117 nerr = int(both_m.group(1))
118 118 nfail = int(both_m.group(2))
119 119 return nerr, nfail
120 120
121 121 # If the input didn't match any of these forms, assume no error/failures
122 122 return 0, 0
123 123
124 124
125 125 # So nose doesn't think this is a test
126 126 parse_test_output.__test__ = False
127 127
128 128
129 129 def default_argv():
130 130 """Return a valid default argv for creating testing instances of ipython"""
131 131
132 132 return ['--quick', # so no config file is loaded
133 133 # Other defaults to minimize side effects on stdout
134 134 '--colors=NoColor', '--no-term-title','--no-banner',
135 135 '--autocall=0']
136 136
137 137
138 138 def default_config():
139 139 """Return a config object with good defaults for testing."""
140 140 config = Config()
141 141 config.TerminalInteractiveShell.colors = 'NoColor'
142 142 config.TerminalTerminalInteractiveShell.term_title = False,
143 143 config.TerminalInteractiveShell.autocall = 0
144 144 f = tempfile.NamedTemporaryFile(suffix=u'test_hist.sqlite', delete=False)
145 145 config.HistoryManager.hist_file = f.name
146 146 f.close()
147 147 config.HistoryManager.db_cache_size = 10000
148 148 return config
149 149
150 150
151 151 def get_ipython_cmd(as_string=False):
152 152 """
153 153 Return appropriate IPython command line name. By default, this will return
154 154 a list that can be used with subprocess.Popen, for example, but passing
155 155 `as_string=True` allows for returning the IPython command as a string.
156 156
157 157 Parameters
158 158 ----------
159 159 as_string: bool
160 160 Flag to allow to return the command as a string.
161 161 """
162 162 ipython_cmd = [sys.executable, "-m", "IPython"]
163 163
164 164 if as_string:
165 165 ipython_cmd = " ".join(ipython_cmd)
166 166
167 167 return ipython_cmd
168 168
169 169 def ipexec(fname, options=None, commands=()):
170 170 """Utility to call 'ipython filename'.
171 171
172 172 Starts IPython with a minimal and safe configuration to make startup as fast
173 173 as possible.
174 174
175 175 Note that this starts IPython in a subprocess!
176 176
177 177 Parameters
178 178 ----------
179 179 fname : str
180 180 Name of file to be executed (should have .py or .ipy extension).
181 181
182 182 options : optional, list
183 183 Extra command-line flags to be passed to IPython.
184 184
185 185 commands : optional, list
186 186 Commands to send in on stdin
187 187
188 188 Returns
189 189 -------
190 190 (stdout, stderr) of ipython subprocess.
191 191 """
192 192 if options is None: options = []
193 193
194 194 cmdargs = default_argv() + options
195 195
196 196 test_dir = os.path.dirname(__file__)
197 197
198 198 ipython_cmd = get_ipython_cmd()
199 199 # Absolute path for filename
200 200 full_fname = os.path.join(test_dir, fname)
201 201 full_cmd = ipython_cmd + cmdargs + [full_fname]
202 202 env = os.environ.copy()
203 203 # FIXME: ignore all warnings in ipexec while we have shims
204 204 # should we keep suppressing warnings here, even after removing shims?
205 205 env['PYTHONWARNINGS'] = 'ignore'
206 206 # env.pop('PYTHONWARNINGS', None) # Avoid extraneous warnings appearing on stderr
207 207 for k, v in env.items():
208 208 # Debug a bizarre failure we've seen on Windows:
209 209 # TypeError: environment can only contain strings
210 210 if not isinstance(v, str):
211 211 print(k, v)
212 212 p = Popen(full_cmd, stdout=PIPE, stderr=PIPE, stdin=PIPE, env=env)
213 213 out, err = p.communicate(input=py3compat.str_to_bytes('\n'.join(commands)) or None)
214 214 out, err = py3compat.bytes_to_str(out), py3compat.bytes_to_str(err)
215 215 # `import readline` causes 'ESC[?1034h' to be output sometimes,
216 216 # so strip that out before doing comparisons
217 217 if out:
218 218 out = re.sub(r'\x1b\[[^h]+h', '', out)
219 219 return out, err
220 220
221 221
222 222 def ipexec_validate(fname, expected_out, expected_err='',
223 223 options=None, commands=()):
224 224 """Utility to call 'ipython filename' and validate output/error.
225 225
226 226 This function raises an AssertionError if the validation fails.
227 227
228 228 Note that this starts IPython in a subprocess!
229 229
230 230 Parameters
231 231 ----------
232 232 fname : str
233 233 Name of the file to be executed (should have .py or .ipy extension).
234 234
235 235 expected_out : str
236 236 Expected stdout of the process.
237 237
238 238 expected_err : optional, str
239 239 Expected stderr of the process.
240 240
241 241 options : optional, list
242 242 Extra command-line flags to be passed to IPython.
243 243
244 244 Returns
245 245 -------
246 246 None
247 247 """
248 248
249 249 import nose.tools as nt
250 250
251 251 out, err = ipexec(fname, options, commands)
252 252 #print 'OUT', out # dbg
253 253 #print 'ERR', err # dbg
254 254 # If there are any errors, we must check those befor stdout, as they may be
255 255 # more informative than simply having an empty stdout.
256 256 if err:
257 257 if expected_err:
258 258 nt.assert_equal("\n".join(err.strip().splitlines()), "\n".join(expected_err.strip().splitlines()))
259 259 else:
260 260 raise ValueError('Running file %r produced error: %r' %
261 261 (fname, err))
262 262 # If no errors or output on stderr was expected, match stdout
263 263 nt.assert_equal("\n".join(out.strip().splitlines()), "\n".join(expected_out.strip().splitlines()))
264 264
265 265
266 266 class TempFileMixin(object):
267 267 """Utility class to create temporary Python/IPython files.
268 268
269 269 Meant as a mixin class for test cases."""
270 270
271 271 def mktmp(self, src, ext='.py'):
272 272 """Make a valid python temp file."""
273 273 fname, f = temp_pyfile(src, ext)
274 274 self.tmpfile = f
275 275 self.fname = fname
276 276
277 277 def tearDown(self):
278 278 if hasattr(self, 'tmpfile'):
279 279 # If the tmpfile wasn't made because of skipped tests, like in
280 280 # win32, there's nothing to cleanup.
281 281 self.tmpfile.close()
282 282 try:
283 283 os.unlink(self.fname)
284 284 except:
285 285 # On Windows, even though we close the file, we still can't
286 286 # delete it. I have no clue why
287 287 pass
288 288
289 289 def __enter__(self):
290 290 return self
291 291
292 292 def __exit__(self, exc_type, exc_value, traceback):
293 293 self.tearDown()
294 294
295 295
296 296 pair_fail_msg = ("Testing {0}\n\n"
297 297 "In:\n"
298 298 " {1!r}\n"
299 299 "Expected:\n"
300 300 " {2!r}\n"
301 301 "Got:\n"
302 302 " {3!r}\n")
303 303 def check_pairs(func, pairs):
304 304 """Utility function for the common case of checking a function with a
305 305 sequence of input/output pairs.
306 306
307 307 Parameters
308 308 ----------
309 309 func : callable
310 310 The function to be tested. Should accept a single argument.
311 311 pairs : iterable
312 312 A list of (input, expected_output) tuples.
313 313
314 314 Returns
315 315 -------
316 316 None. Raises an AssertionError if any output does not match the expected
317 317 value.
318 318 """
319 319 name = getattr(func, "func_name", getattr(func, "__name__", "<unknown>"))
320 320 for inp, expected in pairs:
321 321 out = func(inp)
322 322 assert out == expected, pair_fail_msg.format(name, inp, expected, out)
323 323
324 324
325 325 if py3compat.PY3:
326 326 MyStringIO = StringIO
327 327 else:
328 328 # In Python 2, stdout/stderr can have either bytes or unicode written to them,
329 329 # so we need a class that can handle both.
330 330 class MyStringIO(StringIO):
331 331 def write(self, s):
332 332 s = py3compat.cast_unicode(s, encoding=DEFAULT_ENCODING)
333 333 super(MyStringIO, self).write(s)
334 334
335 335 _re_type = type(re.compile(r''))
336 336
337 337 notprinted_msg = """Did not find {0!r} in printed output (on {1}):
338 338 -------
339 339 {2!s}
340 340 -------
341 341 """
342 342
343 343 class AssertPrints(object):
344 344 """Context manager for testing that code prints certain text.
345 345
346 346 Examples
347 347 --------
348 348 >>> with AssertPrints("abc", suppress=False):
349 349 ... print("abcd")
350 350 ... print("def")
351 351 ...
352 352 abcd
353 353 def
354 354 """
355 355 def __init__(self, s, channel='stdout', suppress=True):
356 356 self.s = s
357 if isinstance(self.s, (py3compat.string_types, _re_type)):
357 if isinstance(self.s, (str, _re_type)):
358 358 self.s = [self.s]
359 359 self.channel = channel
360 360 self.suppress = suppress
361 361
362 362 def __enter__(self):
363 363 self.orig_stream = getattr(sys, self.channel)
364 364 self.buffer = MyStringIO()
365 365 self.tee = Tee(self.buffer, channel=self.channel)
366 366 setattr(sys, self.channel, self.buffer if self.suppress else self.tee)
367 367
368 368 def __exit__(self, etype, value, traceback):
369 369 try:
370 370 if value is not None:
371 371 # If an error was raised, don't check anything else
372 372 return False
373 373 self.tee.flush()
374 374 setattr(sys, self.channel, self.orig_stream)
375 375 printed = self.buffer.getvalue()
376 376 for s in self.s:
377 377 if isinstance(s, _re_type):
378 378 assert s.search(printed), notprinted_msg.format(s.pattern, self.channel, printed)
379 379 else:
380 380 assert s in printed, notprinted_msg.format(s, self.channel, printed)
381 381 return False
382 382 finally:
383 383 self.tee.close()
384 384
385 385 printed_msg = """Found {0!r} in printed output (on {1}):
386 386 -------
387 387 {2!s}
388 388 -------
389 389 """
390 390
391 391 class AssertNotPrints(AssertPrints):
392 392 """Context manager for checking that certain output *isn't* produced.
393 393
394 394 Counterpart of AssertPrints"""
395 395 def __exit__(self, etype, value, traceback):
396 396 try:
397 397 if value is not None:
398 398 # If an error was raised, don't check anything else
399 399 self.tee.close()
400 400 return False
401 401 self.tee.flush()
402 402 setattr(sys, self.channel, self.orig_stream)
403 403 printed = self.buffer.getvalue()
404 404 for s in self.s:
405 405 if isinstance(s, _re_type):
406 406 assert not s.search(printed),printed_msg.format(
407 407 s.pattern, self.channel, printed)
408 408 else:
409 409 assert s not in printed, printed_msg.format(
410 410 s, self.channel, printed)
411 411 return False
412 412 finally:
413 413 self.tee.close()
414 414
415 415 @contextmanager
416 416 def mute_warn():
417 417 from IPython.utils import warn
418 418 save_warn = warn.warn
419 419 warn.warn = lambda *a, **kw: None
420 420 try:
421 421 yield
422 422 finally:
423 423 warn.warn = save_warn
424 424
425 425 @contextmanager
426 426 def make_tempfile(name):
427 427 """ Create an empty, named, temporary file for the duration of the context.
428 428 """
429 429 f = open(name, 'w')
430 430 f.close()
431 431 try:
432 432 yield
433 433 finally:
434 434 os.unlink(name)
435 435
436 436 def fake_input(inputs):
437 437 """Temporarily replace the input() function to return the given values
438 438
439 439 Use as a context manager:
440 440
441 441 with fake_input(['result1', 'result2']):
442 442 ...
443 443
444 444 Values are returned in order. If input() is called again after the last value
445 445 was used, EOFError is raised.
446 446 """
447 447 it = iter(inputs)
448 448 def mock_input(prompt=''):
449 449 try:
450 450 return next(it)
451 451 except StopIteration:
452 452 raise EOFError('No more inputs given')
453 453
454 454 return patch('builtins.input', mock_input)
455 455
456 456 def help_output_test(subcommand=''):
457 457 """test that `ipython [subcommand] -h` works"""
458 458 cmd = get_ipython_cmd() + [subcommand, '-h']
459 459 out, err, rc = get_output_error_code(cmd)
460 460 nt.assert_equal(rc, 0, err)
461 461 nt.assert_not_in("Traceback", err)
462 462 nt.assert_in("Options", out)
463 463 nt.assert_in("--help-all", out)
464 464 return out, err
465 465
466 466
467 467 def help_all_output_test(subcommand=''):
468 468 """test that `ipython [subcommand] --help-all` works"""
469 469 cmd = get_ipython_cmd() + [subcommand, '--help-all']
470 470 out, err, rc = get_output_error_code(cmd)
471 471 nt.assert_equal(rc, 0, err)
472 472 nt.assert_not_in("Traceback", err)
473 473 nt.assert_in("Options", out)
474 474 nt.assert_in("Class parameters", out)
475 475 return out, err
476 476
@@ -1,223 +1,223 b''
1 1 """Common utilities for the various process_* implementations.
2 2
3 3 This file is only meant to be imported by the platform-specific implementations
4 4 of subprocess utilities, and it contains tools that are common to all of them.
5 5 """
6 6
7 7 #-----------------------------------------------------------------------------
8 8 # Copyright (C) 2010-2011 The IPython Development Team
9 9 #
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #-----------------------------------------------------------------------------
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Imports
16 16 #-----------------------------------------------------------------------------
17 17 import subprocess
18 18 import shlex
19 19 import sys
20 20 import os
21 21
22 22 from IPython.utils import py3compat
23 23
24 24 #-----------------------------------------------------------------------------
25 25 # Function definitions
26 26 #-----------------------------------------------------------------------------
27 27
28 28 def read_no_interrupt(p):
29 29 """Read from a pipe ignoring EINTR errors.
30 30
31 31 This is necessary because when reading from pipes with GUI event loops
32 32 running in the background, often interrupts are raised that stop the
33 33 command from completing."""
34 34 import errno
35 35
36 36 try:
37 37 return p.read()
38 38 except IOError as err:
39 39 if err.errno != errno.EINTR:
40 40 raise
41 41
42 42
43 43 def process_handler(cmd, callback, stderr=subprocess.PIPE):
44 44 """Open a command in a shell subprocess and execute a callback.
45 45
46 46 This function provides common scaffolding for creating subprocess.Popen()
47 47 calls. It creates a Popen object and then calls the callback with it.
48 48
49 49 Parameters
50 50 ----------
51 51 cmd : str or list
52 52 A command to be executed by the system, using :class:`subprocess.Popen`.
53 53 If a string is passed, it will be run in the system shell. If a list is
54 54 passed, it will be used directly as arguments.
55 55
56 56 callback : callable
57 57 A one-argument function that will be called with the Popen object.
58 58
59 59 stderr : file descriptor number, optional
60 60 By default this is set to ``subprocess.PIPE``, but you can also pass the
61 61 value ``subprocess.STDOUT`` to force the subprocess' stderr to go into
62 62 the same file descriptor as its stdout. This is useful to read stdout
63 63 and stderr combined in the order they are generated.
64 64
65 65 Returns
66 66 -------
67 67 The return value of the provided callback is returned.
68 68 """
69 69 sys.stdout.flush()
70 70 sys.stderr.flush()
71 71 # On win32, close_fds can't be true when using pipes for stdin/out/err
72 72 close_fds = sys.platform != 'win32'
73 73 # Determine if cmd should be run with system shell.
74 shell = isinstance(cmd, py3compat.string_types)
74 shell = isinstance(cmd, str)
75 75 # On POSIX systems run shell commands with user-preferred shell.
76 76 executable = None
77 77 if shell and os.name == 'posix' and 'SHELL' in os.environ:
78 78 executable = os.environ['SHELL']
79 79 p = subprocess.Popen(cmd, shell=shell,
80 80 executable=executable,
81 81 stdin=subprocess.PIPE,
82 82 stdout=subprocess.PIPE,
83 83 stderr=stderr,
84 84 close_fds=close_fds)
85 85
86 86 try:
87 87 out = callback(p)
88 88 except KeyboardInterrupt:
89 89 print('^C')
90 90 sys.stdout.flush()
91 91 sys.stderr.flush()
92 92 out = None
93 93 finally:
94 94 # Make really sure that we don't leave processes behind, in case the
95 95 # call above raises an exception
96 96 # We start by assuming the subprocess finished (to avoid NameErrors
97 97 # later depending on the path taken)
98 98 if p.returncode is None:
99 99 try:
100 100 p.terminate()
101 101 p.poll()
102 102 except OSError:
103 103 pass
104 104 # One last try on our way out
105 105 if p.returncode is None:
106 106 try:
107 107 p.kill()
108 108 except OSError:
109 109 pass
110 110
111 111 return out
112 112
113 113
114 114 def getoutput(cmd):
115 115 """Run a command and return its stdout/stderr as a string.
116 116
117 117 Parameters
118 118 ----------
119 119 cmd : str or list
120 120 A command to be executed in the system shell.
121 121
122 122 Returns
123 123 -------
124 124 output : str
125 125 A string containing the combination of stdout and stderr from the
126 126 subprocess, in whatever order the subprocess originally wrote to its
127 127 file descriptors (so the order of the information in this string is the
128 128 correct order as would be seen if running the command in a terminal).
129 129 """
130 130 out = process_handler(cmd, lambda p: p.communicate()[0], subprocess.STDOUT)
131 131 if out is None:
132 132 return ''
133 133 return py3compat.bytes_to_str(out)
134 134
135 135
136 136 def getoutputerror(cmd):
137 137 """Return (standard output, standard error) of executing cmd in a shell.
138 138
139 139 Accepts the same arguments as os.system().
140 140
141 141 Parameters
142 142 ----------
143 143 cmd : str or list
144 144 A command to be executed in the system shell.
145 145
146 146 Returns
147 147 -------
148 148 stdout : str
149 149 stderr : str
150 150 """
151 151 return get_output_error_code(cmd)[:2]
152 152
153 153 def get_output_error_code(cmd):
154 154 """Return (standard output, standard error, return code) of executing cmd
155 155 in a shell.
156 156
157 157 Accepts the same arguments as os.system().
158 158
159 159 Parameters
160 160 ----------
161 161 cmd : str or list
162 162 A command to be executed in the system shell.
163 163
164 164 Returns
165 165 -------
166 166 stdout : str
167 167 stderr : str
168 168 returncode: int
169 169 """
170 170
171 171 out_err, p = process_handler(cmd, lambda p: (p.communicate(), p))
172 172 if out_err is None:
173 173 return '', '', p.returncode
174 174 out, err = out_err
175 175 return py3compat.bytes_to_str(out), py3compat.bytes_to_str(err), p.returncode
176 176
177 177 def arg_split(s, posix=False, strict=True):
178 178 """Split a command line's arguments in a shell-like manner.
179 179
180 180 This is a modified version of the standard library's shlex.split()
181 181 function, but with a default of posix=False for splitting, so that quotes
182 182 in inputs are respected.
183 183
184 184 if strict=False, then any errors shlex.split would raise will result in the
185 185 unparsed remainder being the last element of the list, rather than raising.
186 186 This is because we sometimes use arg_split to parse things other than
187 187 command-line args.
188 188 """
189 189
190 190 # Unfortunately, python's shlex module is buggy with unicode input:
191 191 # http://bugs.python.org/issue1170
192 192 # At least encoding the input when it's unicode seems to help, but there
193 193 # may be more problems lurking. Apparently this is fixed in python3.
194 194 is_unicode = False
195 195 if (not py3compat.PY3) and isinstance(s, unicode):
196 196 is_unicode = True
197 197 s = s.encode('utf-8')
198 198 lex = shlex.shlex(s, posix=posix)
199 199 lex.whitespace_split = True
200 200 # Extract tokens, ensuring that things like leaving open quotes
201 201 # does not cause this to raise. This is important, because we
202 202 # sometimes pass Python source through this (e.g. %timeit f(" ")),
203 203 # and it shouldn't raise an exception.
204 204 # It may be a bad idea to parse things that are not command-line args
205 205 # through this function, but we do, so let's be safe about it.
206 206 lex.commenters='' #fix for GH-1269
207 207 tokens = []
208 208 while True:
209 209 try:
210 210 tokens.append(next(lex))
211 211 except StopIteration:
212 212 break
213 213 except ValueError:
214 214 if strict:
215 215 raise
216 216 # couldn't parse, get remaining blob as last token
217 217 tokens.append(lex.token)
218 218 break
219 219
220 220 if is_unicode:
221 221 # Convert the tokens back to unicode.
222 222 tokens = [x.decode('utf-8') for x in tokens]
223 223 return tokens
@@ -1,191 +1,191 b''
1 1 """Windows-specific implementation of process utilities.
2 2
3 3 This file is only meant to be imported by process.py, not by end-users.
4 4 """
5 5
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (C) 2010-2011 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16
17 17 # stdlib
18 18 import os
19 19 import sys
20 20 import ctypes
21 21
22 22 from ctypes import c_int, POINTER
23 23 from ctypes.wintypes import LPCWSTR, HLOCAL
24 24 from subprocess import STDOUT
25 25
26 26 # our own imports
27 27 from ._process_common import read_no_interrupt, process_handler, arg_split as py_arg_split
28 28 from . import py3compat
29 29 from .encoding import DEFAULT_ENCODING
30 30
31 31 #-----------------------------------------------------------------------------
32 32 # Function definitions
33 33 #-----------------------------------------------------------------------------
34 34
35 35 class AvoidUNCPath(object):
36 36 """A context manager to protect command execution from UNC paths.
37 37
38 38 In the Win32 API, commands can't be invoked with the cwd being a UNC path.
39 39 This context manager temporarily changes directory to the 'C:' drive on
40 40 entering, and restores the original working directory on exit.
41 41
42 42 The context manager returns the starting working directory *if* it made a
43 43 change and None otherwise, so that users can apply the necessary adjustment
44 44 to their system calls in the event of a change.
45 45
46 46 Examples
47 47 --------
48 48 ::
49 49 cmd = 'dir'
50 50 with AvoidUNCPath() as path:
51 51 if path is not None:
52 52 cmd = '"pushd %s &&"%s' % (path, cmd)
53 53 os.system(cmd)
54 54 """
55 55 def __enter__(self):
56 self.path = py3compat.getcwd()
56 self.path = os.getcwd()
57 57 self.is_unc_path = self.path.startswith(r"\\")
58 58 if self.is_unc_path:
59 59 # change to c drive (as cmd.exe cannot handle UNC addresses)
60 60 os.chdir("C:")
61 61 return self.path
62 62 else:
63 63 # We return None to signal that there was no change in the working
64 64 # directory
65 65 return None
66 66
67 67 def __exit__(self, exc_type, exc_value, traceback):
68 68 if self.is_unc_path:
69 69 os.chdir(self.path)
70 70
71 71
72 72 def _find_cmd(cmd):
73 73 """Find the full path to a .bat or .exe using the win32api module."""
74 74 try:
75 75 from win32api import SearchPath
76 76 except ImportError:
77 77 raise ImportError('you need to have pywin32 installed for this to work')
78 78 else:
79 79 PATH = os.environ['PATH']
80 80 extensions = ['.exe', '.com', '.bat', '.py']
81 81 path = None
82 82 for ext in extensions:
83 83 try:
84 84 path = SearchPath(PATH, cmd, ext)[0]
85 85 except:
86 86 pass
87 87 if path is None:
88 88 raise OSError("command %r not found" % cmd)
89 89 else:
90 90 return path
91 91
92 92
93 93 def _system_body(p):
94 94 """Callback for _system."""
95 95 enc = DEFAULT_ENCODING
96 96 for line in read_no_interrupt(p.stdout).splitlines():
97 97 line = line.decode(enc, 'replace')
98 98 print(line, file=sys.stdout)
99 99 for line in read_no_interrupt(p.stderr).splitlines():
100 100 line = line.decode(enc, 'replace')
101 101 print(line, file=sys.stderr)
102 102
103 103 # Wait to finish for returncode
104 104 return p.wait()
105 105
106 106
107 107 def system(cmd):
108 108 """Win32 version of os.system() that works with network shares.
109 109
110 110 Note that this implementation returns None, as meant for use in IPython.
111 111
112 112 Parameters
113 113 ----------
114 114 cmd : str or list
115 115 A command to be executed in the system shell.
116 116
117 117 Returns
118 118 -------
119 119 None : we explicitly do NOT return the subprocess status code, as this
120 120 utility is meant to be used extensively in IPython, where any return value
121 121 would trigger :func:`sys.displayhook` calls.
122 122 """
123 123 # The controller provides interactivity with both
124 124 # stdin and stdout
125 125 #import _process_win32_controller
126 126 #_process_win32_controller.system(cmd)
127 127
128 128 with AvoidUNCPath() as path:
129 129 if path is not None:
130 130 cmd = '"pushd %s &&"%s' % (path, cmd)
131 131 return process_handler(cmd, _system_body)
132 132
133 133 def getoutput(cmd):
134 134 """Return standard output of executing cmd in a shell.
135 135
136 136 Accepts the same arguments as os.system().
137 137
138 138 Parameters
139 139 ----------
140 140 cmd : str or list
141 141 A command to be executed in the system shell.
142 142
143 143 Returns
144 144 -------
145 145 stdout : str
146 146 """
147 147
148 148 with AvoidUNCPath() as path:
149 149 if path is not None:
150 150 cmd = '"pushd %s &&"%s' % (path, cmd)
151 151 out = process_handler(cmd, lambda p: p.communicate()[0], STDOUT)
152 152
153 153 if out is None:
154 154 out = b''
155 155 return py3compat.bytes_to_str(out)
156 156
157 157 try:
158 158 CommandLineToArgvW = ctypes.windll.shell32.CommandLineToArgvW
159 159 CommandLineToArgvW.arg_types = [LPCWSTR, POINTER(c_int)]
160 160 CommandLineToArgvW.restype = POINTER(LPCWSTR)
161 161 LocalFree = ctypes.windll.kernel32.LocalFree
162 162 LocalFree.res_type = HLOCAL
163 163 LocalFree.arg_types = [HLOCAL]
164 164
165 165 def arg_split(commandline, posix=False, strict=True):
166 166 """Split a command line's arguments in a shell-like manner.
167 167
168 168 This is a special version for windows that use a ctypes call to CommandLineToArgvW
169 169 to do the argv splitting. The posix paramter is ignored.
170 170
171 171 If strict=False, process_common.arg_split(...strict=False) is used instead.
172 172 """
173 173 #CommandLineToArgvW returns path to executable if called with empty string.
174 174 if commandline.strip() == "":
175 175 return []
176 176 if not strict:
177 177 # not really a cl-arg, fallback on _process_common
178 178 return py_arg_split(commandline, posix=posix, strict=strict)
179 179 argvn = c_int()
180 180 result_pointer = CommandLineToArgvW(py3compat.cast_unicode(commandline.lstrip()), ctypes.byref(argvn))
181 181 result_array_type = LPCWSTR * argvn.value
182 182 result = [arg for arg in result_array_type.from_address(ctypes.addressof(result_pointer.contents))]
183 183 retval = LocalFree(result_pointer)
184 184 return result
185 185 except AttributeError:
186 186 arg_split = py_arg_split
187 187
188 188 def check_pid(pid):
189 189 # OpenProcess returns 0 if no such process (of ours) exists
190 190 # positive int otherwise
191 191 return bool(ctypes.windll.kernel32.OpenProcess(1,0,pid))
@@ -1,576 +1,576 b''
1 1 """Windows-specific implementation of process utilities with direct WinAPI.
2 2
3 3 This file is meant to be used by process.py
4 4 """
5 5
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (C) 2010-2011 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13
14 14 # stdlib
15 15 import os, sys, threading
16 16 import ctypes, msvcrt
17 17
18 18 # local imports
19 19 from . import py3compat
20 20
21 21 # Win32 API types needed for the API calls
22 22 from ctypes import POINTER
23 23 from ctypes.wintypes import HANDLE, HLOCAL, LPVOID, WORD, DWORD, BOOL, \
24 24 ULONG, LPCWSTR
25 25 LPDWORD = POINTER(DWORD)
26 26 LPHANDLE = POINTER(HANDLE)
27 27 ULONG_PTR = POINTER(ULONG)
28 28 class SECURITY_ATTRIBUTES(ctypes.Structure):
29 29 _fields_ = [("nLength", DWORD),
30 30 ("lpSecurityDescriptor", LPVOID),
31 31 ("bInheritHandle", BOOL)]
32 32 LPSECURITY_ATTRIBUTES = POINTER(SECURITY_ATTRIBUTES)
33 33 class STARTUPINFO(ctypes.Structure):
34 34 _fields_ = [("cb", DWORD),
35 35 ("lpReserved", LPCWSTR),
36 36 ("lpDesktop", LPCWSTR),
37 37 ("lpTitle", LPCWSTR),
38 38 ("dwX", DWORD),
39 39 ("dwY", DWORD),
40 40 ("dwXSize", DWORD),
41 41 ("dwYSize", DWORD),
42 42 ("dwXCountChars", DWORD),
43 43 ("dwYCountChars", DWORD),
44 44 ("dwFillAttribute", DWORD),
45 45 ("dwFlags", DWORD),
46 46 ("wShowWindow", WORD),
47 47 ("cbReserved2", WORD),
48 48 ("lpReserved2", LPVOID),
49 49 ("hStdInput", HANDLE),
50 50 ("hStdOutput", HANDLE),
51 51 ("hStdError", HANDLE)]
52 52 LPSTARTUPINFO = POINTER(STARTUPINFO)
53 53 class PROCESS_INFORMATION(ctypes.Structure):
54 54 _fields_ = [("hProcess", HANDLE),
55 55 ("hThread", HANDLE),
56 56 ("dwProcessId", DWORD),
57 57 ("dwThreadId", DWORD)]
58 58 LPPROCESS_INFORMATION = POINTER(PROCESS_INFORMATION)
59 59
60 60 # Win32 API constants needed
61 61 ERROR_HANDLE_EOF = 38
62 62 ERROR_BROKEN_PIPE = 109
63 63 ERROR_NO_DATA = 232
64 64 HANDLE_FLAG_INHERIT = 0x0001
65 65 STARTF_USESTDHANDLES = 0x0100
66 66 CREATE_SUSPENDED = 0x0004
67 67 CREATE_NEW_CONSOLE = 0x0010
68 68 CREATE_NO_WINDOW = 0x08000000
69 69 STILL_ACTIVE = 259
70 70 WAIT_TIMEOUT = 0x0102
71 71 WAIT_FAILED = 0xFFFFFFFF
72 72 INFINITE = 0xFFFFFFFF
73 73 DUPLICATE_SAME_ACCESS = 0x00000002
74 74 ENABLE_ECHO_INPUT = 0x0004
75 75 ENABLE_LINE_INPUT = 0x0002
76 76 ENABLE_PROCESSED_INPUT = 0x0001
77 77
78 78 # Win32 API functions needed
79 79 GetLastError = ctypes.windll.kernel32.GetLastError
80 80 GetLastError.argtypes = []
81 81 GetLastError.restype = DWORD
82 82
83 83 CreateFile = ctypes.windll.kernel32.CreateFileW
84 84 CreateFile.argtypes = [LPCWSTR, DWORD, DWORD, LPVOID, DWORD, DWORD, HANDLE]
85 85 CreateFile.restype = HANDLE
86 86
87 87 CreatePipe = ctypes.windll.kernel32.CreatePipe
88 88 CreatePipe.argtypes = [POINTER(HANDLE), POINTER(HANDLE),
89 89 LPSECURITY_ATTRIBUTES, DWORD]
90 90 CreatePipe.restype = BOOL
91 91
92 92 CreateProcess = ctypes.windll.kernel32.CreateProcessW
93 93 CreateProcess.argtypes = [LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES,
94 94 LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFO,
95 95 LPPROCESS_INFORMATION]
96 96 CreateProcess.restype = BOOL
97 97
98 98 GetExitCodeProcess = ctypes.windll.kernel32.GetExitCodeProcess
99 99 GetExitCodeProcess.argtypes = [HANDLE, LPDWORD]
100 100 GetExitCodeProcess.restype = BOOL
101 101
102 102 GetCurrentProcess = ctypes.windll.kernel32.GetCurrentProcess
103 103 GetCurrentProcess.argtypes = []
104 104 GetCurrentProcess.restype = HANDLE
105 105
106 106 ResumeThread = ctypes.windll.kernel32.ResumeThread
107 107 ResumeThread.argtypes = [HANDLE]
108 108 ResumeThread.restype = DWORD
109 109
110 110 ReadFile = ctypes.windll.kernel32.ReadFile
111 111 ReadFile.argtypes = [HANDLE, LPVOID, DWORD, LPDWORD, LPVOID]
112 112 ReadFile.restype = BOOL
113 113
114 114 WriteFile = ctypes.windll.kernel32.WriteFile
115 115 WriteFile.argtypes = [HANDLE, LPVOID, DWORD, LPDWORD, LPVOID]
116 116 WriteFile.restype = BOOL
117 117
118 118 GetConsoleMode = ctypes.windll.kernel32.GetConsoleMode
119 119 GetConsoleMode.argtypes = [HANDLE, LPDWORD]
120 120 GetConsoleMode.restype = BOOL
121 121
122 122 SetConsoleMode = ctypes.windll.kernel32.SetConsoleMode
123 123 SetConsoleMode.argtypes = [HANDLE, DWORD]
124 124 SetConsoleMode.restype = BOOL
125 125
126 126 FlushConsoleInputBuffer = ctypes.windll.kernel32.FlushConsoleInputBuffer
127 127 FlushConsoleInputBuffer.argtypes = [HANDLE]
128 128 FlushConsoleInputBuffer.restype = BOOL
129 129
130 130 WaitForSingleObject = ctypes.windll.kernel32.WaitForSingleObject
131 131 WaitForSingleObject.argtypes = [HANDLE, DWORD]
132 132 WaitForSingleObject.restype = DWORD
133 133
134 134 DuplicateHandle = ctypes.windll.kernel32.DuplicateHandle
135 135 DuplicateHandle.argtypes = [HANDLE, HANDLE, HANDLE, LPHANDLE,
136 136 DWORD, BOOL, DWORD]
137 137 DuplicateHandle.restype = BOOL
138 138
139 139 SetHandleInformation = ctypes.windll.kernel32.SetHandleInformation
140 140 SetHandleInformation.argtypes = [HANDLE, DWORD, DWORD]
141 141 SetHandleInformation.restype = BOOL
142 142
143 143 CloseHandle = ctypes.windll.kernel32.CloseHandle
144 144 CloseHandle.argtypes = [HANDLE]
145 145 CloseHandle.restype = BOOL
146 146
147 147 CommandLineToArgvW = ctypes.windll.shell32.CommandLineToArgvW
148 148 CommandLineToArgvW.argtypes = [LPCWSTR, POINTER(ctypes.c_int)]
149 149 CommandLineToArgvW.restype = POINTER(LPCWSTR)
150 150
151 151 LocalFree = ctypes.windll.kernel32.LocalFree
152 152 LocalFree.argtypes = [HLOCAL]
153 153 LocalFree.restype = HLOCAL
154 154
155 155 class AvoidUNCPath(object):
156 156 """A context manager to protect command execution from UNC paths.
157 157
158 158 In the Win32 API, commands can't be invoked with the cwd being a UNC path.
159 159 This context manager temporarily changes directory to the 'C:' drive on
160 160 entering, and restores the original working directory on exit.
161 161
162 162 The context manager returns the starting working directory *if* it made a
163 163 change and None otherwise, so that users can apply the necessary adjustment
164 164 to their system calls in the event of a change.
165 165
166 166 Examples
167 167 --------
168 168 ::
169 169 cmd = 'dir'
170 170 with AvoidUNCPath() as path:
171 171 if path is not None:
172 172 cmd = '"pushd %s &&"%s' % (path, cmd)
173 173 os.system(cmd)
174 174 """
175 175 def __enter__(self):
176 self.path = py3compat.getcwd()
176 self.path = os.getcwd()
177 177 self.is_unc_path = self.path.startswith(r"\\")
178 178 if self.is_unc_path:
179 179 # change to c drive (as cmd.exe cannot handle UNC addresses)
180 180 os.chdir("C:")
181 181 return self.path
182 182 else:
183 183 # We return None to signal that there was no change in the working
184 184 # directory
185 185 return None
186 186
187 187 def __exit__(self, exc_type, exc_value, traceback):
188 188 if self.is_unc_path:
189 189 os.chdir(self.path)
190 190
191 191
192 192 class Win32ShellCommandController(object):
193 193 """Runs a shell command in a 'with' context.
194 194
195 195 This implementation is Win32-specific.
196 196
197 197 Example:
198 198 # Runs the command interactively with default console stdin/stdout
199 199 with ShellCommandController('python -i') as scc:
200 200 scc.run()
201 201
202 202 # Runs the command using the provided functions for stdin/stdout
203 203 def my_stdout_func(s):
204 204 # print or save the string 's'
205 205 write_to_stdout(s)
206 206 def my_stdin_func():
207 207 # If input is available, return it as a string.
208 208 if input_available():
209 209 return get_input()
210 210 # If no input available, return None after a short delay to
211 211 # keep from blocking.
212 212 else:
213 213 time.sleep(0.01)
214 214 return None
215 215
216 216 with ShellCommandController('python -i') as scc:
217 217 scc.run(my_stdout_func, my_stdin_func)
218 218 """
219 219
220 220 def __init__(self, cmd, mergeout = True):
221 221 """Initializes the shell command controller.
222 222
223 223 The cmd is the program to execute, and mergeout is
224 224 whether to blend stdout and stderr into one output
225 225 in stdout. Merging them together in this fashion more
226 226 reliably keeps stdout and stderr in the correct order
227 227 especially for interactive shell usage.
228 228 """
229 229 self.cmd = cmd
230 230 self.mergeout = mergeout
231 231
232 232 def __enter__(self):
233 233 cmd = self.cmd
234 234 mergeout = self.mergeout
235 235
236 236 self.hstdout, self.hstdin, self.hstderr = None, None, None
237 237 self.piProcInfo = None
238 238 try:
239 239 p_hstdout, c_hstdout, p_hstderr, \
240 240 c_hstderr, p_hstdin, c_hstdin = [None]*6
241 241
242 242 # SECURITY_ATTRIBUTES with inherit handle set to True
243 243 saAttr = SECURITY_ATTRIBUTES()
244 244 saAttr.nLength = ctypes.sizeof(saAttr)
245 245 saAttr.bInheritHandle = True
246 246 saAttr.lpSecurityDescriptor = None
247 247
248 248 def create_pipe(uninherit):
249 249 """Creates a Windows pipe, which consists of two handles.
250 250
251 251 The 'uninherit' parameter controls which handle is not
252 252 inherited by the child process.
253 253 """
254 254 handles = HANDLE(), HANDLE()
255 255 if not CreatePipe(ctypes.byref(handles[0]),
256 256 ctypes.byref(handles[1]), ctypes.byref(saAttr), 0):
257 257 raise ctypes.WinError()
258 258 if not SetHandleInformation(handles[uninherit],
259 259 HANDLE_FLAG_INHERIT, 0):
260 260 raise ctypes.WinError()
261 261 return handles[0].value, handles[1].value
262 262
263 263 p_hstdout, c_hstdout = create_pipe(uninherit=0)
264 264 # 'mergeout' signals that stdout and stderr should be merged.
265 265 # We do that by using one pipe for both of them.
266 266 if mergeout:
267 267 c_hstderr = HANDLE()
268 268 if not DuplicateHandle(GetCurrentProcess(), c_hstdout,
269 269 GetCurrentProcess(), ctypes.byref(c_hstderr),
270 270 0, True, DUPLICATE_SAME_ACCESS):
271 271 raise ctypes.WinError()
272 272 else:
273 273 p_hstderr, c_hstderr = create_pipe(uninherit=0)
274 274 c_hstdin, p_hstdin = create_pipe(uninherit=1)
275 275
276 276 # Create the process object
277 277 piProcInfo = PROCESS_INFORMATION()
278 278 siStartInfo = STARTUPINFO()
279 279 siStartInfo.cb = ctypes.sizeof(siStartInfo)
280 280 siStartInfo.hStdInput = c_hstdin
281 281 siStartInfo.hStdOutput = c_hstdout
282 282 siStartInfo.hStdError = c_hstderr
283 283 siStartInfo.dwFlags = STARTF_USESTDHANDLES
284 284 dwCreationFlags = CREATE_SUSPENDED | CREATE_NO_WINDOW # | CREATE_NEW_CONSOLE
285 285
286 286 if not CreateProcess(None,
287 287 u"cmd.exe /c " + cmd,
288 288 None, None, True, dwCreationFlags,
289 289 None, None, ctypes.byref(siStartInfo),
290 290 ctypes.byref(piProcInfo)):
291 291 raise ctypes.WinError()
292 292
293 293 # Close this process's versions of the child handles
294 294 CloseHandle(c_hstdin)
295 295 c_hstdin = None
296 296 CloseHandle(c_hstdout)
297 297 c_hstdout = None
298 298 if c_hstderr is not None:
299 299 CloseHandle(c_hstderr)
300 300 c_hstderr = None
301 301
302 302 # Transfer ownership of the parent handles to the object
303 303 self.hstdin = p_hstdin
304 304 p_hstdin = None
305 305 self.hstdout = p_hstdout
306 306 p_hstdout = None
307 307 if not mergeout:
308 308 self.hstderr = p_hstderr
309 309 p_hstderr = None
310 310 self.piProcInfo = piProcInfo
311 311
312 312 finally:
313 313 if p_hstdin:
314 314 CloseHandle(p_hstdin)
315 315 if c_hstdin:
316 316 CloseHandle(c_hstdin)
317 317 if p_hstdout:
318 318 CloseHandle(p_hstdout)
319 319 if c_hstdout:
320 320 CloseHandle(c_hstdout)
321 321 if p_hstderr:
322 322 CloseHandle(p_hstderr)
323 323 if c_hstderr:
324 324 CloseHandle(c_hstderr)
325 325
326 326 return self
327 327
328 328 def _stdin_thread(self, handle, hprocess, func, stdout_func):
329 329 exitCode = DWORD()
330 330 bytesWritten = DWORD(0)
331 331 while True:
332 332 #print("stdin thread loop start")
333 333 # Get the input string (may be bytes or unicode)
334 334 data = func()
335 335
336 336 # None signals to poll whether the process has exited
337 337 if data is None:
338 338 #print("checking for process completion")
339 339 if not GetExitCodeProcess(hprocess, ctypes.byref(exitCode)):
340 340 raise ctypes.WinError()
341 341 if exitCode.value != STILL_ACTIVE:
342 342 return
343 343 # TESTING: Does zero-sized writefile help?
344 344 if not WriteFile(handle, "", 0,
345 345 ctypes.byref(bytesWritten), None):
346 346 raise ctypes.WinError()
347 347 continue
348 348 #print("\nGot str %s\n" % repr(data), file=sys.stderr)
349 349
350 350 # Encode the string to the console encoding
351 351 if isinstance(data, unicode): #FIXME: Python3
352 352 data = data.encode('utf_8')
353 353
354 354 # What we have now must be a string of bytes
355 355 if not isinstance(data, str): #FIXME: Python3
356 356 raise RuntimeError("internal stdin function string error")
357 357
358 358 # An empty string signals EOF
359 359 if len(data) == 0:
360 360 return
361 361
362 362 # In a windows console, sometimes the input is echoed,
363 363 # but sometimes not. How do we determine when to do this?
364 364 stdout_func(data)
365 365 # WriteFile may not accept all the data at once.
366 366 # Loop until everything is processed
367 367 while len(data) != 0:
368 368 #print("Calling writefile")
369 369 if not WriteFile(handle, data, len(data),
370 370 ctypes.byref(bytesWritten), None):
371 371 # This occurs at exit
372 372 if GetLastError() == ERROR_NO_DATA:
373 373 return
374 374 raise ctypes.WinError()
375 375 #print("Called writefile")
376 376 data = data[bytesWritten.value:]
377 377
378 378 def _stdout_thread(self, handle, func):
379 379 # Allocate the output buffer
380 380 data = ctypes.create_string_buffer(4096)
381 381 while True:
382 382 bytesRead = DWORD(0)
383 383 if not ReadFile(handle, data, 4096,
384 384 ctypes.byref(bytesRead), None):
385 385 le = GetLastError()
386 386 if le == ERROR_BROKEN_PIPE:
387 387 return
388 388 else:
389 389 raise ctypes.WinError()
390 390 # FIXME: Python3
391 391 s = data.value[0:bytesRead.value]
392 392 #print("\nv: %s" % repr(s), file=sys.stderr)
393 393 func(s.decode('utf_8', 'replace'))
394 394
395 395 def run(self, stdout_func = None, stdin_func = None, stderr_func = None):
396 396 """Runs the process, using the provided functions for I/O.
397 397
398 398 The function stdin_func should return strings whenever a
399 399 character or characters become available.
400 400 The functions stdout_func and stderr_func are called whenever
401 401 something is printed to stdout or stderr, respectively.
402 402 These functions are called from different threads (but not
403 403 concurrently, because of the GIL).
404 404 """
405 405 if stdout_func is None and stdin_func is None and stderr_func is None:
406 406 return self._run_stdio()
407 407
408 408 if stderr_func is not None and self.mergeout:
409 409 raise RuntimeError("Shell command was initiated with "
410 410 "merged stdin/stdout, but a separate stderr_func "
411 411 "was provided to the run() method")
412 412
413 413 # Create a thread for each input/output handle
414 414 stdin_thread = None
415 415 threads = []
416 416 if stdin_func:
417 417 stdin_thread = threading.Thread(target=self._stdin_thread,
418 418 args=(self.hstdin, self.piProcInfo.hProcess,
419 419 stdin_func, stdout_func))
420 420 threads.append(threading.Thread(target=self._stdout_thread,
421 421 args=(self.hstdout, stdout_func)))
422 422 if not self.mergeout:
423 423 if stderr_func is None:
424 424 stderr_func = stdout_func
425 425 threads.append(threading.Thread(target=self._stdout_thread,
426 426 args=(self.hstderr, stderr_func)))
427 427 # Start the I/O threads and the process
428 428 if ResumeThread(self.piProcInfo.hThread) == 0xFFFFFFFF:
429 429 raise ctypes.WinError()
430 430 if stdin_thread is not None:
431 431 stdin_thread.start()
432 432 for thread in threads:
433 433 thread.start()
434 434 # Wait for the process to complete
435 435 if WaitForSingleObject(self.piProcInfo.hProcess, INFINITE) == \
436 436 WAIT_FAILED:
437 437 raise ctypes.WinError()
438 438 # Wait for the I/O threads to complete
439 439 for thread in threads:
440 440 thread.join()
441 441
442 442 # Wait for the stdin thread to complete
443 443 if stdin_thread is not None:
444 444 stdin_thread.join()
445 445
446 446 def _stdin_raw_nonblock(self):
447 447 """Use the raw Win32 handle of sys.stdin to do non-blocking reads"""
448 448 # WARNING: This is experimental, and produces inconsistent results.
449 449 # It's possible for the handle not to be appropriate for use
450 450 # with WaitForSingleObject, among other things.
451 451 handle = msvcrt.get_osfhandle(sys.stdin.fileno())
452 452 result = WaitForSingleObject(handle, 100)
453 453 if result == WAIT_FAILED:
454 454 raise ctypes.WinError()
455 455 elif result == WAIT_TIMEOUT:
456 456 print(".", end='')
457 457 return None
458 458 else:
459 459 data = ctypes.create_string_buffer(256)
460 460 bytesRead = DWORD(0)
461 461 print('?', end='')
462 462
463 463 if not ReadFile(handle, data, 256,
464 464 ctypes.byref(bytesRead), None):
465 465 raise ctypes.WinError()
466 466 # This ensures the non-blocking works with an actual console
467 467 # Not checking the error, so the processing will still work with
468 468 # other handle types
469 469 FlushConsoleInputBuffer(handle)
470 470
471 471 data = data.value
472 472 data = data.replace('\r\n', '\n')
473 473 data = data.replace('\r', '\n')
474 474 print(repr(data) + " ", end='')
475 475 return data
476 476
477 477 def _stdin_raw_block(self):
478 478 """Use a blocking stdin read"""
479 479 # The big problem with the blocking read is that it doesn't
480 480 # exit when it's supposed to in all contexts. An extra
481 481 # key-press may be required to trigger the exit.
482 482 try:
483 483 data = sys.stdin.read(1)
484 484 data = data.replace('\r', '\n')
485 485 return data
486 486 except WindowsError as we:
487 487 if we.winerror == ERROR_NO_DATA:
488 488 # This error occurs when the pipe is closed
489 489 return None
490 490 else:
491 491 # Otherwise let the error propagate
492 492 raise we
493 493
494 494 def _stdout_raw(self, s):
495 495 """Writes the string to stdout"""
496 496 print(s, end='', file=sys.stdout)
497 497 sys.stdout.flush()
498 498
499 499 def _stderr_raw(self, s):
500 500 """Writes the string to stdout"""
501 501 print(s, end='', file=sys.stderr)
502 502 sys.stderr.flush()
503 503
504 504 def _run_stdio(self):
505 505 """Runs the process using the system standard I/O.
506 506
507 507 IMPORTANT: stdin needs to be asynchronous, so the Python
508 508 sys.stdin object is not used. Instead,
509 509 msvcrt.kbhit/getwch are used asynchronously.
510 510 """
511 511 # Disable Line and Echo mode
512 512 #lpMode = DWORD()
513 513 #handle = msvcrt.get_osfhandle(sys.stdin.fileno())
514 514 #if GetConsoleMode(handle, ctypes.byref(lpMode)):
515 515 # set_console_mode = True
516 516 # if not SetConsoleMode(handle, lpMode.value &
517 517 # ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT)):
518 518 # raise ctypes.WinError()
519 519
520 520 if self.mergeout:
521 521 return self.run(stdout_func = self._stdout_raw,
522 522 stdin_func = self._stdin_raw_block)
523 523 else:
524 524 return self.run(stdout_func = self._stdout_raw,
525 525 stdin_func = self._stdin_raw_block,
526 526 stderr_func = self._stderr_raw)
527 527
528 528 # Restore the previous console mode
529 529 #if set_console_mode:
530 530 # if not SetConsoleMode(handle, lpMode.value):
531 531 # raise ctypes.WinError()
532 532
533 533 def __exit__(self, exc_type, exc_value, traceback):
534 534 if self.hstdin:
535 535 CloseHandle(self.hstdin)
536 536 self.hstdin = None
537 537 if self.hstdout:
538 538 CloseHandle(self.hstdout)
539 539 self.hstdout = None
540 540 if self.hstderr:
541 541 CloseHandle(self.hstderr)
542 542 self.hstderr = None
543 543 if self.piProcInfo is not None:
544 544 CloseHandle(self.piProcInfo.hProcess)
545 545 CloseHandle(self.piProcInfo.hThread)
546 546 self.piProcInfo = None
547 547
548 548
549 549 def system(cmd):
550 550 """Win32 version of os.system() that works with network shares.
551 551
552 552 Note that this implementation returns None, as meant for use in IPython.
553 553
554 554 Parameters
555 555 ----------
556 556 cmd : str
557 557 A command to be executed in the system shell.
558 558
559 559 Returns
560 560 -------
561 561 None : we explicitly do NOT return the subprocess status code, as this
562 562 utility is meant to be used extensively in IPython, where any return value
563 563 would trigger :func:`sys.displayhook` calls.
564 564 """
565 565 with AvoidUNCPath() as path:
566 566 if path is not None:
567 567 cmd = '"pushd %s &&"%s' % (path, cmd)
568 568 with Win32ShellCommandController(cmd) as scc:
569 569 scc.run()
570 570
571 571
572 572 if __name__ == "__main__":
573 573 print("Test starting!")
574 574 #system("cmd")
575 575 system("python -i")
576 576 print("Test finished!")
@@ -1,37 +1,36 b''
1 1 # encoding: utf-8
2 2 """Utilities for working with data structures like lists, dicts and tuples.
3 3 """
4 4
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (C) 2008-2011 The IPython Development Team
7 7 #
8 8 # Distributed under the terms of the BSD License. The full license is in
9 9 # the file COPYING, distributed as part of this software.
10 10 #-----------------------------------------------------------------------------
11 11
12 from .py3compat import xrange
13 12
14 13 def uniq_stable(elems):
15 14 """uniq_stable(elems) -> list
16 15
17 16 Return from an iterable, a list of all the unique elements in the input,
18 17 but maintaining the order in which they first appear.
19 18
20 19 Note: All elements in the input must be hashable for this routine
21 20 to work, as it internally uses a set for efficiency reasons.
22 21 """
23 22 seen = set()
24 23 return [x for x in elems if x not in seen and not seen.add(x)]
25 24
26 25
27 26 def flatten(seq):
28 27 """Flatten a list of lists (NOT recursive, only works for 2d lists)."""
29 28
30 29 return [x for subseq in seq for x in subseq]
31 30
32 31
33 32 def chop(seq, size):
34 33 """Chop a sequence into chunks of the given size."""
35 return [seq[i:i+size] for i in xrange(0,len(seq),size)]
34 return [seq[i:i+size] for i in range(0,len(seq),size)]
36 35
37 36
@@ -1,81 +1,80 b''
1 1 # encoding: utf-8
2 2 """A fancy version of Python's builtin :func:`dir` function.
3 3 """
4 4
5 5 # Copyright (c) IPython Development Team.
6 6 # Distributed under the terms of the Modified BSD License.
7 7
8 8 import inspect
9 from .py3compat import string_types
10 9
11 10
12 11 def safe_hasattr(obj, attr):
13 12 """In recent versions of Python, hasattr() only catches AttributeError.
14 13 This catches all errors.
15 14 """
16 15 try:
17 16 getattr(obj, attr)
18 17 return True
19 18 except:
20 19 return False
21 20
22 21
23 22 def dir2(obj):
24 23 """dir2(obj) -> list of strings
25 24
26 25 Extended version of the Python builtin dir(), which does a few extra
27 26 checks.
28 27
29 28 This version is guaranteed to return only a list of true strings, whereas
30 29 dir() returns anything that objects inject into themselves, even if they
31 30 are later not really valid for attribute access (many extension libraries
32 31 have such bugs).
33 32 """
34 33
35 34 # Start building the attribute list via dir(), and then complete it
36 35 # with a few extra special-purpose calls.
37 36
38 37 try:
39 38 words = set(dir(obj))
40 39 except Exception:
41 40 # TypeError: dir(obj) does not return a list
42 41 words = set()
43 42
44 43 # filter out non-string attributes which may be stuffed by dir() calls
45 44 # and poor coding in third-party modules
46 45
47 words = [w for w in words if isinstance(w, string_types)]
46 words = [w for w in words if isinstance(w, str)]
48 47 return sorted(words)
49 48
50 49
51 50 def get_real_method(obj, name):
52 51 """Like getattr, but with a few extra sanity checks:
53 52
54 53 - If obj is a class, ignore its methods
55 54 - Check if obj is a proxy that claims to have all attributes
56 55 - Catch attribute access failing with any exception
57 56 - Check that the attribute is a callable object
58 57
59 58 Returns the method or None.
60 59 """
61 60 if inspect.isclass(obj):
62 61 return None
63 62
64 63 try:
65 64 canary = getattr(obj, '_ipython_canary_method_should_not_exist_', None)
66 65 except Exception:
67 66 return None
68 67
69 68 if canary is not None:
70 69 # It claimed to have an attribute it should never have
71 70 return None
72 71
73 72 try:
74 73 m = getattr(obj, name, None)
75 74 except Exception:
76 75 return None
77 76
78 77 if callable(m):
79 78 return m
80 79
81 80 return None
@@ -1,240 +1,240 b''
1 1 # encoding: utf-8
2 2 """
3 3 IO related utilities.
4 4 """
5 5
6 6 # Copyright (c) IPython Development Team.
7 7 # Distributed under the terms of the Modified BSD License.
8 8
9 9
10 10
11 11 import atexit
12 12 import os
13 13 import sys
14 14 import tempfile
15 15 import warnings
16 16 from warnings import warn
17 17
18 18 from IPython.utils.decorators import undoc
19 19 from .capture import CapturedIO, capture_output
20 from .py3compat import string_types, input, PY3
20 from .py3compat import input, PY3
21 21
22 22 @undoc
23 23 class IOStream:
24 24
25 25 def __init__(self, stream, fallback=None):
26 26 warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
27 27 DeprecationWarning, stacklevel=2)
28 28 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
29 29 if fallback is not None:
30 30 stream = fallback
31 31 else:
32 32 raise ValueError("fallback required, but not specified")
33 33 self.stream = stream
34 34 self._swrite = stream.write
35 35
36 36 # clone all methods not overridden:
37 37 def clone(meth):
38 38 return not hasattr(self, meth) and not meth.startswith('_')
39 39 for meth in filter(clone, dir(stream)):
40 40 setattr(self, meth, getattr(stream, meth))
41 41
42 42 def __repr__(self):
43 43 cls = self.__class__
44 44 tpl = '{mod}.{cls}({args})'
45 45 return tpl.format(mod=cls.__module__, cls=cls.__name__, args=self.stream)
46 46
47 47 def write(self,data):
48 48 warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
49 49 DeprecationWarning, stacklevel=2)
50 50 try:
51 51 self._swrite(data)
52 52 except:
53 53 try:
54 54 # print handles some unicode issues which may trip a plain
55 55 # write() call. Emulate write() by using an empty end
56 56 # argument.
57 57 print(data, end='', file=self.stream)
58 58 except:
59 59 # if we get here, something is seriously broken.
60 60 print('ERROR - failed to write data to stream:', self.stream,
61 61 file=sys.stderr)
62 62
63 63 def writelines(self, lines):
64 64 warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
65 65 DeprecationWarning, stacklevel=2)
66 if isinstance(lines, string_types):
66 if isinstance(lines, str):
67 67 lines = [lines]
68 68 for line in lines:
69 69 self.write(line)
70 70
71 71 # This class used to have a writeln method, but regular files and streams
72 72 # in Python don't have this method. We need to keep this completely
73 73 # compatible so we removed it.
74 74
75 75 @property
76 76 def closed(self):
77 77 return self.stream.closed
78 78
79 79 def close(self):
80 80 pass
81 81
82 82 # setup stdin/stdout/stderr to sys.stdin/sys.stdout/sys.stderr
83 83 devnull = open(os.devnull, 'w')
84 84 atexit.register(devnull.close)
85 85
86 86 # io.std* are deprecated, but don't show our own deprecation warnings
87 87 # during initialization of the deprecated API.
88 88 with warnings.catch_warnings():
89 89 warnings.simplefilter('ignore', DeprecationWarning)
90 90 stdin = IOStream(sys.stdin, fallback=devnull)
91 91 stdout = IOStream(sys.stdout, fallback=devnull)
92 92 stderr = IOStream(sys.stderr, fallback=devnull)
93 93
94 94 class Tee(object):
95 95 """A class to duplicate an output stream to stdout/err.
96 96
97 97 This works in a manner very similar to the Unix 'tee' command.
98 98
99 99 When the object is closed or deleted, it closes the original file given to
100 100 it for duplication.
101 101 """
102 102 # Inspired by:
103 103 # http://mail.python.org/pipermail/python-list/2007-May/442737.html
104 104
105 105 def __init__(self, file_or_name, mode="w", channel='stdout'):
106 106 """Construct a new Tee object.
107 107
108 108 Parameters
109 109 ----------
110 110 file_or_name : filename or open filehandle (writable)
111 111 File that will be duplicated
112 112
113 113 mode : optional, valid mode for open().
114 114 If a filename was give, open with this mode.
115 115
116 116 channel : str, one of ['stdout', 'stderr']
117 117 """
118 118 if channel not in ['stdout', 'stderr']:
119 119 raise ValueError('Invalid channel spec %s' % channel)
120 120
121 121 if hasattr(file_or_name, 'write') and hasattr(file_or_name, 'seek'):
122 122 self.file = file_or_name
123 123 else:
124 124 self.file = open(file_or_name, mode)
125 125 self.channel = channel
126 126 self.ostream = getattr(sys, channel)
127 127 setattr(sys, channel, self)
128 128 self._closed = False
129 129
130 130 def close(self):
131 131 """Close the file and restore the channel."""
132 132 self.flush()
133 133 setattr(sys, self.channel, self.ostream)
134 134 self.file.close()
135 135 self._closed = True
136 136
137 137 def write(self, data):
138 138 """Write data to both channels."""
139 139 self.file.write(data)
140 140 self.ostream.write(data)
141 141 self.ostream.flush()
142 142
143 143 def flush(self):
144 144 """Flush both channels."""
145 145 self.file.flush()
146 146 self.ostream.flush()
147 147
148 148 def __del__(self):
149 149 if not self._closed:
150 150 self.close()
151 151
152 152
153 153 def ask_yes_no(prompt, default=None, interrupt=None):
154 154 """Asks a question and returns a boolean (y/n) answer.
155 155
156 156 If default is given (one of 'y','n'), it is used if the user input is
157 157 empty. If interrupt is given (one of 'y','n'), it is used if the user
158 158 presses Ctrl-C. Otherwise the question is repeated until an answer is
159 159 given.
160 160
161 161 An EOF is treated as the default answer. If there is no default, an
162 162 exception is raised to prevent infinite loops.
163 163
164 164 Valid answers are: y/yes/n/no (match is not case sensitive)."""
165 165
166 166 answers = {'y':True,'n':False,'yes':True,'no':False}
167 167 ans = None
168 168 while ans not in answers.keys():
169 169 try:
170 170 ans = input(prompt+' ').lower()
171 171 if not ans: # response was an empty string
172 172 ans = default
173 173 except KeyboardInterrupt:
174 174 if interrupt:
175 175 ans = interrupt
176 176 print("\r")
177 177 except EOFError:
178 178 if default in answers.keys():
179 179 ans = default
180 180 print()
181 181 else:
182 182 raise
183 183
184 184 return answers[ans]
185 185
186 186
187 187 def temp_pyfile(src, ext='.py'):
188 188 """Make a temporary python file, return filename and filehandle.
189 189
190 190 Parameters
191 191 ----------
192 192 src : string or list of strings (no need for ending newlines if list)
193 193 Source code to be written to the file.
194 194
195 195 ext : optional, string
196 196 Extension for the generated file.
197 197
198 198 Returns
199 199 -------
200 200 (filename, open filehandle)
201 201 It is the caller's responsibility to close the open file and unlink it.
202 202 """
203 203 fname = tempfile.mkstemp(ext)[1]
204 204 f = open(fname,'w')
205 205 f.write(src)
206 206 f.flush()
207 207 return fname, f
208 208
209 209 def atomic_writing(*args, **kwargs):
210 210 """DEPRECATED: moved to notebook.services.contents.fileio"""
211 211 warn("IPython.utils.io.atomic_writing has moved to notebook.services.contents.fileio", stacklevel=2)
212 212 from notebook.services.contents.fileio import atomic_writing
213 213 return atomic_writing(*args, **kwargs)
214 214
215 215 def raw_print(*args, **kw):
216 216 """Raw print to sys.__stdout__, otherwise identical interface to print()."""
217 217
218 218 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
219 219 file=sys.__stdout__)
220 220 sys.__stdout__.flush()
221 221
222 222
223 223 def raw_print_err(*args, **kw):
224 224 """Raw print to sys.__stderr__, otherwise identical interface to print()."""
225 225
226 226 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
227 227 file=sys.__stderr__)
228 228 sys.__stderr__.flush()
229 229
230 230
231 231 # Short aliases for quick debugging, do NOT use these in production code.
232 232 rprint = raw_print
233 233 rprinte = raw_print_err
234 234
235 235
236 236 def unicode_std_stream(stream='stdout'):
237 237 """DEPRECATED, moved to nbconvert.utils.io"""
238 238 warn("IPython.utils.io.unicode_std_stream has moved to nbconvert.utils.io", stacklevel=2)
239 239 from nbconvert.utils.io import unicode_std_stream
240 240 return unicode_std_stream(stream)
@@ -1,248 +1,247 b''
1 1 """
2 2 Tools to open .py files as Unicode, using the encoding specified within the file,
3 3 as per PEP 263.
4 4
5 5 Much of the code is taken from the tokenize module in Python 3.2.
6 6 """
7 7
8 8 import io
9 9 from io import TextIOWrapper, BytesIO
10 10 import os.path
11 11 import re
12 12
13 from .py3compat import unicode_type
14 13
15 14 cookie_re = re.compile(r"coding[:=]\s*([-\w.]+)", re.UNICODE)
16 15 cookie_comment_re = re.compile(r"^\s*#.*coding[:=]\s*([-\w.]+)", re.UNICODE)
17 16
18 17 try:
19 18 # Available in Python 3
20 19 from tokenize import detect_encoding
21 20 except ImportError:
22 21 from codecs import lookup, BOM_UTF8
23 22
24 23 # Copied from Python 3.2 tokenize
25 24 def _get_normal_name(orig_enc):
26 25 """Imitates get_normal_name in tokenizer.c."""
27 26 # Only care about the first 12 characters.
28 27 enc = orig_enc[:12].lower().replace("_", "-")
29 28 if enc == "utf-8" or enc.startswith("utf-8-"):
30 29 return "utf-8"
31 30 if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \
32 31 enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")):
33 32 return "iso-8859-1"
34 33 return orig_enc
35 34
36 35 # Copied from Python 3.2 tokenize
37 36 def detect_encoding(readline):
38 37 """
39 38 The detect_encoding() function is used to detect the encoding that should
40 39 be used to decode a Python source file. It requires one argment, readline,
41 40 in the same way as the tokenize() generator.
42 41
43 42 It will call readline a maximum of twice, and return the encoding used
44 43 (as a string) and a list of any lines (left as bytes) it has read in.
45 44
46 45 It detects the encoding from the presence of a utf-8 bom or an encoding
47 46 cookie as specified in pep-0263. If both a bom and a cookie are present,
48 47 but disagree, a SyntaxError will be raised. If the encoding cookie is an
49 48 invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found,
50 49 'utf-8-sig' is returned.
51 50
52 51 If no encoding is specified, then the default of 'utf-8' will be returned.
53 52 """
54 53 bom_found = False
55 54 encoding = None
56 55 default = 'utf-8'
57 56 def read_or_stop():
58 57 try:
59 58 return readline()
60 59 except StopIteration:
61 60 return b''
62 61
63 62 def find_cookie(line):
64 63 try:
65 64 line_string = line.decode('ascii')
66 65 except UnicodeDecodeError:
67 66 return None
68 67
69 68 matches = cookie_re.findall(line_string)
70 69 if not matches:
71 70 return None
72 71 encoding = _get_normal_name(matches[0])
73 72 try:
74 73 codec = lookup(encoding)
75 74 except LookupError:
76 75 # This behaviour mimics the Python interpreter
77 76 raise SyntaxError("unknown encoding: " + encoding)
78 77
79 78 if bom_found:
80 79 if codec.name != 'utf-8':
81 80 # This behaviour mimics the Python interpreter
82 81 raise SyntaxError('encoding problem: utf-8')
83 82 encoding += '-sig'
84 83 return encoding
85 84
86 85 first = read_or_stop()
87 86 if first.startswith(BOM_UTF8):
88 87 bom_found = True
89 88 first = first[3:]
90 89 default = 'utf-8-sig'
91 90 if not first:
92 91 return default, []
93 92
94 93 encoding = find_cookie(first)
95 94 if encoding:
96 95 return encoding, [first]
97 96
98 97 second = read_or_stop()
99 98 if not second:
100 99 return default, [first]
101 100
102 101 encoding = find_cookie(second)
103 102 if encoding:
104 103 return encoding, [first, second]
105 104
106 105 return default, [first, second]
107 106
108 107 try:
109 108 # Available in Python 3.2 and above.
110 109 from tokenize import open
111 110 except ImportError:
112 111 # Copied from Python 3.2 tokenize
113 112 def open(filename):
114 113 """Open a file in read only mode using the encoding detected by
115 114 detect_encoding().
116 115 """
117 116 buffer = io.open(filename, 'rb') # Tweaked to use io.open for Python 2
118 117 encoding, lines = detect_encoding(buffer.readline)
119 118 buffer.seek(0)
120 119 text = TextIOWrapper(buffer, encoding, line_buffering=True)
121 120 text.mode = 'r'
122 121 return text
123 122
124 123 def source_to_unicode(txt, errors='replace', skip_encoding_cookie=True):
125 124 """Converts a bytes string with python source code to unicode.
126 125
127 126 Unicode strings are passed through unchanged. Byte strings are checked
128 127 for the python source file encoding cookie to determine encoding.
129 128 txt can be either a bytes buffer or a string containing the source
130 129 code.
131 130 """
132 if isinstance(txt, unicode_type):
131 if isinstance(txt, str):
133 132 return txt
134 133 if isinstance(txt, bytes):
135 134 buffer = BytesIO(txt)
136 135 else:
137 136 buffer = txt
138 137 try:
139 138 encoding, _ = detect_encoding(buffer.readline)
140 139 except SyntaxError:
141 140 encoding = "ascii"
142 141 buffer.seek(0)
143 142 text = TextIOWrapper(buffer, encoding, errors=errors, line_buffering=True)
144 143 text.mode = 'r'
145 144 if skip_encoding_cookie:
146 145 return u"".join(strip_encoding_cookie(text))
147 146 else:
148 147 return text.read()
149 148
150 149 def strip_encoding_cookie(filelike):
151 150 """Generator to pull lines from a text-mode file, skipping the encoding
152 151 cookie if it is found in the first two lines.
153 152 """
154 153 it = iter(filelike)
155 154 try:
156 155 first = next(it)
157 156 if not cookie_comment_re.match(first):
158 157 yield first
159 158 second = next(it)
160 159 if not cookie_comment_re.match(second):
161 160 yield second
162 161 except StopIteration:
163 162 return
164 163
165 164 for line in it:
166 165 yield line
167 166
168 167 def read_py_file(filename, skip_encoding_cookie=True):
169 168 """Read a Python file, using the encoding declared inside the file.
170 169
171 170 Parameters
172 171 ----------
173 172 filename : str
174 173 The path to the file to read.
175 174 skip_encoding_cookie : bool
176 175 If True (the default), and the encoding declaration is found in the first
177 176 two lines, that line will be excluded from the output - compiling a
178 177 unicode string with an encoding declaration is a SyntaxError in Python 2.
179 178
180 179 Returns
181 180 -------
182 181 A unicode string containing the contents of the file.
183 182 """
184 183 with open(filename) as f: # the open function defined in this module.
185 184 if skip_encoding_cookie:
186 185 return "".join(strip_encoding_cookie(f))
187 186 else:
188 187 return f.read()
189 188
190 189 def read_py_url(url, errors='replace', skip_encoding_cookie=True):
191 190 """Read a Python file from a URL, using the encoding declared inside the file.
192 191
193 192 Parameters
194 193 ----------
195 194 url : str
196 195 The URL from which to fetch the file.
197 196 errors : str
198 197 How to handle decoding errors in the file. Options are the same as for
199 198 bytes.decode(), but here 'replace' is the default.
200 199 skip_encoding_cookie : bool
201 200 If True (the default), and the encoding declaration is found in the first
202 201 two lines, that line will be excluded from the output - compiling a
203 202 unicode string with an encoding declaration is a SyntaxError in Python 2.
204 203
205 204 Returns
206 205 -------
207 206 A unicode string containing the contents of the file.
208 207 """
209 208 # Deferred import for faster start
210 209 try:
211 210 from urllib.request import urlopen # Py 3
212 211 except ImportError:
213 212 from urllib import urlopen
214 213 response = urlopen(url)
215 214 buffer = io.BytesIO(response.read())
216 215 return source_to_unicode(buffer, errors, skip_encoding_cookie)
217 216
218 217 def _list_readline(x):
219 218 """Given a list, returns a readline() function that returns the next element
220 219 with each call.
221 220 """
222 221 x = iter(x)
223 222 def readline():
224 223 return next(x)
225 224 return readline
226 225
227 226 # Code for going between .py files and cached .pyc files ----------------------
228 227
229 228 try: # Python 3.2, see PEP 3147
230 229 try:
231 230 from importlib.util import source_from_cache, cache_from_source
232 231 except ImportError :
233 232 ## deprecated since 3.4
234 233 from imp import source_from_cache, cache_from_source
235 234 except ImportError:
236 235 # Python <= 3.1: .pyc files go next to .py
237 236 def source_from_cache(path):
238 237 basename, ext = os.path.splitext(path)
239 238 if ext not in ('.pyc', '.pyo'):
240 239 raise ValueError('Not a cached Python file extension', ext)
241 240 # Should we look for .pyw files?
242 241 return basename + '.py'
243 242
244 243 def cache_from_source(path, debug_override=None):
245 244 if debug_override is None:
246 245 debug_override = __debug__
247 246 basename, ext = os.path.splitext(path)
248 247 return basename + '.pyc' if debug_override else '.pyo'
@@ -1,447 +1,446 b''
1 1 # encoding: utf-8
2 2 """
3 3 Utilities for path handling.
4 4 """
5 5
6 6 # Copyright (c) IPython Development Team.
7 7 # Distributed under the terms of the Modified BSD License.
8 8
9 9 import os
10 10 import sys
11 11 import errno
12 12 import shutil
13 13 import random
14 14 import glob
15 15 from warnings import warn
16 16 from hashlib import md5
17 17
18 18 from IPython.utils.process import system
19 19 from IPython.utils import py3compat
20 20 from IPython.utils.decorators import undoc
21 21
22 22 #-----------------------------------------------------------------------------
23 23 # Code
24 24 #-----------------------------------------------------------------------------
25 25
26 26 fs_encoding = sys.getfilesystemencoding()
27 27
28 28 def _writable_dir(path):
29 29 """Whether `path` is a directory, to which the user has write access."""
30 30 return os.path.isdir(path) and os.access(path, os.W_OK)
31 31
32 32 if sys.platform == 'win32':
33 33 def _get_long_path_name(path):
34 34 """Get a long path name (expand ~) on Windows using ctypes.
35 35
36 36 Examples
37 37 --------
38 38
39 39 >>> get_long_path_name('c:\\docume~1')
40 40 u'c:\\\\Documents and Settings'
41 41
42 42 """
43 43 try:
44 44 import ctypes
45 45 except ImportError:
46 46 raise ImportError('you need to have ctypes installed for this to work')
47 47 _GetLongPathName = ctypes.windll.kernel32.GetLongPathNameW
48 48 _GetLongPathName.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p,
49 49 ctypes.c_uint ]
50 50
51 51 buf = ctypes.create_unicode_buffer(260)
52 52 rv = _GetLongPathName(path, buf, 260)
53 53 if rv == 0 or rv > 260:
54 54 return path
55 55 else:
56 56 return buf.value
57 57 else:
58 58 def _get_long_path_name(path):
59 59 """Dummy no-op."""
60 60 return path
61 61
62 62
63 63
64 64 def get_long_path_name(path):
65 65 """Expand a path into its long form.
66 66
67 67 On Windows this expands any ~ in the paths. On other platforms, it is
68 68 a null operation.
69 69 """
70 70 return _get_long_path_name(path)
71 71
72 72
73 73 def unquote_filename(name, win32=(sys.platform=='win32')):
74 74 """ On Windows, remove leading and trailing quotes from filenames.
75 75
76 76 This function has been deprecated and should not be used any more:
77 77 unquoting is now taken care of by :func:`IPython.utils.process.arg_split`.
78 78 """
79 79 warn("'unquote_filename' is deprecated since IPython 5.0 and should not "
80 80 "be used anymore", DeprecationWarning, stacklevel=2)
81 81 if win32:
82 82 if name.startswith(("'", '"')) and name.endswith(("'", '"')):
83 83 name = name[1:-1]
84 84 return name
85 85
86 86
87 87 def compress_user(path):
88 88 """Reverse of :func:`os.path.expanduser`
89 89 """
90 path = py3compat.unicode_to_str(path, sys.getfilesystemencoding())
91 90 home = os.path.expanduser('~')
92 91 if path.startswith(home):
93 92 path = "~" + path[len(home):]
94 93 return path
95 94
96 95 def get_py_filename(name, force_win32=None):
97 96 """Return a valid python filename in the current directory.
98 97
99 98 If the given name is not a file, it adds '.py' and searches again.
100 99 Raises IOError with an informative message if the file isn't found.
101 100 """
102 101
103 102 name = os.path.expanduser(name)
104 103 if force_win32 is not None:
105 104 warn("The 'force_win32' argument to 'get_py_filename' is deprecated "
106 105 "since IPython 5.0 and should not be used anymore",
107 106 DeprecationWarning, stacklevel=2)
108 107 if not os.path.isfile(name) and not name.endswith('.py'):
109 108 name += '.py'
110 109 if os.path.isfile(name):
111 110 return name
112 111 else:
113 112 raise IOError('File `%r` not found.' % name)
114 113
115 114
116 115 def filefind(filename, path_dirs=None):
117 116 """Find a file by looking through a sequence of paths.
118 117
119 118 This iterates through a sequence of paths looking for a file and returns
120 119 the full, absolute path of the first occurence of the file. If no set of
121 120 path dirs is given, the filename is tested as is, after running through
122 121 :func:`expandvars` and :func:`expanduser`. Thus a simple call::
123 122
124 123 filefind('myfile.txt')
125 124
126 125 will find the file in the current working dir, but::
127 126
128 127 filefind('~/myfile.txt')
129 128
130 129 Will find the file in the users home directory. This function does not
131 130 automatically try any paths, such as the cwd or the user's home directory.
132 131
133 132 Parameters
134 133 ----------
135 134 filename : str
136 135 The filename to look for.
137 136 path_dirs : str, None or sequence of str
138 137 The sequence of paths to look for the file in. If None, the filename
139 138 need to be absolute or be in the cwd. If a string, the string is
140 139 put into a sequence and the searched. If a sequence, walk through
141 140 each element and join with ``filename``, calling :func:`expandvars`
142 141 and :func:`expanduser` before testing for existence.
143 142
144 143 Returns
145 144 -------
146 145 Raises :exc:`IOError` or returns absolute path to file.
147 146 """
148 147
149 148 # If paths are quoted, abspath gets confused, strip them...
150 149 filename = filename.strip('"').strip("'")
151 150 # If the input is an absolute path, just check it exists
152 151 if os.path.isabs(filename) and os.path.isfile(filename):
153 152 return filename
154 153
155 154 if path_dirs is None:
156 155 path_dirs = ("",)
157 elif isinstance(path_dirs, py3compat.string_types):
156 elif isinstance(path_dirs, str):
158 157 path_dirs = (path_dirs,)
159 158
160 159 for path in path_dirs:
161 if path == '.': path = py3compat.getcwd()
160 if path == '.': path = os.getcwd()
162 161 testname = expand_path(os.path.join(path, filename))
163 162 if os.path.isfile(testname):
164 163 return os.path.abspath(testname)
165 164
166 165 raise IOError("File %r does not exist in any of the search paths: %r" %
167 166 (filename, path_dirs) )
168 167
169 168
170 169 class HomeDirError(Exception):
171 170 pass
172 171
173 172
174 173 def get_home_dir(require_writable=False):
175 174 """Return the 'home' directory, as a unicode string.
176 175
177 176 Uses os.path.expanduser('~'), and checks for writability.
178 177
179 178 See stdlib docs for how this is determined.
180 179 $HOME is first priority on *ALL* platforms.
181 180
182 181 Parameters
183 182 ----------
184 183
185 184 require_writable : bool [default: False]
186 185 if True:
187 186 guarantees the return value is a writable directory, otherwise
188 187 raises HomeDirError
189 188 if False:
190 189 The path is resolved, but it is not guaranteed to exist or be writable.
191 190 """
192 191
193 192 homedir = os.path.expanduser('~')
194 193 # Next line will make things work even when /home/ is a symlink to
195 194 # /usr/home as it is on FreeBSD, for example
196 195 homedir = os.path.realpath(homedir)
197 196
198 197 if not _writable_dir(homedir) and os.name == 'nt':
199 198 # expanduser failed, use the registry to get the 'My Documents' folder.
200 199 try:
201 200 try:
202 201 import winreg as wreg # Py 3
203 202 except ImportError:
204 203 import _winreg as wreg # Py 2
205 204 key = wreg.OpenKey(
206 205 wreg.HKEY_CURRENT_USER,
207 206 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
208 207 )
209 208 homedir = wreg.QueryValueEx(key,'Personal')[0]
210 209 key.Close()
211 210 except:
212 211 pass
213 212
214 213 if (not require_writable) or _writable_dir(homedir):
215 214 return py3compat.cast_unicode(homedir, fs_encoding)
216 215 else:
217 216 raise HomeDirError('%s is not a writable dir, '
218 217 'set $HOME environment variable to override' % homedir)
219 218
220 219 def get_xdg_dir():
221 220 """Return the XDG_CONFIG_HOME, if it is defined and exists, else None.
222 221
223 222 This is only for non-OS X posix (Linux,Unix,etc.) systems.
224 223 """
225 224
226 225 env = os.environ
227 226
228 227 if os.name == 'posix' and sys.platform != 'darwin':
229 228 # Linux, Unix, AIX, etc.
230 229 # use ~/.config if empty OR not set
231 230 xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config')
232 231 if xdg and _writable_dir(xdg):
233 232 return py3compat.cast_unicode(xdg, fs_encoding)
234 233
235 234 return None
236 235
237 236
238 237 def get_xdg_cache_dir():
239 238 """Return the XDG_CACHE_HOME, if it is defined and exists, else None.
240 239
241 240 This is only for non-OS X posix (Linux,Unix,etc.) systems.
242 241 """
243 242
244 243 env = os.environ
245 244
246 245 if os.name == 'posix' and sys.platform != 'darwin':
247 246 # Linux, Unix, AIX, etc.
248 247 # use ~/.cache if empty OR not set
249 248 xdg = env.get("XDG_CACHE_HOME", None) or os.path.join(get_home_dir(), '.cache')
250 249 if xdg and _writable_dir(xdg):
251 250 return py3compat.cast_unicode(xdg, fs_encoding)
252 251
253 252 return None
254 253
255 254
256 255 @undoc
257 256 def get_ipython_dir():
258 257 warn("get_ipython_dir has moved to the IPython.paths module since IPython 4.0.", stacklevel=2)
259 258 from IPython.paths import get_ipython_dir
260 259 return get_ipython_dir()
261 260
262 261 @undoc
263 262 def get_ipython_cache_dir():
264 263 warn("get_ipython_cache_dir has moved to the IPython.paths module since IPython 4.0.", stacklevel=2)
265 264 from IPython.paths import get_ipython_cache_dir
266 265 return get_ipython_cache_dir()
267 266
268 267 @undoc
269 268 def get_ipython_package_dir():
270 269 warn("get_ipython_package_dir has moved to the IPython.paths module since IPython 4.0.", stacklevel=2)
271 270 from IPython.paths import get_ipython_package_dir
272 271 return get_ipython_package_dir()
273 272
274 273 @undoc
275 274 def get_ipython_module_path(module_str):
276 275 warn("get_ipython_module_path has moved to the IPython.paths module since IPython 4.0.", stacklevel=2)
277 276 from IPython.paths import get_ipython_module_path
278 277 return get_ipython_module_path(module_str)
279 278
280 279 @undoc
281 280 def locate_profile(profile='default'):
282 281 warn("locate_profile has moved to the IPython.paths module since IPython 4.0.", stacklevel=2)
283 282 from IPython.paths import locate_profile
284 283 return locate_profile(profile=profile)
285 284
286 285 def expand_path(s):
287 286 """Expand $VARS and ~names in a string, like a shell
288 287
289 288 :Examples:
290 289
291 290 In [2]: os.environ['FOO']='test'
292 291
293 292 In [3]: expand_path('variable FOO is $FOO')
294 293 Out[3]: 'variable FOO is test'
295 294 """
296 295 # This is a pretty subtle hack. When expand user is given a UNC path
297 296 # on Windows (\\server\share$\%username%), os.path.expandvars, removes
298 297 # the $ to get (\\server\share\%username%). I think it considered $
299 298 # alone an empty var. But, we need the $ to remains there (it indicates
300 299 # a hidden share).
301 300 if os.name=='nt':
302 301 s = s.replace('$\\', 'IPYTHON_TEMP')
303 302 s = os.path.expandvars(os.path.expanduser(s))
304 303 if os.name=='nt':
305 304 s = s.replace('IPYTHON_TEMP', '$\\')
306 305 return s
307 306
308 307
309 308 def unescape_glob(string):
310 309 """Unescape glob pattern in `string`."""
311 310 def unescape(s):
312 311 for pattern in '*[]!?':
313 312 s = s.replace(r'\{0}'.format(pattern), pattern)
314 313 return s
315 314 return '\\'.join(map(unescape, string.split('\\\\')))
316 315
317 316
318 317 def shellglob(args):
319 318 """
320 319 Do glob expansion for each element in `args` and return a flattened list.
321 320
322 321 Unmatched glob pattern will remain as-is in the returned list.
323 322
324 323 """
325 324 expanded = []
326 325 # Do not unescape backslash in Windows as it is interpreted as
327 326 # path separator:
328 327 unescape = unescape_glob if sys.platform != 'win32' else lambda x: x
329 328 for a in args:
330 329 expanded.extend(glob.glob(a) or [unescape(a)])
331 330 return expanded
332 331
333 332
334 333 def target_outdated(target,deps):
335 334 """Determine whether a target is out of date.
336 335
337 336 target_outdated(target,deps) -> 1/0
338 337
339 338 deps: list of filenames which MUST exist.
340 339 target: single filename which may or may not exist.
341 340
342 341 If target doesn't exist or is older than any file listed in deps, return
343 342 true, otherwise return false.
344 343 """
345 344 try:
346 345 target_time = os.path.getmtime(target)
347 346 except os.error:
348 347 return 1
349 348 for dep in deps:
350 349 dep_time = os.path.getmtime(dep)
351 350 if dep_time > target_time:
352 351 #print "For target",target,"Dep failed:",dep # dbg
353 352 #print "times (dep,tar):",dep_time,target_time # dbg
354 353 return 1
355 354 return 0
356 355
357 356
358 357 def target_update(target,deps,cmd):
359 358 """Update a target with a given command given a list of dependencies.
360 359
361 360 target_update(target,deps,cmd) -> runs cmd if target is outdated.
362 361
363 362 This is just a wrapper around target_outdated() which calls the given
364 363 command if target is outdated."""
365 364
366 365 if target_outdated(target,deps):
367 366 system(cmd)
368 367
369 368 @undoc
370 369 def filehash(path):
371 370 """Make an MD5 hash of a file, ignoring any differences in line
372 371 ending characters."""
373 372 warn("filehash() is deprecated since IPython 4.0", DeprecationWarning, stacklevel=2)
374 373 with open(path, "rU") as f:
375 374 return md5(py3compat.str_to_bytes(f.read())).hexdigest()
376 375
377 376 ENOLINK = 1998
378 377
379 378 def link(src, dst):
380 379 """Hard links ``src`` to ``dst``, returning 0 or errno.
381 380
382 381 Note that the special errno ``ENOLINK`` will be returned if ``os.link`` isn't
383 382 supported by the operating system.
384 383 """
385 384
386 385 if not hasattr(os, "link"):
387 386 return ENOLINK
388 387 link_errno = 0
389 388 try:
390 389 os.link(src, dst)
391 390 except OSError as e:
392 391 link_errno = e.errno
393 392 return link_errno
394 393
395 394
396 395 def link_or_copy(src, dst):
397 396 """Attempts to hardlink ``src`` to ``dst``, copying if the link fails.
398 397
399 398 Attempts to maintain the semantics of ``shutil.copy``.
400 399
401 400 Because ``os.link`` does not overwrite files, a unique temporary file
402 401 will be used if the target already exists, then that file will be moved
403 402 into place.
404 403 """
405 404
406 405 if os.path.isdir(dst):
407 406 dst = os.path.join(dst, os.path.basename(src))
408 407
409 408 link_errno = link(src, dst)
410 409 if link_errno == errno.EEXIST:
411 410 if os.stat(src).st_ino == os.stat(dst).st_ino:
412 411 # dst is already a hard link to the correct file, so we don't need
413 412 # to do anything else. If we try to link and rename the file
414 413 # anyway, we get duplicate files - see http://bugs.python.org/issue21876
415 414 return
416 415
417 416 new_dst = dst + "-temp-%04X" %(random.randint(1, 16**4), )
418 417 try:
419 418 link_or_copy(src, new_dst)
420 419 except:
421 420 try:
422 421 os.remove(new_dst)
423 422 except OSError:
424 423 pass
425 424 raise
426 425 os.rename(new_dst, dst)
427 426 elif link_errno != 0:
428 427 # Either link isn't supported, or the filesystem doesn't support
429 428 # linking, or 'src' and 'dst' are on different filesystems.
430 429 shutil.copy(src, dst)
431 430
432 431 def ensure_dir_exists(path, mode=0o755):
433 432 """ensure that a directory exists
434 433
435 434 If it doesn't exist, try to create it and protect against a race condition
436 435 if another process is doing the same.
437 436
438 437 The default permissions are 755, which differ from os.makedirs default of 777.
439 438 """
440 439 if not os.path.exists(path):
441 440 try:
442 441 os.makedirs(path, mode=mode)
443 442 except OSError as e:
444 443 if e.errno != errno.EEXIST:
445 444 raise
446 445 elif not os.path.isdir(path):
447 446 raise IOError("%r exists but is not a directory" % path)
@@ -1,69 +1,69 b''
1 1 # encoding: utf-8
2 2 """
3 3 Utilities for working with external processes.
4 4 """
5 5
6 6 # Copyright (c) IPython Development Team.
7 7 # Distributed under the terms of the Modified BSD License.
8 8
9 9
10 10 import os
11 11 import sys
12 12
13 13 if sys.platform == 'win32':
14 14 from ._process_win32 import system, getoutput, arg_split, check_pid
15 15 elif sys.platform == 'cli':
16 16 from ._process_cli import system, getoutput, arg_split, check_pid
17 17 else:
18 18 from ._process_posix import system, getoutput, arg_split, check_pid
19 19
20 20 from ._process_common import getoutputerror, get_output_error_code, process_handler
21 21 from . import py3compat
22 22
23 23
24 24 class FindCmdError(Exception):
25 25 pass
26 26
27 27
28 28 def find_cmd(cmd):
29 29 """Find absolute path to executable cmd in a cross platform manner.
30 30
31 31 This function tries to determine the full path to a command line program
32 32 using `which` on Unix/Linux/OS X and `win32api` on Windows. Most of the
33 33 time it will use the version that is first on the users `PATH`.
34 34
35 35 Warning, don't use this to find IPython command line programs as there
36 36 is a risk you will find the wrong one. Instead find those using the
37 37 following code and looking for the application itself::
38 38
39 39 import sys
40 40 argv = [sys.executable, '-m', 'IPython']
41 41
42 42 Parameters
43 43 ----------
44 44 cmd : str
45 45 The command line program to look for.
46 46 """
47 47 path = py3compat.which(cmd)
48 48 if path is None:
49 49 raise FindCmdError('command could not be found: %s' % cmd)
50 50 return path
51 51
52 52
53 53 def abbrev_cwd():
54 54 """ Return abbreviated version of cwd, e.g. d:mydir """
55 cwd = py3compat.getcwd().replace('\\','/')
55 cwd = os.getcwd().replace('\\','/')
56 56 drivepart = ''
57 57 tail = cwd
58 58 if sys.platform == 'win32':
59 59 if len(cwd) < 4:
60 60 return cwd
61 61 drivepart,tail = os.path.splitdrive(cwd)
62 62
63 63
64 64 parts = tail.split('/')
65 65 if len(parts) > 2:
66 66 tail = '/'.join(parts[-2:])
67 67
68 68 return (drivepart + (
69 69 cwd == '/' and '/' or tail))
@@ -1,120 +1,120 b''
1 1 # encoding: utf-8
2 2 """
3 3 Utilities for working with terminals.
4 4
5 5 Authors:
6 6
7 7 * Brian E. Granger
8 8 * Fernando Perez
9 9 * Alexander Belchenko (e-mail: bialix AT ukr.net)
10 10 """
11 11
12 12 # Copyright (c) IPython Development Team.
13 13 # Distributed under the terms of the Modified BSD License.
14 14
15 15 import os
16 16 import sys
17 17 import warnings
18 18 try:
19 19 from shutil import get_terminal_size as _get_terminal_size
20 20 except ImportError:
21 21 # use backport on Python 2
22 22 from backports.shutil_get_terminal_size import get_terminal_size as _get_terminal_size
23 23
24 24 from . import py3compat
25 25
26 26 #-----------------------------------------------------------------------------
27 27 # Code
28 28 #-----------------------------------------------------------------------------
29 29
30 30 # This variable is part of the expected API of the module:
31 31 ignore_termtitle = True
32 32
33 33
34 34
35 35 if os.name == 'posix':
36 36 def _term_clear():
37 37 os.system('clear')
38 38 elif sys.platform == 'win32':
39 39 def _term_clear():
40 40 os.system('cls')
41 41 else:
42 42 def _term_clear():
43 43 pass
44 44
45 45
46 46
47 47 def toggle_set_term_title(val):
48 48 """Control whether set_term_title is active or not.
49 49
50 50 set_term_title() allows writing to the console titlebar. In embedded
51 51 widgets this can cause problems, so this call can be used to toggle it on
52 52 or off as needed.
53 53
54 54 The default state of the module is for the function to be disabled.
55 55
56 56 Parameters
57 57 ----------
58 58 val : bool
59 59 If True, set_term_title() actually writes to the terminal (using the
60 60 appropriate platform-specific module). If False, it is a no-op.
61 61 """
62 62 global ignore_termtitle
63 63 ignore_termtitle = not(val)
64 64
65 65
66 66 def _set_term_title(*args,**kw):
67 67 """Dummy no-op."""
68 68 pass
69 69
70 70
71 71 def _set_term_title_xterm(title):
72 72 """ Change virtual terminal title in xterm-workalikes """
73 73 sys.stdout.write('\033]0;%s\007' % title)
74 74
75 75 if os.name == 'posix':
76 76 TERM = os.environ.get('TERM','')
77 77 if TERM.startswith('xterm'):
78 78 _set_term_title = _set_term_title_xterm
79 79 elif sys.platform == 'win32':
80 80 try:
81 81 import ctypes
82 82
83 83 SetConsoleTitleW = ctypes.windll.kernel32.SetConsoleTitleW
84 84 SetConsoleTitleW.argtypes = [ctypes.c_wchar_p]
85 85
86 86 def _set_term_title(title):
87 87 """Set terminal title using ctypes to access the Win32 APIs."""
88 88 SetConsoleTitleW(title)
89 89 except ImportError:
90 90 def _set_term_title(title):
91 91 """Set terminal title using the 'title' command."""
92 92 global ignore_termtitle
93 93
94 94 try:
95 95 # Cannot be on network share when issuing system commands
96 curr = py3compat.getcwd()
96 curr = os.getcwd()
97 97 os.chdir("C:")
98 98 ret = os.system("title " + title)
99 99 finally:
100 100 os.chdir(curr)
101 101 if ret:
102 102 # non-zero return code signals error, don't try again
103 103 ignore_termtitle = True
104 104
105 105
106 106 def set_term_title(title):
107 107 """Set terminal title using the necessary platform-dependent calls."""
108 108 if ignore_termtitle:
109 109 return
110 110 _set_term_title(title)
111 111
112 112
113 113 def freeze_term_title():
114 114 warnings.warn("This function is deprecated, use toggle_set_term_title()")
115 115 global ignore_termtitle
116 116 ignore_termtitle = True
117 117
118 118
119 119 def get_terminal_size(defaultx=80, defaulty=25):
120 120 return _get_terminal_size((defaultx, defaulty))
@@ -1,496 +1,496 b''
1 1 # encoding: utf-8
2 2 """Tests for IPython.utils.path.py"""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7 import errno
8 8 import os
9 9 import shutil
10 10 import sys
11 11 import tempfile
12 12 import warnings
13 13 from contextlib import contextmanager
14 14
15 15 try: # Python 3.3+
16 16 from unittest.mock import patch
17 17 except ImportError:
18 18 from mock import patch
19 19
20 20 from os.path import join, abspath, split
21 21
22 22 from nose import SkipTest
23 23 import nose.tools as nt
24 24
25 25 from nose import with_setup
26 26
27 27 import IPython
28 28 from IPython import paths
29 29 from IPython.testing import decorators as dec
30 30 from IPython.testing.decorators import (skip_if_not_win32, skip_win32,
31 31 onlyif_unicode_paths,)
32 32 from IPython.testing.tools import make_tempfile, AssertPrints
33 33 from IPython.utils import path
34 34 from IPython.utils import py3compat
35 35 from IPython.utils.tempdir import TemporaryDirectory
36 36
37 37 # Platform-dependent imports
38 38 try:
39 39 import winreg as wreg # Py 3
40 40 except ImportError:
41 41 try:
42 42 import _winreg as wreg # Py 2
43 43 except ImportError:
44 44 #Fake _winreg module on none windows platforms
45 45 import types
46 46 wr_name = "winreg" if py3compat.PY3 else "_winreg"
47 47 sys.modules[wr_name] = types.ModuleType(wr_name)
48 48 try:
49 49 import winreg as wreg
50 50 except ImportError:
51 51 import _winreg as wreg
52 52 #Add entries that needs to be stubbed by the testing code
53 53 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
54 54
55 55 try:
56 56 reload
57 57 except NameError: # Python 3
58 58 from imp import reload
59 59
60 60 #-----------------------------------------------------------------------------
61 61 # Globals
62 62 #-----------------------------------------------------------------------------
63 63 env = os.environ
64 64 TMP_TEST_DIR = tempfile.mkdtemp()
65 65 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
66 66 #
67 67 # Setup/teardown functions/decorators
68 68 #
69 69
70 70 def setup():
71 71 """Setup testenvironment for the module:
72 72
73 73 - Adds dummy home dir tree
74 74 """
75 75 # Do not mask exceptions here. In particular, catching WindowsError is a
76 76 # problem because that exception is only defined on Windows...
77 77 os.makedirs(os.path.join(HOME_TEST_DIR, 'ipython'))
78 78
79 79
80 80 def teardown():
81 81 """Teardown testenvironment for the module:
82 82
83 83 - Remove dummy home dir tree
84 84 """
85 85 # Note: we remove the parent test dir, which is the root of all test
86 86 # subdirs we may have created. Use shutil instead of os.removedirs, so
87 87 # that non-empty directories are all recursively removed.
88 88 shutil.rmtree(TMP_TEST_DIR)
89 89
90 90
91 91 def setup_environment():
92 92 """Setup testenvironment for some functions that are tested
93 93 in this module. In particular this functions stores attributes
94 94 and other things that we need to stub in some test functions.
95 95 This needs to be done on a function level and not module level because
96 96 each testfunction needs a pristine environment.
97 97 """
98 98 global oldstuff, platformstuff
99 99 oldstuff = (env.copy(), os.name, sys.platform, path.get_home_dir, IPython.__file__, os.getcwd())
100 100
101 101 def teardown_environment():
102 102 """Restore things that were remembered by the setup_environment function
103 103 """
104 104 (oldenv, os.name, sys.platform, path.get_home_dir, IPython.__file__, old_wd) = oldstuff
105 105 os.chdir(old_wd)
106 106 reload(path)
107 107
108 108 for key in list(env):
109 109 if key not in oldenv:
110 110 del env[key]
111 111 env.update(oldenv)
112 112 if hasattr(sys, 'frozen'):
113 113 del sys.frozen
114 114
115 115 # Build decorator that uses the setup_environment/setup_environment
116 116 with_environment = with_setup(setup_environment, teardown_environment)
117 117
118 118 @skip_if_not_win32
119 119 @with_environment
120 120 def test_get_home_dir_1():
121 121 """Testcase for py2exe logic, un-compressed lib
122 122 """
123 123 unfrozen = path.get_home_dir()
124 124 sys.frozen = True
125 125
126 126 #fake filename for IPython.__init__
127 127 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py"))
128 128
129 129 home_dir = path.get_home_dir()
130 130 nt.assert_equal(home_dir, unfrozen)
131 131
132 132
133 133 @skip_if_not_win32
134 134 @with_environment
135 135 def test_get_home_dir_2():
136 136 """Testcase for py2exe logic, compressed lib
137 137 """
138 138 unfrozen = path.get_home_dir()
139 139 sys.frozen = True
140 140 #fake filename for IPython.__init__
141 141 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower()
142 142
143 143 home_dir = path.get_home_dir(True)
144 144 nt.assert_equal(home_dir, unfrozen)
145 145
146 146
147 147 @with_environment
148 148 def test_get_home_dir_3():
149 149 """get_home_dir() uses $HOME if set"""
150 150 env["HOME"] = HOME_TEST_DIR
151 151 home_dir = path.get_home_dir(True)
152 152 # get_home_dir expands symlinks
153 153 nt.assert_equal(home_dir, os.path.realpath(env["HOME"]))
154 154
155 155
156 156 @with_environment
157 157 def test_get_home_dir_4():
158 158 """get_home_dir() still works if $HOME is not set"""
159 159
160 160 if 'HOME' in env: del env['HOME']
161 161 # this should still succeed, but we don't care what the answer is
162 162 home = path.get_home_dir(False)
163 163
164 164 @with_environment
165 165 def test_get_home_dir_5():
166 166 """raise HomeDirError if $HOME is specified, but not a writable dir"""
167 167 env['HOME'] = abspath(HOME_TEST_DIR+'garbage')
168 168 # set os.name = posix, to prevent My Documents fallback on Windows
169 169 os.name = 'posix'
170 170 nt.assert_raises(path.HomeDirError, path.get_home_dir, True)
171 171
172 172 # Should we stub wreg fully so we can run the test on all platforms?
173 173 @skip_if_not_win32
174 174 @with_environment
175 175 def test_get_home_dir_8():
176 176 """Using registry hack for 'My Documents', os=='nt'
177 177
178 178 HOMESHARE, HOMEDRIVE, HOMEPATH, USERPROFILE and others are missing.
179 179 """
180 180 os.name = 'nt'
181 181 # Remove from stub environment all keys that may be set
182 182 for key in ['HOME', 'HOMESHARE', 'HOMEDRIVE', 'HOMEPATH', 'USERPROFILE']:
183 183 env.pop(key, None)
184 184
185 185 class key:
186 186 def Close(self):
187 187 pass
188 188
189 189 with patch.object(wreg, 'OpenKey', return_value=key()), \
190 190 patch.object(wreg, 'QueryValueEx', return_value=[abspath(HOME_TEST_DIR)]):
191 191 home_dir = path.get_home_dir()
192 192 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
193 193
194 194 @with_environment
195 195 def test_get_xdg_dir_0():
196 196 """test_get_xdg_dir_0, check xdg_dir"""
197 197 reload(path)
198 198 path._writable_dir = lambda path: True
199 199 path.get_home_dir = lambda : 'somewhere'
200 200 os.name = "posix"
201 201 sys.platform = "linux2"
202 202 env.pop('IPYTHON_DIR', None)
203 203 env.pop('IPYTHONDIR', None)
204 204 env.pop('XDG_CONFIG_HOME', None)
205 205
206 206 nt.assert_equal(path.get_xdg_dir(), os.path.join('somewhere', '.config'))
207 207
208 208
209 209 @with_environment
210 210 def test_get_xdg_dir_1():
211 211 """test_get_xdg_dir_1, check nonexistant xdg_dir"""
212 212 reload(path)
213 213 path.get_home_dir = lambda : HOME_TEST_DIR
214 214 os.name = "posix"
215 215 sys.platform = "linux2"
216 216 env.pop('IPYTHON_DIR', None)
217 217 env.pop('IPYTHONDIR', None)
218 218 env.pop('XDG_CONFIG_HOME', None)
219 219 nt.assert_equal(path.get_xdg_dir(), None)
220 220
221 221 @with_environment
222 222 def test_get_xdg_dir_2():
223 223 """test_get_xdg_dir_2, check xdg_dir default to ~/.config"""
224 224 reload(path)
225 225 path.get_home_dir = lambda : HOME_TEST_DIR
226 226 os.name = "posix"
227 227 sys.platform = "linux2"
228 228 env.pop('IPYTHON_DIR', None)
229 229 env.pop('IPYTHONDIR', None)
230 230 env.pop('XDG_CONFIG_HOME', None)
231 231 cfgdir=os.path.join(path.get_home_dir(), '.config')
232 232 if not os.path.exists(cfgdir):
233 233 os.makedirs(cfgdir)
234 234
235 235 nt.assert_equal(path.get_xdg_dir(), cfgdir)
236 236
237 237 @with_environment
238 238 def test_get_xdg_dir_3():
239 239 """test_get_xdg_dir_3, check xdg_dir not used on OS X"""
240 240 reload(path)
241 241 path.get_home_dir = lambda : HOME_TEST_DIR
242 242 os.name = "posix"
243 243 sys.platform = "darwin"
244 244 env.pop('IPYTHON_DIR', None)
245 245 env.pop('IPYTHONDIR', None)
246 246 env.pop('XDG_CONFIG_HOME', None)
247 247 cfgdir=os.path.join(path.get_home_dir(), '.config')
248 248 if not os.path.exists(cfgdir):
249 249 os.makedirs(cfgdir)
250 250
251 251 nt.assert_equal(path.get_xdg_dir(), None)
252 252
253 253 def test_filefind():
254 254 """Various tests for filefind"""
255 255 f = tempfile.NamedTemporaryFile()
256 256 # print 'fname:',f.name
257 257 alt_dirs = paths.get_ipython_dir()
258 258 t = path.filefind(f.name, alt_dirs)
259 259 # print 'found:',t
260 260
261 261
262 262 @dec.skip_if_not_win32
263 263 def test_get_long_path_name_win32():
264 264 with TemporaryDirectory() as tmpdir:
265 265
266 266 # Make a long path. Expands the path of tmpdir prematurely as it may already have a long
267 267 # path component, so ensure we include the long form of it
268 268 long_path = os.path.join(path.get_long_path_name(tmpdir), u'this is my long path name')
269 269 os.makedirs(long_path)
270 270
271 271 # Test to see if the short path evaluates correctly.
272 272 short_path = os.path.join(tmpdir, u'THISIS~1')
273 273 evaluated_path = path.get_long_path_name(short_path)
274 274 nt.assert_equal(evaluated_path.lower(), long_path.lower())
275 275
276 276
277 277 @dec.skip_win32
278 278 def test_get_long_path_name():
279 279 p = path.get_long_path_name('/usr/local')
280 280 nt.assert_equal(p,'/usr/local')
281 281
282 282 @dec.skip_win32 # can't create not-user-writable dir on win
283 283 @with_environment
284 284 def test_not_writable_ipdir():
285 285 tmpdir = tempfile.mkdtemp()
286 286 os.name = "posix"
287 287 env.pop('IPYTHON_DIR', None)
288 288 env.pop('IPYTHONDIR', None)
289 289 env.pop('XDG_CONFIG_HOME', None)
290 290 env['HOME'] = tmpdir
291 291 ipdir = os.path.join(tmpdir, '.ipython')
292 292 os.mkdir(ipdir, 0o555)
293 293 try:
294 294 open(os.path.join(ipdir, "_foo_"), 'w').close()
295 295 except IOError:
296 296 pass
297 297 else:
298 298 # I can still write to an unwritable dir,
299 299 # assume I'm root and skip the test
300 300 raise SkipTest("I can't create directories that I can't write to")
301 301 with AssertPrints('is not a writable location', channel='stderr'):
302 302 ipdir = paths.get_ipython_dir()
303 303 env.pop('IPYTHON_DIR', None)
304 304
305 305 @with_environment
306 306 def test_get_py_filename():
307 307 os.chdir(TMP_TEST_DIR)
308 308 with make_tempfile('foo.py'):
309 309 nt.assert_equal(path.get_py_filename('foo.py'), 'foo.py')
310 310 nt.assert_equal(path.get_py_filename('foo'), 'foo.py')
311 311 with make_tempfile('foo'):
312 312 nt.assert_equal(path.get_py_filename('foo'), 'foo')
313 313 nt.assert_raises(IOError, path.get_py_filename, 'foo.py')
314 314 nt.assert_raises(IOError, path.get_py_filename, 'foo')
315 315 nt.assert_raises(IOError, path.get_py_filename, 'foo.py')
316 316 true_fn = 'foo with spaces.py'
317 317 with make_tempfile(true_fn):
318 318 nt.assert_equal(path.get_py_filename('foo with spaces'), true_fn)
319 319 nt.assert_equal(path.get_py_filename('foo with spaces.py'), true_fn)
320 320 nt.assert_raises(IOError, path.get_py_filename, '"foo with spaces.py"')
321 321 nt.assert_raises(IOError, path.get_py_filename, "'foo with spaces.py'")
322 322
323 323 @onlyif_unicode_paths
324 324 def test_unicode_in_filename():
325 325 """When a file doesn't exist, the exception raised should be safe to call
326 326 str() on - i.e. in Python 2 it must only have ASCII characters.
327 327
328 328 https://github.com/ipython/ipython/issues/875
329 329 """
330 330 try:
331 331 # these calls should not throw unicode encode exceptions
332 332 path.get_py_filename(u'fooéè.py', force_win32=False)
333 333 except IOError as ex:
334 334 str(ex)
335 335
336 336
337 337 class TestShellGlob(object):
338 338
339 339 @classmethod
340 340 def setUpClass(cls):
341 341 cls.filenames_start_with_a = ['a0', 'a1', 'a2']
342 342 cls.filenames_end_with_b = ['0b', '1b', '2b']
343 343 cls.filenames = cls.filenames_start_with_a + cls.filenames_end_with_b
344 344 cls.tempdir = TemporaryDirectory()
345 345 td = cls.tempdir.name
346 346
347 347 with cls.in_tempdir():
348 348 # Create empty files
349 349 for fname in cls.filenames:
350 350 open(os.path.join(td, fname), 'w').close()
351 351
352 352 @classmethod
353 353 def tearDownClass(cls):
354 354 cls.tempdir.cleanup()
355 355
356 356 @classmethod
357 357 @contextmanager
358 358 def in_tempdir(cls):
359 save = py3compat.getcwd()
359 save = os.getcwd()
360 360 try:
361 361 os.chdir(cls.tempdir.name)
362 362 yield
363 363 finally:
364 364 os.chdir(save)
365 365
366 366 def check_match(self, patterns, matches):
367 367 with self.in_tempdir():
368 368 # glob returns unordered list. that's why sorted is required.
369 369 nt.assert_equal(sorted(path.shellglob(patterns)),
370 370 sorted(matches))
371 371
372 372 def common_cases(self):
373 373 return [
374 374 (['*'], self.filenames),
375 375 (['a*'], self.filenames_start_with_a),
376 376 (['*c'], ['*c']),
377 377 (['*', 'a*', '*b', '*c'], self.filenames
378 378 + self.filenames_start_with_a
379 379 + self.filenames_end_with_b
380 380 + ['*c']),
381 381 (['a[012]'], self.filenames_start_with_a),
382 382 ]
383 383
384 384 @skip_win32
385 385 def test_match_posix(self):
386 386 for (patterns, matches) in self.common_cases() + [
387 387 ([r'\*'], ['*']),
388 388 ([r'a\*', 'a*'], ['a*'] + self.filenames_start_with_a),
389 389 ([r'a\[012]'], ['a[012]']),
390 390 ]:
391 391 yield (self.check_match, patterns, matches)
392 392
393 393 @skip_if_not_win32
394 394 def test_match_windows(self):
395 395 for (patterns, matches) in self.common_cases() + [
396 396 # In windows, backslash is interpreted as path
397 397 # separator. Therefore, you can't escape glob
398 398 # using it.
399 399 ([r'a\*', 'a*'], [r'a\*'] + self.filenames_start_with_a),
400 400 ([r'a\[012]'], [r'a\[012]']),
401 401 ]:
402 402 yield (self.check_match, patterns, matches)
403 403
404 404
405 405 def test_unescape_glob():
406 406 nt.assert_equal(path.unescape_glob(r'\*\[\!\]\?'), '*[!]?')
407 407 nt.assert_equal(path.unescape_glob(r'\\*'), r'\*')
408 408 nt.assert_equal(path.unescape_glob(r'\\\*'), r'\*')
409 409 nt.assert_equal(path.unescape_glob(r'\\a'), r'\a')
410 410 nt.assert_equal(path.unescape_glob(r'\a'), r'\a')
411 411
412 412
413 413 def test_ensure_dir_exists():
414 414 with TemporaryDirectory() as td:
415 415 d = os.path.join(td, u'∂ir')
416 416 path.ensure_dir_exists(d) # create it
417 417 assert os.path.isdir(d)
418 418 path.ensure_dir_exists(d) # no-op
419 419 f = os.path.join(td, u'Æ’ile')
420 420 open(f, 'w').close() # touch
421 421 with nt.assert_raises(IOError):
422 422 path.ensure_dir_exists(f)
423 423
424 424 class TestLinkOrCopy(object):
425 425 def setUp(self):
426 426 self.tempdir = TemporaryDirectory()
427 427 self.src = self.dst("src")
428 428 with open(self.src, "w") as f:
429 429 f.write("Hello, world!")
430 430
431 431 def tearDown(self):
432 432 self.tempdir.cleanup()
433 433
434 434 def dst(self, *args):
435 435 return os.path.join(self.tempdir.name, *args)
436 436
437 437 def assert_inode_not_equal(self, a, b):
438 438 nt.assert_not_equal(os.stat(a).st_ino, os.stat(b).st_ino,
439 439 "%r and %r do reference the same indoes" %(a, b))
440 440
441 441 def assert_inode_equal(self, a, b):
442 442 nt.assert_equal(os.stat(a).st_ino, os.stat(b).st_ino,
443 443 "%r and %r do not reference the same indoes" %(a, b))
444 444
445 445 def assert_content_equal(self, a, b):
446 446 with open(a) as a_f:
447 447 with open(b) as b_f:
448 448 nt.assert_equal(a_f.read(), b_f.read())
449 449
450 450 @skip_win32
451 451 def test_link_successful(self):
452 452 dst = self.dst("target")
453 453 path.link_or_copy(self.src, dst)
454 454 self.assert_inode_equal(self.src, dst)
455 455
456 456 @skip_win32
457 457 def test_link_into_dir(self):
458 458 dst = self.dst("some_dir")
459 459 os.mkdir(dst)
460 460 path.link_or_copy(self.src, dst)
461 461 expected_dst = self.dst("some_dir", os.path.basename(self.src))
462 462 self.assert_inode_equal(self.src, expected_dst)
463 463
464 464 @skip_win32
465 465 def test_target_exists(self):
466 466 dst = self.dst("target")
467 467 open(dst, "w").close()
468 468 path.link_or_copy(self.src, dst)
469 469 self.assert_inode_equal(self.src, dst)
470 470
471 471 @skip_win32
472 472 def test_no_link(self):
473 473 real_link = os.link
474 474 try:
475 475 del os.link
476 476 dst = self.dst("target")
477 477 path.link_or_copy(self.src, dst)
478 478 self.assert_content_equal(self.src, dst)
479 479 self.assert_inode_not_equal(self.src, dst)
480 480 finally:
481 481 os.link = real_link
482 482
483 483 @skip_if_not_win32
484 484 def test_windows(self):
485 485 dst = self.dst("target")
486 486 path.link_or_copy(self.src, dst)
487 487 self.assert_content_equal(self.src, dst)
488 488
489 489 def test_link_twice(self):
490 490 # Linking the same file twice shouldn't leave duplicates around.
491 491 # See https://github.com/ipython/ipython/issues/6450
492 492 dst = self.dst('target')
493 493 path.link_or_copy(self.src, dst)
494 494 path.link_or_copy(self.src, dst)
495 495 self.assert_inode_equal(self.src, dst)
496 496 nt.assert_equal(sorted(os.listdir(self.tempdir.name)), ['src', 'target'])
@@ -1,774 +1,776 b''
1 1 # encoding: utf-8
2 2 """
3 3 Utilities for working with strings and text.
4 4
5 5 Inheritance diagram:
6 6
7 7 .. inheritance-diagram:: IPython.utils.text
8 8 :parts: 3
9 9 """
10 10
11 11 import os
12 12 import re
13 13 import sys
14 14 import textwrap
15 15 from string import Formatter
16 16 try:
17 17 from pathlib import Path
18 18 except ImportError:
19 19 # Python 2 backport
20 20 from pathlib2 import Path
21 21
22 22 from IPython.utils import py3compat
23 23
24 24 # datetime.strftime date format for ipython
25 25 if sys.platform == 'win32':
26 26 date_format = "%B %d, %Y"
27 27 else:
28 28 date_format = "%B %-d, %Y"
29 29
30 30 class LSString(str):
31 31 """String derivative with a special access attributes.
32 32
33 33 These are normal strings, but with the special attributes:
34 34
35 35 .l (or .list) : value as list (split on newlines).
36 36 .n (or .nlstr): original value (the string itself).
37 37 .s (or .spstr): value as whitespace-separated string.
38 38 .p (or .paths): list of path objects (requires path.py package)
39 39
40 40 Any values which require transformations are computed only once and
41 41 cached.
42 42
43 43 Such strings are very useful to efficiently interact with the shell, which
44 44 typically only understands whitespace-separated options for commands."""
45 45
46 46 def get_list(self):
47 47 try:
48 48 return self.__list
49 49 except AttributeError:
50 50 self.__list = self.split('\n')
51 51 return self.__list
52 52
53 53 l = list = property(get_list)
54 54
55 55 def get_spstr(self):
56 56 try:
57 57 return self.__spstr
58 58 except AttributeError:
59 59 self.__spstr = self.replace('\n',' ')
60 60 return self.__spstr
61 61
62 62 s = spstr = property(get_spstr)
63 63
64 64 def get_nlstr(self):
65 65 return self
66 66
67 67 n = nlstr = property(get_nlstr)
68 68
69 69 def get_paths(self):
70 70 try:
71 71 return self.__paths
72 72 except AttributeError:
73 73 self.__paths = [Path(p) for p in self.split('\n') if os.path.exists(p)]
74 74 return self.__paths
75 75
76 76 p = paths = property(get_paths)
77 77
78 78 # FIXME: We need to reimplement type specific displayhook and then add this
79 79 # back as a custom printer. This should also be moved outside utils into the
80 80 # core.
81 81
82 82 # def print_lsstring(arg):
83 83 # """ Prettier (non-repr-like) and more informative printer for LSString """
84 84 # print "LSString (.p, .n, .l, .s available). Value:"
85 85 # print arg
86 86 #
87 87 #
88 88 # print_lsstring = result_display.when_type(LSString)(print_lsstring)
89 89
90 90
91 91 class SList(list):
92 92 """List derivative with a special access attributes.
93 93
94 94 These are normal lists, but with the special attributes:
95 95
96 96 * .l (or .list) : value as list (the list itself).
97 97 * .n (or .nlstr): value as a string, joined on newlines.
98 98 * .s (or .spstr): value as a string, joined on spaces.
99 99 * .p (or .paths): list of path objects (requires path.py package)
100 100
101 101 Any values which require transformations are computed only once and
102 102 cached."""
103 103
104 104 def get_list(self):
105 105 return self
106 106
107 107 l = list = property(get_list)
108 108
109 109 def get_spstr(self):
110 110 try:
111 111 return self.__spstr
112 112 except AttributeError:
113 113 self.__spstr = ' '.join(self)
114 114 return self.__spstr
115 115
116 116 s = spstr = property(get_spstr)
117 117
118 118 def get_nlstr(self):
119 119 try:
120 120 return self.__nlstr
121 121 except AttributeError:
122 122 self.__nlstr = '\n'.join(self)
123 123 return self.__nlstr
124 124
125 125 n = nlstr = property(get_nlstr)
126 126
127 127 def get_paths(self):
128 128 try:
129 129 return self.__paths
130 130 except AttributeError:
131 131 self.__paths = [Path(p) for p in self if os.path.exists(p)]
132 132 return self.__paths
133 133
134 134 p = paths = property(get_paths)
135 135
136 136 def grep(self, pattern, prune = False, field = None):
137 137 """ Return all strings matching 'pattern' (a regex or callable)
138 138
139 139 This is case-insensitive. If prune is true, return all items
140 140 NOT matching the pattern.
141 141
142 142 If field is specified, the match must occur in the specified
143 143 whitespace-separated field.
144 144
145 145 Examples::
146 146
147 147 a.grep( lambda x: x.startswith('C') )
148 148 a.grep('Cha.*log', prune=1)
149 149 a.grep('chm', field=-1)
150 150 """
151 151
152 152 def match_target(s):
153 153 if field is None:
154 154 return s
155 155 parts = s.split()
156 156 try:
157 157 tgt = parts[field]
158 158 return tgt
159 159 except IndexError:
160 160 return ""
161 161
162 if isinstance(pattern, py3compat.string_types):
162 if isinstance(pattern, str):
163 163 pred = lambda x : re.search(pattern, x, re.IGNORECASE)
164 164 else:
165 165 pred = pattern
166 166 if not prune:
167 167 return SList([el for el in self if pred(match_target(el))])
168 168 else:
169 169 return SList([el for el in self if not pred(match_target(el))])
170 170
171 171 def fields(self, *fields):
172 172 """ Collect whitespace-separated fields from string list
173 173
174 174 Allows quick awk-like usage of string lists.
175 175
176 176 Example data (in var a, created by 'a = !ls -l')::
177 177
178 178 -rwxrwxrwx 1 ville None 18 Dec 14 2006 ChangeLog
179 179 drwxrwxrwx+ 6 ville None 0 Oct 24 18:05 IPython
180 180
181 181 * ``a.fields(0)`` is ``['-rwxrwxrwx', 'drwxrwxrwx+']``
182 182 * ``a.fields(1,0)`` is ``['1 -rwxrwxrwx', '6 drwxrwxrwx+']``
183 183 (note the joining by space).
184 184 * ``a.fields(-1)`` is ``['ChangeLog', 'IPython']``
185 185
186 186 IndexErrors are ignored.
187 187
188 188 Without args, fields() just split()'s the strings.
189 189 """
190 190 if len(fields) == 0:
191 191 return [el.split() for el in self]
192 192
193 193 res = SList()
194 194 for el in [f.split() for f in self]:
195 195 lineparts = []
196 196
197 197 for fd in fields:
198 198 try:
199 199 lineparts.append(el[fd])
200 200 except IndexError:
201 201 pass
202 202 if lineparts:
203 203 res.append(" ".join(lineparts))
204 204
205 205 return res
206 206
207 207 def sort(self,field= None, nums = False):
208 208 """ sort by specified fields (see fields())
209 209
210 210 Example::
211 211
212 212 a.sort(1, nums = True)
213 213
214 214 Sorts a by second field, in numerical order (so that 21 > 3)
215 215
216 216 """
217 217
218 218 #decorate, sort, undecorate
219 219 if field is not None:
220 220 dsu = [[SList([line]).fields(field), line] for line in self]
221 221 else:
222 222 dsu = [[line, line] for line in self]
223 223 if nums:
224 224 for i in range(len(dsu)):
225 225 numstr = "".join([ch for ch in dsu[i][0] if ch.isdigit()])
226 226 try:
227 227 n = int(numstr)
228 228 except ValueError:
229 229 n = 0
230 230 dsu[i][0] = n
231 231
232 232
233 233 dsu.sort()
234 234 return SList([t[1] for t in dsu])
235 235
236 236
237 237 # FIXME: We need to reimplement type specific displayhook and then add this
238 238 # back as a custom printer. This should also be moved outside utils into the
239 239 # core.
240 240
241 241 # def print_slist(arg):
242 242 # """ Prettier (non-repr-like) and more informative printer for SList """
243 243 # print "SList (.p, .n, .l, .s, .grep(), .fields(), sort() available):"
244 244 # if hasattr(arg, 'hideonce') and arg.hideonce:
245 245 # arg.hideonce = False
246 246 # return
247 247 #
248 248 # nlprint(arg) # This was a nested list printer, now removed.
249 249 #
250 250 # print_slist = result_display.when_type(SList)(print_slist)
251 251
252 252
253 253 def indent(instr,nspaces=4, ntabs=0, flatten=False):
254 254 """Indent a string a given number of spaces or tabstops.
255 255
256 256 indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
257 257
258 258 Parameters
259 259 ----------
260 260
261 261 instr : basestring
262 262 The string to be indented.
263 263 nspaces : int (default: 4)
264 264 The number of spaces to be indented.
265 265 ntabs : int (default: 0)
266 266 The number of tabs to be indented.
267 267 flatten : bool (default: False)
268 268 Whether to scrub existing indentation. If True, all lines will be
269 269 aligned to the same indentation. If False, existing indentation will
270 270 be strictly increased.
271 271
272 272 Returns
273 273 -------
274 274
275 275 str|unicode : string indented by ntabs and nspaces.
276 276
277 277 """
278 278 if instr is None:
279 279 return
280 280 ind = '\t'*ntabs+' '*nspaces
281 281 if flatten:
282 282 pat = re.compile(r'^\s*', re.MULTILINE)
283 283 else:
284 284 pat = re.compile(r'^', re.MULTILINE)
285 285 outstr = re.sub(pat, ind, instr)
286 286 if outstr.endswith(os.linesep+ind):
287 287 return outstr[:-len(ind)]
288 288 else:
289 289 return outstr
290 290
291 291
292 292 def list_strings(arg):
293 293 """Always return a list of strings, given a string or list of strings
294 294 as input.
295 295
296 296 Examples
297 297 --------
298 298 ::
299 299
300 300 In [7]: list_strings('A single string')
301 301 Out[7]: ['A single string']
302 302
303 303 In [8]: list_strings(['A single string in a list'])
304 304 Out[8]: ['A single string in a list']
305 305
306 306 In [9]: list_strings(['A','list','of','strings'])
307 307 Out[9]: ['A', 'list', 'of', 'strings']
308 308 """
309 309
310 if isinstance(arg, py3compat.string_types): return [arg]
311 else: return arg
310 if isinstance(arg, str):
311 return [arg]
312 else:
313 return arg
312 314
313 315
314 316 def marquee(txt='',width=78,mark='*'):
315 317 """Return the input string centered in a 'marquee'.
316 318
317 319 Examples
318 320 --------
319 321 ::
320 322
321 323 In [16]: marquee('A test',40)
322 324 Out[16]: '**************** A test ****************'
323 325
324 326 In [17]: marquee('A test',40,'-')
325 327 Out[17]: '---------------- A test ----------------'
326 328
327 329 In [18]: marquee('A test',40,' ')
328 330 Out[18]: ' A test '
329 331
330 332 """
331 333 if not txt:
332 334 return (mark*width)[:width]
333 335 nmark = (width-len(txt)-2)//len(mark)//2
334 336 if nmark < 0: nmark =0
335 337 marks = mark*nmark
336 338 return '%s %s %s' % (marks,txt,marks)
337 339
338 340
339 341 ini_spaces_re = re.compile(r'^(\s+)')
340 342
341 343 def num_ini_spaces(strng):
342 344 """Return the number of initial spaces in a string"""
343 345
344 346 ini_spaces = ini_spaces_re.match(strng)
345 347 if ini_spaces:
346 348 return ini_spaces.end()
347 349 else:
348 350 return 0
349 351
350 352
351 353 def format_screen(strng):
352 354 """Format a string for screen printing.
353 355
354 356 This removes some latex-type format codes."""
355 357 # Paragraph continue
356 358 par_re = re.compile(r'\\$',re.MULTILINE)
357 359 strng = par_re.sub('',strng)
358 360 return strng
359 361
360 362
361 363 def dedent(text):
362 364 """Equivalent of textwrap.dedent that ignores unindented first line.
363 365
364 366 This means it will still dedent strings like:
365 367 '''foo
366 368 is a bar
367 369 '''
368 370
369 371 For use in wrap_paragraphs.
370 372 """
371 373
372 374 if text.startswith('\n'):
373 375 # text starts with blank line, don't ignore the first line
374 376 return textwrap.dedent(text)
375 377
376 378 # split first line
377 379 splits = text.split('\n',1)
378 380 if len(splits) == 1:
379 381 # only one line
380 382 return textwrap.dedent(text)
381 383
382 384 first, rest = splits
383 385 # dedent everything but the first line
384 386 rest = textwrap.dedent(rest)
385 387 return '\n'.join([first, rest])
386 388
387 389
388 390 def wrap_paragraphs(text, ncols=80):
389 391 """Wrap multiple paragraphs to fit a specified width.
390 392
391 393 This is equivalent to textwrap.wrap, but with support for multiple
392 394 paragraphs, as separated by empty lines.
393 395
394 396 Returns
395 397 -------
396 398
397 399 list of complete paragraphs, wrapped to fill `ncols` columns.
398 400 """
399 401 paragraph_re = re.compile(r'\n(\s*\n)+', re.MULTILINE)
400 402 text = dedent(text).strip()
401 403 paragraphs = paragraph_re.split(text)[::2] # every other entry is space
402 404 out_ps = []
403 405 indent_re = re.compile(r'\n\s+', re.MULTILINE)
404 406 for p in paragraphs:
405 407 # presume indentation that survives dedent is meaningful formatting,
406 408 # so don't fill unless text is flush.
407 409 if indent_re.search(p) is None:
408 410 # wrap paragraph
409 411 p = textwrap.fill(p, ncols)
410 412 out_ps.append(p)
411 413 return out_ps
412 414
413 415
414 416 def long_substr(data):
415 417 """Return the longest common substring in a list of strings.
416 418
417 419 Credit: http://stackoverflow.com/questions/2892931/longest-common-substring-from-more-than-two-strings-python
418 420 """
419 421 substr = ''
420 422 if len(data) > 1 and len(data[0]) > 0:
421 423 for i in range(len(data[0])):
422 424 for j in range(len(data[0])-i+1):
423 425 if j > len(substr) and all(data[0][i:i+j] in x for x in data):
424 426 substr = data[0][i:i+j]
425 427 elif len(data) == 1:
426 428 substr = data[0]
427 429 return substr
428 430
429 431
430 432 def strip_email_quotes(text):
431 433 """Strip leading email quotation characters ('>').
432 434
433 435 Removes any combination of leading '>' interspersed with whitespace that
434 436 appears *identically* in all lines of the input text.
435 437
436 438 Parameters
437 439 ----------
438 440 text : str
439 441
440 442 Examples
441 443 --------
442 444
443 445 Simple uses::
444 446
445 447 In [2]: strip_email_quotes('> > text')
446 448 Out[2]: 'text'
447 449
448 450 In [3]: strip_email_quotes('> > text\\n> > more')
449 451 Out[3]: 'text\\nmore'
450 452
451 453 Note how only the common prefix that appears in all lines is stripped::
452 454
453 455 In [4]: strip_email_quotes('> > text\\n> > more\\n> more...')
454 456 Out[4]: '> text\\n> more\\nmore...'
455 457
456 458 So if any line has no quote marks ('>') , then none are stripped from any
457 459 of them ::
458 460
459 461 In [5]: strip_email_quotes('> > text\\n> > more\\nlast different')
460 462 Out[5]: '> > text\\n> > more\\nlast different'
461 463 """
462 464 lines = text.splitlines()
463 465 matches = set()
464 466 for line in lines:
465 467 prefix = re.match(r'^(\s*>[ >]*)', line)
466 468 if prefix:
467 469 matches.add(prefix.group(1))
468 470 else:
469 471 break
470 472 else:
471 473 prefix = long_substr(list(matches))
472 474 if prefix:
473 475 strip = len(prefix)
474 476 text = '\n'.join([ ln[strip:] for ln in lines])
475 477 return text
476 478
477 479 def strip_ansi(source):
478 480 """
479 481 Remove ansi escape codes from text.
480 482
481 483 Parameters
482 484 ----------
483 485 source : str
484 486 Source to remove the ansi from
485 487 """
486 488 return re.sub(r'\033\[(\d|;)+?m', '', source)
487 489
488 490
489 491 class EvalFormatter(Formatter):
490 492 """A String Formatter that allows evaluation of simple expressions.
491 493
492 494 Note that this version interprets a : as specifying a format string (as per
493 495 standard string formatting), so if slicing is required, you must explicitly
494 496 create a slice.
495 497
496 498 This is to be used in templating cases, such as the parallel batch
497 499 script templates, where simple arithmetic on arguments is useful.
498 500
499 501 Examples
500 502 --------
501 503 ::
502 504
503 505 In [1]: f = EvalFormatter()
504 506 In [2]: f.format('{n//4}', n=8)
505 507 Out[2]: '2'
506 508
507 509 In [3]: f.format("{greeting[slice(2,4)]}", greeting="Hello")
508 510 Out[3]: 'll'
509 511 """
510 512 def get_field(self, name, args, kwargs):
511 513 v = eval(name, kwargs)
512 514 return v, name
513 515
514 516 #XXX: As of Python 3.4, the format string parsing no longer splits on a colon
515 517 # inside [], so EvalFormatter can handle slicing. Once we only support 3.4 and
516 518 # above, it should be possible to remove FullEvalFormatter.
517 519
518 520 class FullEvalFormatter(Formatter):
519 521 """A String Formatter that allows evaluation of simple expressions.
520 522
521 523 Any time a format key is not found in the kwargs,
522 524 it will be tried as an expression in the kwargs namespace.
523 525
524 526 Note that this version allows slicing using [1:2], so you cannot specify
525 527 a format string. Use :class:`EvalFormatter` to permit format strings.
526 528
527 529 Examples
528 530 --------
529 531 ::
530 532
531 533 In [1]: f = FullEvalFormatter()
532 534 In [2]: f.format('{n//4}', n=8)
533 535 Out[2]: '2'
534 536
535 537 In [3]: f.format('{list(range(5))[2:4]}')
536 538 Out[3]: '[2, 3]'
537 539
538 540 In [4]: f.format('{3*2}')
539 541 Out[4]: '6'
540 542 """
541 543 # copied from Formatter._vformat with minor changes to allow eval
542 544 # and replace the format_spec code with slicing
543 545 def vformat(self, format_string, args, kwargs):
544 546 result = []
545 547 for literal_text, field_name, format_spec, conversion in \
546 548 self.parse(format_string):
547 549
548 550 # output the literal text
549 551 if literal_text:
550 552 result.append(literal_text)
551 553
552 554 # if there's a field, output it
553 555 if field_name is not None:
554 556 # this is some markup, find the object and do
555 557 # the formatting
556 558
557 559 if format_spec:
558 560 # override format spec, to allow slicing:
559 561 field_name = ':'.join([field_name, format_spec])
560 562
561 563 # eval the contents of the field for the object
562 564 # to be formatted
563 565 obj = eval(field_name, kwargs)
564 566
565 567 # do any conversion on the resulting object
566 568 obj = self.convert_field(obj, conversion)
567 569
568 570 # format the object and append to the result
569 571 result.append(self.format_field(obj, ''))
570 572
571 573 return u''.join(py3compat.cast_unicode(s) for s in result)
572 574
573 575
574 576 class DollarFormatter(FullEvalFormatter):
575 577 """Formatter allowing Itpl style $foo replacement, for names and attribute
576 578 access only. Standard {foo} replacement also works, and allows full
577 579 evaluation of its arguments.
578 580
579 581 Examples
580 582 --------
581 583 ::
582 584
583 585 In [1]: f = DollarFormatter()
584 586 In [2]: f.format('{n//4}', n=8)
585 587 Out[2]: '2'
586 588
587 589 In [3]: f.format('23 * 76 is $result', result=23*76)
588 590 Out[3]: '23 * 76 is 1748'
589 591
590 592 In [4]: f.format('$a or {b}', a=1, b=2)
591 593 Out[4]: '1 or 2'
592 594 """
593 595 _dollar_pattern = re.compile("(.*?)\$(\$?[\w\.]+)")
594 596 def parse(self, fmt_string):
595 597 for literal_txt, field_name, format_spec, conversion \
596 598 in Formatter.parse(self, fmt_string):
597 599
598 600 # Find $foo patterns in the literal text.
599 601 continue_from = 0
600 602 txt = ""
601 603 for m in self._dollar_pattern.finditer(literal_txt):
602 604 new_txt, new_field = m.group(1,2)
603 605 # $$foo --> $foo
604 606 if new_field.startswith("$"):
605 607 txt += new_txt + new_field
606 608 else:
607 609 yield (txt + new_txt, new_field, "", None)
608 610 txt = ""
609 611 continue_from = m.end()
610 612
611 613 # Re-yield the {foo} style pattern
612 614 yield (txt + literal_txt[continue_from:], field_name, format_spec, conversion)
613 615
614 616 #-----------------------------------------------------------------------------
615 617 # Utils to columnize a list of string
616 618 #-----------------------------------------------------------------------------
617 619
618 620 def _col_chunks(l, max_rows, row_first=False):
619 621 """Yield successive max_rows-sized column chunks from l."""
620 622 if row_first:
621 623 ncols = (len(l) // max_rows) + (len(l) % max_rows > 0)
622 for i in py3compat.xrange(ncols):
623 yield [l[j] for j in py3compat.xrange(i, len(l), ncols)]
624 for i in range(ncols):
625 yield [l[j] for j in range(i, len(l), ncols)]
624 626 else:
625 for i in py3compat.xrange(0, len(l), max_rows):
627 for i in range(0, len(l), max_rows):
626 628 yield l[i:(i + max_rows)]
627 629
628 630
629 631 def _find_optimal(rlist, row_first=False, separator_size=2, displaywidth=80):
630 632 """Calculate optimal info to columnize a list of string"""
631 633 for max_rows in range(1, len(rlist) + 1):
632 634 col_widths = list(map(max, _col_chunks(rlist, max_rows, row_first)))
633 635 sumlength = sum(col_widths)
634 636 ncols = len(col_widths)
635 637 if sumlength + separator_size * (ncols - 1) <= displaywidth:
636 638 break
637 639 return {'num_columns': ncols,
638 640 'optimal_separator_width': (displaywidth - sumlength) // (ncols - 1) if (ncols - 1) else 0,
639 641 'max_rows': max_rows,
640 642 'column_widths': col_widths
641 643 }
642 644
643 645
644 646 def _get_or_default(mylist, i, default=None):
645 647 """return list item number, or default if don't exist"""
646 648 if i >= len(mylist):
647 649 return default
648 650 else :
649 651 return mylist[i]
650 652
651 653
652 654 def compute_item_matrix(items, row_first=False, empty=None, *args, **kwargs) :
653 655 """Returns a nested list, and info to columnize items
654 656
655 657 Parameters
656 658 ----------
657 659
658 660 items
659 661 list of strings to columize
660 662 row_first : (default False)
661 663 Whether to compute columns for a row-first matrix instead of
662 664 column-first (default).
663 665 empty : (default None)
664 666 default value to fill list if needed
665 667 separator_size : int (default=2)
666 668 How much caracters will be used as a separation between each columns.
667 669 displaywidth : int (default=80)
668 670 The width of the area onto wich the columns should enter
669 671
670 672 Returns
671 673 -------
672 674
673 675 strings_matrix
674 676
675 677 nested list of string, the outer most list contains as many list as
676 678 rows, the innermost lists have each as many element as colums. If the
677 679 total number of elements in `items` does not equal the product of
678 680 rows*columns, the last element of some lists are filled with `None`.
679 681
680 682 dict_info
681 683 some info to make columnize easier:
682 684
683 685 num_columns
684 686 number of columns
685 687 max_rows
686 688 maximum number of rows (final number may be less)
687 689 column_widths
688 690 list of with of each columns
689 691 optimal_separator_width
690 692 best separator width between columns
691 693
692 694 Examples
693 695 --------
694 696 ::
695 697
696 698 In [1]: l = ['aaa','b','cc','d','eeeee','f','g','h','i','j','k','l']
697 699 In [2]: list, info = compute_item_matrix(l, displaywidth=12)
698 700 In [3]: list
699 701 Out[3]: [['aaa', 'f', 'k'], ['b', 'g', 'l'], ['cc', 'h', None], ['d', 'i', None], ['eeeee', 'j', None]]
700 702 In [4]: ideal = {'num_columns': 3, 'column_widths': [5, 1, 1], 'optimal_separator_width': 2, 'max_rows': 5}
701 703 In [5]: all((info[k] == ideal[k] for k in ideal.keys()))
702 704 Out[5]: True
703 705 """
704 706 info = _find_optimal(list(map(len, items)), row_first, *args, **kwargs)
705 707 nrow, ncol = info['max_rows'], info['num_columns']
706 708 if row_first:
707 709 return ([[_get_or_default(items, r * ncol + c, default=empty) for c in range(ncol)] for r in range(nrow)], info)
708 710 else:
709 711 return ([[_get_or_default(items, c * nrow + r, default=empty) for c in range(ncol)] for r in range(nrow)], info)
710 712
711 713
712 714 def columnize(items, row_first=False, separator=' ', displaywidth=80, spread=False):
713 715 """ Transform a list of strings into a single string with columns.
714 716
715 717 Parameters
716 718 ----------
717 719 items : sequence of strings
718 720 The strings to process.
719 721
720 722 row_first : (default False)
721 723 Whether to compute columns for a row-first matrix instead of
722 724 column-first (default).
723 725
724 726 separator : str, optional [default is two spaces]
725 727 The string that separates columns.
726 728
727 729 displaywidth : int, optional [default is 80]
728 730 Width of the display in number of characters.
729 731
730 732 Returns
731 733 -------
732 734 The formatted string.
733 735 """
734 736 if not items:
735 737 return '\n'
736 738 matrix, info = compute_item_matrix(items, row_first=row_first, separator_size=len(separator), displaywidth=displaywidth)
737 739 if spread:
738 740 separator = separator.ljust(int(info['optimal_separator_width']))
739 741 fmatrix = [filter(None, x) for x in matrix]
740 742 sjoin = lambda x : separator.join([ y.ljust(w, ' ') for y, w in zip(x, info['column_widths'])])
741 743 return '\n'.join(map(sjoin, fmatrix))+'\n'
742 744
743 745
744 746 def get_text_list(list_, last_sep=' and ', sep=", ", wrap_item_with=""):
745 747 """
746 748 Return a string with a natural enumeration of items
747 749
748 750 >>> get_text_list(['a', 'b', 'c', 'd'])
749 751 'a, b, c and d'
750 752 >>> get_text_list(['a', 'b', 'c'], ' or ')
751 753 'a, b or c'
752 754 >>> get_text_list(['a', 'b', 'c'], ', ')
753 755 'a, b, c'
754 756 >>> get_text_list(['a', 'b'], ' or ')
755 757 'a or b'
756 758 >>> get_text_list(['a'])
757 759 'a'
758 760 >>> get_text_list([])
759 761 ''
760 762 >>> get_text_list(['a', 'b'], wrap_item_with="`")
761 763 '`a` and `b`'
762 764 >>> get_text_list(['a', 'b', 'c', 'd'], " = ", sep=" + ")
763 765 'a + b + c = d'
764 766 """
765 767 if len(list_) == 0:
766 768 return ''
767 769 if wrap_item_with:
768 770 list_ = ['%s%s%s' % (wrap_item_with, item, wrap_item_with) for
769 771 item in list_]
770 772 if len(list_) == 1:
771 773 return list_[0]
772 774 return '%s%s%s' % (
773 775 sep.join(i for i in list_[:-1]),
774 776 last_sep, list_[-1])
@@ -1,118 +1,116 b''
1 1 # encoding: utf-8
2 2 """
3 3 Utilities for timing code execution.
4 4 """
5 5
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (C) 2008-2011 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16
17 17 import time
18 18
19 from .py3compat import xrange
20
21 19 #-----------------------------------------------------------------------------
22 20 # Code
23 21 #-----------------------------------------------------------------------------
24 22
25 23 # If possible (Unix), use the resource module instead of time.clock()
26 24 try:
27 25 import resource
28 26 def clocku():
29 27 """clocku() -> floating point number
30 28
31 29 Return the *USER* CPU time in seconds since the start of the process.
32 30 This is done via a call to resource.getrusage, so it avoids the
33 31 wraparound problems in time.clock()."""
34 32
35 33 return resource.getrusage(resource.RUSAGE_SELF)[0]
36 34
37 35 def clocks():
38 36 """clocks() -> floating point number
39 37
40 38 Return the *SYSTEM* CPU time in seconds since the start of the process.
41 39 This is done via a call to resource.getrusage, so it avoids the
42 40 wraparound problems in time.clock()."""
43 41
44 42 return resource.getrusage(resource.RUSAGE_SELF)[1]
45 43
46 44 def clock():
47 45 """clock() -> floating point number
48 46
49 47 Return the *TOTAL USER+SYSTEM* CPU time in seconds since the start of
50 48 the process. This is done via a call to resource.getrusage, so it
51 49 avoids the wraparound problems in time.clock()."""
52 50
53 51 u,s = resource.getrusage(resource.RUSAGE_SELF)[:2]
54 52 return u+s
55 53
56 54 def clock2():
57 55 """clock2() -> (t_user,t_system)
58 56
59 57 Similar to clock(), but return a tuple of user/system times."""
60 58 return resource.getrusage(resource.RUSAGE_SELF)[:2]
61 59 except ImportError:
62 60 # There is no distinction of user/system time under windows, so we just use
63 61 # time.clock() for everything...
64 62 clocku = clocks = clock = time.clock
65 63 def clock2():
66 64 """Under windows, system CPU time can't be measured.
67 65
68 66 This just returns clock() and zero."""
69 67 return time.clock(),0.0
70 68
71 69
72 70 def timings_out(reps,func,*args,**kw):
73 71 """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
74 72
75 73 Execute a function reps times, return a tuple with the elapsed total
76 74 CPU time in seconds, the time per call and the function's output.
77 75
78 76 Under Unix, the return value is the sum of user+system time consumed by
79 77 the process, computed via the resource module. This prevents problems
80 78 related to the wraparound effect which the time.clock() function has.
81 79
82 80 Under Windows the return value is in wall clock seconds. See the
83 81 documentation for the time module for more details."""
84 82
85 83 reps = int(reps)
86 84 assert reps >=1, 'reps must be >= 1'
87 85 if reps==1:
88 86 start = clock()
89 87 out = func(*args,**kw)
90 88 tot_time = clock()-start
91 89 else:
92 rng = xrange(reps-1) # the last time is executed separately to store output
90 rng = range(reps-1) # the last time is executed separately to store output
93 91 start = clock()
94 92 for dummy in rng: func(*args,**kw)
95 93 out = func(*args,**kw) # one last time
96 94 tot_time = clock()-start
97 95 av_time = tot_time / reps
98 96 return tot_time,av_time,out
99 97
100 98
101 99 def timings(reps,func,*args,**kw):
102 100 """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
103 101
104 102 Execute a function reps times, return a tuple with the elapsed total CPU
105 103 time in seconds and the time per call. These are just the first two values
106 104 in timings_out()."""
107 105
108 106 return timings_out(reps,func,*args,**kw)[0:2]
109 107
110 108
111 109 def timing(func,*args,**kw):
112 110 """timing(func,*args,**kw) -> t_total
113 111
114 112 Execute a function once, return the elapsed total CPU time in
115 113 seconds. This is just the first value in timings_out()."""
116 114
117 115 return timings_out(1,func,*args,**kw)[0]
118 116
@@ -1,45 +1,44 b''
1 1 """Wrapper around linecache which decodes files to unicode according to PEP 263.
2 2
3 3 This is only needed for Python 2 - linecache in Python 3 does the same thing
4 4 itself.
5 5 """
6 6 import functools
7 7 import linecache
8 8 import sys
9 9
10 10 from IPython.utils import py3compat
11 11 from IPython.utils import openpy
12 12
13 13 if py3compat.PY3:
14 14 getline = linecache.getline
15 15
16 16 # getlines has to be looked up at runtime, because doctests monkeypatch it.
17 17 @functools.wraps(linecache.getlines)
18 18 def getlines(filename, module_globals=None):
19 19 return linecache.getlines(filename, module_globals=module_globals)
20 20
21 21 else:
22 22 def getlines(filename, module_globals=None):
23 23 """Get the lines (as unicode) for a file from the cache.
24 24 Update the cache if it doesn't contain an entry for this file already."""
25 25 filename = py3compat.cast_bytes(filename, sys.getfilesystemencoding())
26 26 lines = linecache.getlines(filename, module_globals=module_globals)
27 27
28 # The bits we cache ourselves can be unicode.
29 if (not lines) or isinstance(lines[0], py3compat.unicode_type):
28 if (not lines) or isinstance(lines[0], str):
30 29 return lines
31 30
32 31 readline = openpy._list_readline(lines)
33 32 try:
34 33 encoding, _ = openpy.detect_encoding(readline)
35 34 except SyntaxError:
36 35 encoding = 'ascii'
37 36 return [l.decode(encoding, 'replace') for l in lines]
38 37
39 38 # This is a straight copy of linecache.getline
40 39 def getline(filename, lineno, module_globals=None):
41 40 lines = getlines(filename, module_globals)
42 41 if 1 <= lineno <= len(lines):
43 42 return lines[lineno-1]
44 43 else:
45 44 return ''
@@ -1,112 +1,111 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Support for wildcard pattern matching in object inspection.
3 3
4 4 Authors
5 5 -------
6 6 - Jörgen Stenarson <jorgen.stenarson@bostream.nu>
7 7 - Thomas Kluyver
8 8 """
9 9
10 10 #*****************************************************************************
11 11 # Copyright (C) 2005 Jörgen Stenarson <jorgen.stenarson@bostream.nu>
12 12 #
13 13 # Distributed under the terms of the BSD License. The full license is in
14 14 # the file COPYING, distributed as part of this software.
15 15 #*****************************************************************************
16 16
17 17 import re
18 18 import types
19 19
20 20 from IPython.utils.dir2 import dir2
21 from .py3compat import iteritems
22 21
23 22 def create_typestr2type_dicts(dont_include_in_type2typestr=["lambda"]):
24 23 """Return dictionaries mapping lower case typename (e.g. 'tuple') to type
25 24 objects from the types package, and vice versa."""
26 25 typenamelist = [tname for tname in dir(types) if tname.endswith("Type")]
27 26 typestr2type, type2typestr = {}, {}
28 27
29 28 for tname in typenamelist:
30 29 name = tname[:-4].lower() # Cut 'Type' off the end of the name
31 30 obj = getattr(types, tname)
32 31 typestr2type[name] = obj
33 32 if name not in dont_include_in_type2typestr:
34 33 type2typestr[obj] = name
35 34 return typestr2type, type2typestr
36 35
37 36 typestr2type, type2typestr = create_typestr2type_dicts()
38 37
39 38 def is_type(obj, typestr_or_type):
40 39 """is_type(obj, typestr_or_type) verifies if obj is of a certain type. It
41 40 can take strings or actual python types for the second argument, i.e.
42 41 'tuple'<->TupleType. 'all' matches all types.
43 42
44 43 TODO: Should be extended for choosing more than one type."""
45 44 if typestr_or_type == "all":
46 45 return True
47 46 if type(typestr_or_type) == type:
48 47 test_type = typestr_or_type
49 48 else:
50 49 test_type = typestr2type.get(typestr_or_type, False)
51 50 if test_type:
52 51 return isinstance(obj, test_type)
53 52 return False
54 53
55 54 def show_hidden(str, show_all=False):
56 55 """Return true for strings starting with single _ if show_all is true."""
57 56 return show_all or str.startswith("__") or not str.startswith("_")
58 57
59 58 def dict_dir(obj):
60 59 """Produce a dictionary of an object's attributes. Builds on dir2 by
61 60 checking that a getattr() call actually succeeds."""
62 61 ns = {}
63 62 for key in dir2(obj):
64 63 # This seemingly unnecessary try/except is actually needed
65 64 # because there is code out there with metaclasses that
66 65 # create 'write only' attributes, where a getattr() call
67 66 # will fail even if the attribute appears listed in the
68 67 # object's dictionary. Properties can actually do the same
69 68 # thing. In particular, Traits use this pattern
70 69 try:
71 70 ns[key] = getattr(obj, key)
72 71 except AttributeError:
73 72 pass
74 73 return ns
75 74
76 75 def filter_ns(ns, name_pattern="*", type_pattern="all", ignore_case=True,
77 76 show_all=True):
78 77 """Filter a namespace dictionary by name pattern and item type."""
79 78 pattern = name_pattern.replace("*",".*").replace("?",".")
80 79 if ignore_case:
81 80 reg = re.compile(pattern+"$", re.I)
82 81 else:
83 82 reg = re.compile(pattern+"$")
84 83
85 84 # Check each one matches regex; shouldn't be hidden; of correct type.
86 return dict((key,obj) for key, obj in iteritems(ns) if reg.match(key) \
85 return dict((key,obj) for key, obj in ns.items() if reg.match(key) \
87 86 and show_hidden(key, show_all) \
88 87 and is_type(obj, type_pattern) )
89 88
90 89 def list_namespace(namespace, type_pattern, filter, ignore_case=False, show_all=False):
91 90 """Return dictionary of all objects in a namespace dictionary that match
92 91 type_pattern and filter."""
93 92 pattern_list=filter.split(".")
94 93 if len(pattern_list) == 1:
95 94 return filter_ns(namespace, name_pattern=pattern_list[0],
96 95 type_pattern=type_pattern,
97 96 ignore_case=ignore_case, show_all=show_all)
98 97 else:
99 98 # This is where we can change if all objects should be searched or
100 99 # only modules. Just change the type_pattern to module to search only
101 100 # modules
102 101 filtered = filter_ns(namespace, name_pattern=pattern_list[0],
103 102 type_pattern="all",
104 103 ignore_case=ignore_case, show_all=show_all)
105 104 results = {}
106 for name, obj in iteritems(filtered):
105 for name, obj in filtered.items():
107 106 ns = list_namespace(dict_dir(obj), type_pattern,
108 107 ".".join(pattern_list[1:]),
109 108 ignore_case=ignore_case, show_all=show_all)
110 for inner_name, inner_obj in iteritems(ns):
109 for inner_name, inner_obj in ns.items():
111 110 results["%s.%s"%(name,inner_name)] = inner_obj
112 111 return results
General Comments 0
You need to be logged in to leave comments. Login now