##// END OF EJS Templates
Remove many deprecation and bump traitlets to 5+...
Matthias Bussonnier -
Show More
@@ -1,486 +1,476 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 pathlib import Path
24 24
25 25 from traitlets.config.application import Application, catch_config_error
26 26 from traitlets.config.loader import ConfigFileNotFound, PyFileConfigLoader
27 27 from IPython.core import release, crashhandler
28 28 from IPython.core.profiledir import ProfileDir, ProfileDirError
29 29 from IPython.paths import get_ipython_dir, get_ipython_package_dir
30 30 from IPython.utils.path import ensure_dir_exists
31 31 from traitlets import (
32 32 List, Unicode, Type, Bool, Set, Instance, Undefined,
33 33 default, observe,
34 34 )
35 35
36 36 if os.name == "nt":
37 37 programdata = Path(os.environ.get("PROGRAMDATA", None))
38 38 if programdata:
39 39 SYSTEM_CONFIG_DIRS = [str(programdata / "ipython")]
40 40 else: # PROGRAMDATA is not defined by default on XP.
41 41 SYSTEM_CONFIG_DIRS = []
42 42 else:
43 43 SYSTEM_CONFIG_DIRS = [
44 44 "/usr/local/etc/ipython",
45 45 "/etc/ipython",
46 46 ]
47 47
48 48
49 49 ENV_CONFIG_DIRS = []
50 50 _env_config_dir = os.path.join(sys.prefix, 'etc', 'ipython')
51 51 if _env_config_dir not in SYSTEM_CONFIG_DIRS:
52 52 # only add ENV_CONFIG if sys.prefix is not already included
53 53 ENV_CONFIG_DIRS.append(_env_config_dir)
54 54
55 55
56 56 _envvar = os.environ.get('IPYTHON_SUPPRESS_CONFIG_ERRORS')
57 57 if _envvar in {None, ''}:
58 58 IPYTHON_SUPPRESS_CONFIG_ERRORS = None
59 59 else:
60 60 if _envvar.lower() in {'1','true'}:
61 61 IPYTHON_SUPPRESS_CONFIG_ERRORS = True
62 62 elif _envvar.lower() in {'0','false'} :
63 63 IPYTHON_SUPPRESS_CONFIG_ERRORS = False
64 64 else:
65 65 sys.exit("Unsupported value for environment variable: 'IPYTHON_SUPPRESS_CONFIG_ERRORS' is set to '%s' which is none of {'0', '1', 'false', 'true', ''}."% _envvar )
66 66
67 67 # aliases and flags
68 68
69 69 base_aliases = {}
70 70 if isinstance(Application.aliases, dict):
71 71 # traitlets 5
72 72 base_aliases.update(Application.aliases)
73 73 base_aliases.update(
74 74 {
75 75 "profile-dir": "ProfileDir.location",
76 76 "profile": "BaseIPythonApplication.profile",
77 77 "ipython-dir": "BaseIPythonApplication.ipython_dir",
78 78 "log-level": "Application.log_level",
79 79 "config": "BaseIPythonApplication.extra_config_file",
80 80 }
81 81 )
82 82
83 83 base_flags = dict()
84 84 if isinstance(Application.flags, dict):
85 85 # traitlets 5
86 86 base_flags.update(Application.flags)
87 87 base_flags.update(
88 88 dict(
89 89 debug=(
90 90 {"Application": {"log_level": logging.DEBUG}},
91 91 "set log level to logging.DEBUG (maximize logging output)",
92 92 ),
93 93 quiet=(
94 94 {"Application": {"log_level": logging.CRITICAL}},
95 95 "set log level to logging.CRITICAL (minimize logging output)",
96 96 ),
97 97 init=(
98 98 {
99 99 "BaseIPythonApplication": {
100 100 "copy_config_files": True,
101 101 "auto_create": True,
102 102 }
103 103 },
104 104 """Initialize profile with default config files. This is equivalent
105 105 to running `ipython profile create <profile>` prior to startup.
106 106 """,
107 107 ),
108 108 )
109 109 )
110 110
111 111
112 112 class ProfileAwareConfigLoader(PyFileConfigLoader):
113 113 """A Python file config loader that is aware of IPython profiles."""
114 114 def load_subconfig(self, fname, path=None, profile=None):
115 115 if profile is not None:
116 116 try:
117 117 profile_dir = ProfileDir.find_profile_dir_by_name(
118 118 get_ipython_dir(),
119 119 profile,
120 120 )
121 121 except ProfileDirError:
122 122 return
123 123 path = profile_dir.location
124 124 return super(ProfileAwareConfigLoader, self).load_subconfig(fname, path=path)
125 125
126 126 class BaseIPythonApplication(Application):
127 127
128 128 name = u'ipython'
129 129 description = Unicode(u'IPython: an enhanced interactive Python shell.')
130 130 version = Unicode(release.version)
131 131
132 132 aliases = base_aliases
133 133 flags = base_flags
134 134 classes = List([ProfileDir])
135 135
136 136 # enable `load_subconfig('cfg.py', profile='name')`
137 137 python_config_loader_class = ProfileAwareConfigLoader
138 138
139 139 # Track whether the config_file has changed,
140 140 # because some logic happens only if we aren't using the default.
141 141 config_file_specified = Set()
142 142
143 143 config_file_name = Unicode()
144 144 @default('config_file_name')
145 145 def _config_file_name_default(self):
146 146 return self.name.replace('-','_') + u'_config.py'
147 147 @observe('config_file_name')
148 148 def _config_file_name_changed(self, change):
149 149 if change['new'] != change['old']:
150 150 self.config_file_specified.add(change['new'])
151 151
152 152 # The directory that contains IPython's builtin profiles.
153 153 builtin_profile_dir = Unicode(
154 154 os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
155 155 )
156 156
157 157 config_file_paths = List(Unicode())
158 158 @default('config_file_paths')
159 159 def _config_file_paths_default(self):
160 160 return [os.getcwd()]
161 161
162 162 extra_config_file = Unicode(
163 163 help="""Path to an extra config file to load.
164 164
165 165 If specified, load this config file in addition to any other IPython config.
166 166 """).tag(config=True)
167 167 @observe('extra_config_file')
168 168 def _extra_config_file_changed(self, change):
169 169 old = change['old']
170 170 new = change['new']
171 171 try:
172 172 self.config_files.remove(old)
173 173 except ValueError:
174 174 pass
175 175 self.config_file_specified.add(new)
176 176 self.config_files.append(new)
177 177
178 178 profile = Unicode(u'default',
179 179 help="""The IPython profile to use."""
180 180 ).tag(config=True)
181 181
182 182 @observe('profile')
183 183 def _profile_changed(self, change):
184 184 self.builtin_profile_dir = os.path.join(
185 185 get_ipython_package_dir(), u'config', u'profile', change['new']
186 186 )
187 187
188 188 ipython_dir = Unicode(
189 189 help="""
190 190 The name of the IPython directory. This directory is used for logging
191 191 configuration (through profiles), history storage, etc. The default
192 192 is usually $HOME/.ipython. This option can also be specified through
193 193 the environment variable IPYTHONDIR.
194 194 """
195 195 ).tag(config=True)
196 196 @default('ipython_dir')
197 197 def _ipython_dir_default(self):
198 198 d = get_ipython_dir()
199 199 self._ipython_dir_changed({
200 200 'name': 'ipython_dir',
201 201 'old': d,
202 202 'new': d,
203 203 })
204 204 return d
205 205
206 206 _in_init_profile_dir = False
207 207 profile_dir = Instance(ProfileDir, allow_none=True)
208 208 @default('profile_dir')
209 209 def _profile_dir_default(self):
210 210 # avoid recursion
211 211 if self._in_init_profile_dir:
212 212 return
213 213 # profile_dir requested early, force initialization
214 214 self.init_profile_dir()
215 215 return self.profile_dir
216 216
217 217 overwrite = Bool(False,
218 218 help="""Whether to overwrite existing config files when copying"""
219 219 ).tag(config=True)
220 220 auto_create = Bool(False,
221 221 help="""Whether to create profile dir if it doesn't exist"""
222 222 ).tag(config=True)
223 223
224 224 config_files = List(Unicode())
225 225 @default('config_files')
226 226 def _config_files_default(self):
227 227 return [self.config_file_name]
228 228
229 229 copy_config_files = Bool(False,
230 230 help="""Whether to install the default config files into the profile dir.
231 231 If a new profile is being created, and IPython contains config files for that
232 232 profile, then they will be staged into the new directory. Otherwise,
233 233 default config files will be automatically generated.
234 234 """).tag(config=True)
235 235
236 236 verbose_crash = Bool(False,
237 237 help="""Create a massive crash report when IPython encounters what may be an
238 238 internal error. The default is to append a short message to the
239 239 usual traceback""").tag(config=True)
240 240
241 241 # The class to use as the crash handler.
242 242 crash_handler_class = Type(crashhandler.CrashHandler)
243 243
244 244 @catch_config_error
245 245 def __init__(self, **kwargs):
246 246 super(BaseIPythonApplication, self).__init__(**kwargs)
247 247 # ensure current working directory exists
248 248 try:
249 249 os.getcwd()
250 250 except:
251 251 # exit if cwd doesn't exist
252 252 self.log.error("Current working directory doesn't exist.")
253 253 self.exit(1)
254 254
255 255 #-------------------------------------------------------------------------
256 256 # Various stages of Application creation
257 257 #-------------------------------------------------------------------------
258 258
259 deprecated_subcommands = {}
260
261 def initialize_subcommand(self, subc, argv=None):
262 if subc in self.deprecated_subcommands:
263 self.log.warning("Subcommand `ipython {sub}` is deprecated and will be removed "
264 "in future versions.".format(sub=subc))
265 self.log.warning("You likely want to use `jupyter {sub}` in the "
266 "future".format(sub=subc))
267 return super(BaseIPythonApplication, self).initialize_subcommand(subc, argv)
268
269 259 def init_crash_handler(self):
270 260 """Create a crash handler, typically setting sys.excepthook to it."""
271 261 self.crash_handler = self.crash_handler_class(self)
272 262 sys.excepthook = self.excepthook
273 263 def unset_crashhandler():
274 264 sys.excepthook = sys.__excepthook__
275 265 atexit.register(unset_crashhandler)
276 266
277 267 def excepthook(self, etype, evalue, tb):
278 268 """this is sys.excepthook after init_crashhandler
279 269
280 270 set self.verbose_crash=True to use our full crashhandler, instead of
281 271 a regular traceback with a short message (crash_handler_lite)
282 272 """
283 273
284 274 if self.verbose_crash:
285 275 return self.crash_handler(etype, evalue, tb)
286 276 else:
287 277 return crashhandler.crash_handler_lite(etype, evalue, tb)
288 278
289 279 @observe('ipython_dir')
290 280 def _ipython_dir_changed(self, change):
291 281 old = change['old']
292 282 new = change['new']
293 283 if old is not Undefined:
294 284 str_old = os.path.abspath(old)
295 285 if str_old in sys.path:
296 286 sys.path.remove(str_old)
297 287 str_path = os.path.abspath(new)
298 288 sys.path.append(str_path)
299 289 ensure_dir_exists(new)
300 290 readme = os.path.join(new, 'README')
301 291 readme_src = os.path.join(get_ipython_package_dir(), u'config', u'profile', 'README')
302 292 if not os.path.exists(readme) and os.path.exists(readme_src):
303 293 shutil.copy(readme_src, readme)
304 294 for d in ('extensions', 'nbextensions'):
305 295 path = os.path.join(new, d)
306 296 try:
307 297 ensure_dir_exists(path)
308 298 except OSError as e:
309 299 # this will not be EEXIST
310 300 self.log.error("couldn't create path %s: %s", path, e)
311 301 self.log.debug("IPYTHONDIR set to: %s" % new)
312 302
313 303 def load_config_file(self, suppress_errors=IPYTHON_SUPPRESS_CONFIG_ERRORS):
314 304 """Load the config file.
315 305
316 306 By default, errors in loading config are handled, and a warning
317 307 printed on screen. For testing, the suppress_errors option is set
318 308 to False, so errors will make tests fail.
319 309
320 310 `suppress_errors` default value is to be `None` in which case the
321 311 behavior default to the one of `traitlets.Application`.
322 312
323 313 The default value can be set :
324 314 - to `False` by setting 'IPYTHON_SUPPRESS_CONFIG_ERRORS' environment variable to '0', or 'false' (case insensitive).
325 315 - to `True` by setting 'IPYTHON_SUPPRESS_CONFIG_ERRORS' environment variable to '1' or 'true' (case insensitive).
326 316 - to `None` by setting 'IPYTHON_SUPPRESS_CONFIG_ERRORS' environment variable to '' (empty string) or leaving it unset.
327 317
328 318 Any other value are invalid, and will make IPython exit with a non-zero return code.
329 319 """
330 320
331 321
332 322 self.log.debug("Searching path %s for config files", self.config_file_paths)
333 323 base_config = 'ipython_config.py'
334 324 self.log.debug("Attempting to load config file: %s" %
335 325 base_config)
336 326 try:
337 327 if suppress_errors is not None:
338 328 old_value = Application.raise_config_file_errors
339 329 Application.raise_config_file_errors = not suppress_errors;
340 330 Application.load_config_file(
341 331 self,
342 332 base_config,
343 333 path=self.config_file_paths
344 334 )
345 335 except ConfigFileNotFound:
346 336 # ignore errors loading parent
347 337 self.log.debug("Config file %s not found", base_config)
348 338 pass
349 339 if suppress_errors is not None:
350 340 Application.raise_config_file_errors = old_value
351 341
352 342 for config_file_name in self.config_files:
353 343 if not config_file_name or config_file_name == base_config:
354 344 continue
355 345 self.log.debug("Attempting to load config file: %s" %
356 346 self.config_file_name)
357 347 try:
358 348 Application.load_config_file(
359 349 self,
360 350 config_file_name,
361 351 path=self.config_file_paths
362 352 )
363 353 except ConfigFileNotFound:
364 354 # Only warn if the default config file was NOT being used.
365 355 if config_file_name in self.config_file_specified:
366 356 msg = self.log.warning
367 357 else:
368 358 msg = self.log.debug
369 359 msg("Config file not found, skipping: %s", config_file_name)
370 360 except Exception:
371 361 # For testing purposes.
372 362 if not suppress_errors:
373 363 raise
374 364 self.log.warning("Error loading config file: %s" %
375 365 self.config_file_name, exc_info=True)
376 366
377 367 def init_profile_dir(self):
378 368 """initialize the profile dir"""
379 369 self._in_init_profile_dir = True
380 370 if self.profile_dir is not None:
381 371 # already ran
382 372 return
383 373 if 'ProfileDir.location' not in self.config:
384 374 # location not specified, find by profile name
385 375 try:
386 376 p = ProfileDir.find_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
387 377 except ProfileDirError:
388 378 # not found, maybe create it (always create default profile)
389 379 if self.auto_create or self.profile == 'default':
390 380 try:
391 381 p = ProfileDir.create_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
392 382 except ProfileDirError:
393 383 self.log.fatal("Could not create profile: %r"%self.profile)
394 384 self.exit(1)
395 385 else:
396 386 self.log.info("Created profile dir: %r"%p.location)
397 387 else:
398 388 self.log.fatal("Profile %r not found."%self.profile)
399 389 self.exit(1)
400 390 else:
401 391 self.log.debug(f"Using existing profile dir: {p.location!r}")
402 392 else:
403 393 location = self.config.ProfileDir.location
404 394 # location is fully specified
405 395 try:
406 396 p = ProfileDir.find_profile_dir(location, self.config)
407 397 except ProfileDirError:
408 398 # not found, maybe create it
409 399 if self.auto_create:
410 400 try:
411 401 p = ProfileDir.create_profile_dir(location, self.config)
412 402 except ProfileDirError:
413 403 self.log.fatal("Could not create profile directory: %r"%location)
414 404 self.exit(1)
415 405 else:
416 406 self.log.debug("Creating new profile dir: %r"%location)
417 407 else:
418 408 self.log.fatal("Profile directory %r not found."%location)
419 409 self.exit(1)
420 410 else:
421 411 self.log.debug(f"Using existing profile dir: {p.location!r}")
422 412 # if profile_dir is specified explicitly, set profile name
423 413 dir_name = os.path.basename(p.location)
424 414 if dir_name.startswith('profile_'):
425 415 self.profile = dir_name[8:]
426 416
427 417 self.profile_dir = p
428 418 self.config_file_paths.append(p.location)
429 419 self._in_init_profile_dir = False
430 420
431 421 def init_config_files(self):
432 422 """[optionally] copy default config files into profile dir."""
433 423 self.config_file_paths.extend(ENV_CONFIG_DIRS)
434 424 self.config_file_paths.extend(SYSTEM_CONFIG_DIRS)
435 425 # copy config files
436 426 path = Path(self.builtin_profile_dir)
437 427 if self.copy_config_files:
438 428 src = self.profile
439 429
440 430 cfg = self.config_file_name
441 431 if path and (path / cfg).exists():
442 432 self.log.warning(
443 433 "Staging %r from %s into %r [overwrite=%s]"
444 434 % (cfg, src, self.profile_dir.location, self.overwrite)
445 435 )
446 436 self.profile_dir.copy_config_file(cfg, path=path, overwrite=self.overwrite)
447 437 else:
448 438 self.stage_default_config_file()
449 439 else:
450 440 # Still stage *bundled* config files, but not generated ones
451 441 # This is necessary for `ipython profile=sympy` to load the profile
452 442 # on the first go
453 443 files = path.glob("*.py")
454 444 for fullpath in files:
455 445 cfg = fullpath.name
456 446 if self.profile_dir.copy_config_file(cfg, path=path, overwrite=False):
457 447 # file was copied
458 448 self.log.warning("Staging bundled %s from %s into %r"%(
459 449 cfg, self.profile, self.profile_dir.location)
460 450 )
461 451
462 452
463 453 def stage_default_config_file(self):
464 454 """auto generate default config file, and stage it into the profile."""
465 455 s = self.generate_config_file()
466 456 config_file = Path(self.profile_dir.location) / self.config_file_name
467 457 if self.overwrite or not config_file.exists():
468 458 self.log.warning("Generating default config file: %r" % (config_file))
469 459 config_file.write_text(s)
470 460
471 461 @catch_config_error
472 462 def initialize(self, argv=None):
473 463 # don't hook up crash handler before parsing command-line
474 464 self.parse_command_line(argv)
475 465 self.init_crash_handler()
476 466 if self.subapp is not None:
477 467 # stop here if subapp is taking over
478 468 return
479 469 # save a copy of CLI config to re-load after config files
480 470 # so that it has highest priority
481 471 cl_config = deepcopy(self.config)
482 472 self.init_profile_dir()
483 473 self.init_config_files()
484 474 self.load_config_file()
485 475 # enforce cl-opts override configfile opts:
486 476 self.update_config(cl_config)
@@ -1,1010 +1,1003 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Pdb debugger class.
4 4
5 5
6 6 This is an extension to PDB which adds a number of new features.
7 7 Note that there is also the `IPython.terminal.debugger` class which provides UI
8 8 improvements.
9 9
10 10 We also strongly recommend to use this via the `ipdb` package, which provides
11 11 extra configuration options.
12 12
13 13 Among other things, this subclass of PDB:
14 14 - supports many IPython magics like pdef/psource
15 15 - hide frames in tracebacks based on `__tracebackhide__`
16 16 - allows to skip frames based on `__debuggerskip__`
17 17
18 18 The skipping and hiding frames are configurable via the `skip_predicates`
19 19 command.
20 20
21 21 By default, frames from readonly files will be hidden, frames containing
22 22 ``__tracebackhide__=True`` will be hidden.
23 23
24 24 Frames containing ``__debuggerskip__`` will be stepped over, frames who's parent
25 25 frames value of ``__debuggerskip__`` is ``True`` will be skipped.
26 26
27 27 >>> def helpers_helper():
28 28 ... pass
29 29 ...
30 30 ... def helper_1():
31 31 ... print("don't step in me")
32 32 ... helpers_helpers() # will be stepped over unless breakpoint set.
33 33 ...
34 34 ...
35 35 ... def helper_2():
36 36 ... print("in me neither")
37 37 ...
38 38
39 39 One can define a decorator that wraps a function between the two helpers:
40 40
41 41 >>> def pdb_skipped_decorator(function):
42 42 ...
43 43 ...
44 44 ... def wrapped_fn(*args, **kwargs):
45 45 ... __debuggerskip__ = True
46 46 ... helper_1()
47 47 ... __debuggerskip__ = False
48 48 ... result = function(*args, **kwargs)
49 49 ... __debuggerskip__ = True
50 50 ... helper_2()
51 51 ... # setting __debuggerskip__ to False again is not necessary
52 52 ... return result
53 53 ...
54 54 ... return wrapped_fn
55 55
56 56 When decorating a function, ipdb will directly step into ``bar()`` by
57 57 default:
58 58
59 59 >>> @foo_decorator
60 60 ... def bar(x, y):
61 61 ... return x * y
62 62
63 63
64 64 You can toggle the behavior with
65 65
66 66 ipdb> skip_predicates debuggerskip false
67 67
68 68 or configure it in your ``.pdbrc``
69 69
70 70
71 71
72 72 License
73 73 -------
74 74
75 75 Modified from the standard pdb.Pdb class to avoid including readline, so that
76 76 the command line completion of other programs which include this isn't
77 77 damaged.
78 78
79 79 In the future, this class will be expanded with improvements over the standard
80 80 pdb.
81 81
82 82 The original code in this file is mainly lifted out of cmd.py in Python 2.2,
83 83 with minor changes. Licensing should therefore be under the standard Python
84 84 terms. For details on the PSF (Python Software Foundation) standard license,
85 85 see:
86 86
87 87 https://docs.python.org/2/license.html
88 88
89 89
90 90 All the changes since then are under the same license as IPython.
91 91
92 92 """
93 93
94 94 #*****************************************************************************
95 95 #
96 96 # This file is licensed under the PSF license.
97 97 #
98 98 # Copyright (C) 2001 Python Software Foundation, www.python.org
99 99 # Copyright (C) 2005-2006 Fernando Perez. <fperez@colorado.edu>
100 100 #
101 101 #
102 102 #*****************************************************************************
103 103
104 104 import bdb
105 105 import inspect
106 106 import linecache
107 107 import sys
108 108 import warnings
109 109 import re
110 110 import os
111 111
112 112 from IPython import get_ipython
113 113 from IPython.utils import PyColorize
114 114 from IPython.utils import coloransi, py3compat
115 115 from IPython.core.excolors import exception_colors
116 116
117 117 # skip module docstests
118 118 __skip_doctest__ = True
119 119
120 120 prompt = 'ipdb> '
121 121
122 122 # We have to check this directly from sys.argv, config struct not yet available
123 123 from pdb import Pdb as OldPdb
124 124
125 125 # Allow the set_trace code to operate outside of an ipython instance, even if
126 126 # it does so with some limitations. The rest of this support is implemented in
127 127 # the Tracer constructor.
128 128
129 129 DEBUGGERSKIP = "__debuggerskip__"
130 130
131 131
132 132 def make_arrow(pad):
133 133 """generate the leading arrow in front of traceback or debugger"""
134 134 if pad >= 2:
135 135 return '-'*(pad-2) + '> '
136 136 elif pad == 1:
137 137 return '>'
138 138 return ''
139 139
140 140
141 141 def BdbQuit_excepthook(et, ev, tb, excepthook=None):
142 142 """Exception hook which handles `BdbQuit` exceptions.
143 143
144 144 All other exceptions are processed using the `excepthook`
145 145 parameter.
146 146 """
147 warnings.warn("`BdbQuit_excepthook` is deprecated since version 5.1",
148 DeprecationWarning, stacklevel=2)
149 if et == bdb.BdbQuit:
150 print('Exiting Debugger.')
151 elif excepthook is not None:
152 excepthook(et, ev, tb)
153 else:
154 # Backwards compatibility. Raise deprecation warning?
155 BdbQuit_excepthook.excepthook_ori(et, ev, tb)
147 raise ValueError(
148 "`BdbQuit_excepthook` is deprecated since version 5.1",
149 )
156 150
157 151
158 152 def BdbQuit_IPython_excepthook(self, et, ev, tb, tb_offset=None):
159 warnings.warn(
153 raise ValueError(
160 154 "`BdbQuit_IPython_excepthook` is deprecated since version 5.1",
161 155 DeprecationWarning, stacklevel=2)
162 print('Exiting Debugger.')
163 156
164 157
165 158 RGX_EXTRA_INDENT = re.compile(r'(?<=\n)\s+')
166 159
167 160
168 161 def strip_indentation(multiline_string):
169 162 return RGX_EXTRA_INDENT.sub('', multiline_string)
170 163
171 164
172 165 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
173 166 """Make new_fn have old_fn's doc string. This is particularly useful
174 167 for the ``do_...`` commands that hook into the help system.
175 168 Adapted from from a comp.lang.python posting
176 169 by Duncan Booth."""
177 170 def wrapper(*args, **kw):
178 171 return new_fn(*args, **kw)
179 172 if old_fn.__doc__:
180 173 wrapper.__doc__ = strip_indentation(old_fn.__doc__) + additional_text
181 174 return wrapper
182 175
183 176
184 177 class Pdb(OldPdb):
185 178 """Modified Pdb class, does not load readline.
186 179
187 180 for a standalone version that uses prompt_toolkit, see
188 181 `IPython.terminal.debugger.TerminalPdb` and
189 182 `IPython.terminal.debugger.set_trace()`
190 183
191 184
192 185 This debugger can hide and skip frames that are tagged according to some predicates.
193 186 See the `skip_predicates` commands.
194 187
195 188 """
196 189
197 190 default_predicates = {
198 191 "tbhide": True,
199 192 "readonly": False,
200 193 "ipython_internal": True,
201 194 "debuggerskip": True,
202 195 }
203 196
204 197 def __init__(self, completekey=None, stdin=None, stdout=None, context=5, **kwargs):
205 198 """Create a new IPython debugger.
206 199
207 200 Parameters
208 201 ----------
209 202 completekey : default None
210 203 Passed to pdb.Pdb.
211 204 stdin : default None
212 205 Passed to pdb.Pdb.
213 206 stdout : default None
214 207 Passed to pdb.Pdb.
215 208 context : int
216 209 Number of lines of source code context to show when
217 210 displaying stacktrace information.
218 211 **kwargs
219 212 Passed to pdb.Pdb.
220 213
221 214 Notes
222 215 -----
223 216 The possibilities are python version dependent, see the python
224 217 docs for more info.
225 218 """
226 219
227 220 # Parent constructor:
228 221 try:
229 222 self.context = int(context)
230 223 if self.context <= 0:
231 224 raise ValueError("Context must be a positive integer")
232 225 except (TypeError, ValueError) as e:
233 226 raise ValueError("Context must be a positive integer") from e
234 227
235 228 # `kwargs` ensures full compatibility with stdlib's `pdb.Pdb`.
236 229 OldPdb.__init__(self, completekey, stdin, stdout, **kwargs)
237 230
238 231 # IPython changes...
239 232 self.shell = get_ipython()
240 233
241 234 if self.shell is None:
242 235 save_main = sys.modules['__main__']
243 236 # No IPython instance running, we must create one
244 237 from IPython.terminal.interactiveshell import \
245 238 TerminalInteractiveShell
246 239 self.shell = TerminalInteractiveShell.instance()
247 240 # needed by any code which calls __import__("__main__") after
248 241 # the debugger was entered. See also #9941.
249 242 sys.modules["__main__"] = save_main
250 243
251 244
252 245 color_scheme = self.shell.colors
253 246
254 247 self.aliases = {}
255 248
256 249 # Create color table: we copy the default one from the traceback
257 250 # module and add a few attributes needed for debugging
258 251 self.color_scheme_table = exception_colors()
259 252
260 253 # shorthands
261 254 C = coloransi.TermColors
262 255 cst = self.color_scheme_table
263 256
264 257 cst['NoColor'].colors.prompt = C.NoColor
265 258 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
266 259 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
267 260
268 261 cst['Linux'].colors.prompt = C.Green
269 262 cst['Linux'].colors.breakpoint_enabled = C.LightRed
270 263 cst['Linux'].colors.breakpoint_disabled = C.Red
271 264
272 265 cst['LightBG'].colors.prompt = C.Blue
273 266 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
274 267 cst['LightBG'].colors.breakpoint_disabled = C.Red
275 268
276 269 cst['Neutral'].colors.prompt = C.Blue
277 270 cst['Neutral'].colors.breakpoint_enabled = C.LightRed
278 271 cst['Neutral'].colors.breakpoint_disabled = C.Red
279 272
280 273 # Add a python parser so we can syntax highlight source while
281 274 # debugging.
282 275 self.parser = PyColorize.Parser(style=color_scheme)
283 276 self.set_colors(color_scheme)
284 277
285 278 # Set the prompt - the default prompt is '(Pdb)'
286 279 self.prompt = prompt
287 280 self.skip_hidden = True
288 281 self.report_skipped = True
289 282
290 283 # list of predicates we use to skip frames
291 284 self._predicates = self.default_predicates
292 285
293 286 #
294 287 def set_colors(self, scheme):
295 288 """Shorthand access to the color table scheme selector method."""
296 289 self.color_scheme_table.set_active_scheme(scheme)
297 290 self.parser.style = scheme
298 291
299 292 def set_trace(self, frame=None):
300 293 if frame is None:
301 294 frame = sys._getframe().f_back
302 295 self.initial_frame = frame
303 296 return super().set_trace(frame)
304 297
305 298 def _hidden_predicate(self, frame):
306 299 """
307 300 Given a frame return whether it it should be hidden or not by IPython.
308 301 """
309 302
310 303 if self._predicates["readonly"]:
311 304 fname = frame.f_code.co_filename
312 305 # we need to check for file existence and interactively define
313 306 # function would otherwise appear as RO.
314 307 if os.path.isfile(fname) and not os.access(fname, os.W_OK):
315 308 return True
316 309
317 310 if self._predicates["tbhide"]:
318 311 if frame in (self.curframe, getattr(self, "initial_frame", None)):
319 312 return False
320 313 frame_locals = self._get_frame_locals(frame)
321 314 if "__tracebackhide__" not in frame_locals:
322 315 return False
323 316 return frame_locals["__tracebackhide__"]
324 317 return False
325 318
326 319 def hidden_frames(self, stack):
327 320 """
328 321 Given an index in the stack return whether it should be skipped.
329 322
330 323 This is used in up/down and where to skip frames.
331 324 """
332 325 # The f_locals dictionary is updated from the actual frame
333 326 # locals whenever the .f_locals accessor is called, so we
334 327 # avoid calling it here to preserve self.curframe_locals.
335 328 # Furthermore, there is no good reason to hide the current frame.
336 329 ip_hide = [self._hidden_predicate(s[0]) for s in stack]
337 330 ip_start = [i for i, s in enumerate(ip_hide) if s == "__ipython_bottom__"]
338 331 if ip_start and self._predicates["ipython_internal"]:
339 332 ip_hide = [h if i > ip_start[0] else True for (i, h) in enumerate(ip_hide)]
340 333 return ip_hide
341 334
342 335 def interaction(self, frame, traceback):
343 336 try:
344 337 OldPdb.interaction(self, frame, traceback)
345 338 except KeyboardInterrupt:
346 339 self.stdout.write("\n" + self.shell.get_exception_only())
347 340
348 341 def precmd(self, line):
349 342 """Perform useful escapes on the command before it is executed."""
350 343
351 344 if line.endswith("??"):
352 345 line = "pinfo2 " + line[:-2]
353 346 elif line.endswith("?"):
354 347 line = "pinfo " + line[:-1]
355 348
356 349 line = super().precmd(line)
357 350
358 351 return line
359 352
360 353 def new_do_frame(self, arg):
361 354 OldPdb.do_frame(self, arg)
362 355
363 356 def new_do_quit(self, arg):
364 357
365 358 if hasattr(self, 'old_all_completions'):
366 359 self.shell.Completer.all_completions = self.old_all_completions
367 360
368 361 return OldPdb.do_quit(self, arg)
369 362
370 363 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
371 364
372 365 def new_do_restart(self, arg):
373 366 """Restart command. In the context of ipython this is exactly the same
374 367 thing as 'quit'."""
375 368 self.msg("Restart doesn't make sense here. Using 'quit' instead.")
376 369 return self.do_quit(arg)
377 370
378 371 def print_stack_trace(self, context=None):
379 372 Colors = self.color_scheme_table.active_colors
380 373 ColorsNormal = Colors.Normal
381 374 if context is None:
382 375 context = self.context
383 376 try:
384 377 context = int(context)
385 378 if context <= 0:
386 379 raise ValueError("Context must be a positive integer")
387 380 except (TypeError, ValueError) as e:
388 381 raise ValueError("Context must be a positive integer") from e
389 382 try:
390 383 skipped = 0
391 384 for hidden, frame_lineno in zip(self.hidden_frames(self.stack), self.stack):
392 385 if hidden and self.skip_hidden:
393 386 skipped += 1
394 387 continue
395 388 if skipped:
396 389 print(
397 390 f"{Colors.excName} [... skipping {skipped} hidden frame(s)]{ColorsNormal}\n"
398 391 )
399 392 skipped = 0
400 393 self.print_stack_entry(frame_lineno, context=context)
401 394 if skipped:
402 395 print(
403 396 f"{Colors.excName} [... skipping {skipped} hidden frame(s)]{ColorsNormal}\n"
404 397 )
405 398 except KeyboardInterrupt:
406 399 pass
407 400
408 401 def print_stack_entry(self, frame_lineno, prompt_prefix='\n-> ',
409 402 context=None):
410 403 if context is None:
411 404 context = self.context
412 405 try:
413 406 context = int(context)
414 407 if context <= 0:
415 408 raise ValueError("Context must be a positive integer")
416 409 except (TypeError, ValueError) as e:
417 410 raise ValueError("Context must be a positive integer") from e
418 411 print(self.format_stack_entry(frame_lineno, '', context), file=self.stdout)
419 412
420 413 # vds: >>
421 414 frame, lineno = frame_lineno
422 415 filename = frame.f_code.co_filename
423 416 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
424 417 # vds: <<
425 418
426 419 def _get_frame_locals(self, frame):
427 420 """ "
428 421 Accessing f_local of current frame reset the namespace, so we want to avoid
429 422 that or the following can happen
430 423
431 424 ipdb> foo
432 425 "old"
433 426 ipdb> foo = "new"
434 427 ipdb> foo
435 428 "new"
436 429 ipdb> where
437 430 ipdb> foo
438 431 "old"
439 432
440 433 So if frame is self.current_frame we instead return self.curframe_locals
441 434
442 435 """
443 436 if frame is self.curframe:
444 437 return self.curframe_locals
445 438 else:
446 439 return frame.f_locals
447 440
448 441 def format_stack_entry(self, frame_lineno, lprefix=': ', context=None):
449 442 if context is None:
450 443 context = self.context
451 444 try:
452 445 context = int(context)
453 446 if context <= 0:
454 447 print("Context must be a positive integer", file=self.stdout)
455 448 except (TypeError, ValueError):
456 449 print("Context must be a positive integer", file=self.stdout)
457 450
458 451 import reprlib
459 452
460 453 ret = []
461 454
462 455 Colors = self.color_scheme_table.active_colors
463 456 ColorsNormal = Colors.Normal
464 457 tpl_link = "%s%%s%s" % (Colors.filenameEm, ColorsNormal)
465 458 tpl_call = "%s%%s%s%%s%s" % (Colors.vName, Colors.valEm, ColorsNormal)
466 459 tpl_line = "%%s%s%%s %s%%s" % (Colors.lineno, ColorsNormal)
467 460 tpl_line_em = "%%s%s%%s %s%%s%s" % (Colors.linenoEm, Colors.line, ColorsNormal)
468 461
469 462 frame, lineno = frame_lineno
470 463
471 464 return_value = ''
472 465 loc_frame = self._get_frame_locals(frame)
473 466 if "__return__" in loc_frame:
474 467 rv = loc_frame["__return__"]
475 468 # return_value += '->'
476 469 return_value += reprlib.repr(rv) + "\n"
477 470 ret.append(return_value)
478 471
479 472 #s = filename + '(' + `lineno` + ')'
480 473 filename = self.canonic(frame.f_code.co_filename)
481 474 link = tpl_link % py3compat.cast_unicode(filename)
482 475
483 476 if frame.f_code.co_name:
484 477 func = frame.f_code.co_name
485 478 else:
486 479 func = "<lambda>"
487 480
488 481 call = ""
489 482 if func != "?":
490 483 if "__args__" in loc_frame:
491 484 args = reprlib.repr(loc_frame["__args__"])
492 485 else:
493 486 args = '()'
494 487 call = tpl_call % (func, args)
495 488
496 489 # The level info should be generated in the same format pdb uses, to
497 490 # avoid breaking the pdbtrack functionality of python-mode in *emacs.
498 491 if frame is self.curframe:
499 492 ret.append('> ')
500 493 else:
501 494 ret.append(" ")
502 495 ret.append("%s(%s)%s\n" % (link, lineno, call))
503 496
504 497 start = lineno - 1 - context//2
505 498 lines = linecache.getlines(filename)
506 499 start = min(start, len(lines) - context)
507 500 start = max(start, 0)
508 501 lines = lines[start : start + context]
509 502
510 503 for i, line in enumerate(lines):
511 504 show_arrow = start + 1 + i == lineno
512 505 linetpl = (frame is self.curframe or show_arrow) and tpl_line_em or tpl_line
513 506 ret.append(
514 507 self.__format_line(
515 508 linetpl, filename, start + 1 + i, line, arrow=show_arrow
516 509 )
517 510 )
518 511 return "".join(ret)
519 512
520 513 def __format_line(self, tpl_line, filename, lineno, line, arrow=False):
521 514 bp_mark = ""
522 515 bp_mark_color = ""
523 516
524 517 new_line, err = self.parser.format2(line, 'str')
525 518 if not err:
526 519 line = new_line
527 520
528 521 bp = None
529 522 if lineno in self.get_file_breaks(filename):
530 523 bps = self.get_breaks(filename, lineno)
531 524 bp = bps[-1]
532 525
533 526 if bp:
534 527 Colors = self.color_scheme_table.active_colors
535 528 bp_mark = str(bp.number)
536 529 bp_mark_color = Colors.breakpoint_enabled
537 530 if not bp.enabled:
538 531 bp_mark_color = Colors.breakpoint_disabled
539 532
540 533 numbers_width = 7
541 534 if arrow:
542 535 # This is the line with the error
543 536 pad = numbers_width - len(str(lineno)) - len(bp_mark)
544 537 num = '%s%s' % (make_arrow(pad), str(lineno))
545 538 else:
546 539 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
547 540
548 541 return tpl_line % (bp_mark_color + bp_mark, num, line)
549 542
550 543 def print_list_lines(self, filename, first, last):
551 544 """The printing (as opposed to the parsing part of a 'list'
552 545 command."""
553 546 try:
554 547 Colors = self.color_scheme_table.active_colors
555 548 ColorsNormal = Colors.Normal
556 549 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
557 550 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
558 551 src = []
559 552 if filename == "<string>" and hasattr(self, "_exec_filename"):
560 553 filename = self._exec_filename
561 554
562 555 for lineno in range(first, last+1):
563 556 line = linecache.getline(filename, lineno)
564 557 if not line:
565 558 break
566 559
567 560 if lineno == self.curframe.f_lineno:
568 561 line = self.__format_line(
569 562 tpl_line_em, filename, lineno, line, arrow=True
570 563 )
571 564 else:
572 565 line = self.__format_line(
573 566 tpl_line, filename, lineno, line, arrow=False
574 567 )
575 568
576 569 src.append(line)
577 570 self.lineno = lineno
578 571
579 572 print(''.join(src), file=self.stdout)
580 573
581 574 except KeyboardInterrupt:
582 575 pass
583 576
584 577 def do_skip_predicates(self, args):
585 578 """
586 579 Turn on/off individual predicates as to whether a frame should be hidden/skip.
587 580
588 581 The global option to skip (or not) hidden frames is set with skip_hidden
589 582
590 583 To change the value of a predicate
591 584
592 585 skip_predicates key [true|false]
593 586
594 587 Call without arguments to see the current values.
595 588
596 589 To permanently change the value of an option add the corresponding
597 590 command to your ``~/.pdbrc`` file. If you are programmatically using the
598 591 Pdb instance you can also change the ``default_predicates`` class
599 592 attribute.
600 593 """
601 594 if not args.strip():
602 595 print("current predicates:")
603 596 for (p, v) in self._predicates.items():
604 597 print(" ", p, ":", v)
605 598 return
606 599 type_value = args.strip().split(" ")
607 600 if len(type_value) != 2:
608 601 print(
609 602 f"Usage: skip_predicates <type> <value>, with <type> one of {set(self._predicates.keys())}"
610 603 )
611 604 return
612 605
613 606 type_, value = type_value
614 607 if type_ not in self._predicates:
615 608 print(f"{type_!r} not in {set(self._predicates.keys())}")
616 609 return
617 610 if value.lower() not in ("true", "yes", "1", "no", "false", "0"):
618 611 print(
619 612 f"{value!r} is invalid - use one of ('true', 'yes', '1', 'no', 'false', '0')"
620 613 )
621 614 return
622 615
623 616 self._predicates[type_] = value.lower() in ("true", "yes", "1")
624 617 if not any(self._predicates.values()):
625 618 print(
626 619 "Warning, all predicates set to False, skip_hidden may not have any effects."
627 620 )
628 621
629 622 def do_skip_hidden(self, arg):
630 623 """
631 624 Change whether or not we should skip frames with the
632 625 __tracebackhide__ attribute.
633 626 """
634 627 if not arg.strip():
635 628 print(
636 629 f"skip_hidden = {self.skip_hidden}, use 'yes','no', 'true', or 'false' to change."
637 630 )
638 631 elif arg.strip().lower() in ("true", "yes"):
639 632 self.skip_hidden = True
640 633 elif arg.strip().lower() in ("false", "no"):
641 634 self.skip_hidden = False
642 635 if not any(self._predicates.values()):
643 636 print(
644 637 "Warning, all predicates set to False, skip_hidden may not have any effects."
645 638 )
646 639
647 640 def do_list(self, arg):
648 641 """Print lines of code from the current stack frame
649 642 """
650 643 self.lastcmd = 'list'
651 644 last = None
652 645 if arg:
653 646 try:
654 647 x = eval(arg, {}, {})
655 648 if type(x) == type(()):
656 649 first, last = x
657 650 first = int(first)
658 651 last = int(last)
659 652 if last < first:
660 653 # Assume it's a count
661 654 last = first + last
662 655 else:
663 656 first = max(1, int(x) - 5)
664 657 except:
665 658 print('*** Error in argument:', repr(arg), file=self.stdout)
666 659 return
667 660 elif self.lineno is None:
668 661 first = max(1, self.curframe.f_lineno - 5)
669 662 else:
670 663 first = self.lineno + 1
671 664 if last is None:
672 665 last = first + 10
673 666 self.print_list_lines(self.curframe.f_code.co_filename, first, last)
674 667
675 668 # vds: >>
676 669 lineno = first
677 670 filename = self.curframe.f_code.co_filename
678 671 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
679 672 # vds: <<
680 673
681 674 do_l = do_list
682 675
683 676 def getsourcelines(self, obj):
684 677 lines, lineno = inspect.findsource(obj)
685 678 if inspect.isframe(obj) and obj.f_globals is self._get_frame_locals(obj):
686 679 # must be a module frame: do not try to cut a block out of it
687 680 return lines, 1
688 681 elif inspect.ismodule(obj):
689 682 return lines, 1
690 683 return inspect.getblock(lines[lineno:]), lineno+1
691 684
692 685 def do_longlist(self, arg):
693 686 """Print lines of code from the current stack frame.
694 687
695 688 Shows more lines than 'list' does.
696 689 """
697 690 self.lastcmd = 'longlist'
698 691 try:
699 692 lines, lineno = self.getsourcelines(self.curframe)
700 693 except OSError as err:
701 694 self.error(err)
702 695 return
703 696 last = lineno + len(lines)
704 697 self.print_list_lines(self.curframe.f_code.co_filename, lineno, last)
705 698 do_ll = do_longlist
706 699
707 700 def do_debug(self, arg):
708 701 """debug code
709 702 Enter a recursive debugger that steps through the code
710 703 argument (which is an arbitrary expression or statement to be
711 704 executed in the current environment).
712 705 """
713 706 trace_function = sys.gettrace()
714 707 sys.settrace(None)
715 708 globals = self.curframe.f_globals
716 709 locals = self.curframe_locals
717 710 p = self.__class__(completekey=self.completekey,
718 711 stdin=self.stdin, stdout=self.stdout)
719 712 p.use_rawinput = self.use_rawinput
720 713 p.prompt = "(%s) " % self.prompt.strip()
721 714 self.message("ENTERING RECURSIVE DEBUGGER")
722 715 sys.call_tracing(p.run, (arg, globals, locals))
723 716 self.message("LEAVING RECURSIVE DEBUGGER")
724 717 sys.settrace(trace_function)
725 718 self.lastcmd = p.lastcmd
726 719
727 720 def do_pdef(self, arg):
728 721 """Print the call signature for any callable object.
729 722
730 723 The debugger interface to %pdef"""
731 724 namespaces = [
732 725 ("Locals", self.curframe_locals),
733 726 ("Globals", self.curframe.f_globals),
734 727 ]
735 728 self.shell.find_line_magic("pdef")(arg, namespaces=namespaces)
736 729
737 730 def do_pdoc(self, arg):
738 731 """Print the docstring for an object.
739 732
740 733 The debugger interface to %pdoc."""
741 734 namespaces = [
742 735 ("Locals", self.curframe_locals),
743 736 ("Globals", self.curframe.f_globals),
744 737 ]
745 738 self.shell.find_line_magic("pdoc")(arg, namespaces=namespaces)
746 739
747 740 def do_pfile(self, arg):
748 741 """Print (or run through pager) the file where an object is defined.
749 742
750 743 The debugger interface to %pfile.
751 744 """
752 745 namespaces = [
753 746 ("Locals", self.curframe_locals),
754 747 ("Globals", self.curframe.f_globals),
755 748 ]
756 749 self.shell.find_line_magic("pfile")(arg, namespaces=namespaces)
757 750
758 751 def do_pinfo(self, arg):
759 752 """Provide detailed information about an object.
760 753
761 754 The debugger interface to %pinfo, i.e., obj?."""
762 755 namespaces = [
763 756 ("Locals", self.curframe_locals),
764 757 ("Globals", self.curframe.f_globals),
765 758 ]
766 759 self.shell.find_line_magic("pinfo")(arg, namespaces=namespaces)
767 760
768 761 def do_pinfo2(self, arg):
769 762 """Provide extra detailed information about an object.
770 763
771 764 The debugger interface to %pinfo2, i.e., obj??."""
772 765 namespaces = [
773 766 ("Locals", self.curframe_locals),
774 767 ("Globals", self.curframe.f_globals),
775 768 ]
776 769 self.shell.find_line_magic("pinfo2")(arg, namespaces=namespaces)
777 770
778 771 def do_psource(self, arg):
779 772 """Print (or run through pager) the source code for an object."""
780 773 namespaces = [
781 774 ("Locals", self.curframe_locals),
782 775 ("Globals", self.curframe.f_globals),
783 776 ]
784 777 self.shell.find_line_magic("psource")(arg, namespaces=namespaces)
785 778
786 779 def do_where(self, arg):
787 780 """w(here)
788 781 Print a stack trace, with the most recent frame at the bottom.
789 782 An arrow indicates the "current frame", which determines the
790 783 context of most commands. 'bt' is an alias for this command.
791 784
792 785 Take a number as argument as an (optional) number of context line to
793 786 print"""
794 787 if arg:
795 788 try:
796 789 context = int(arg)
797 790 except ValueError as err:
798 791 self.error(err)
799 792 return
800 793 self.print_stack_trace(context)
801 794 else:
802 795 self.print_stack_trace()
803 796
804 797 do_w = do_where
805 798
806 799 def break_anywhere(self, frame):
807 800 """
808 801
809 802 _stop_in_decorator_internals is overly restrictive, as we may still want
810 803 to trace function calls, so we need to also update break_anywhere so
811 804 that is we don't `stop_here`, because of debugger skip, we may still
812 805 stop at any point inside the function
813 806
814 807 """
815 808
816 809 sup = super().break_anywhere(frame)
817 810 if sup:
818 811 return sup
819 812 if self._predicates["debuggerskip"]:
820 813 if DEBUGGERSKIP in frame.f_code.co_varnames:
821 814 return True
822 815 if frame.f_back and self._get_frame_locals(frame.f_back).get(DEBUGGERSKIP):
823 816 return True
824 817 return False
825 818
826 819 def _is_in_decorator_internal_and_should_skip(self, frame):
827 820 """
828 821 Utility to tell us whether we are in a decorator internal and should stop.
829 822
830 823
831 824
832 825 """
833 826
834 827 # if we are disabled don't skip
835 828 if not self._predicates["debuggerskip"]:
836 829 return False
837 830
838 831 # if frame is tagged, skip by default.
839 832 if DEBUGGERSKIP in frame.f_code.co_varnames:
840 833 return True
841 834
842 835 # if one of the parent frame value set to True skip as well.
843 836
844 837 cframe = frame
845 838 while getattr(cframe, "f_back", None):
846 839 cframe = cframe.f_back
847 840 if self._get_frame_locals(cframe).get(DEBUGGERSKIP):
848 841 return True
849 842
850 843 return False
851 844
852 845 def stop_here(self, frame):
853 846
854 847 if self._is_in_decorator_internal_and_should_skip(frame) is True:
855 848 return False
856 849
857 850 hidden = False
858 851 if self.skip_hidden:
859 852 hidden = self._hidden_predicate(frame)
860 853 if hidden:
861 854 if self.report_skipped:
862 855 Colors = self.color_scheme_table.active_colors
863 856 ColorsNormal = Colors.Normal
864 857 print(
865 858 f"{Colors.excName} [... skipped 1 hidden frame]{ColorsNormal}\n"
866 859 )
867 860 return super().stop_here(frame)
868 861
869 862 def do_up(self, arg):
870 863 """u(p) [count]
871 864 Move the current frame count (default one) levels up in the
872 865 stack trace (to an older frame).
873 866
874 867 Will skip hidden frames.
875 868 """
876 869 # modified version of upstream that skips
877 870 # frames with __tracebackhide__
878 871 if self.curindex == 0:
879 872 self.error("Oldest frame")
880 873 return
881 874 try:
882 875 count = int(arg or 1)
883 876 except ValueError:
884 877 self.error("Invalid frame count (%s)" % arg)
885 878 return
886 879 skipped = 0
887 880 if count < 0:
888 881 _newframe = 0
889 882 else:
890 883 counter = 0
891 884 hidden_frames = self.hidden_frames(self.stack)
892 885 for i in range(self.curindex - 1, -1, -1):
893 886 if hidden_frames[i] and self.skip_hidden:
894 887 skipped += 1
895 888 continue
896 889 counter += 1
897 890 if counter >= count:
898 891 break
899 892 else:
900 893 # if no break occurred.
901 894 self.error(
902 895 "all frames above hidden, use `skip_hidden False` to get get into those."
903 896 )
904 897 return
905 898
906 899 Colors = self.color_scheme_table.active_colors
907 900 ColorsNormal = Colors.Normal
908 901 _newframe = i
909 902 self._select_frame(_newframe)
910 903 if skipped:
911 904 print(
912 905 f"{Colors.excName} [... skipped {skipped} hidden frame(s)]{ColorsNormal}\n"
913 906 )
914 907
915 908 def do_down(self, arg):
916 909 """d(own) [count]
917 910 Move the current frame count (default one) levels down in the
918 911 stack trace (to a newer frame).
919 912
920 913 Will skip hidden frames.
921 914 """
922 915 if self.curindex + 1 == len(self.stack):
923 916 self.error("Newest frame")
924 917 return
925 918 try:
926 919 count = int(arg or 1)
927 920 except ValueError:
928 921 self.error("Invalid frame count (%s)" % arg)
929 922 return
930 923 if count < 0:
931 924 _newframe = len(self.stack) - 1
932 925 else:
933 926 counter = 0
934 927 skipped = 0
935 928 hidden_frames = self.hidden_frames(self.stack)
936 929 for i in range(self.curindex + 1, len(self.stack)):
937 930 if hidden_frames[i] and self.skip_hidden:
938 931 skipped += 1
939 932 continue
940 933 counter += 1
941 934 if counter >= count:
942 935 break
943 936 else:
944 937 self.error(
945 938 "all frames below hidden, use `skip_hidden False` to get get into those."
946 939 )
947 940 return
948 941
949 942 Colors = self.color_scheme_table.active_colors
950 943 ColorsNormal = Colors.Normal
951 944 if skipped:
952 945 print(
953 946 f"{Colors.excName} [... skipped {skipped} hidden frame(s)]{ColorsNormal}\n"
954 947 )
955 948 _newframe = i
956 949
957 950 self._select_frame(_newframe)
958 951
959 952 do_d = do_down
960 953 do_u = do_up
961 954
962 955 def do_context(self, context):
963 956 """context number_of_lines
964 957 Set the number of lines of source code to show when displaying
965 958 stacktrace information.
966 959 """
967 960 try:
968 961 new_context = int(context)
969 962 if new_context <= 0:
970 963 raise ValueError()
971 964 self.context = new_context
972 965 except ValueError:
973 966 self.error("The 'context' command requires a positive integer argument.")
974 967
975 968
976 969 class InterruptiblePdb(Pdb):
977 970 """Version of debugger where KeyboardInterrupt exits the debugger altogether."""
978 971
979 972 def cmdloop(self, intro=None):
980 973 """Wrap cmdloop() such that KeyboardInterrupt stops the debugger."""
981 974 try:
982 975 return OldPdb.cmdloop(self, intro=intro)
983 976 except KeyboardInterrupt:
984 977 self.stop_here = lambda frame: False
985 978 self.do_quit("")
986 979 sys.settrace(None)
987 980 self.quitting = False
988 981 raise
989 982
990 983 def _cmdloop(self):
991 984 while True:
992 985 try:
993 986 # keyboard interrupts allow for an easy way to cancel
994 987 # the current command, so allow them during interactive input
995 988 self.allow_kbdint = True
996 989 self.cmdloop()
997 990 self.allow_kbdint = False
998 991 break
999 992 except KeyboardInterrupt:
1000 993 self.message('--KeyboardInterrupt--')
1001 994 raise
1002 995
1003 996
1004 997 def set_trace(frame=None):
1005 998 """
1006 999 Start debugging from `frame`.
1007 1000
1008 1001 If frame is not specified, debugging starts from caller's frame.
1009 1002 """
1010 1003 Pdb().set_trace(frame or sys._getframe().f_back)
@@ -1,1026 +1,1024 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 from io import StringIO
19 19
20 20 from decorator import decorator
21 21
22 22 from traitlets.config.configurable import Configurable
23 23 from .getipython import get_ipython
24 24 from ..utils.sentinel import Sentinel
25 25 from ..utils.dir2 import get_real_method
26 26 from ..lib import pretty
27 27 from traitlets import (
28 28 Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List,
29 29 ForwardDeclaredInstance,
30 30 default, observe,
31 31 )
32 32
33 33
34 34 class DisplayFormatter(Configurable):
35 35
36 36 active_types = List(Unicode(),
37 37 help="""List of currently active mime-types to display.
38 38 You can use this to set a white-list for formats to display.
39 39
40 40 Most users will not need to change this value.
41 41 """).tag(config=True)
42 42
43 43 @default('active_types')
44 44 def _active_types_default(self):
45 45 return self.format_types
46 46
47 47 @observe('active_types')
48 48 def _active_types_changed(self, change):
49 49 for key, formatter in self.formatters.items():
50 50 if key in change['new']:
51 51 formatter.enabled = True
52 52 else:
53 53 formatter.enabled = False
54 54
55 55 ipython_display_formatter = ForwardDeclaredInstance('FormatterABC')
56 56 @default('ipython_display_formatter')
57 57 def _default_formatter(self):
58 58 return IPythonDisplayFormatter(parent=self)
59 59
60 60 mimebundle_formatter = ForwardDeclaredInstance('FormatterABC')
61 61 @default('mimebundle_formatter')
62 62 def _default_mime_formatter(self):
63 63 return MimeBundleFormatter(parent=self)
64 64
65 65 # A dict of formatter whose keys are format types (MIME types) and whose
66 66 # values are subclasses of BaseFormatter.
67 67 formatters = Dict()
68 68 @default('formatters')
69 69 def _formatters_default(self):
70 70 """Activate the default formatters."""
71 71 formatter_classes = [
72 72 PlainTextFormatter,
73 73 HTMLFormatter,
74 74 MarkdownFormatter,
75 75 SVGFormatter,
76 76 PNGFormatter,
77 77 PDFFormatter,
78 78 JPEGFormatter,
79 79 LatexFormatter,
80 80 JSONFormatter,
81 81 JavascriptFormatter
82 82 ]
83 83 d = {}
84 84 for cls in formatter_classes:
85 85 f = cls(parent=self)
86 86 d[f.format_type] = f
87 87 return d
88 88
89 89 def format(self, obj, include=None, exclude=None):
90 90 """Return a format data dict for an object.
91 91
92 92 By default all format types will be computed.
93 93
94 94 The following MIME types are usually implemented:
95 95
96 96 * text/plain
97 97 * text/html
98 98 * text/markdown
99 99 * text/latex
100 100 * application/json
101 101 * application/javascript
102 102 * application/pdf
103 103 * image/png
104 104 * image/jpeg
105 105 * image/svg+xml
106 106
107 107 Parameters
108 108 ----------
109 109 obj : object
110 110 The Python object whose format data will be computed.
111 111 include : list, tuple or set; optional
112 112 A list of format type strings (MIME types) to include in the
113 113 format data dict. If this is set *only* the format types included
114 114 in this list will be computed.
115 115 exclude : list, tuple or set; optional
116 116 A list of format type string (MIME types) to exclude in the format
117 117 data dict. If this is set all format types will be computed,
118 118 except for those included in this argument.
119 119 Mimetypes present in exclude will take precedence over the ones in include
120 120
121 121 Returns
122 122 -------
123 123 (format_dict, metadata_dict) : tuple of two dicts
124 124 format_dict is a dictionary of key/value pairs, one of each format that was
125 125 generated for the object. The keys are the format types, which
126 126 will usually be MIME type strings and the values and JSON'able
127 127 data structure containing the raw data for the representation in
128 128 that format.
129 129
130 130 metadata_dict is a dictionary of metadata about each mime-type output.
131 131 Its keys will be a strict subset of the keys in format_dict.
132 132
133 133 Notes
134 134 -----
135 135 If an object implement `_repr_mimebundle_` as well as various
136 136 `_repr_*_`, the data returned by `_repr_mimebundle_` will take
137 137 precedence and the corresponding `_repr_*_` for this mimetype will
138 138 not be called.
139 139
140 140 """
141 141 format_dict = {}
142 142 md_dict = {}
143 143
144 144 if self.ipython_display_formatter(obj):
145 145 # object handled itself, don't proceed
146 146 return {}, {}
147 147
148 148 format_dict, md_dict = self.mimebundle_formatter(obj, include=include, exclude=exclude)
149 149
150 150 if format_dict or md_dict:
151 151 if include:
152 152 format_dict = {k:v for k,v in format_dict.items() if k in include}
153 153 md_dict = {k:v for k,v in md_dict.items() if k in include}
154 154 if exclude:
155 155 format_dict = {k:v for k,v in format_dict.items() if k not in exclude}
156 156 md_dict = {k:v for k,v in md_dict.items() if k not in exclude}
157 157
158 158 for format_type, formatter in self.formatters.items():
159 159 if format_type in format_dict:
160 160 # already got it from mimebundle, maybe don't render again.
161 161 # exception: manually registered per-mime renderer
162 162 # check priority:
163 163 # 1. user-registered per-mime formatter
164 164 # 2. mime-bundle (user-registered or repr method)
165 165 # 3. default per-mime formatter (e.g. repr method)
166 166 try:
167 167 formatter.lookup(obj)
168 168 except KeyError:
169 169 # no special formatter, use mime-bundle-provided value
170 170 continue
171 171 if include and format_type not in include:
172 172 continue
173 173 if exclude and format_type in exclude:
174 174 continue
175 175
176 176 md = None
177 177 try:
178 178 data = formatter(obj)
179 179 except:
180 180 # FIXME: log the exception
181 181 raise
182 182
183 183 # formatters can return raw data or (data, metadata)
184 184 if isinstance(data, tuple) and len(data) == 2:
185 185 data, md = data
186 186
187 187 if data is not None:
188 188 format_dict[format_type] = data
189 189 if md is not None:
190 190 md_dict[format_type] = md
191 191 return format_dict, md_dict
192 192
193 193 @property
194 194 def format_types(self):
195 195 """Return the format types (MIME types) of the active formatters."""
196 196 return list(self.formatters.keys())
197 197
198 198
199 199 #-----------------------------------------------------------------------------
200 200 # Formatters for specific format types (text, html, svg, etc.)
201 201 #-----------------------------------------------------------------------------
202 202
203 203
204 204 def _safe_repr(obj):
205 205 """Try to return a repr of an object
206 206
207 207 always returns a string, at least.
208 208 """
209 209 try:
210 210 return repr(obj)
211 211 except Exception as e:
212 212 return "un-repr-able object (%r)" % e
213 213
214 214
215 215 class FormatterWarning(UserWarning):
216 216 """Warning class for errors in formatters"""
217 217
218 218 @decorator
219 219 def catch_format_error(method, self, *args, **kwargs):
220 220 """show traceback on failed format call"""
221 221 try:
222 222 r = method(self, *args, **kwargs)
223 223 except NotImplementedError:
224 224 # don't warn on NotImplementedErrors
225 225 return self._check_return(None, args[0])
226 226 except Exception:
227 227 exc_info = sys.exc_info()
228 228 ip = get_ipython()
229 229 if ip is not None:
230 230 ip.showtraceback(exc_info)
231 231 else:
232 232 traceback.print_exception(*exc_info)
233 233 return self._check_return(None, args[0])
234 234 return self._check_return(r, args[0])
235 235
236 236
237 237 class FormatterABC(metaclass=abc.ABCMeta):
238 238 """ Abstract base class for Formatters.
239 239
240 240 A formatter is a callable class that is responsible for computing the
241 241 raw format data for a particular format type (MIME type). For example,
242 242 an HTML formatter would have a format type of `text/html` and would return
243 243 the HTML representation of the object when called.
244 244 """
245 245
246 246 # The format type of the data returned, usually a MIME type.
247 247 format_type = 'text/plain'
248 248
249 249 # Is the formatter enabled...
250 250 enabled = True
251 251
252 252 @abc.abstractmethod
253 253 def __call__(self, obj):
254 254 """Return a JSON'able representation of the object.
255 255
256 256 If the object cannot be formatted by this formatter,
257 257 warn and return None.
258 258 """
259 259 return repr(obj)
260 260
261 261
262 262 def _mod_name_key(typ):
263 263 """Return a (__module__, __name__) tuple for a type.
264 264
265 265 Used as key in Formatter.deferred_printers.
266 266 """
267 267 module = getattr(typ, '__module__', None)
268 268 name = getattr(typ, '__name__', None)
269 269 return (module, name)
270 270
271 271
272 272 def _get_type(obj):
273 273 """Return the type of an instance (old and new-style)"""
274 274 return getattr(obj, '__class__', None) or type(obj)
275 275
276 276
277 277 _raise_key_error = Sentinel('_raise_key_error', __name__,
278 278 """
279 279 Special value to raise a KeyError
280 280
281 281 Raise KeyError in `BaseFormatter.pop` if passed as the default value to `pop`
282 282 """)
283 283
284 284
285 285 class BaseFormatter(Configurable):
286 286 """A base formatter class that is configurable.
287 287
288 288 This formatter should usually be used as the base class of all formatters.
289 289 It is a traited :class:`Configurable` class and includes an extensible
290 290 API for users to determine how their objects are formatted. The following
291 291 logic is used to find a function to format an given object.
292 292
293 293 1. The object is introspected to see if it has a method with the name
294 294 :attr:`print_method`. If is does, that object is passed to that method
295 295 for formatting.
296 296 2. If no print method is found, three internal dictionaries are consulted
297 297 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
298 298 and :attr:`deferred_printers`.
299 299
300 300 Users should use these dictionaries to register functions that will be
301 301 used to compute the format data for their objects (if those objects don't
302 302 have the special print methods). The easiest way of using these
303 303 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
304 304 methods.
305 305
306 306 If no function/callable is found to compute the format data, ``None`` is
307 307 returned and this format type is not used.
308 308 """
309 309
310 310 format_type = Unicode('text/plain')
311 311 _return_type = str
312 312
313 313 enabled = Bool(True).tag(config=True)
314 314
315 315 print_method = ObjectName('__repr__')
316 316
317 317 # The singleton printers.
318 318 # Maps the IDs of the builtin singleton objects to the format functions.
319 319 singleton_printers = Dict().tag(config=True)
320 320
321 321 # The type-specific printers.
322 322 # Map type objects to the format functions.
323 323 type_printers = Dict().tag(config=True)
324 324
325 325 # The deferred-import type-specific printers.
326 326 # Map (modulename, classname) pairs to the format functions.
327 327 deferred_printers = Dict().tag(config=True)
328 328
329 329 @catch_format_error
330 330 def __call__(self, obj):
331 331 """Compute the format for an object."""
332 332 if self.enabled:
333 333 # lookup registered printer
334 334 try:
335 335 printer = self.lookup(obj)
336 336 except KeyError:
337 337 pass
338 338 else:
339 339 return printer(obj)
340 340 # Finally look for special method names
341 341 method = get_real_method(obj, self.print_method)
342 342 if method is not None:
343 343 return method()
344 344 return None
345 345 else:
346 346 return None
347 347
348 348 def __contains__(self, typ):
349 349 """map in to lookup_by_type"""
350 350 try:
351 351 self.lookup_by_type(typ)
352 352 except KeyError:
353 353 return False
354 354 else:
355 355 return True
356 356
357 357 def _check_return(self, r, obj):
358 358 """Check that a return value is appropriate
359 359
360 360 Return the value if so, None otherwise, warning if invalid.
361 361 """
362 362 if r is None or isinstance(r, self._return_type) or \
363 363 (isinstance(r, tuple) and r and isinstance(r[0], self._return_type)):
364 364 return r
365 365 else:
366 366 warnings.warn(
367 367 "%s formatter returned invalid type %s (expected %s) for object: %s" % \
368 368 (self.format_type, type(r), self._return_type, _safe_repr(obj)),
369 369 FormatterWarning
370 370 )
371 371
372 372 def lookup(self, obj):
373 373 """Look up the formatter for a given instance.
374 374
375 375 Parameters
376 376 ----------
377 377 obj : object instance
378 378
379 379 Returns
380 380 -------
381 381 f : callable
382 382 The registered formatting callable for the type.
383 383
384 384 Raises
385 385 ------
386 386 KeyError if the type has not been registered.
387 387 """
388 388 # look for singleton first
389 389 obj_id = id(obj)
390 390 if obj_id in self.singleton_printers:
391 391 return self.singleton_printers[obj_id]
392 392 # then lookup by type
393 393 return self.lookup_by_type(_get_type(obj))
394 394
395 395 def lookup_by_type(self, typ):
396 396 """Look up the registered formatter for a type.
397 397
398 398 Parameters
399 399 ----------
400 400 typ : type or '__module__.__name__' string for a type
401 401
402 402 Returns
403 403 -------
404 404 f : callable
405 405 The registered formatting callable for the type.
406 406
407 407 Raises
408 408 ------
409 409 KeyError if the type has not been registered.
410 410 """
411 411 if isinstance(typ, str):
412 412 typ_key = tuple(typ.rsplit('.',1))
413 413 if typ_key not in self.deferred_printers:
414 414 # We may have it cached in the type map. We will have to
415 415 # iterate over all of the types to check.
416 416 for cls in self.type_printers:
417 417 if _mod_name_key(cls) == typ_key:
418 418 return self.type_printers[cls]
419 419 else:
420 420 return self.deferred_printers[typ_key]
421 421 else:
422 422 for cls in pretty._get_mro(typ):
423 423 if cls in self.type_printers or self._in_deferred_types(cls):
424 424 return self.type_printers[cls]
425 425
426 426 # If we have reached here, the lookup failed.
427 427 raise KeyError("No registered printer for {0!r}".format(typ))
428 428
429 429 def for_type(self, typ, func=None):
430 430 """Add a format function for a given type.
431 431
432 432 Parameters
433 433 ----------
434 434 typ : type or '__module__.__name__' string for a type
435 435 The class of the object that will be formatted using `func`.
436 436 func : callable
437 437 A callable for computing the format data.
438 438 `func` will be called with the object to be formatted,
439 439 and will return the raw data in this formatter's format.
440 440 Subclasses may use a different call signature for the
441 441 `func` argument.
442 442
443 443 If `func` is None or not specified, there will be no change,
444 444 only returning the current value.
445 445
446 446 Returns
447 447 -------
448 448 oldfunc : callable
449 449 The currently registered callable.
450 450 If you are registering a new formatter,
451 451 this will be the previous value (to enable restoring later).
452 452 """
453 453 # if string given, interpret as 'pkg.module.class_name'
454 454 if isinstance(typ, str):
455 455 type_module, type_name = typ.rsplit('.', 1)
456 456 return self.for_type_by_name(type_module, type_name, func)
457 457
458 458 try:
459 459 oldfunc = self.lookup_by_type(typ)
460 460 except KeyError:
461 461 oldfunc = None
462 462
463 463 if func is not None:
464 464 self.type_printers[typ] = func
465 465
466 466 return oldfunc
467 467
468 468 def for_type_by_name(self, type_module, type_name, func=None):
469 469 """Add a format function for a type specified by the full dotted
470 470 module and name of the type, rather than the type of the object.
471 471
472 472 Parameters
473 473 ----------
474 474 type_module : str
475 475 The full dotted name of the module the type is defined in, like
476 476 ``numpy``.
477 477 type_name : str
478 478 The name of the type (the class name), like ``dtype``
479 479 func : callable
480 480 A callable for computing the format data.
481 481 `func` will be called with the object to be formatted,
482 482 and will return the raw data in this formatter's format.
483 483 Subclasses may use a different call signature for the
484 484 `func` argument.
485 485
486 486 If `func` is None or unspecified, there will be no change,
487 487 only returning the current value.
488 488
489 489 Returns
490 490 -------
491 491 oldfunc : callable
492 492 The currently registered callable.
493 493 If you are registering a new formatter,
494 494 this will be the previous value (to enable restoring later).
495 495 """
496 496 key = (type_module, type_name)
497 497
498 498 try:
499 499 oldfunc = self.lookup_by_type("%s.%s" % key)
500 500 except KeyError:
501 501 oldfunc = None
502 502
503 503 if func is not None:
504 504 self.deferred_printers[key] = func
505 505 return oldfunc
506 506
507 507 def pop(self, typ, default=_raise_key_error):
508 508 """Pop a formatter for the given type.
509 509
510 510 Parameters
511 511 ----------
512 512 typ : type or '__module__.__name__' string for a type
513 513 default : object
514 514 value to be returned if no formatter is registered for typ.
515 515
516 516 Returns
517 517 -------
518 518 obj : object
519 519 The last registered object for the type.
520 520
521 521 Raises
522 522 ------
523 523 KeyError if the type is not registered and default is not specified.
524 524 """
525 525
526 526 if isinstance(typ, str):
527 527 typ_key = tuple(typ.rsplit('.',1))
528 528 if typ_key not in self.deferred_printers:
529 529 # We may have it cached in the type map. We will have to
530 530 # iterate over all of the types to check.
531 531 for cls in self.type_printers:
532 532 if _mod_name_key(cls) == typ_key:
533 533 old = self.type_printers.pop(cls)
534 534 break
535 535 else:
536 536 old = default
537 537 else:
538 538 old = self.deferred_printers.pop(typ_key)
539 539 else:
540 540 if typ in self.type_printers:
541 541 old = self.type_printers.pop(typ)
542 542 else:
543 543 old = self.deferred_printers.pop(_mod_name_key(typ), default)
544 544 if old is _raise_key_error:
545 545 raise KeyError("No registered value for {0!r}".format(typ))
546 546 return old
547 547
548 548 def _in_deferred_types(self, cls):
549 549 """
550 550 Check if the given class is specified in the deferred type registry.
551 551
552 552 Successful matches will be moved to the regular type registry for future use.
553 553 """
554 554 mod = getattr(cls, '__module__', None)
555 555 name = getattr(cls, '__name__', None)
556 556 key = (mod, name)
557 557 if key in self.deferred_printers:
558 558 # Move the printer over to the regular registry.
559 559 printer = self.deferred_printers.pop(key)
560 560 self.type_printers[cls] = printer
561 561 return True
562 562 return False
563 563
564 564
565 565 class PlainTextFormatter(BaseFormatter):
566 566 """The default pretty-printer.
567 567
568 568 This uses :mod:`IPython.lib.pretty` to compute the format data of
569 569 the object. If the object cannot be pretty printed, :func:`repr` is used.
570 570 See the documentation of :mod:`IPython.lib.pretty` for details on
571 571 how to write pretty printers. Here is a simple example::
572 572
573 573 def dtype_pprinter(obj, p, cycle):
574 574 if cycle:
575 575 return p.text('dtype(...)')
576 576 if hasattr(obj, 'fields'):
577 577 if obj.fields is None:
578 578 p.text(repr(obj))
579 579 else:
580 580 p.begin_group(7, 'dtype([')
581 581 for i, field in enumerate(obj.descr):
582 582 if i > 0:
583 583 p.text(',')
584 584 p.breakable()
585 585 p.pretty(field)
586 586 p.end_group(7, '])')
587 587 """
588 588
589 589 # The format type of data returned.
590 590 format_type = Unicode('text/plain')
591 591
592 592 # This subclass ignores this attribute as it always need to return
593 593 # something.
594 594 enabled = Bool(True).tag(config=False)
595 595
596 596 max_seq_length = Integer(pretty.MAX_SEQ_LENGTH,
597 597 help="""Truncate large collections (lists, dicts, tuples, sets) to this size.
598 598
599 599 Set to 0 to disable truncation.
600 600 """
601 601 ).tag(config=True)
602 602
603 603 # Look for a _repr_pretty_ methods to use for pretty printing.
604 604 print_method = ObjectName('_repr_pretty_')
605 605
606 606 # Whether to pretty-print or not.
607 607 pprint = Bool(True).tag(config=True)
608 608
609 609 # Whether to be verbose or not.
610 610 verbose = Bool(False).tag(config=True)
611 611
612 612 # The maximum width.
613 613 max_width = Integer(79).tag(config=True)
614 614
615 615 # The newline character.
616 616 newline = Unicode('\n').tag(config=True)
617 617
618 618 # format-string for pprinting floats
619 619 float_format = Unicode('%r')
620 620 # setter for float precision, either int or direct format-string
621 621 float_precision = CUnicode('').tag(config=True)
622 622
623 623 @observe('float_precision')
624 624 def _float_precision_changed(self, change):
625 625 """float_precision changed, set float_format accordingly.
626 626
627 627 float_precision can be set by int or str.
628 628 This will set float_format, after interpreting input.
629 629 If numpy has been imported, numpy print precision will also be set.
630 630
631 631 integer `n` sets format to '%.nf', otherwise, format set directly.
632 632
633 633 An empty string returns to defaults (repr for float, 8 for numpy).
634 634
635 635 This parameter can be set via the '%precision' magic.
636 636 """
637 637 new = change['new']
638 638 if '%' in new:
639 639 # got explicit format string
640 640 fmt = new
641 641 try:
642 642 fmt%3.14159
643 643 except Exception as e:
644 644 raise ValueError("Precision must be int or format string, not %r"%new) from e
645 645 elif new:
646 646 # otherwise, should be an int
647 647 try:
648 648 i = int(new)
649 649 assert i >= 0
650 650 except ValueError as e:
651 651 raise ValueError("Precision must be int or format string, not %r"%new) from e
652 652 except AssertionError as e:
653 653 raise ValueError("int precision must be non-negative, not %r"%i) from e
654 654
655 655 fmt = '%%.%if'%i
656 656 if 'numpy' in sys.modules:
657 657 # set numpy precision if it has been imported
658 658 import numpy
659 659 numpy.set_printoptions(precision=i)
660 660 else:
661 661 # default back to repr
662 662 fmt = '%r'
663 663 if 'numpy' in sys.modules:
664 664 import numpy
665 665 # numpy default is 8
666 666 numpy.set_printoptions(precision=8)
667 667 self.float_format = fmt
668 668
669 669 # Use the default pretty printers from IPython.lib.pretty.
670 670 @default('singleton_printers')
671 671 def _singleton_printers_default(self):
672 672 return pretty._singleton_pprinters.copy()
673 673
674 674 @default('type_printers')
675 675 def _type_printers_default(self):
676 676 d = pretty._type_pprinters.copy()
677 677 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
678 678 # if NumPy is used, set precision for its float64 type
679 679 if "numpy" in sys.modules:
680 680 import numpy
681 681
682 682 d[numpy.float64] = lambda obj, p, cycle: p.text(self.float_format % obj)
683 683 return d
684 684
685 685 @default('deferred_printers')
686 686 def _deferred_printers_default(self):
687 687 return pretty._deferred_type_pprinters.copy()
688 688
689 689 #### FormatterABC interface ####
690 690
691 691 @catch_format_error
692 692 def __call__(self, obj):
693 693 """Compute the pretty representation of the object."""
694 694 if not self.pprint:
695 695 return repr(obj)
696 696 else:
697 697 stream = StringIO()
698 698 printer = pretty.RepresentationPrinter(stream, self.verbose,
699 699 self.max_width, self.newline,
700 700 max_seq_length=self.max_seq_length,
701 701 singleton_pprinters=self.singleton_printers,
702 702 type_pprinters=self.type_printers,
703 703 deferred_pprinters=self.deferred_printers)
704 704 printer.pretty(obj)
705 705 printer.flush()
706 706 return stream.getvalue()
707 707
708 708
709 709 class HTMLFormatter(BaseFormatter):
710 710 """An HTML formatter.
711 711
712 712 To define the callables that compute the HTML representation of your
713 713 objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
714 714 or :meth:`for_type_by_name` methods to register functions that handle
715 715 this.
716 716
717 717 The return value of this formatter should be a valid HTML snippet that
718 718 could be injected into an existing DOM. It should *not* include the
719 719 ```<html>`` or ```<body>`` tags.
720 720 """
721 721 format_type = Unicode('text/html')
722 722
723 723 print_method = ObjectName('_repr_html_')
724 724
725 725
726 726 class MarkdownFormatter(BaseFormatter):
727 727 """A Markdown formatter.
728 728
729 729 To define the callables that compute the Markdown representation of your
730 730 objects, define a :meth:`_repr_markdown_` method or use the :meth:`for_type`
731 731 or :meth:`for_type_by_name` methods to register functions that handle
732 732 this.
733 733
734 734 The return value of this formatter should be a valid Markdown.
735 735 """
736 736 format_type = Unicode('text/markdown')
737 737
738 738 print_method = ObjectName('_repr_markdown_')
739 739
740 740 class SVGFormatter(BaseFormatter):
741 741 """An SVG formatter.
742 742
743 743 To define the callables that compute the SVG representation of your
744 744 objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
745 745 or :meth:`for_type_by_name` methods to register functions that handle
746 746 this.
747 747
748 748 The return value of this formatter should be valid SVG enclosed in
749 749 ```<svg>``` tags, that could be injected into an existing DOM. It should
750 750 *not* include the ```<html>`` or ```<body>`` tags.
751 751 """
752 752 format_type = Unicode('image/svg+xml')
753 753
754 754 print_method = ObjectName('_repr_svg_')
755 755
756 756
757 757 class PNGFormatter(BaseFormatter):
758 758 """A PNG formatter.
759 759
760 760 To define the callables that compute the PNG representation of your
761 761 objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
762 762 or :meth:`for_type_by_name` methods to register functions that handle
763 763 this.
764 764
765 765 The return value of this formatter should be raw PNG data, *not*
766 766 base64 encoded.
767 767 """
768 768 format_type = Unicode('image/png')
769 769
770 770 print_method = ObjectName('_repr_png_')
771 771
772 772 _return_type = (bytes, str)
773 773
774 774
775 775 class JPEGFormatter(BaseFormatter):
776 776 """A JPEG formatter.
777 777
778 778 To define the callables that compute the JPEG representation of your
779 779 objects, define a :meth:`_repr_jpeg_` method or use the :meth:`for_type`
780 780 or :meth:`for_type_by_name` methods to register functions that handle
781 781 this.
782 782
783 783 The return value of this formatter should be raw JPEG data, *not*
784 784 base64 encoded.
785 785 """
786 786 format_type = Unicode('image/jpeg')
787 787
788 788 print_method = ObjectName('_repr_jpeg_')
789 789
790 790 _return_type = (bytes, str)
791 791
792 792
793 793 class LatexFormatter(BaseFormatter):
794 794 """A LaTeX formatter.
795 795
796 796 To define the callables that compute the LaTeX representation of your
797 797 objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
798 798 or :meth:`for_type_by_name` methods to register functions that handle
799 799 this.
800 800
801 801 The return value of this formatter should be a valid LaTeX equation,
802 802 enclosed in either ```$```, ```$$``` or another LaTeX equation
803 803 environment.
804 804 """
805 805 format_type = Unicode('text/latex')
806 806
807 807 print_method = ObjectName('_repr_latex_')
808 808
809 809
810 810 class JSONFormatter(BaseFormatter):
811 811 """A JSON string formatter.
812 812
813 813 To define the callables that compute the JSONable representation of
814 814 your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
815 815 or :meth:`for_type_by_name` methods to register functions that handle
816 816 this.
817 817
818 818 The return value of this formatter should be a JSONable list or dict.
819 819 JSON scalars (None, number, string) are not allowed, only dict or list containers.
820 820 """
821 821 format_type = Unicode('application/json')
822 822 _return_type = (list, dict)
823 823
824 824 print_method = ObjectName('_repr_json_')
825 825
826 826 def _check_return(self, r, obj):
827 827 """Check that a return value is appropriate
828 828
829 829 Return the value if so, None otherwise, warning if invalid.
830 830 """
831 831 if r is None:
832 832 return
833 833 md = None
834 834 if isinstance(r, tuple):
835 835 # unpack data, metadata tuple for type checking on first element
836 836 r, md = r
837
838 # handle deprecated JSON-as-string form from IPython < 3
839 if isinstance(r, str):
840 warnings.warn("JSON expects JSONable list/dict containers, not JSON strings",
841 FormatterWarning)
842 r = json.loads(r)
843
837
838 assert not isinstance(
839 r, str
840 ), "JSON-as-string has been deprecated since IPython < 3"
841
844 842 if md is not None:
845 843 # put the tuple back together
846 844 r = (r, md)
847 845 return super(JSONFormatter, self)._check_return(r, obj)
848 846
849 847
850 848 class JavascriptFormatter(BaseFormatter):
851 849 """A Javascript formatter.
852 850
853 851 To define the callables that compute the Javascript representation of
854 852 your objects, define a :meth:`_repr_javascript_` method or use the
855 853 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
856 854 that handle this.
857 855
858 856 The return value of this formatter should be valid Javascript code and
859 857 should *not* be enclosed in ```<script>``` tags.
860 858 """
861 859 format_type = Unicode('application/javascript')
862 860
863 861 print_method = ObjectName('_repr_javascript_')
864 862
865 863
866 864 class PDFFormatter(BaseFormatter):
867 865 """A PDF formatter.
868 866
869 867 To define the callables that compute the PDF representation of your
870 868 objects, define a :meth:`_repr_pdf_` method or use the :meth:`for_type`
871 869 or :meth:`for_type_by_name` methods to register functions that handle
872 870 this.
873 871
874 872 The return value of this formatter should be raw PDF data, *not*
875 873 base64 encoded.
876 874 """
877 875 format_type = Unicode('application/pdf')
878 876
879 877 print_method = ObjectName('_repr_pdf_')
880 878
881 879 _return_type = (bytes, str)
882 880
883 881 class IPythonDisplayFormatter(BaseFormatter):
884 882 """An escape-hatch Formatter for objects that know how to display themselves.
885 883
886 884 To define the callables that compute the representation of your
887 885 objects, define a :meth:`_ipython_display_` method or use the :meth:`for_type`
888 886 or :meth:`for_type_by_name` methods to register functions that handle
889 887 this. Unlike mime-type displays, this method should not return anything,
890 888 instead calling any appropriate display methods itself.
891 889
892 890 This display formatter has highest priority.
893 891 If it fires, no other display formatter will be called.
894 892
895 893 Prior to IPython 6.1, `_ipython_display_` was the only way to display custom mime-types
896 894 without registering a new Formatter.
897 895
898 896 IPython 6.1 introduces `_repr_mimebundle_` for displaying custom mime-types,
899 897 so `_ipython_display_` should only be used for objects that require unusual
900 898 display patterns, such as multiple display calls.
901 899 """
902 900 print_method = ObjectName('_ipython_display_')
903 901 _return_type = (type(None), bool)
904 902
905 903 @catch_format_error
906 904 def __call__(self, obj):
907 905 """Compute the format for an object."""
908 906 if self.enabled:
909 907 # lookup registered printer
910 908 try:
911 909 printer = self.lookup(obj)
912 910 except KeyError:
913 911 pass
914 912 else:
915 913 printer(obj)
916 914 return True
917 915 # Finally look for special method names
918 916 method = get_real_method(obj, self.print_method)
919 917 if method is not None:
920 918 method()
921 919 return True
922 920
923 921
924 922 class MimeBundleFormatter(BaseFormatter):
925 923 """A Formatter for arbitrary mime-types.
926 924
927 925 Unlike other `_repr_<mimetype>_` methods,
928 926 `_repr_mimebundle_` should return mime-bundle data,
929 927 either the mime-keyed `data` dictionary or the tuple `(data, metadata)`.
930 928 Any mime-type is valid.
931 929
932 930 To define the callables that compute the mime-bundle representation of your
933 931 objects, define a :meth:`_repr_mimebundle_` method or use the :meth:`for_type`
934 932 or :meth:`for_type_by_name` methods to register functions that handle
935 933 this.
936 934
937 935 .. versionadded:: 6.1
938 936 """
939 937 print_method = ObjectName('_repr_mimebundle_')
940 938 _return_type = dict
941 939
942 940 def _check_return(self, r, obj):
943 941 r = super(MimeBundleFormatter, self)._check_return(r, obj)
944 942 # always return (data, metadata):
945 943 if r is None:
946 944 return {}, {}
947 945 if not isinstance(r, tuple):
948 946 return r, {}
949 947 return r
950 948
951 949 @catch_format_error
952 950 def __call__(self, obj, include=None, exclude=None):
953 951 """Compute the format for an object.
954 952
955 953 Identical to parent's method but we pass extra parameters to the method.
956 954
957 955 Unlike other _repr_*_ `_repr_mimebundle_` should allow extra kwargs, in
958 956 particular `include` and `exclude`.
959 957 """
960 958 if self.enabled:
961 959 # lookup registered printer
962 960 try:
963 961 printer = self.lookup(obj)
964 962 except KeyError:
965 963 pass
966 964 else:
967 965 return printer(obj)
968 966 # Finally look for special method names
969 967 method = get_real_method(obj, self.print_method)
970 968
971 969 if method is not None:
972 970 return method(include=include, exclude=exclude)
973 971 return None
974 972 else:
975 973 return None
976 974
977 975
978 976 FormatterABC.register(BaseFormatter)
979 977 FormatterABC.register(PlainTextFormatter)
980 978 FormatterABC.register(HTMLFormatter)
981 979 FormatterABC.register(MarkdownFormatter)
982 980 FormatterABC.register(SVGFormatter)
983 981 FormatterABC.register(PNGFormatter)
984 982 FormatterABC.register(PDFFormatter)
985 983 FormatterABC.register(JPEGFormatter)
986 984 FormatterABC.register(LatexFormatter)
987 985 FormatterABC.register(JSONFormatter)
988 986 FormatterABC.register(JavascriptFormatter)
989 987 FormatterABC.register(IPythonDisplayFormatter)
990 988 FormatterABC.register(MimeBundleFormatter)
991 989
992 990
993 991 def format_display_data(obj, include=None, exclude=None):
994 992 """Return a format data dict for an object.
995 993
996 994 By default all format types will be computed.
997 995
998 996 Parameters
999 997 ----------
1000 998 obj : object
1001 999 The Python object whose format data will be computed.
1002 1000
1003 1001 Returns
1004 1002 -------
1005 1003 format_dict : dict
1006 1004 A dictionary of key/value pairs, one or each format that was
1007 1005 generated for the object. The keys are the format types, which
1008 1006 will usually be MIME type strings and the values and JSON'able
1009 1007 data structure containing the raw data for the representation in
1010 1008 that format.
1011 1009 include : list or tuple, optional
1012 1010 A list of format type strings (MIME types) to include in the
1013 1011 format data dict. If this is set *only* the format types included
1014 1012 in this list will be computed.
1015 1013 exclude : list or tuple, optional
1016 1014 A list of format type string (MIME types) to exclude in the format
1017 1015 data dict. If this is set all format types will be computed,
1018 1016 except for those included in this argument.
1019 1017 """
1020 1018 from .interactiveshell import InteractiveShell
1021 1019
1022 1020 return InteractiveShell.instance().display_formatter.format(
1023 1021 obj,
1024 1022 include,
1025 1023 exclude
1026 1024 )
@@ -1,3655 +1,3660 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 abc
15 15 import ast
16 16 import atexit
17 17 import builtins as builtin_mod
18 18 import functools
19 19 import inspect
20 20 import os
21 21 import re
22 22 import runpy
23 23 import sys
24 24 import tempfile
25 25 import traceback
26 26 import types
27 27 import subprocess
28 28 import warnings
29 29 from io import open as io_open
30 30
31 31 from pathlib import Path
32 32 from pickleshare import PickleShareDB
33 33
34 34 from traitlets.config.configurable import SingletonConfigurable
35 35 from traitlets.utils.importstring import import_item
36 36 from IPython.core import oinspect
37 37 from IPython.core import magic
38 38 from IPython.core import page
39 39 from IPython.core import prefilter
40 40 from IPython.core import ultratb
41 41 from IPython.core.alias import Alias, AliasManager
42 42 from IPython.core.autocall import ExitAutocall
43 43 from IPython.core.builtin_trap import BuiltinTrap
44 44 from IPython.core.events import EventManager, available_events
45 45 from IPython.core.compilerop import CachingCompiler, check_linecache_ipython
46 46 from IPython.core.debugger import InterruptiblePdb
47 47 from IPython.core.display_trap import DisplayTrap
48 48 from IPython.core.displayhook import DisplayHook
49 49 from IPython.core.displaypub import DisplayPublisher
50 50 from IPython.core.error import InputRejected, UsageError
51 51 from IPython.core.extensions import ExtensionManager
52 52 from IPython.core.formatters import DisplayFormatter
53 53 from IPython.core.history import HistoryManager
54 54 from IPython.core.inputtransformer2 import ESC_MAGIC, ESC_MAGIC2
55 55 from IPython.core.logger import Logger
56 56 from IPython.core.macro import Macro
57 57 from IPython.core.payload import PayloadManager
58 58 from IPython.core.prefilter import PrefilterManager
59 59 from IPython.core.profiledir import ProfileDir
60 60 from IPython.core.usage import default_banner
61 61 from IPython.display import display
62 62 from IPython.testing.skipdoctest import skip_doctest
63 63 from IPython.utils import PyColorize
64 64 from IPython.utils import io
65 65 from IPython.utils import py3compat
66 66 from IPython.utils import openpy
67 67 from IPython.utils.decorators import undoc
68 68 from IPython.utils.io import ask_yes_no
69 69 from IPython.utils.ipstruct import Struct
70 70 from IPython.paths import get_ipython_dir
71 71 from IPython.utils.path import get_home_dir, get_py_filename, ensure_dir_exists
72 72 from IPython.utils.process import system, getoutput
73 73 from IPython.utils.strdispatch import StrDispatch
74 74 from IPython.utils.syspathcontext import prepended_to_syspath
75 75 from IPython.utils.text import format_screen, LSString, SList, DollarFormatter
76 76 from IPython.utils.tempdir import TemporaryDirectory
77 77 from traitlets import (
78 78 Integer, Bool, CaselessStrEnum, Enum, List, Dict, Unicode, Instance, Type,
79 79 observe, default, validate, Any
80 80 )
81 81 from warnings import warn
82 82 from logging import error
83 83 import IPython.core.hooks
84 84
85 85 from typing import List as ListType, Tuple, Optional, Callable
86 86 from ast import stmt
87 87
88 88 sphinxify: Optional[Callable]
89 89
90 90 try:
91 91 import docrepr.sphinxify as sphx
92 92
93 93 def sphinxify(doc):
94 94 with TemporaryDirectory() as dirname:
95 95 return {
96 96 'text/html': sphx.sphinxify(doc, dirname),
97 97 'text/plain': doc
98 98 }
99 99 except ImportError:
100 100 sphinxify = None
101 101
102 102
103 103 class ProvisionalWarning(DeprecationWarning):
104 104 """
105 105 Warning class for unstable features
106 106 """
107 107 pass
108 108
109 109 from ast import Module
110 110
111 111 _assign_nodes = (ast.AugAssign, ast.AnnAssign, ast.Assign)
112 112 _single_targets_nodes = (ast.AugAssign, ast.AnnAssign)
113 113
114 114 #-----------------------------------------------------------------------------
115 115 # Await Helpers
116 116 #-----------------------------------------------------------------------------
117 117
118 118 # we still need to run things using the asyncio eventloop, but there is no
119 119 # async integration
120 120 from .async_helpers import _asyncio_runner, _pseudo_sync_runner
121 121 from .async_helpers import _curio_runner, _trio_runner, _should_be_async
122 122
123 123 #-----------------------------------------------------------------------------
124 124 # Globals
125 125 #-----------------------------------------------------------------------------
126 126
127 127 # compiled regexps for autoindent management
128 128 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
129 129
130 130 #-----------------------------------------------------------------------------
131 131 # Utilities
132 132 #-----------------------------------------------------------------------------
133 133
134 134 @undoc
135 135 def softspace(file, newvalue):
136 136 """Copied from code.py, to remove the dependency"""
137 137
138 138 oldvalue = 0
139 139 try:
140 140 oldvalue = file.softspace
141 141 except AttributeError:
142 142 pass
143 143 try:
144 144 file.softspace = newvalue
145 145 except (AttributeError, TypeError):
146 146 # "attribute-less object" or "read-only attributes"
147 147 pass
148 148 return oldvalue
149 149
150 150 @undoc
151 151 def no_op(*a, **kw):
152 152 pass
153 153
154 154
155 155 class SpaceInInput(Exception): pass
156 156
157 157
158 158 class SeparateUnicode(Unicode):
159 159 r"""A Unicode subclass to validate separate_in, separate_out, etc.
160 160
161 161 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
162 162 """
163 163
164 164 def validate(self, obj, value):
165 165 if value == '0': value = ''
166 166 value = value.replace('\\n','\n')
167 167 return super(SeparateUnicode, self).validate(obj, value)
168 168
169 169
170 170 @undoc
171 171 class DummyMod(object):
172 172 """A dummy module used for IPython's interactive module when
173 173 a namespace must be assigned to the module's __dict__."""
174 174 __spec__ = None
175 175
176 176
177 177 class ExecutionInfo(object):
178 178 """The arguments used for a call to :meth:`InteractiveShell.run_cell`
179 179
180 180 Stores information about what is going to happen.
181 181 """
182 182 raw_cell = None
183 183 store_history = False
184 184 silent = False
185 185 shell_futures = True
186 186
187 187 def __init__(self, raw_cell, store_history, silent, shell_futures):
188 188 self.raw_cell = raw_cell
189 189 self.store_history = store_history
190 190 self.silent = silent
191 191 self.shell_futures = shell_futures
192 192
193 193 def __repr__(self):
194 194 name = self.__class__.__qualname__
195 195 raw_cell = ((self.raw_cell[:50] + '..')
196 196 if len(self.raw_cell) > 50 else self.raw_cell)
197 197 return '<%s object at %x, raw_cell="%s" store_history=%s silent=%s shell_futures=%s>' %\
198 198 (name, id(self), raw_cell, self.store_history, self.silent, self.shell_futures)
199 199
200 200
201 201 class ExecutionResult(object):
202 202 """The result of a call to :meth:`InteractiveShell.run_cell`
203 203
204 204 Stores information about what took place.
205 205 """
206 206 execution_count = None
207 207 error_before_exec = None
208 208 error_in_exec: Optional[BaseException] = None
209 209 info = None
210 210 result = None
211 211
212 212 def __init__(self, info):
213 213 self.info = info
214 214
215 215 @property
216 216 def success(self):
217 217 return (self.error_before_exec is None) and (self.error_in_exec is None)
218 218
219 219 def raise_error(self):
220 220 """Reraises error if `success` is `False`, otherwise does nothing"""
221 221 if self.error_before_exec is not None:
222 222 raise self.error_before_exec
223 223 if self.error_in_exec is not None:
224 224 raise self.error_in_exec
225 225
226 226 def __repr__(self):
227 227 name = self.__class__.__qualname__
228 228 return '<%s object at %x, execution_count=%s error_before_exec=%s error_in_exec=%s info=%s result=%s>' %\
229 229 (name, id(self), self.execution_count, self.error_before_exec, self.error_in_exec, repr(self.info), repr(self.result))
230 230
231 231
232 232 class InteractiveShell(SingletonConfigurable):
233 233 """An enhanced, interactive shell for Python."""
234 234
235 235 _instance = None
236 236
237 237 ast_transformers = List([], help=
238 238 """
239 239 A list of ast.NodeTransformer subclass instances, which will be applied
240 240 to user input before code is run.
241 241 """
242 242 ).tag(config=True)
243 243
244 244 autocall = Enum((0,1,2), default_value=0, help=
245 245 """
246 246 Make IPython automatically call any callable object even if you didn't
247 247 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
248 248 automatically. The value can be '0' to disable the feature, '1' for
249 249 'smart' autocall, where it is not applied if there are no more
250 250 arguments on the line, and '2' for 'full' autocall, where all callable
251 251 objects are automatically called (even if no arguments are present).
252 252 """
253 253 ).tag(config=True)
254 254
255 255 autoindent = Bool(True, help=
256 256 """
257 257 Autoindent IPython code entered interactively.
258 258 """
259 259 ).tag(config=True)
260 260
261 261 autoawait = Bool(True, help=
262 262 """
263 263 Automatically run await statement in the top level repl.
264 264 """
265 265 ).tag(config=True)
266 266
267 267 loop_runner_map ={
268 268 'asyncio':(_asyncio_runner, True),
269 269 'curio':(_curio_runner, True),
270 270 'trio':(_trio_runner, True),
271 271 'sync': (_pseudo_sync_runner, False)
272 272 }
273 273
274 274 loop_runner = Any(default_value="IPython.core.interactiveshell._asyncio_runner",
275 275 allow_none=True,
276 276 help="""Select the loop runner that will be used to execute top-level asynchronous code"""
277 277 ).tag(config=True)
278 278
279 279 @default('loop_runner')
280 280 def _default_loop_runner(self):
281 281 return import_item("IPython.core.interactiveshell._asyncio_runner")
282 282
283 283 @validate('loop_runner')
284 284 def _import_runner(self, proposal):
285 285 if isinstance(proposal.value, str):
286 286 if proposal.value in self.loop_runner_map:
287 287 runner, autoawait = self.loop_runner_map[proposal.value]
288 288 self.autoawait = autoawait
289 289 return runner
290 290 runner = import_item(proposal.value)
291 291 if not callable(runner):
292 292 raise ValueError('loop_runner must be callable')
293 293 return runner
294 294 if not callable(proposal.value):
295 295 raise ValueError('loop_runner must be callable')
296 296 return proposal.value
297 297
298 298 automagic = Bool(True, help=
299 299 """
300 300 Enable magic commands to be called without the leading %.
301 301 """
302 302 ).tag(config=True)
303 303
304 304 banner1 = Unicode(default_banner,
305 305 help="""The part of the banner to be printed before the profile"""
306 306 ).tag(config=True)
307 307 banner2 = Unicode('',
308 308 help="""The part of the banner to be printed after the profile"""
309 309 ).tag(config=True)
310 310
311 311 cache_size = Integer(1000, help=
312 312 """
313 313 Set the size of the output cache. The default is 1000, you can
314 314 change it permanently in your config file. Setting it to 0 completely
315 315 disables the caching system, and the minimum value accepted is 3 (if
316 316 you provide a value less than 3, it is reset to 0 and a warning is
317 317 issued). This limit is defined because otherwise you'll spend more
318 318 time re-flushing a too small cache than working
319 319 """
320 320 ).tag(config=True)
321 321 color_info = Bool(True, help=
322 322 """
323 323 Use colors for displaying information about objects. Because this
324 324 information is passed through a pager (like 'less'), and some pagers
325 325 get confused with color codes, this capability can be turned off.
326 326 """
327 327 ).tag(config=True)
328 328 colors = CaselessStrEnum(('Neutral', 'NoColor','LightBG','Linux'),
329 329 default_value='Neutral',
330 330 help="Set the color scheme (NoColor, Neutral, Linux, or LightBG)."
331 331 ).tag(config=True)
332 332 debug = Bool(False).tag(config=True)
333 333 disable_failing_post_execute = Bool(False,
334 334 help="Don't call post-execute functions that have failed in the past."
335 335 ).tag(config=True)
336 336 display_formatter = Instance(DisplayFormatter, allow_none=True)
337 337 displayhook_class = Type(DisplayHook)
338 338 display_pub_class = Type(DisplayPublisher)
339 339 compiler_class = Type(CachingCompiler)
340 340
341 341 sphinxify_docstring = Bool(False, help=
342 342 """
343 343 Enables rich html representation of docstrings. (This requires the
344 344 docrepr module).
345 345 """).tag(config=True)
346 346
347 347 @observe("sphinxify_docstring")
348 348 def _sphinxify_docstring_changed(self, change):
349 349 if change['new']:
350 350 warn("`sphinxify_docstring` is provisional since IPython 5.0 and might change in future versions." , ProvisionalWarning)
351 351
352 352 enable_html_pager = Bool(False, help=
353 353 """
354 354 (Provisional API) enables html representation in mime bundles sent
355 355 to pagers.
356 356 """).tag(config=True)
357 357
358 358 @observe("enable_html_pager")
359 359 def _enable_html_pager_changed(self, change):
360 360 if change['new']:
361 361 warn("`enable_html_pager` is provisional since IPython 5.0 and might change in future versions.", ProvisionalWarning)
362 362
363 363 data_pub_class = None
364 364
365 365 exit_now = Bool(False)
366 366 exiter = Instance(ExitAutocall)
367 367 @default('exiter')
368 368 def _exiter_default(self):
369 369 return ExitAutocall(self)
370 370 # Monotonically increasing execution counter
371 371 execution_count = Integer(1)
372 372 filename = Unicode("<ipython console>")
373 373 ipython_dir= Unicode('').tag(config=True) # Set to get_ipython_dir() in __init__
374 374
375 375 # Used to transform cells before running them, and check whether code is complete
376 376 input_transformer_manager = Instance('IPython.core.inputtransformer2.TransformerManager',
377 377 ())
378 378
379 379 @property
380 380 def input_transformers_cleanup(self):
381 381 return self.input_transformer_manager.cleanup_transforms
382 382
383 383 input_transformers_post = List([],
384 384 help="A list of string input transformers, to be applied after IPython's "
385 385 "own input transformations."
386 386 )
387 387
388 388 @property
389 389 def input_splitter(self):
390 390 """Make this available for backward compatibility (pre-7.0 release) with existing code.
391 391
392 392 For example, ipykernel ipykernel currently uses
393 393 `shell.input_splitter.check_complete`
394 394 """
395 395 from warnings import warn
396 396 warn("`input_splitter` is deprecated since IPython 7.0, prefer `input_transformer_manager`.",
397 397 DeprecationWarning, stacklevel=2
398 398 )
399 399 return self.input_transformer_manager
400 400
401 401 logstart = Bool(False, help=
402 402 """
403 403 Start logging to the default log file in overwrite mode.
404 404 Use `logappend` to specify a log file to **append** logs to.
405 405 """
406 406 ).tag(config=True)
407 407 logfile = Unicode('', help=
408 408 """
409 409 The name of the logfile to use.
410 410 """
411 411 ).tag(config=True)
412 412 logappend = Unicode('', help=
413 413 """
414 414 Start logging to the given file in append mode.
415 415 Use `logfile` to specify a log file to **overwrite** logs to.
416 416 """
417 417 ).tag(config=True)
418 418 object_info_string_level = Enum((0,1,2), default_value=0,
419 419 ).tag(config=True)
420 420 pdb = Bool(False, help=
421 421 """
422 422 Automatically call the pdb debugger after every exception.
423 423 """
424 424 ).tag(config=True)
425 425 display_page = Bool(False,
426 426 help="""If True, anything that would be passed to the pager
427 427 will be displayed as regular output instead."""
428 428 ).tag(config=True)
429 429
430 430
431 431 show_rewritten_input = Bool(True,
432 432 help="Show rewritten input, e.g. for autocall."
433 433 ).tag(config=True)
434 434
435 435 quiet = Bool(False).tag(config=True)
436 436
437 437 history_length = Integer(10000,
438 438 help='Total length of command history'
439 439 ).tag(config=True)
440 440
441 441 history_load_length = Integer(1000, help=
442 442 """
443 443 The number of saved history entries to be loaded
444 444 into the history buffer at startup.
445 445 """
446 446 ).tag(config=True)
447 447
448 448 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none', 'last_expr_or_assign'],
449 449 default_value='last_expr',
450 450 help="""
451 451 'all', 'last', 'last_expr' or 'none', 'last_expr_or_assign' specifying
452 452 which nodes should be run interactively (displaying output from expressions).
453 453 """
454 454 ).tag(config=True)
455 455
456 456 # TODO: this part of prompt management should be moved to the frontends.
457 457 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
458 458 separate_in = SeparateUnicode('\n').tag(config=True)
459 459 separate_out = SeparateUnicode('').tag(config=True)
460 460 separate_out2 = SeparateUnicode('').tag(config=True)
461 461 wildcards_case_sensitive = Bool(True).tag(config=True)
462 462 xmode = CaselessStrEnum(('Context', 'Plain', 'Verbose', 'Minimal'),
463 463 default_value='Context',
464 464 help="Switch modes for the IPython exception handlers."
465 465 ).tag(config=True)
466 466
467 467 # Subcomponents of InteractiveShell
468 468 alias_manager = Instance('IPython.core.alias.AliasManager', allow_none=True)
469 469 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
470 470 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap', allow_none=True)
471 471 display_trap = Instance('IPython.core.display_trap.DisplayTrap', allow_none=True)
472 472 extension_manager = Instance('IPython.core.extensions.ExtensionManager', allow_none=True)
473 473 payload_manager = Instance('IPython.core.payload.PayloadManager', allow_none=True)
474 474 history_manager = Instance('IPython.core.history.HistoryAccessorBase', allow_none=True)
475 475 magics_manager = Instance('IPython.core.magic.MagicsManager', allow_none=True)
476 476
477 477 profile_dir = Instance('IPython.core.application.ProfileDir', allow_none=True)
478 478 @property
479 479 def profile(self):
480 480 if self.profile_dir is not None:
481 481 name = os.path.basename(self.profile_dir.location)
482 482 return name.replace('profile_','')
483 483
484 484
485 485 # Private interface
486 486 _post_execute = Dict()
487 487
488 488 # Tracks any GUI loop loaded for pylab
489 489 pylab_gui_select = None
490 490
491 491 last_execution_succeeded = Bool(True, help='Did last executed command succeeded')
492 492
493 493 last_execution_result = Instance('IPython.core.interactiveshell.ExecutionResult', help='Result of executing the last command', allow_none=True)
494 494
495 495 def __init__(self, ipython_dir=None, profile_dir=None,
496 496 user_module=None, user_ns=None,
497 497 custom_exceptions=((), None), **kwargs):
498 498
499 499 # This is where traits with a config_key argument are updated
500 500 # from the values on config.
501 501 super(InteractiveShell, self).__init__(**kwargs)
502 502 if 'PromptManager' in self.config:
503 503 warn('As of IPython 5.0 `PromptManager` config will have no effect'
504 504 ' and has been replaced by TerminalInteractiveShell.prompts_class')
505 505 self.configurables = [self]
506 506
507 507 # These are relatively independent and stateless
508 508 self.init_ipython_dir(ipython_dir)
509 509 self.init_profile_dir(profile_dir)
510 510 self.init_instance_attrs()
511 511 self.init_environment()
512 512
513 513 # Check if we're in a virtualenv, and set up sys.path.
514 514 self.init_virtualenv()
515 515
516 516 # Create namespaces (user_ns, user_global_ns, etc.)
517 517 self.init_create_namespaces(user_module, user_ns)
518 518 # This has to be done after init_create_namespaces because it uses
519 519 # something in self.user_ns, but before init_sys_modules, which
520 520 # is the first thing to modify sys.
521 521 # TODO: When we override sys.stdout and sys.stderr before this class
522 522 # is created, we are saving the overridden ones here. Not sure if this
523 523 # is what we want to do.
524 524 self.save_sys_module_state()
525 525 self.init_sys_modules()
526 526
527 527 # While we're trying to have each part of the code directly access what
528 528 # it needs without keeping redundant references to objects, we have too
529 529 # much legacy code that expects ip.db to exist.
530 530 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
531 531
532 532 self.init_history()
533 533 self.init_encoding()
534 534 self.init_prefilter()
535 535
536 536 self.init_syntax_highlighting()
537 537 self.init_hooks()
538 538 self.init_events()
539 539 self.init_pushd_popd_magic()
540 540 self.init_user_ns()
541 541 self.init_logger()
542 542 self.init_builtins()
543 543
544 544 # The following was in post_config_initialization
545 545 self.init_inspector()
546 546 self.raw_input_original = input
547 547 self.init_completer()
548 548 # TODO: init_io() needs to happen before init_traceback handlers
549 549 # because the traceback handlers hardcode the stdout/stderr streams.
550 550 # This logic in in debugger.Pdb and should eventually be changed.
551 551 self.init_io()
552 552 self.init_traceback_handlers(custom_exceptions)
553 553 self.init_prompts()
554 554 self.init_display_formatter()
555 555 self.init_display_pub()
556 556 self.init_data_pub()
557 557 self.init_displayhook()
558 558 self.init_magics()
559 559 self.init_alias()
560 560 self.init_logstart()
561 561 self.init_pdb()
562 562 self.init_extension_manager()
563 563 self.init_payload()
564 564 self.hooks.late_startup_hook()
565 565 self.events.trigger('shell_initialized', self)
566 566 atexit.register(self.atexit_operations)
567 567
568 568 # The trio runner is used for running Trio in the foreground thread. It
569 569 # is different from `_trio_runner(async_fn)` in `async_helpers.py`
570 570 # which calls `trio.run()` for every cell. This runner runs all cells
571 571 # inside a single Trio event loop. If used, it is set from
572 572 # `ipykernel.kernelapp`.
573 573 self.trio_runner = None
574 574
575 575 def get_ipython(self):
576 576 """Return the currently running IPython instance."""
577 577 return self
578 578
579 579 #-------------------------------------------------------------------------
580 580 # Trait changed handlers
581 581 #-------------------------------------------------------------------------
582 582 @observe('ipython_dir')
583 583 def _ipython_dir_changed(self, change):
584 584 ensure_dir_exists(change['new'])
585 585
586 586 def set_autoindent(self,value=None):
587 587 """Set the autoindent flag.
588 588
589 589 If called with no arguments, it acts as a toggle."""
590 590 if value is None:
591 591 self.autoindent = not self.autoindent
592 592 else:
593 593 self.autoindent = value
594 594
595 595 def set_trio_runner(self, tr):
596 596 self.trio_runner = tr
597 597
598 598 #-------------------------------------------------------------------------
599 599 # init_* methods called by __init__
600 600 #-------------------------------------------------------------------------
601 601
602 602 def init_ipython_dir(self, ipython_dir):
603 603 if ipython_dir is not None:
604 604 self.ipython_dir = ipython_dir
605 605 return
606 606
607 607 self.ipython_dir = get_ipython_dir()
608 608
609 609 def init_profile_dir(self, profile_dir):
610 610 if profile_dir is not None:
611 611 self.profile_dir = profile_dir
612 612 return
613 613 self.profile_dir = ProfileDir.create_profile_dir_by_name(
614 614 self.ipython_dir, "default"
615 615 )
616 616
617 617 def init_instance_attrs(self):
618 618 self.more = False
619 619
620 620 # command compiler
621 621 self.compile = self.compiler_class()
622 622
623 623 # Make an empty namespace, which extension writers can rely on both
624 624 # existing and NEVER being used by ipython itself. This gives them a
625 625 # convenient location for storing additional information and state
626 626 # their extensions may require, without fear of collisions with other
627 627 # ipython names that may develop later.
628 628 self.meta = Struct()
629 629
630 630 # Temporary files used for various purposes. Deleted at exit.
631 631 # The files here are stored with Path from Pathlib
632 632 self.tempfiles = []
633 633 self.tempdirs = []
634 634
635 635 # keep track of where we started running (mainly for crash post-mortem)
636 636 # This is not being used anywhere currently.
637 637 self.starting_dir = os.getcwd()
638 638
639 639 # Indentation management
640 640 self.indent_current_nsp = 0
641 641
642 642 # Dict to track post-execution functions that have been registered
643 643 self._post_execute = {}
644 644
645 645 def init_environment(self):
646 646 """Any changes we need to make to the user's environment."""
647 647 pass
648 648
649 649 def init_encoding(self):
650 650 # Get system encoding at startup time. Certain terminals (like Emacs
651 651 # under Win32 have it set to None, and we need to have a known valid
652 652 # encoding to use in the raw_input() method
653 653 try:
654 654 self.stdin_encoding = sys.stdin.encoding or 'ascii'
655 655 except AttributeError:
656 656 self.stdin_encoding = 'ascii'
657 657
658 658
659 659 @observe('colors')
660 660 def init_syntax_highlighting(self, changes=None):
661 661 # Python source parser/formatter for syntax highlighting
662 662 pyformat = PyColorize.Parser(style=self.colors, parent=self).format
663 663 self.pycolorize = lambda src: pyformat(src,'str')
664 664
665 665 def refresh_style(self):
666 666 # No-op here, used in subclass
667 667 pass
668 668
669 669 def init_pushd_popd_magic(self):
670 670 # for pushd/popd management
671 671 self.home_dir = get_home_dir()
672 672
673 673 self.dir_stack = []
674 674
675 675 def init_logger(self):
676 676 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
677 677 logmode='rotate')
678 678
679 679 def init_logstart(self):
680 680 """Initialize logging in case it was requested at the command line.
681 681 """
682 682 if self.logappend:
683 683 self.magic('logstart %s append' % self.logappend)
684 684 elif self.logfile:
685 685 self.magic('logstart %s' % self.logfile)
686 686 elif self.logstart:
687 687 self.magic('logstart')
688 688
689 689
690 690 def init_builtins(self):
691 691 # A single, static flag that we set to True. Its presence indicates
692 692 # that an IPython shell has been created, and we make no attempts at
693 693 # removing on exit or representing the existence of more than one
694 694 # IPython at a time.
695 695 builtin_mod.__dict__['__IPYTHON__'] = True
696 696 builtin_mod.__dict__['display'] = display
697 697
698 698 self.builtin_trap = BuiltinTrap(shell=self)
699 699
700 700 @observe('colors')
701 701 def init_inspector(self, changes=None):
702 702 # Object inspector
703 703 self.inspector = oinspect.Inspector(oinspect.InspectColors,
704 704 PyColorize.ANSICodeColors,
705 705 self.colors,
706 706 self.object_info_string_level)
707 707
708 708 def init_io(self):
709 709 # implemented in subclasses, TerminalInteractiveShell does call
710 710 # colorama.init().
711 711 pass
712 712
713 713 def init_prompts(self):
714 714 # Set system prompts, so that scripts can decide if they are running
715 715 # interactively.
716 716 sys.ps1 = 'In : '
717 717 sys.ps2 = '...: '
718 718 sys.ps3 = 'Out: '
719 719
720 720 def init_display_formatter(self):
721 721 self.display_formatter = DisplayFormatter(parent=self)
722 722 self.configurables.append(self.display_formatter)
723 723
724 724 def init_display_pub(self):
725 725 self.display_pub = self.display_pub_class(parent=self, shell=self)
726 726 self.configurables.append(self.display_pub)
727 727
728 728 def init_data_pub(self):
729 729 if not self.data_pub_class:
730 730 self.data_pub = None
731 731 return
732 732 self.data_pub = self.data_pub_class(parent=self)
733 733 self.configurables.append(self.data_pub)
734 734
735 735 def init_displayhook(self):
736 736 # Initialize displayhook, set in/out prompts and printing system
737 737 self.displayhook = self.displayhook_class(
738 738 parent=self,
739 739 shell=self,
740 740 cache_size=self.cache_size,
741 741 )
742 742 self.configurables.append(self.displayhook)
743 743 # This is a context manager that installs/revmoes the displayhook at
744 744 # the appropriate time.
745 745 self.display_trap = DisplayTrap(hook=self.displayhook)
746 746
747 747 def init_virtualenv(self):
748 748 """Add the current virtualenv to sys.path so the user can import modules from it.
749 749 This isn't perfect: it doesn't use the Python interpreter with which the
750 750 virtualenv was built, and it ignores the --no-site-packages option. A
751 751 warning will appear suggesting the user installs IPython in the
752 752 virtualenv, but for many cases, it probably works well enough.
753 753
754 754 Adapted from code snippets online.
755 755
756 756 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
757 757 """
758 758 if 'VIRTUAL_ENV' not in os.environ:
759 759 # Not in a virtualenv
760 760 return
761 761 elif os.environ["VIRTUAL_ENV"] == "":
762 762 warn("Virtual env path set to '', please check if this is intended.")
763 763 return
764 764
765 765 p = Path(sys.executable)
766 766 p_venv = Path(os.environ["VIRTUAL_ENV"])
767 767
768 768 # fallback venv detection:
769 769 # stdlib venv may symlink sys.executable, so we can't use realpath.
770 770 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
771 771 # So we just check every item in the symlink tree (generally <= 3)
772 772 paths = [p]
773 773 while p.is_symlink():
774 774 p = Path(os.readlink(p))
775 775 paths.append(p.resolve())
776 776
777 777 # In Cygwin paths like "c:\..." and '\cygdrive\c\...' are possible
778 778 if p_venv.parts[1] == "cygdrive":
779 779 drive_name = p_venv.parts[2]
780 780 p_venv = (drive_name + ":/") / Path(*p_venv.parts[3:])
781 781
782 782 if any(p_venv == p.parents[1] for p in paths):
783 783 # Our exe is inside or has access to the virtualenv, don't need to do anything.
784 784 return
785 785
786 786 if sys.platform == "win32":
787 787 virtual_env = str(Path(os.environ["VIRTUAL_ENV"], "Lib", "site-packages"))
788 788 else:
789 789 virtual_env_path = Path(
790 790 os.environ["VIRTUAL_ENV"], "lib", "python{}.{}", "site-packages"
791 791 )
792 792 p_ver = sys.version_info[:2]
793 793
794 794 # Predict version from py[thon]-x.x in the $VIRTUAL_ENV
795 795 re_m = re.search(r"\bpy(?:thon)?([23])\.(\d+)\b", os.environ["VIRTUAL_ENV"])
796 796 if re_m:
797 797 predicted_path = Path(str(virtual_env_path).format(*re_m.groups()))
798 798 if predicted_path.exists():
799 799 p_ver = re_m.groups()
800 800
801 801 virtual_env = str(virtual_env_path).format(*p_ver)
802 802
803 803 warn(
804 804 "Attempting to work in a virtualenv. If you encounter problems, "
805 805 "please install IPython inside the virtualenv."
806 806 )
807 807 import site
808 808 sys.path.insert(0, virtual_env)
809 809 site.addsitedir(virtual_env)
810 810
811 811 #-------------------------------------------------------------------------
812 812 # Things related to injections into the sys module
813 813 #-------------------------------------------------------------------------
814 814
815 815 def save_sys_module_state(self):
816 816 """Save the state of hooks in the sys module.
817 817
818 818 This has to be called after self.user_module is created.
819 819 """
820 820 self._orig_sys_module_state = {'stdin': sys.stdin,
821 821 'stdout': sys.stdout,
822 822 'stderr': sys.stderr,
823 823 'excepthook': sys.excepthook}
824 824 self._orig_sys_modules_main_name = self.user_module.__name__
825 825 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
826 826
827 827 def restore_sys_module_state(self):
828 828 """Restore the state of the sys module."""
829 829 try:
830 830 for k, v in self._orig_sys_module_state.items():
831 831 setattr(sys, k, v)
832 832 except AttributeError:
833 833 pass
834 834 # Reset what what done in self.init_sys_modules
835 835 if self._orig_sys_modules_main_mod is not None:
836 836 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
837 837
838 838 #-------------------------------------------------------------------------
839 839 # Things related to the banner
840 840 #-------------------------------------------------------------------------
841 841
842 842 @property
843 843 def banner(self):
844 844 banner = self.banner1
845 845 if self.profile and self.profile != 'default':
846 846 banner += '\nIPython profile: %s\n' % self.profile
847 847 if self.banner2:
848 848 banner += '\n' + self.banner2
849 849 return banner
850 850
851 851 def show_banner(self, banner=None):
852 852 if banner is None:
853 853 banner = self.banner
854 854 sys.stdout.write(banner)
855 855
856 856 #-------------------------------------------------------------------------
857 857 # Things related to hooks
858 858 #-------------------------------------------------------------------------
859 859
860 860 def init_hooks(self):
861 861 # hooks holds pointers used for user-side customizations
862 862 self.hooks = Struct()
863 863
864 864 self.strdispatchers = {}
865 865
866 866 # Set all default hooks, defined in the IPython.hooks module.
867 867 hooks = IPython.core.hooks
868 868 for hook_name in hooks.__all__:
869 869 # default hooks have priority 100, i.e. low; user hooks should have
870 870 # 0-100 priority
871 871 self.set_hook(hook_name,getattr(hooks,hook_name), 100, _warn_deprecated=False)
872 872
873 873 if self.display_page:
874 874 self.set_hook('show_in_pager', page.as_hook(page.display_page), 90)
875 875
876 876 def set_hook(self,name,hook, priority=50, str_key=None, re_key=None,
877 877 _warn_deprecated=True):
878 878 """set_hook(name,hook) -> sets an internal IPython hook.
879 879
880 880 IPython exposes some of its internal API as user-modifiable hooks. By
881 881 adding your function to one of these hooks, you can modify IPython's
882 882 behavior to call at runtime your own routines."""
883 883
884 884 # At some point in the future, this should validate the hook before it
885 885 # accepts it. Probably at least check that the hook takes the number
886 886 # of args it's supposed to.
887 887
888 888 f = types.MethodType(hook,self)
889 889
890 890 # check if the hook is for strdispatcher first
891 891 if str_key is not None:
892 892 sdp = self.strdispatchers.get(name, StrDispatch())
893 893 sdp.add_s(str_key, f, priority )
894 894 self.strdispatchers[name] = sdp
895 895 return
896 896 if re_key is not None:
897 897 sdp = self.strdispatchers.get(name, StrDispatch())
898 898 sdp.add_re(re.compile(re_key), f, priority )
899 899 self.strdispatchers[name] = sdp
900 900 return
901 901
902 902 dp = getattr(self.hooks, name, None)
903 903 if name not in IPython.core.hooks.__all__:
904 904 print("Warning! Hook '%s' is not one of %s" % \
905 905 (name, IPython.core.hooks.__all__ ))
906 906
907 907 if _warn_deprecated and (name in IPython.core.hooks.deprecated):
908 908 alternative = IPython.core.hooks.deprecated[name]
909 warn("Hook {} is deprecated. Use {} instead.".format(name, alternative), stacklevel=2)
909 raise ValueError(
910 "Hook {} has been deprecated since IPython 5.0. Use {} instead.".format(
911 name, alternative
912 )
913 )
910 914
911 915 if not dp:
912 916 dp = IPython.core.hooks.CommandChainDispatcher()
913 917
914 918 try:
915 919 dp.add(f,priority)
916 920 except AttributeError:
917 921 # it was not commandchain, plain old func - replace
918 922 dp = f
919 923
920 924 setattr(self.hooks,name, dp)
921 925
922 926 #-------------------------------------------------------------------------
923 927 # Things related to events
924 928 #-------------------------------------------------------------------------
925 929
926 930 def init_events(self):
927 931 self.events = EventManager(self, available_events)
928 932
929 933 self.events.register("pre_execute", self._clear_warning_registry)
930 934
931 935 def register_post_execute(self, func):
932 936 """DEPRECATED: Use ip.events.register('post_run_cell', func)
933 937
934 938 Register a function for calling after code execution.
935 939 """
936 warn("ip.register_post_execute is deprecated, use "
937 "ip.events.register('post_run_cell', func) instead.", stacklevel=2)
938 self.events.register('post_run_cell', func)
940 raise ValueError(
941 "ip.register_post_execute is deprecated since IPython 1.0, use "
942 "ip.events.register('post_run_cell', func) instead."
943 )
939 944
940 945 def _clear_warning_registry(self):
941 946 # clear the warning registry, so that different code blocks with
942 947 # overlapping line number ranges don't cause spurious suppression of
943 948 # warnings (see gh-6611 for details)
944 949 if "__warningregistry__" in self.user_global_ns:
945 950 del self.user_global_ns["__warningregistry__"]
946 951
947 952 #-------------------------------------------------------------------------
948 953 # Things related to the "main" module
949 954 #-------------------------------------------------------------------------
950 955
951 956 def new_main_mod(self, filename, modname):
952 957 """Return a new 'main' module object for user code execution.
953 958
954 959 ``filename`` should be the path of the script which will be run in the
955 960 module. Requests with the same filename will get the same module, with
956 961 its namespace cleared.
957 962
958 963 ``modname`` should be the module name - normally either '__main__' or
959 964 the basename of the file without the extension.
960 965
961 966 When scripts are executed via %run, we must keep a reference to their
962 967 __main__ module around so that Python doesn't
963 968 clear it, rendering references to module globals useless.
964 969
965 970 This method keeps said reference in a private dict, keyed by the
966 971 absolute path of the script. This way, for multiple executions of the
967 972 same script we only keep one copy of the namespace (the last one),
968 973 thus preventing memory leaks from old references while allowing the
969 974 objects from the last execution to be accessible.
970 975 """
971 976 filename = os.path.abspath(filename)
972 977 try:
973 978 main_mod = self._main_mod_cache[filename]
974 979 except KeyError:
975 980 main_mod = self._main_mod_cache[filename] = types.ModuleType(
976 981 modname,
977 982 doc="Module created for script run in IPython")
978 983 else:
979 984 main_mod.__dict__.clear()
980 985 main_mod.__name__ = modname
981 986
982 987 main_mod.__file__ = filename
983 988 # It seems pydoc (and perhaps others) needs any module instance to
984 989 # implement a __nonzero__ method
985 990 main_mod.__nonzero__ = lambda : True
986 991
987 992 return main_mod
988 993
989 994 def clear_main_mod_cache(self):
990 995 """Clear the cache of main modules.
991 996
992 997 Mainly for use by utilities like %reset.
993 998
994 999 Examples
995 1000 --------
996 1001 In [15]: import IPython
997 1002
998 1003 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
999 1004
1000 1005 In [17]: len(_ip._main_mod_cache) > 0
1001 1006 Out[17]: True
1002 1007
1003 1008 In [18]: _ip.clear_main_mod_cache()
1004 1009
1005 1010 In [19]: len(_ip._main_mod_cache) == 0
1006 1011 Out[19]: True
1007 1012 """
1008 1013 self._main_mod_cache.clear()
1009 1014
1010 1015 #-------------------------------------------------------------------------
1011 1016 # Things related to debugging
1012 1017 #-------------------------------------------------------------------------
1013 1018
1014 1019 def init_pdb(self):
1015 1020 # Set calling of pdb on exceptions
1016 1021 # self.call_pdb is a property
1017 1022 self.call_pdb = self.pdb
1018 1023
1019 1024 def _get_call_pdb(self):
1020 1025 return self._call_pdb
1021 1026
1022 1027 def _set_call_pdb(self,val):
1023 1028
1024 1029 if val not in (0,1,False,True):
1025 1030 raise ValueError('new call_pdb value must be boolean')
1026 1031
1027 1032 # store value in instance
1028 1033 self._call_pdb = val
1029 1034
1030 1035 # notify the actual exception handlers
1031 1036 self.InteractiveTB.call_pdb = val
1032 1037
1033 1038 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
1034 1039 'Control auto-activation of pdb at exceptions')
1035 1040
1036 1041 def debugger(self,force=False):
1037 1042 """Call the pdb debugger.
1038 1043
1039 1044 Keywords:
1040 1045
1041 1046 - force(False): by default, this routine checks the instance call_pdb
1042 1047 flag and does not actually invoke the debugger if the flag is false.
1043 1048 The 'force' option forces the debugger to activate even if the flag
1044 1049 is false.
1045 1050 """
1046 1051
1047 1052 if not (force or self.call_pdb):
1048 1053 return
1049 1054
1050 1055 if not hasattr(sys,'last_traceback'):
1051 1056 error('No traceback has been produced, nothing to debug.')
1052 1057 return
1053 1058
1054 1059 self.InteractiveTB.debugger(force=True)
1055 1060
1056 1061 #-------------------------------------------------------------------------
1057 1062 # Things related to IPython's various namespaces
1058 1063 #-------------------------------------------------------------------------
1059 1064 default_user_namespaces = True
1060 1065
1061 1066 def init_create_namespaces(self, user_module=None, user_ns=None):
1062 1067 # Create the namespace where the user will operate. user_ns is
1063 1068 # normally the only one used, and it is passed to the exec calls as
1064 1069 # the locals argument. But we do carry a user_global_ns namespace
1065 1070 # given as the exec 'globals' argument, This is useful in embedding
1066 1071 # situations where the ipython shell opens in a context where the
1067 1072 # distinction between locals and globals is meaningful. For
1068 1073 # non-embedded contexts, it is just the same object as the user_ns dict.
1069 1074
1070 1075 # FIXME. For some strange reason, __builtins__ is showing up at user
1071 1076 # level as a dict instead of a module. This is a manual fix, but I
1072 1077 # should really track down where the problem is coming from. Alex
1073 1078 # Schmolck reported this problem first.
1074 1079
1075 1080 # A useful post by Alex Martelli on this topic:
1076 1081 # Re: inconsistent value from __builtins__
1077 1082 # Von: Alex Martelli <aleaxit@yahoo.com>
1078 1083 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
1079 1084 # Gruppen: comp.lang.python
1080 1085
1081 1086 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
1082 1087 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
1083 1088 # > <type 'dict'>
1084 1089 # > >>> print type(__builtins__)
1085 1090 # > <type 'module'>
1086 1091 # > Is this difference in return value intentional?
1087 1092
1088 1093 # Well, it's documented that '__builtins__' can be either a dictionary
1089 1094 # or a module, and it's been that way for a long time. Whether it's
1090 1095 # intentional (or sensible), I don't know. In any case, the idea is
1091 1096 # that if you need to access the built-in namespace directly, you
1092 1097 # should start with "import __builtin__" (note, no 's') which will
1093 1098 # definitely give you a module. Yeah, it's somewhat confusing:-(.
1094 1099
1095 1100 # These routines return a properly built module and dict as needed by
1096 1101 # the rest of the code, and can also be used by extension writers to
1097 1102 # generate properly initialized namespaces.
1098 1103 if (user_ns is not None) or (user_module is not None):
1099 1104 self.default_user_namespaces = False
1100 1105 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
1101 1106
1102 1107 # A record of hidden variables we have added to the user namespace, so
1103 1108 # we can list later only variables defined in actual interactive use.
1104 1109 self.user_ns_hidden = {}
1105 1110
1106 1111 # Now that FakeModule produces a real module, we've run into a nasty
1107 1112 # problem: after script execution (via %run), the module where the user
1108 1113 # code ran is deleted. Now that this object is a true module (needed
1109 1114 # so doctest and other tools work correctly), the Python module
1110 1115 # teardown mechanism runs over it, and sets to None every variable
1111 1116 # present in that module. Top-level references to objects from the
1112 1117 # script survive, because the user_ns is updated with them. However,
1113 1118 # calling functions defined in the script that use other things from
1114 1119 # the script will fail, because the function's closure had references
1115 1120 # to the original objects, which are now all None. So we must protect
1116 1121 # these modules from deletion by keeping a cache.
1117 1122 #
1118 1123 # To avoid keeping stale modules around (we only need the one from the
1119 1124 # last run), we use a dict keyed with the full path to the script, so
1120 1125 # only the last version of the module is held in the cache. Note,
1121 1126 # however, that we must cache the module *namespace contents* (their
1122 1127 # __dict__). Because if we try to cache the actual modules, old ones
1123 1128 # (uncached) could be destroyed while still holding references (such as
1124 1129 # those held by GUI objects that tend to be long-lived)>
1125 1130 #
1126 1131 # The %reset command will flush this cache. See the cache_main_mod()
1127 1132 # and clear_main_mod_cache() methods for details on use.
1128 1133
1129 1134 # This is the cache used for 'main' namespaces
1130 1135 self._main_mod_cache = {}
1131 1136
1132 1137 # A table holding all the namespaces IPython deals with, so that
1133 1138 # introspection facilities can search easily.
1134 1139 self.ns_table = {'user_global':self.user_module.__dict__,
1135 1140 'user_local':self.user_ns,
1136 1141 'builtin':builtin_mod.__dict__
1137 1142 }
1138 1143
1139 1144 @property
1140 1145 def user_global_ns(self):
1141 1146 return self.user_module.__dict__
1142 1147
1143 1148 def prepare_user_module(self, user_module=None, user_ns=None):
1144 1149 """Prepare the module and namespace in which user code will be run.
1145 1150
1146 1151 When IPython is started normally, both parameters are None: a new module
1147 1152 is created automatically, and its __dict__ used as the namespace.
1148 1153
1149 1154 If only user_module is provided, its __dict__ is used as the namespace.
1150 1155 If only user_ns is provided, a dummy module is created, and user_ns
1151 1156 becomes the global namespace. If both are provided (as they may be
1152 1157 when embedding), user_ns is the local namespace, and user_module
1153 1158 provides the global namespace.
1154 1159
1155 1160 Parameters
1156 1161 ----------
1157 1162 user_module : module, optional
1158 1163 The current user module in which IPython is being run. If None,
1159 1164 a clean module will be created.
1160 1165 user_ns : dict, optional
1161 1166 A namespace in which to run interactive commands.
1162 1167
1163 1168 Returns
1164 1169 -------
1165 1170 A tuple of user_module and user_ns, each properly initialised.
1166 1171 """
1167 1172 if user_module is None and user_ns is not None:
1168 1173 user_ns.setdefault("__name__", "__main__")
1169 1174 user_module = DummyMod()
1170 1175 user_module.__dict__ = user_ns
1171 1176
1172 1177 if user_module is None:
1173 1178 user_module = types.ModuleType("__main__",
1174 1179 doc="Automatically created module for IPython interactive environment")
1175 1180
1176 1181 # We must ensure that __builtin__ (without the final 's') is always
1177 1182 # available and pointing to the __builtin__ *module*. For more details:
1178 1183 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1179 1184 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1180 1185 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1181 1186
1182 1187 if user_ns is None:
1183 1188 user_ns = user_module.__dict__
1184 1189
1185 1190 return user_module, user_ns
1186 1191
1187 1192 def init_sys_modules(self):
1188 1193 # We need to insert into sys.modules something that looks like a
1189 1194 # module but which accesses the IPython namespace, for shelve and
1190 1195 # pickle to work interactively. Normally they rely on getting
1191 1196 # everything out of __main__, but for embedding purposes each IPython
1192 1197 # instance has its own private namespace, so we can't go shoving
1193 1198 # everything into __main__.
1194 1199
1195 1200 # note, however, that we should only do this for non-embedded
1196 1201 # ipythons, which really mimic the __main__.__dict__ with their own
1197 1202 # namespace. Embedded instances, on the other hand, should not do
1198 1203 # this because they need to manage the user local/global namespaces
1199 1204 # only, but they live within a 'normal' __main__ (meaning, they
1200 1205 # shouldn't overtake the execution environment of the script they're
1201 1206 # embedded in).
1202 1207
1203 1208 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1204 1209 main_name = self.user_module.__name__
1205 1210 sys.modules[main_name] = self.user_module
1206 1211
1207 1212 def init_user_ns(self):
1208 1213 """Initialize all user-visible namespaces to their minimum defaults.
1209 1214
1210 1215 Certain history lists are also initialized here, as they effectively
1211 1216 act as user namespaces.
1212 1217
1213 1218 Notes
1214 1219 -----
1215 1220 All data structures here are only filled in, they are NOT reset by this
1216 1221 method. If they were not empty before, data will simply be added to
1217 1222 them.
1218 1223 """
1219 1224 # This function works in two parts: first we put a few things in
1220 1225 # user_ns, and we sync that contents into user_ns_hidden so that these
1221 1226 # initial variables aren't shown by %who. After the sync, we add the
1222 1227 # rest of what we *do* want the user to see with %who even on a new
1223 1228 # session (probably nothing, so they really only see their own stuff)
1224 1229
1225 1230 # The user dict must *always* have a __builtin__ reference to the
1226 1231 # Python standard __builtin__ namespace, which must be imported.
1227 1232 # This is so that certain operations in prompt evaluation can be
1228 1233 # reliably executed with builtins. Note that we can NOT use
1229 1234 # __builtins__ (note the 's'), because that can either be a dict or a
1230 1235 # module, and can even mutate at runtime, depending on the context
1231 1236 # (Python makes no guarantees on it). In contrast, __builtin__ is
1232 1237 # always a module object, though it must be explicitly imported.
1233 1238
1234 1239 # For more details:
1235 1240 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1236 1241 ns = {}
1237 1242
1238 1243 # make global variables for user access to the histories
1239 1244 ns['_ih'] = self.history_manager.input_hist_parsed
1240 1245 ns['_oh'] = self.history_manager.output_hist
1241 1246 ns['_dh'] = self.history_manager.dir_hist
1242 1247
1243 1248 # user aliases to input and output histories. These shouldn't show up
1244 1249 # in %who, as they can have very large reprs.
1245 1250 ns['In'] = self.history_manager.input_hist_parsed
1246 1251 ns['Out'] = self.history_manager.output_hist
1247 1252
1248 1253 # Store myself as the public api!!!
1249 1254 ns['get_ipython'] = self.get_ipython
1250 1255
1251 1256 ns['exit'] = self.exiter
1252 1257 ns['quit'] = self.exiter
1253 1258
1254 1259 # Sync what we've added so far to user_ns_hidden so these aren't seen
1255 1260 # by %who
1256 1261 self.user_ns_hidden.update(ns)
1257 1262
1258 1263 # Anything put into ns now would show up in %who. Think twice before
1259 1264 # putting anything here, as we really want %who to show the user their
1260 1265 # stuff, not our variables.
1261 1266
1262 1267 # Finally, update the real user's namespace
1263 1268 self.user_ns.update(ns)
1264 1269
1265 1270 @property
1266 1271 def all_ns_refs(self):
1267 1272 """Get a list of references to all the namespace dictionaries in which
1268 1273 IPython might store a user-created object.
1269 1274
1270 1275 Note that this does not include the displayhook, which also caches
1271 1276 objects from the output."""
1272 1277 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1273 1278 [m.__dict__ for m in self._main_mod_cache.values()]
1274 1279
1275 1280 def reset(self, new_session=True, aggressive=False):
1276 1281 """Clear all internal namespaces, and attempt to release references to
1277 1282 user objects.
1278 1283
1279 1284 If new_session is True, a new history session will be opened.
1280 1285 """
1281 1286 # Clear histories
1282 1287 self.history_manager.reset(new_session)
1283 1288 # Reset counter used to index all histories
1284 1289 if new_session:
1285 1290 self.execution_count = 1
1286 1291
1287 1292 # Reset last execution result
1288 1293 self.last_execution_succeeded = True
1289 1294 self.last_execution_result = None
1290 1295
1291 1296 # Flush cached output items
1292 1297 if self.displayhook.do_full_cache:
1293 1298 self.displayhook.flush()
1294 1299
1295 1300 # The main execution namespaces must be cleared very carefully,
1296 1301 # skipping the deletion of the builtin-related keys, because doing so
1297 1302 # would cause errors in many object's __del__ methods.
1298 1303 if self.user_ns is not self.user_global_ns:
1299 1304 self.user_ns.clear()
1300 1305 ns = self.user_global_ns
1301 1306 drop_keys = set(ns.keys())
1302 1307 drop_keys.discard('__builtin__')
1303 1308 drop_keys.discard('__builtins__')
1304 1309 drop_keys.discard('__name__')
1305 1310 for k in drop_keys:
1306 1311 del ns[k]
1307 1312
1308 1313 self.user_ns_hidden.clear()
1309 1314
1310 1315 # Restore the user namespaces to minimal usability
1311 1316 self.init_user_ns()
1312 1317 if aggressive and not hasattr(self, "_sys_modules_keys"):
1313 1318 print("Cannot restore sys.module, no snapshot")
1314 1319 elif aggressive:
1315 1320 print("culling sys module...")
1316 1321 current_keys = set(sys.modules.keys())
1317 1322 for k in current_keys - self._sys_modules_keys:
1318 1323 if k.startswith("multiprocessing"):
1319 1324 continue
1320 1325 del sys.modules[k]
1321 1326
1322 1327 # Restore the default and user aliases
1323 1328 self.alias_manager.clear_aliases()
1324 1329 self.alias_manager.init_aliases()
1325 1330
1326 1331 # Now define aliases that only make sense on the terminal, because they
1327 1332 # need direct access to the console in a way that we can't emulate in
1328 1333 # GUI or web frontend
1329 1334 if os.name == 'posix':
1330 1335 for cmd in ('clear', 'more', 'less', 'man'):
1331 1336 if cmd not in self.magics_manager.magics['line']:
1332 1337 self.alias_manager.soft_define_alias(cmd, cmd)
1333 1338
1334 1339 # Flush the private list of module references kept for script
1335 1340 # execution protection
1336 1341 self.clear_main_mod_cache()
1337 1342
1338 1343 def del_var(self, varname, by_name=False):
1339 1344 """Delete a variable from the various namespaces, so that, as
1340 1345 far as possible, we're not keeping any hidden references to it.
1341 1346
1342 1347 Parameters
1343 1348 ----------
1344 1349 varname : str
1345 1350 The name of the variable to delete.
1346 1351 by_name : bool
1347 1352 If True, delete variables with the given name in each
1348 1353 namespace. If False (default), find the variable in the user
1349 1354 namespace, and delete references to it.
1350 1355 """
1351 1356 if varname in ('__builtin__', '__builtins__'):
1352 1357 raise ValueError("Refusing to delete %s" % varname)
1353 1358
1354 1359 ns_refs = self.all_ns_refs
1355 1360
1356 1361 if by_name: # Delete by name
1357 1362 for ns in ns_refs:
1358 1363 try:
1359 1364 del ns[varname]
1360 1365 except KeyError:
1361 1366 pass
1362 1367 else: # Delete by object
1363 1368 try:
1364 1369 obj = self.user_ns[varname]
1365 1370 except KeyError as e:
1366 1371 raise NameError("name '%s' is not defined" % varname) from e
1367 1372 # Also check in output history
1368 1373 ns_refs.append(self.history_manager.output_hist)
1369 1374 for ns in ns_refs:
1370 1375 to_delete = [n for n, o in ns.items() if o is obj]
1371 1376 for name in to_delete:
1372 1377 del ns[name]
1373 1378
1374 1379 # Ensure it is removed from the last execution result
1375 1380 if self.last_execution_result.result is obj:
1376 1381 self.last_execution_result = None
1377 1382
1378 1383 # displayhook keeps extra references, but not in a dictionary
1379 1384 for name in ('_', '__', '___'):
1380 1385 if getattr(self.displayhook, name) is obj:
1381 1386 setattr(self.displayhook, name, None)
1382 1387
1383 1388 def reset_selective(self, regex=None):
1384 1389 """Clear selective variables from internal namespaces based on a
1385 1390 specified regular expression.
1386 1391
1387 1392 Parameters
1388 1393 ----------
1389 1394 regex : string or compiled pattern, optional
1390 1395 A regular expression pattern that will be used in searching
1391 1396 variable names in the users namespaces.
1392 1397 """
1393 1398 if regex is not None:
1394 1399 try:
1395 1400 m = re.compile(regex)
1396 1401 except TypeError as e:
1397 1402 raise TypeError('regex must be a string or compiled pattern') from e
1398 1403 # Search for keys in each namespace that match the given regex
1399 1404 # If a match is found, delete the key/value pair.
1400 1405 for ns in self.all_ns_refs:
1401 1406 for var in ns:
1402 1407 if m.search(var):
1403 1408 del ns[var]
1404 1409
1405 1410 def push(self, variables, interactive=True):
1406 1411 """Inject a group of variables into the IPython user namespace.
1407 1412
1408 1413 Parameters
1409 1414 ----------
1410 1415 variables : dict, str or list/tuple of str
1411 1416 The variables to inject into the user's namespace. If a dict, a
1412 1417 simple update is done. If a str, the string is assumed to have
1413 1418 variable names separated by spaces. A list/tuple of str can also
1414 1419 be used to give the variable names. If just the variable names are
1415 1420 give (list/tuple/str) then the variable values looked up in the
1416 1421 callers frame.
1417 1422 interactive : bool
1418 1423 If True (default), the variables will be listed with the ``who``
1419 1424 magic.
1420 1425 """
1421 1426 vdict = None
1422 1427
1423 1428 # We need a dict of name/value pairs to do namespace updates.
1424 1429 if isinstance(variables, dict):
1425 1430 vdict = variables
1426 1431 elif isinstance(variables, (str, list, tuple)):
1427 1432 if isinstance(variables, str):
1428 1433 vlist = variables.split()
1429 1434 else:
1430 1435 vlist = variables
1431 1436 vdict = {}
1432 1437 cf = sys._getframe(1)
1433 1438 for name in vlist:
1434 1439 try:
1435 1440 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1436 1441 except:
1437 1442 print('Could not get variable %s from %s' %
1438 1443 (name,cf.f_code.co_name))
1439 1444 else:
1440 1445 raise ValueError('variables must be a dict/str/list/tuple')
1441 1446
1442 1447 # Propagate variables to user namespace
1443 1448 self.user_ns.update(vdict)
1444 1449
1445 1450 # And configure interactive visibility
1446 1451 user_ns_hidden = self.user_ns_hidden
1447 1452 if interactive:
1448 1453 for name in vdict:
1449 1454 user_ns_hidden.pop(name, None)
1450 1455 else:
1451 1456 user_ns_hidden.update(vdict)
1452 1457
1453 1458 def drop_by_id(self, variables):
1454 1459 """Remove a dict of variables from the user namespace, if they are the
1455 1460 same as the values in the dictionary.
1456 1461
1457 1462 This is intended for use by extensions: variables that they've added can
1458 1463 be taken back out if they are unloaded, without removing any that the
1459 1464 user has overwritten.
1460 1465
1461 1466 Parameters
1462 1467 ----------
1463 1468 variables : dict
1464 1469 A dictionary mapping object names (as strings) to the objects.
1465 1470 """
1466 1471 for name, obj in variables.items():
1467 1472 if name in self.user_ns and self.user_ns[name] is obj:
1468 1473 del self.user_ns[name]
1469 1474 self.user_ns_hidden.pop(name, None)
1470 1475
1471 1476 #-------------------------------------------------------------------------
1472 1477 # Things related to object introspection
1473 1478 #-------------------------------------------------------------------------
1474 1479
1475 1480 def _ofind(self, oname, namespaces=None):
1476 1481 """Find an object in the available namespaces.
1477 1482
1478 1483 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1479 1484
1480 1485 Has special code to detect magic functions.
1481 1486 """
1482 1487 oname = oname.strip()
1483 1488 if not oname.startswith(ESC_MAGIC) and \
1484 1489 not oname.startswith(ESC_MAGIC2) and \
1485 1490 not all(a.isidentifier() for a in oname.split(".")):
1486 1491 return {'found': False}
1487 1492
1488 1493 if namespaces is None:
1489 1494 # Namespaces to search in:
1490 1495 # Put them in a list. The order is important so that we
1491 1496 # find things in the same order that Python finds them.
1492 1497 namespaces = [ ('Interactive', self.user_ns),
1493 1498 ('Interactive (global)', self.user_global_ns),
1494 1499 ('Python builtin', builtin_mod.__dict__),
1495 1500 ]
1496 1501
1497 1502 ismagic = False
1498 1503 isalias = False
1499 1504 found = False
1500 1505 ospace = None
1501 1506 parent = None
1502 1507 obj = None
1503 1508
1504 1509
1505 1510 # Look for the given name by splitting it in parts. If the head is
1506 1511 # found, then we look for all the remaining parts as members, and only
1507 1512 # declare success if we can find them all.
1508 1513 oname_parts = oname.split('.')
1509 1514 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1510 1515 for nsname,ns in namespaces:
1511 1516 try:
1512 1517 obj = ns[oname_head]
1513 1518 except KeyError:
1514 1519 continue
1515 1520 else:
1516 1521 for idx, part in enumerate(oname_rest):
1517 1522 try:
1518 1523 parent = obj
1519 1524 # The last part is looked up in a special way to avoid
1520 1525 # descriptor invocation as it may raise or have side
1521 1526 # effects.
1522 1527 if idx == len(oname_rest) - 1:
1523 1528 obj = self._getattr_property(obj, part)
1524 1529 else:
1525 1530 obj = getattr(obj, part)
1526 1531 except:
1527 1532 # Blanket except b/c some badly implemented objects
1528 1533 # allow __getattr__ to raise exceptions other than
1529 1534 # AttributeError, which then crashes IPython.
1530 1535 break
1531 1536 else:
1532 1537 # If we finish the for loop (no break), we got all members
1533 1538 found = True
1534 1539 ospace = nsname
1535 1540 break # namespace loop
1536 1541
1537 1542 # Try to see if it's magic
1538 1543 if not found:
1539 1544 obj = None
1540 1545 if oname.startswith(ESC_MAGIC2):
1541 1546 oname = oname.lstrip(ESC_MAGIC2)
1542 1547 obj = self.find_cell_magic(oname)
1543 1548 elif oname.startswith(ESC_MAGIC):
1544 1549 oname = oname.lstrip(ESC_MAGIC)
1545 1550 obj = self.find_line_magic(oname)
1546 1551 else:
1547 1552 # search without prefix, so run? will find %run?
1548 1553 obj = self.find_line_magic(oname)
1549 1554 if obj is None:
1550 1555 obj = self.find_cell_magic(oname)
1551 1556 if obj is not None:
1552 1557 found = True
1553 1558 ospace = 'IPython internal'
1554 1559 ismagic = True
1555 1560 isalias = isinstance(obj, Alias)
1556 1561
1557 1562 # Last try: special-case some literals like '', [], {}, etc:
1558 1563 if not found and oname_head in ["''",'""','[]','{}','()']:
1559 1564 obj = eval(oname_head)
1560 1565 found = True
1561 1566 ospace = 'Interactive'
1562 1567
1563 1568 return {
1564 1569 'obj':obj,
1565 1570 'found':found,
1566 1571 'parent':parent,
1567 1572 'ismagic':ismagic,
1568 1573 'isalias':isalias,
1569 1574 'namespace':ospace
1570 1575 }
1571 1576
1572 1577 @staticmethod
1573 1578 def _getattr_property(obj, attrname):
1574 1579 """Property-aware getattr to use in object finding.
1575 1580
1576 1581 If attrname represents a property, return it unevaluated (in case it has
1577 1582 side effects or raises an error.
1578 1583
1579 1584 """
1580 1585 if not isinstance(obj, type):
1581 1586 try:
1582 1587 # `getattr(type(obj), attrname)` is not guaranteed to return
1583 1588 # `obj`, but does so for property:
1584 1589 #
1585 1590 # property.__get__(self, None, cls) -> self
1586 1591 #
1587 1592 # The universal alternative is to traverse the mro manually
1588 1593 # searching for attrname in class dicts.
1589 1594 attr = getattr(type(obj), attrname)
1590 1595 except AttributeError:
1591 1596 pass
1592 1597 else:
1593 1598 # This relies on the fact that data descriptors (with both
1594 1599 # __get__ & __set__ magic methods) take precedence over
1595 1600 # instance-level attributes:
1596 1601 #
1597 1602 # class A(object):
1598 1603 # @property
1599 1604 # def foobar(self): return 123
1600 1605 # a = A()
1601 1606 # a.__dict__['foobar'] = 345
1602 1607 # a.foobar # == 123
1603 1608 #
1604 1609 # So, a property may be returned right away.
1605 1610 if isinstance(attr, property):
1606 1611 return attr
1607 1612
1608 1613 # Nothing helped, fall back.
1609 1614 return getattr(obj, attrname)
1610 1615
1611 1616 def _object_find(self, oname, namespaces=None):
1612 1617 """Find an object and return a struct with info about it."""
1613 1618 return Struct(self._ofind(oname, namespaces))
1614 1619
1615 1620 def _inspect(self, meth, oname, namespaces=None, **kw):
1616 1621 """Generic interface to the inspector system.
1617 1622
1618 1623 This function is meant to be called by pdef, pdoc & friends.
1619 1624 """
1620 1625 info = self._object_find(oname, namespaces)
1621 1626 docformat = sphinxify if self.sphinxify_docstring else None
1622 1627 if info.found:
1623 1628 pmethod = getattr(self.inspector, meth)
1624 1629 # TODO: only apply format_screen to the plain/text repr of the mime
1625 1630 # bundle.
1626 1631 formatter = format_screen if info.ismagic else docformat
1627 1632 if meth == 'pdoc':
1628 1633 pmethod(info.obj, oname, formatter)
1629 1634 elif meth == 'pinfo':
1630 1635 pmethod(
1631 1636 info.obj,
1632 1637 oname,
1633 1638 formatter,
1634 1639 info,
1635 1640 enable_html_pager=self.enable_html_pager,
1636 1641 **kw
1637 1642 )
1638 1643 else:
1639 1644 pmethod(info.obj, oname)
1640 1645 else:
1641 1646 print('Object `%s` not found.' % oname)
1642 1647 return 'not found' # so callers can take other action
1643 1648
1644 1649 def object_inspect(self, oname, detail_level=0):
1645 1650 """Get object info about oname"""
1646 1651 with self.builtin_trap:
1647 1652 info = self._object_find(oname)
1648 1653 if info.found:
1649 1654 return self.inspector.info(info.obj, oname, info=info,
1650 1655 detail_level=detail_level
1651 1656 )
1652 1657 else:
1653 1658 return oinspect.object_info(name=oname, found=False)
1654 1659
1655 1660 def object_inspect_text(self, oname, detail_level=0):
1656 1661 """Get object info as formatted text"""
1657 1662 return self.object_inspect_mime(oname, detail_level)['text/plain']
1658 1663
1659 1664 def object_inspect_mime(self, oname, detail_level=0, omit_sections=()):
1660 1665 """Get object info as a mimebundle of formatted representations.
1661 1666
1662 1667 A mimebundle is a dictionary, keyed by mime-type.
1663 1668 It must always have the key `'text/plain'`.
1664 1669 """
1665 1670 with self.builtin_trap:
1666 1671 info = self._object_find(oname)
1667 1672 if info.found:
1668 1673 docformat = sphinxify if self.sphinxify_docstring else None
1669 1674 return self.inspector._get_info(
1670 1675 info.obj,
1671 1676 oname,
1672 1677 info=info,
1673 1678 detail_level=detail_level,
1674 1679 formatter=docformat,
1675 1680 omit_sections=omit_sections,
1676 1681 )
1677 1682 else:
1678 1683 raise KeyError(oname)
1679 1684
1680 1685 #-------------------------------------------------------------------------
1681 1686 # Things related to history management
1682 1687 #-------------------------------------------------------------------------
1683 1688
1684 1689 def init_history(self):
1685 1690 """Sets up the command history, and starts regular autosaves."""
1686 1691 self.history_manager = HistoryManager(shell=self, parent=self)
1687 1692 self.configurables.append(self.history_manager)
1688 1693
1689 1694 #-------------------------------------------------------------------------
1690 1695 # Things related to exception handling and tracebacks (not debugging)
1691 1696 #-------------------------------------------------------------------------
1692 1697
1693 1698 debugger_cls = InterruptiblePdb
1694 1699
1695 1700 def init_traceback_handlers(self, custom_exceptions):
1696 1701 # Syntax error handler.
1697 1702 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor', parent=self)
1698 1703
1699 1704 # The interactive one is initialized with an offset, meaning we always
1700 1705 # want to remove the topmost item in the traceback, which is our own
1701 1706 # internal code. Valid modes: ['Plain','Context','Verbose','Minimal']
1702 1707 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1703 1708 color_scheme='NoColor',
1704 1709 tb_offset = 1,
1705 1710 check_cache=check_linecache_ipython,
1706 1711 debugger_cls=self.debugger_cls, parent=self)
1707 1712
1708 1713 # The instance will store a pointer to the system-wide exception hook,
1709 1714 # so that runtime code (such as magics) can access it. This is because
1710 1715 # during the read-eval loop, it may get temporarily overwritten.
1711 1716 self.sys_excepthook = sys.excepthook
1712 1717
1713 1718 # and add any custom exception handlers the user may have specified
1714 1719 self.set_custom_exc(*custom_exceptions)
1715 1720
1716 1721 # Set the exception mode
1717 1722 self.InteractiveTB.set_mode(mode=self.xmode)
1718 1723
1719 1724 def set_custom_exc(self, exc_tuple, handler):
1720 1725 """set_custom_exc(exc_tuple, handler)
1721 1726
1722 1727 Set a custom exception handler, which will be called if any of the
1723 1728 exceptions in exc_tuple occur in the mainloop (specifically, in the
1724 1729 run_code() method).
1725 1730
1726 1731 Parameters
1727 1732 ----------
1728 1733
1729 1734 exc_tuple : tuple of exception classes
1730 1735 A *tuple* of exception classes, for which to call the defined
1731 1736 handler. It is very important that you use a tuple, and NOT A
1732 1737 LIST here, because of the way Python's except statement works. If
1733 1738 you only want to trap a single exception, use a singleton tuple::
1734 1739
1735 1740 exc_tuple == (MyCustomException,)
1736 1741
1737 1742 handler : callable
1738 1743 handler must have the following signature::
1739 1744
1740 1745 def my_handler(self, etype, value, tb, tb_offset=None):
1741 1746 ...
1742 1747 return structured_traceback
1743 1748
1744 1749 Your handler must return a structured traceback (a list of strings),
1745 1750 or None.
1746 1751
1747 1752 This will be made into an instance method (via types.MethodType)
1748 1753 of IPython itself, and it will be called if any of the exceptions
1749 1754 listed in the exc_tuple are caught. If the handler is None, an
1750 1755 internal basic one is used, which just prints basic info.
1751 1756
1752 1757 To protect IPython from crashes, if your handler ever raises an
1753 1758 exception or returns an invalid result, it will be immediately
1754 1759 disabled.
1755 1760
1756 1761 Notes
1757 1762 -----
1758 1763
1759 1764 WARNING: by putting in your own exception handler into IPython's main
1760 1765 execution loop, you run a very good chance of nasty crashes. This
1761 1766 facility should only be used if you really know what you are doing.
1762 1767 """
1763 1768
1764 1769 if not isinstance(exc_tuple, tuple):
1765 1770 raise TypeError("The custom exceptions must be given as a tuple.")
1766 1771
1767 1772 def dummy_handler(self, etype, value, tb, tb_offset=None):
1768 1773 print('*** Simple custom exception handler ***')
1769 1774 print('Exception type :', etype)
1770 1775 print('Exception value:', value)
1771 1776 print('Traceback :', tb)
1772 1777
1773 1778 def validate_stb(stb):
1774 1779 """validate structured traceback return type
1775 1780
1776 1781 return type of CustomTB *should* be a list of strings, but allow
1777 1782 single strings or None, which are harmless.
1778 1783
1779 1784 This function will *always* return a list of strings,
1780 1785 and will raise a TypeError if stb is inappropriate.
1781 1786 """
1782 1787 msg = "CustomTB must return list of strings, not %r" % stb
1783 1788 if stb is None:
1784 1789 return []
1785 1790 elif isinstance(stb, str):
1786 1791 return [stb]
1787 1792 elif not isinstance(stb, list):
1788 1793 raise TypeError(msg)
1789 1794 # it's a list
1790 1795 for line in stb:
1791 1796 # check every element
1792 1797 if not isinstance(line, str):
1793 1798 raise TypeError(msg)
1794 1799 return stb
1795 1800
1796 1801 if handler is None:
1797 1802 wrapped = dummy_handler
1798 1803 else:
1799 1804 def wrapped(self,etype,value,tb,tb_offset=None):
1800 1805 """wrap CustomTB handler, to protect IPython from user code
1801 1806
1802 1807 This makes it harder (but not impossible) for custom exception
1803 1808 handlers to crash IPython.
1804 1809 """
1805 1810 try:
1806 1811 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1807 1812 return validate_stb(stb)
1808 1813 except:
1809 1814 # clear custom handler immediately
1810 1815 self.set_custom_exc((), None)
1811 1816 print("Custom TB Handler failed, unregistering", file=sys.stderr)
1812 1817 # show the exception in handler first
1813 1818 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1814 1819 print(self.InteractiveTB.stb2text(stb))
1815 1820 print("The original exception:")
1816 1821 stb = self.InteractiveTB.structured_traceback(
1817 1822 (etype,value,tb), tb_offset=tb_offset
1818 1823 )
1819 1824 return stb
1820 1825
1821 1826 self.CustomTB = types.MethodType(wrapped,self)
1822 1827 self.custom_exceptions = exc_tuple
1823 1828
1824 1829 def excepthook(self, etype, value, tb):
1825 1830 """One more defense for GUI apps that call sys.excepthook.
1826 1831
1827 1832 GUI frameworks like wxPython trap exceptions and call
1828 1833 sys.excepthook themselves. I guess this is a feature that
1829 1834 enables them to keep running after exceptions that would
1830 1835 otherwise kill their mainloop. This is a bother for IPython
1831 1836 which expects to catch all of the program exceptions with a try:
1832 1837 except: statement.
1833 1838
1834 1839 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1835 1840 any app directly invokes sys.excepthook, it will look to the user like
1836 1841 IPython crashed. In order to work around this, we can disable the
1837 1842 CrashHandler and replace it with this excepthook instead, which prints a
1838 1843 regular traceback using our InteractiveTB. In this fashion, apps which
1839 1844 call sys.excepthook will generate a regular-looking exception from
1840 1845 IPython, and the CrashHandler will only be triggered by real IPython
1841 1846 crashes.
1842 1847
1843 1848 This hook should be used sparingly, only in places which are not likely
1844 1849 to be true IPython errors.
1845 1850 """
1846 1851 self.showtraceback((etype, value, tb), tb_offset=0)
1847 1852
1848 1853 def _get_exc_info(self, exc_tuple=None):
1849 1854 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1850 1855
1851 1856 Ensures sys.last_type,value,traceback hold the exc_info we found,
1852 1857 from whichever source.
1853 1858
1854 1859 raises ValueError if none of these contain any information
1855 1860 """
1856 1861 if exc_tuple is None:
1857 1862 etype, value, tb = sys.exc_info()
1858 1863 else:
1859 1864 etype, value, tb = exc_tuple
1860 1865
1861 1866 if etype is None:
1862 1867 if hasattr(sys, 'last_type'):
1863 1868 etype, value, tb = sys.last_type, sys.last_value, \
1864 1869 sys.last_traceback
1865 1870
1866 1871 if etype is None:
1867 1872 raise ValueError("No exception to find")
1868 1873
1869 1874 # Now store the exception info in sys.last_type etc.
1870 1875 # WARNING: these variables are somewhat deprecated and not
1871 1876 # necessarily safe to use in a threaded environment, but tools
1872 1877 # like pdb depend on their existence, so let's set them. If we
1873 1878 # find problems in the field, we'll need to revisit their use.
1874 1879 sys.last_type = etype
1875 1880 sys.last_value = value
1876 1881 sys.last_traceback = tb
1877 1882
1878 1883 return etype, value, tb
1879 1884
1880 1885 def show_usage_error(self, exc):
1881 1886 """Show a short message for UsageErrors
1882 1887
1883 1888 These are special exceptions that shouldn't show a traceback.
1884 1889 """
1885 1890 print("UsageError: %s" % exc, file=sys.stderr)
1886 1891
1887 1892 def get_exception_only(self, exc_tuple=None):
1888 1893 """
1889 1894 Return as a string (ending with a newline) the exception that
1890 1895 just occurred, without any traceback.
1891 1896 """
1892 1897 etype, value, tb = self._get_exc_info(exc_tuple)
1893 1898 msg = traceback.format_exception_only(etype, value)
1894 1899 return ''.join(msg)
1895 1900
1896 1901 def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None,
1897 1902 exception_only=False, running_compiled_code=False):
1898 1903 """Display the exception that just occurred.
1899 1904
1900 1905 If nothing is known about the exception, this is the method which
1901 1906 should be used throughout the code for presenting user tracebacks,
1902 1907 rather than directly invoking the InteractiveTB object.
1903 1908
1904 1909 A specific showsyntaxerror() also exists, but this method can take
1905 1910 care of calling it if needed, so unless you are explicitly catching a
1906 1911 SyntaxError exception, don't try to analyze the stack manually and
1907 1912 simply call this method."""
1908 1913
1909 1914 try:
1910 1915 try:
1911 1916 etype, value, tb = self._get_exc_info(exc_tuple)
1912 1917 except ValueError:
1913 1918 print('No traceback available to show.', file=sys.stderr)
1914 1919 return
1915 1920
1916 1921 if issubclass(etype, SyntaxError):
1917 1922 # Though this won't be called by syntax errors in the input
1918 1923 # line, there may be SyntaxError cases with imported code.
1919 1924 self.showsyntaxerror(filename, running_compiled_code)
1920 1925 elif etype is UsageError:
1921 1926 self.show_usage_error(value)
1922 1927 else:
1923 1928 if exception_only:
1924 1929 stb = ['An exception has occurred, use %tb to see '
1925 1930 'the full traceback.\n']
1926 1931 stb.extend(self.InteractiveTB.get_exception_only(etype,
1927 1932 value))
1928 1933 else:
1929 1934 try:
1930 1935 # Exception classes can customise their traceback - we
1931 1936 # use this in IPython.parallel for exceptions occurring
1932 1937 # in the engines. This should return a list of strings.
1933 1938 stb = value._render_traceback_()
1934 1939 except Exception:
1935 1940 stb = self.InteractiveTB.structured_traceback(etype,
1936 1941 value, tb, tb_offset=tb_offset)
1937 1942
1938 1943 self._showtraceback(etype, value, stb)
1939 1944 if self.call_pdb:
1940 1945 # drop into debugger
1941 1946 self.debugger(force=True)
1942 1947 return
1943 1948
1944 1949 # Actually show the traceback
1945 1950 self._showtraceback(etype, value, stb)
1946 1951
1947 1952 except KeyboardInterrupt:
1948 1953 print('\n' + self.get_exception_only(), file=sys.stderr)
1949 1954
1950 1955 def _showtraceback(self, etype, evalue, stb: str):
1951 1956 """Actually show a traceback.
1952 1957
1953 1958 Subclasses may override this method to put the traceback on a different
1954 1959 place, like a side channel.
1955 1960 """
1956 1961 val = self.InteractiveTB.stb2text(stb)
1957 1962 try:
1958 1963 print(val)
1959 1964 except UnicodeEncodeError:
1960 1965 print(val.encode("utf-8", "backslashreplace").decode())
1961 1966
1962 1967 def showsyntaxerror(self, filename=None, running_compiled_code=False):
1963 1968 """Display the syntax error that just occurred.
1964 1969
1965 1970 This doesn't display a stack trace because there isn't one.
1966 1971
1967 1972 If a filename is given, it is stuffed in the exception instead
1968 1973 of what was there before (because Python's parser always uses
1969 1974 "<string>" when reading from a string).
1970 1975
1971 1976 If the syntax error occurred when running a compiled code (i.e. running_compile_code=True),
1972 1977 longer stack trace will be displayed.
1973 1978 """
1974 1979 etype, value, last_traceback = self._get_exc_info()
1975 1980
1976 1981 if filename and issubclass(etype, SyntaxError):
1977 1982 try:
1978 1983 value.filename = filename
1979 1984 except:
1980 1985 # Not the format we expect; leave it alone
1981 1986 pass
1982 1987
1983 1988 # If the error occurred when executing compiled code, we should provide full stacktrace.
1984 1989 elist = traceback.extract_tb(last_traceback) if running_compiled_code else []
1985 1990 stb = self.SyntaxTB.structured_traceback(etype, value, elist)
1986 1991 self._showtraceback(etype, value, stb)
1987 1992
1988 1993 # This is overridden in TerminalInteractiveShell to show a message about
1989 1994 # the %paste magic.
1990 1995 def showindentationerror(self):
1991 1996 """Called by _run_cell when there's an IndentationError in code entered
1992 1997 at the prompt.
1993 1998
1994 1999 This is overridden in TerminalInteractiveShell to show a message about
1995 2000 the %paste magic."""
1996 2001 self.showsyntaxerror()
1997 2002
1998 2003 @skip_doctest
1999 2004 def set_next_input(self, s, replace=False):
2000 2005 """ Sets the 'default' input string for the next command line.
2001 2006
2002 2007 Example::
2003 2008
2004 2009 In [1]: _ip.set_next_input("Hello Word")
2005 2010 In [2]: Hello Word_ # cursor is here
2006 2011 """
2007 2012 self.rl_next_input = s
2008 2013
2009 2014 def _indent_current_str(self):
2010 2015 """return the current level of indentation as a string"""
2011 2016 return self.input_splitter.get_indent_spaces() * ' '
2012 2017
2013 2018 #-------------------------------------------------------------------------
2014 2019 # Things related to text completion
2015 2020 #-------------------------------------------------------------------------
2016 2021
2017 2022 def init_completer(self):
2018 2023 """Initialize the completion machinery.
2019 2024
2020 2025 This creates completion machinery that can be used by client code,
2021 2026 either interactively in-process (typically triggered by the readline
2022 2027 library), programmatically (such as in test suites) or out-of-process
2023 2028 (typically over the network by remote frontends).
2024 2029 """
2025 2030 from IPython.core.completer import IPCompleter
2026 2031 from IPython.core.completerlib import (module_completer,
2027 2032 magic_run_completer, cd_completer, reset_completer)
2028 2033
2029 2034 self.Completer = IPCompleter(shell=self,
2030 2035 namespace=self.user_ns,
2031 2036 global_namespace=self.user_global_ns,
2032 2037 parent=self,
2033 2038 )
2034 2039 self.configurables.append(self.Completer)
2035 2040
2036 2041 # Add custom completers to the basic ones built into IPCompleter
2037 2042 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
2038 2043 self.strdispatchers['complete_command'] = sdisp
2039 2044 self.Completer.custom_completers = sdisp
2040 2045
2041 2046 self.set_hook('complete_command', module_completer, str_key = 'import')
2042 2047 self.set_hook('complete_command', module_completer, str_key = 'from')
2043 2048 self.set_hook('complete_command', module_completer, str_key = '%aimport')
2044 2049 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
2045 2050 self.set_hook('complete_command', cd_completer, str_key = '%cd')
2046 2051 self.set_hook('complete_command', reset_completer, str_key = '%reset')
2047 2052
2048 2053 @skip_doctest
2049 2054 def complete(self, text, line=None, cursor_pos=None):
2050 2055 """Return the completed text and a list of completions.
2051 2056
2052 2057 Parameters
2053 2058 ----------
2054 2059
2055 2060 text : string
2056 2061 A string of text to be completed on. It can be given as empty and
2057 2062 instead a line/position pair are given. In this case, the
2058 2063 completer itself will split the line like readline does.
2059 2064
2060 2065 line : string, optional
2061 2066 The complete line that text is part of.
2062 2067
2063 2068 cursor_pos : int, optional
2064 2069 The position of the cursor on the input line.
2065 2070
2066 2071 Returns
2067 2072 -------
2068 2073 text : string
2069 2074 The actual text that was completed.
2070 2075
2071 2076 matches : list
2072 2077 A sorted list with all possible completions.
2073 2078
2074 2079
2075 2080 Notes
2076 2081 -----
2077 2082 The optional arguments allow the completion to take more context into
2078 2083 account, and are part of the low-level completion API.
2079 2084
2080 2085 This is a wrapper around the completion mechanism, similar to what
2081 2086 readline does at the command line when the TAB key is hit. By
2082 2087 exposing it as a method, it can be used by other non-readline
2083 2088 environments (such as GUIs) for text completion.
2084 2089
2085 2090 Examples
2086 2091 --------
2087 2092
2088 2093 In [1]: x = 'hello'
2089 2094
2090 2095 In [2]: _ip.complete('x.l')
2091 2096 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2092 2097 """
2093 2098
2094 2099 # Inject names into __builtin__ so we can complete on the added names.
2095 2100 with self.builtin_trap:
2096 2101 return self.Completer.complete(text, line, cursor_pos)
2097 2102
2098 2103 def set_custom_completer(self, completer, pos=0) -> None:
2099 2104 """Adds a new custom completer function.
2100 2105
2101 2106 The position argument (defaults to 0) is the index in the completers
2102 2107 list where you want the completer to be inserted.
2103 2108
2104 2109 `completer` should have the following signature::
2105 2110
2106 2111 def completion(self: Completer, text: string) -> List[str]:
2107 2112 raise NotImplementedError
2108 2113
2109 2114 It will be bound to the current Completer instance and pass some text
2110 2115 and return a list with current completions to suggest to the user.
2111 2116 """
2112 2117
2113 2118 newcomp = types.MethodType(completer, self.Completer)
2114 2119 self.Completer.custom_matchers.insert(pos,newcomp)
2115 2120
2116 2121 def set_completer_frame(self, frame=None):
2117 2122 """Set the frame of the completer."""
2118 2123 if frame:
2119 2124 self.Completer.namespace = frame.f_locals
2120 2125 self.Completer.global_namespace = frame.f_globals
2121 2126 else:
2122 2127 self.Completer.namespace = self.user_ns
2123 2128 self.Completer.global_namespace = self.user_global_ns
2124 2129
2125 2130 #-------------------------------------------------------------------------
2126 2131 # Things related to magics
2127 2132 #-------------------------------------------------------------------------
2128 2133
2129 2134 def init_magics(self):
2130 2135 from IPython.core import magics as m
2131 2136 self.magics_manager = magic.MagicsManager(shell=self,
2132 2137 parent=self,
2133 2138 user_magics=m.UserMagics(self))
2134 2139 self.configurables.append(self.magics_manager)
2135 2140
2136 2141 # Expose as public API from the magics manager
2137 2142 self.register_magics = self.magics_manager.register
2138 2143
2139 2144 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2140 2145 m.ConfigMagics, m.DisplayMagics, m.ExecutionMagics,
2141 2146 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2142 2147 m.NamespaceMagics, m.OSMagics, m.PackagingMagics,
2143 2148 m.PylabMagics, m.ScriptMagics,
2144 2149 )
2145 2150 self.register_magics(m.AsyncMagics)
2146 2151
2147 2152 # Register Magic Aliases
2148 2153 mman = self.magics_manager
2149 2154 # FIXME: magic aliases should be defined by the Magics classes
2150 2155 # or in MagicsManager, not here
2151 2156 mman.register_alias('ed', 'edit')
2152 2157 mman.register_alias('hist', 'history')
2153 2158 mman.register_alias('rep', 'recall')
2154 2159 mman.register_alias('SVG', 'svg', 'cell')
2155 2160 mman.register_alias('HTML', 'html', 'cell')
2156 2161 mman.register_alias('file', 'writefile', 'cell')
2157 2162
2158 2163 # FIXME: Move the color initialization to the DisplayHook, which
2159 2164 # should be split into a prompt manager and displayhook. We probably
2160 2165 # even need a centralize colors management object.
2161 2166 self.run_line_magic('colors', self.colors)
2162 2167
2163 2168 # Defined here so that it's included in the documentation
2164 2169 @functools.wraps(magic.MagicsManager.register_function)
2165 2170 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2166 2171 self.magics_manager.register_function(
2167 2172 func, magic_kind=magic_kind, magic_name=magic_name
2168 2173 )
2169 2174
2170 2175 def run_line_magic(self, magic_name, line, _stack_depth=1):
2171 2176 """Execute the given line magic.
2172 2177
2173 2178 Parameters
2174 2179 ----------
2175 2180 magic_name : str
2176 2181 Name of the desired magic function, without '%' prefix.
2177 2182 line : str
2178 2183 The rest of the input line as a single string.
2179 2184 _stack_depth : int
2180 2185 If run_line_magic() is called from magic() then _stack_depth=2.
2181 2186 This is added to ensure backward compatibility for use of 'get_ipython().magic()'
2182 2187 """
2183 2188 fn = self.find_line_magic(magic_name)
2184 2189 if fn is None:
2185 2190 cm = self.find_cell_magic(magic_name)
2186 2191 etpl = "Line magic function `%%%s` not found%s."
2187 2192 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2188 2193 'did you mean that instead?)' % magic_name )
2189 2194 raise UsageError(etpl % (magic_name, extra))
2190 2195 else:
2191 2196 # Note: this is the distance in the stack to the user's frame.
2192 2197 # This will need to be updated if the internal calling logic gets
2193 2198 # refactored, or else we'll be expanding the wrong variables.
2194 2199
2195 2200 # Determine stack_depth depending on where run_line_magic() has been called
2196 2201 stack_depth = _stack_depth
2197 2202 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2198 2203 # magic has opted out of var_expand
2199 2204 magic_arg_s = line
2200 2205 else:
2201 2206 magic_arg_s = self.var_expand(line, stack_depth)
2202 2207 # Put magic args in a list so we can call with f(*a) syntax
2203 2208 args = [magic_arg_s]
2204 2209 kwargs = {}
2205 2210 # Grab local namespace if we need it:
2206 2211 if getattr(fn, "needs_local_scope", False):
2207 2212 kwargs['local_ns'] = self.get_local_scope(stack_depth)
2208 2213 with self.builtin_trap:
2209 2214 result = fn(*args, **kwargs)
2210 2215 return result
2211 2216
2212 2217 def get_local_scope(self, stack_depth):
2213 2218 """Get local scope at given stack depth.
2214 2219
2215 2220 Parameters
2216 2221 ----------
2217 2222 stack_depth : int
2218 2223 Depth relative to calling frame
2219 2224 """
2220 2225 return sys._getframe(stack_depth + 1).f_locals
2221 2226
2222 2227 def run_cell_magic(self, magic_name, line, cell):
2223 2228 """Execute the given cell magic.
2224 2229
2225 2230 Parameters
2226 2231 ----------
2227 2232 magic_name : str
2228 2233 Name of the desired magic function, without '%' prefix.
2229 2234 line : str
2230 2235 The rest of the first input line as a single string.
2231 2236 cell : str
2232 2237 The body of the cell as a (possibly multiline) string.
2233 2238 """
2234 2239 fn = self.find_cell_magic(magic_name)
2235 2240 if fn is None:
2236 2241 lm = self.find_line_magic(magic_name)
2237 2242 etpl = "Cell magic `%%{0}` not found{1}."
2238 2243 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2239 2244 'did you mean that instead?)'.format(magic_name))
2240 2245 raise UsageError(etpl.format(magic_name, extra))
2241 2246 elif cell == '':
2242 2247 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2243 2248 if self.find_line_magic(magic_name) is not None:
2244 2249 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2245 2250 raise UsageError(message)
2246 2251 else:
2247 2252 # Note: this is the distance in the stack to the user's frame.
2248 2253 # This will need to be updated if the internal calling logic gets
2249 2254 # refactored, or else we'll be expanding the wrong variables.
2250 2255 stack_depth = 2
2251 2256 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2252 2257 # magic has opted out of var_expand
2253 2258 magic_arg_s = line
2254 2259 else:
2255 2260 magic_arg_s = self.var_expand(line, stack_depth)
2256 2261 kwargs = {}
2257 2262 if getattr(fn, "needs_local_scope", False):
2258 2263 kwargs['local_ns'] = self.user_ns
2259 2264
2260 2265 with self.builtin_trap:
2261 2266 args = (magic_arg_s, cell)
2262 2267 result = fn(*args, **kwargs)
2263 2268 return result
2264 2269
2265 2270 def find_line_magic(self, magic_name):
2266 2271 """Find and return a line magic by name.
2267 2272
2268 2273 Returns None if the magic isn't found."""
2269 2274 return self.magics_manager.magics['line'].get(magic_name)
2270 2275
2271 2276 def find_cell_magic(self, magic_name):
2272 2277 """Find and return a cell magic by name.
2273 2278
2274 2279 Returns None if the magic isn't found."""
2275 2280 return self.magics_manager.magics['cell'].get(magic_name)
2276 2281
2277 2282 def find_magic(self, magic_name, magic_kind='line'):
2278 2283 """Find and return a magic of the given type by name.
2279 2284
2280 2285 Returns None if the magic isn't found."""
2281 2286 return self.magics_manager.magics[magic_kind].get(magic_name)
2282 2287
2283 2288 def magic(self, arg_s):
2284 2289 """DEPRECATED. Use run_line_magic() instead.
2285 2290
2286 2291 Call a magic function by name.
2287 2292
2288 2293 Input: a string containing the name of the magic function to call and
2289 2294 any additional arguments to be passed to the magic.
2290 2295
2291 2296 magic('name -opt foo bar') is equivalent to typing at the ipython
2292 2297 prompt:
2293 2298
2294 2299 In[1]: %name -opt foo bar
2295 2300
2296 2301 To call a magic without arguments, simply use magic('name').
2297 2302
2298 2303 This provides a proper Python function to call IPython's magics in any
2299 2304 valid Python code you can type at the interpreter, including loops and
2300 2305 compound statements.
2301 2306 """
2302 2307 # TODO: should we issue a loud deprecation warning here?
2303 2308 magic_name, _, magic_arg_s = arg_s.partition(' ')
2304 2309 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2305 2310 return self.run_line_magic(magic_name, magic_arg_s, _stack_depth=2)
2306 2311
2307 2312 #-------------------------------------------------------------------------
2308 2313 # Things related to macros
2309 2314 #-------------------------------------------------------------------------
2310 2315
2311 2316 def define_macro(self, name, themacro):
2312 2317 """Define a new macro
2313 2318
2314 2319 Parameters
2315 2320 ----------
2316 2321 name : str
2317 2322 The name of the macro.
2318 2323 themacro : str or Macro
2319 2324 The action to do upon invoking the macro. If a string, a new
2320 2325 Macro object is created by passing the string to it.
2321 2326 """
2322 2327
2323 2328 from IPython.core import macro
2324 2329
2325 2330 if isinstance(themacro, str):
2326 2331 themacro = macro.Macro(themacro)
2327 2332 if not isinstance(themacro, macro.Macro):
2328 2333 raise ValueError('A macro must be a string or a Macro instance.')
2329 2334 self.user_ns[name] = themacro
2330 2335
2331 2336 #-------------------------------------------------------------------------
2332 2337 # Things related to the running of system commands
2333 2338 #-------------------------------------------------------------------------
2334 2339
2335 2340 def system_piped(self, cmd):
2336 2341 """Call the given cmd in a subprocess, piping stdout/err
2337 2342
2338 2343 Parameters
2339 2344 ----------
2340 2345 cmd : str
2341 2346 Command to execute (can not end in '&', as background processes are
2342 2347 not supported. Should not be a command that expects input
2343 2348 other than simple text.
2344 2349 """
2345 2350 if cmd.rstrip().endswith('&'):
2346 2351 # this is *far* from a rigorous test
2347 2352 # We do not support backgrounding processes because we either use
2348 2353 # pexpect or pipes to read from. Users can always just call
2349 2354 # os.system() or use ip.system=ip.system_raw
2350 2355 # if they really want a background process.
2351 2356 raise OSError("Background processes not supported.")
2352 2357
2353 2358 # we explicitly do NOT return the subprocess status code, because
2354 2359 # a non-None value would trigger :func:`sys.displayhook` calls.
2355 2360 # Instead, we store the exit_code in user_ns.
2356 2361 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2357 2362
2358 2363 def system_raw(self, cmd):
2359 2364 """Call the given cmd in a subprocess using os.system on Windows or
2360 2365 subprocess.call using the system shell on other platforms.
2361 2366
2362 2367 Parameters
2363 2368 ----------
2364 2369 cmd : str
2365 2370 Command to execute.
2366 2371 """
2367 2372 cmd = self.var_expand(cmd, depth=1)
2368 2373 # warn if there is an IPython magic alternative.
2369 2374 main_cmd = cmd.split()[0]
2370 2375 has_magic_alternatives = ("pip", "conda", "cd", "ls")
2371 2376
2372 2377 # had to check if the command was an alias expanded because of `ls`
2373 2378 is_alias_expanded = self.alias_manager.is_alias(main_cmd) and (
2374 2379 self.alias_manager.retrieve_alias(main_cmd).strip() == cmd.strip()
2375 2380 )
2376 2381
2377 2382 if main_cmd in has_magic_alternatives and not is_alias_expanded:
2378 2383 warnings.warn(
2379 2384 (
2380 2385 "You executed the system command !{0} which may not work "
2381 2386 "as expected. Try the IPython magic %{0} instead."
2382 2387 ).format(main_cmd)
2383 2388 )
2384 2389
2385 2390 # protect os.system from UNC paths on Windows, which it can't handle:
2386 2391 if sys.platform == 'win32':
2387 2392 from IPython.utils._process_win32 import AvoidUNCPath
2388 2393 with AvoidUNCPath() as path:
2389 2394 if path is not None:
2390 2395 cmd = '"pushd %s &&"%s' % (path, cmd)
2391 2396 try:
2392 2397 ec = os.system(cmd)
2393 2398 except KeyboardInterrupt:
2394 2399 print('\n' + self.get_exception_only(), file=sys.stderr)
2395 2400 ec = -2
2396 2401 else:
2397 2402 # For posix the result of the subprocess.call() below is an exit
2398 2403 # code, which by convention is zero for success, positive for
2399 2404 # program failure. Exit codes above 128 are reserved for signals,
2400 2405 # and the formula for converting a signal to an exit code is usually
2401 2406 # signal_number+128. To more easily differentiate between exit
2402 2407 # codes and signals, ipython uses negative numbers. For instance
2403 2408 # since control-c is signal 2 but exit code 130, ipython's
2404 2409 # _exit_code variable will read -2. Note that some shells like
2405 2410 # csh and fish don't follow sh/bash conventions for exit codes.
2406 2411 executable = os.environ.get('SHELL', None)
2407 2412 try:
2408 2413 # Use env shell instead of default /bin/sh
2409 2414 ec = subprocess.call(cmd, shell=True, executable=executable)
2410 2415 except KeyboardInterrupt:
2411 2416 # intercept control-C; a long traceback is not useful here
2412 2417 print('\n' + self.get_exception_only(), file=sys.stderr)
2413 2418 ec = 130
2414 2419 if ec > 128:
2415 2420 ec = -(ec - 128)
2416 2421
2417 2422 # We explicitly do NOT return the subprocess status code, because
2418 2423 # a non-None value would trigger :func:`sys.displayhook` calls.
2419 2424 # Instead, we store the exit_code in user_ns. Note the semantics
2420 2425 # of _exit_code: for control-c, _exit_code == -signal.SIGNIT,
2421 2426 # but raising SystemExit(_exit_code) will give status 254!
2422 2427 self.user_ns['_exit_code'] = ec
2423 2428
2424 2429 # use piped system by default, because it is better behaved
2425 2430 system = system_piped
2426 2431
2427 2432 def getoutput(self, cmd, split=True, depth=0):
2428 2433 """Get output (possibly including stderr) from a subprocess.
2429 2434
2430 2435 Parameters
2431 2436 ----------
2432 2437 cmd : str
2433 2438 Command to execute (can not end in '&', as background processes are
2434 2439 not supported.
2435 2440 split : bool, optional
2436 2441 If True, split the output into an IPython SList. Otherwise, an
2437 2442 IPython LSString is returned. These are objects similar to normal
2438 2443 lists and strings, with a few convenience attributes for easier
2439 2444 manipulation of line-based output. You can use '?' on them for
2440 2445 details.
2441 2446 depth : int, optional
2442 2447 How many frames above the caller are the local variables which should
2443 2448 be expanded in the command string? The default (0) assumes that the
2444 2449 expansion variables are in the stack frame calling this function.
2445 2450 """
2446 2451 if cmd.rstrip().endswith('&'):
2447 2452 # this is *far* from a rigorous test
2448 2453 raise OSError("Background processes not supported.")
2449 2454 out = getoutput(self.var_expand(cmd, depth=depth+1))
2450 2455 if split:
2451 2456 out = SList(out.splitlines())
2452 2457 else:
2453 2458 out = LSString(out)
2454 2459 return out
2455 2460
2456 2461 #-------------------------------------------------------------------------
2457 2462 # Things related to aliases
2458 2463 #-------------------------------------------------------------------------
2459 2464
2460 2465 def init_alias(self):
2461 2466 self.alias_manager = AliasManager(shell=self, parent=self)
2462 2467 self.configurables.append(self.alias_manager)
2463 2468
2464 2469 #-------------------------------------------------------------------------
2465 2470 # Things related to extensions
2466 2471 #-------------------------------------------------------------------------
2467 2472
2468 2473 def init_extension_manager(self):
2469 2474 self.extension_manager = ExtensionManager(shell=self, parent=self)
2470 2475 self.configurables.append(self.extension_manager)
2471 2476
2472 2477 #-------------------------------------------------------------------------
2473 2478 # Things related to payloads
2474 2479 #-------------------------------------------------------------------------
2475 2480
2476 2481 def init_payload(self):
2477 2482 self.payload_manager = PayloadManager(parent=self)
2478 2483 self.configurables.append(self.payload_manager)
2479 2484
2480 2485 #-------------------------------------------------------------------------
2481 2486 # Things related to the prefilter
2482 2487 #-------------------------------------------------------------------------
2483 2488
2484 2489 def init_prefilter(self):
2485 2490 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2486 2491 self.configurables.append(self.prefilter_manager)
2487 2492 # Ultimately this will be refactored in the new interpreter code, but
2488 2493 # for now, we should expose the main prefilter method (there's legacy
2489 2494 # code out there that may rely on this).
2490 2495 self.prefilter = self.prefilter_manager.prefilter_lines
2491 2496
2492 2497 def auto_rewrite_input(self, cmd):
2493 2498 """Print to the screen the rewritten form of the user's command.
2494 2499
2495 2500 This shows visual feedback by rewriting input lines that cause
2496 2501 automatic calling to kick in, like::
2497 2502
2498 2503 /f x
2499 2504
2500 2505 into::
2501 2506
2502 2507 ------> f(x)
2503 2508
2504 2509 after the user's input prompt. This helps the user understand that the
2505 2510 input line was transformed automatically by IPython.
2506 2511 """
2507 2512 if not self.show_rewritten_input:
2508 2513 return
2509 2514
2510 2515 # This is overridden in TerminalInteractiveShell to use fancy prompts
2511 2516 print("------> " + cmd)
2512 2517
2513 2518 #-------------------------------------------------------------------------
2514 2519 # Things related to extracting values/expressions from kernel and user_ns
2515 2520 #-------------------------------------------------------------------------
2516 2521
2517 2522 def _user_obj_error(self):
2518 2523 """return simple exception dict
2519 2524
2520 2525 for use in user_expressions
2521 2526 """
2522 2527
2523 2528 etype, evalue, tb = self._get_exc_info()
2524 2529 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2525 2530
2526 2531 exc_info = {
2527 2532 "status": "error",
2528 2533 "traceback": stb,
2529 2534 "ename": etype.__name__,
2530 2535 "evalue": py3compat.safe_unicode(evalue),
2531 2536 }
2532 2537
2533 2538 return exc_info
2534 2539
2535 2540 def _format_user_obj(self, obj):
2536 2541 """format a user object to display dict
2537 2542
2538 2543 for use in user_expressions
2539 2544 """
2540 2545
2541 2546 data, md = self.display_formatter.format(obj)
2542 2547 value = {
2543 2548 'status' : 'ok',
2544 2549 'data' : data,
2545 2550 'metadata' : md,
2546 2551 }
2547 2552 return value
2548 2553
2549 2554 def user_expressions(self, expressions):
2550 2555 """Evaluate a dict of expressions in the user's namespace.
2551 2556
2552 2557 Parameters
2553 2558 ----------
2554 2559 expressions : dict
2555 2560 A dict with string keys and string values. The expression values
2556 2561 should be valid Python expressions, each of which will be evaluated
2557 2562 in the user namespace.
2558 2563
2559 2564 Returns
2560 2565 -------
2561 2566 A dict, keyed like the input expressions dict, with the rich mime-typed
2562 2567 display_data of each value.
2563 2568 """
2564 2569 out = {}
2565 2570 user_ns = self.user_ns
2566 2571 global_ns = self.user_global_ns
2567 2572
2568 2573 for key, expr in expressions.items():
2569 2574 try:
2570 2575 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2571 2576 except:
2572 2577 value = self._user_obj_error()
2573 2578 out[key] = value
2574 2579 return out
2575 2580
2576 2581 #-------------------------------------------------------------------------
2577 2582 # Things related to the running of code
2578 2583 #-------------------------------------------------------------------------
2579 2584
2580 2585 def ex(self, cmd):
2581 2586 """Execute a normal python statement in user namespace."""
2582 2587 with self.builtin_trap:
2583 2588 exec(cmd, self.user_global_ns, self.user_ns)
2584 2589
2585 2590 def ev(self, expr):
2586 2591 """Evaluate python expression expr in user namespace.
2587 2592
2588 2593 Returns the result of evaluation
2589 2594 """
2590 2595 with self.builtin_trap:
2591 2596 return eval(expr, self.user_global_ns, self.user_ns)
2592 2597
2593 2598 def safe_execfile(self, fname, *where, exit_ignore=False, raise_exceptions=False, shell_futures=False):
2594 2599 """A safe version of the builtin execfile().
2595 2600
2596 2601 This version will never throw an exception, but instead print
2597 2602 helpful error messages to the screen. This only works on pure
2598 2603 Python files with the .py extension.
2599 2604
2600 2605 Parameters
2601 2606 ----------
2602 2607 fname : string
2603 2608 The name of the file to be executed.
2604 2609 where : tuple
2605 2610 One or two namespaces, passed to execfile() as (globals,locals).
2606 2611 If only one is given, it is passed as both.
2607 2612 exit_ignore : bool (False)
2608 2613 If True, then silence SystemExit for non-zero status (it is always
2609 2614 silenced for zero status, as it is so common).
2610 2615 raise_exceptions : bool (False)
2611 2616 If True raise exceptions everywhere. Meant for testing.
2612 2617 shell_futures : bool (False)
2613 2618 If True, the code will share future statements with the interactive
2614 2619 shell. It will both be affected by previous __future__ imports, and
2615 2620 any __future__ imports in the code will affect the shell. If False,
2616 2621 __future__ imports are not shared in either direction.
2617 2622
2618 2623 """
2619 2624 fname = Path(fname).expanduser().resolve()
2620 2625
2621 2626 # Make sure we can open the file
2622 2627 try:
2623 2628 with fname.open():
2624 2629 pass
2625 2630 except:
2626 2631 warn('Could not open file <%s> for safe execution.' % fname)
2627 2632 return
2628 2633
2629 2634 # Find things also in current directory. This is needed to mimic the
2630 2635 # behavior of running a script from the system command line, where
2631 2636 # Python inserts the script's directory into sys.path
2632 2637 dname = str(fname.parent)
2633 2638
2634 2639 with prepended_to_syspath(dname), self.builtin_trap:
2635 2640 try:
2636 2641 glob, loc = (where + (None, ))[:2]
2637 2642 py3compat.execfile(
2638 2643 fname, glob, loc,
2639 2644 self.compile if shell_futures else None)
2640 2645 except SystemExit as status:
2641 2646 # If the call was made with 0 or None exit status (sys.exit(0)
2642 2647 # or sys.exit() ), don't bother showing a traceback, as both of
2643 2648 # these are considered normal by the OS:
2644 2649 # > python -c'import sys;sys.exit(0)'; echo $?
2645 2650 # 0
2646 2651 # > python -c'import sys;sys.exit()'; echo $?
2647 2652 # 0
2648 2653 # For other exit status, we show the exception unless
2649 2654 # explicitly silenced, but only in short form.
2650 2655 if status.code:
2651 2656 if raise_exceptions:
2652 2657 raise
2653 2658 if not exit_ignore:
2654 2659 self.showtraceback(exception_only=True)
2655 2660 except:
2656 2661 if raise_exceptions:
2657 2662 raise
2658 2663 # tb offset is 2 because we wrap execfile
2659 2664 self.showtraceback(tb_offset=2)
2660 2665
2661 2666 def safe_execfile_ipy(self, fname, shell_futures=False, raise_exceptions=False):
2662 2667 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2663 2668
2664 2669 Parameters
2665 2670 ----------
2666 2671 fname : str
2667 2672 The name of the file to execute. The filename must have a
2668 2673 .ipy or .ipynb extension.
2669 2674 shell_futures : bool (False)
2670 2675 If True, the code will share future statements with the interactive
2671 2676 shell. It will both be affected by previous __future__ imports, and
2672 2677 any __future__ imports in the code will affect the shell. If False,
2673 2678 __future__ imports are not shared in either direction.
2674 2679 raise_exceptions : bool (False)
2675 2680 If True raise exceptions everywhere. Meant for testing.
2676 2681 """
2677 2682 fname = Path(fname).expanduser().resolve()
2678 2683
2679 2684 # Make sure we can open the file
2680 2685 try:
2681 2686 with fname.open():
2682 2687 pass
2683 2688 except:
2684 2689 warn('Could not open file <%s> for safe execution.' % fname)
2685 2690 return
2686 2691
2687 2692 # Find things also in current directory. This is needed to mimic the
2688 2693 # behavior of running a script from the system command line, where
2689 2694 # Python inserts the script's directory into sys.path
2690 2695 dname = str(fname.parent)
2691 2696
2692 2697 def get_cells():
2693 2698 """generator for sequence of code blocks to run"""
2694 2699 if fname.suffix == ".ipynb":
2695 2700 from nbformat import read
2696 2701 nb = read(fname, as_version=4)
2697 2702 if not nb.cells:
2698 2703 return
2699 2704 for cell in nb.cells:
2700 2705 if cell.cell_type == 'code':
2701 2706 yield cell.source
2702 2707 else:
2703 2708 yield fname.read_text()
2704 2709
2705 2710 with prepended_to_syspath(dname):
2706 2711 try:
2707 2712 for cell in get_cells():
2708 2713 result = self.run_cell(cell, silent=True, shell_futures=shell_futures)
2709 2714 if raise_exceptions:
2710 2715 result.raise_error()
2711 2716 elif not result.success:
2712 2717 break
2713 2718 except:
2714 2719 if raise_exceptions:
2715 2720 raise
2716 2721 self.showtraceback()
2717 2722 warn('Unknown failure executing file: <%s>' % fname)
2718 2723
2719 2724 def safe_run_module(self, mod_name, where):
2720 2725 """A safe version of runpy.run_module().
2721 2726
2722 2727 This version will never throw an exception, but instead print
2723 2728 helpful error messages to the screen.
2724 2729
2725 2730 `SystemExit` exceptions with status code 0 or None are ignored.
2726 2731
2727 2732 Parameters
2728 2733 ----------
2729 2734 mod_name : string
2730 2735 The name of the module to be executed.
2731 2736 where : dict
2732 2737 The globals namespace.
2733 2738 """
2734 2739 try:
2735 2740 try:
2736 2741 where.update(
2737 2742 runpy.run_module(str(mod_name), run_name="__main__",
2738 2743 alter_sys=True)
2739 2744 )
2740 2745 except SystemExit as status:
2741 2746 if status.code:
2742 2747 raise
2743 2748 except:
2744 2749 self.showtraceback()
2745 2750 warn('Unknown failure executing module: <%s>' % mod_name)
2746 2751
2747 2752 def run_cell(self, raw_cell, store_history=False, silent=False, shell_futures=True):
2748 2753 """Run a complete IPython cell.
2749 2754
2750 2755 Parameters
2751 2756 ----------
2752 2757 raw_cell : str
2753 2758 The code (including IPython code such as %magic functions) to run.
2754 2759 store_history : bool
2755 2760 If True, the raw and translated cell will be stored in IPython's
2756 2761 history. For user code calling back into IPython's machinery, this
2757 2762 should be set to False.
2758 2763 silent : bool
2759 2764 If True, avoid side-effects, such as implicit displayhooks and
2760 2765 and logging. silent=True forces store_history=False.
2761 2766 shell_futures : bool
2762 2767 If True, the code will share future statements with the interactive
2763 2768 shell. It will both be affected by previous __future__ imports, and
2764 2769 any __future__ imports in the code will affect the shell. If False,
2765 2770 __future__ imports are not shared in either direction.
2766 2771
2767 2772 Returns
2768 2773 -------
2769 2774 result : :class:`ExecutionResult`
2770 2775 """
2771 2776 result = None
2772 2777 try:
2773 2778 result = self._run_cell(
2774 2779 raw_cell, store_history, silent, shell_futures)
2775 2780 finally:
2776 2781 self.events.trigger('post_execute')
2777 2782 if not silent:
2778 2783 self.events.trigger('post_run_cell', result)
2779 2784 return result
2780 2785
2781 2786 def _run_cell(self, raw_cell:str, store_history:bool, silent:bool, shell_futures:bool) -> ExecutionResult:
2782 2787 """Internal method to run a complete IPython cell."""
2783 2788
2784 2789 # we need to avoid calling self.transform_cell multiple time on the same thing
2785 2790 # so we need to store some results:
2786 2791 preprocessing_exc_tuple = None
2787 2792 try:
2788 2793 transformed_cell = self.transform_cell(raw_cell)
2789 2794 except Exception:
2790 2795 transformed_cell = raw_cell
2791 2796 preprocessing_exc_tuple = sys.exc_info()
2792 2797
2793 2798 assert transformed_cell is not None
2794 2799 coro = self.run_cell_async(
2795 2800 raw_cell,
2796 2801 store_history=store_history,
2797 2802 silent=silent,
2798 2803 shell_futures=shell_futures,
2799 2804 transformed_cell=transformed_cell,
2800 2805 preprocessing_exc_tuple=preprocessing_exc_tuple,
2801 2806 )
2802 2807
2803 2808 # run_cell_async is async, but may not actually need an eventloop.
2804 2809 # when this is the case, we want to run it using the pseudo_sync_runner
2805 2810 # so that code can invoke eventloops (for example via the %run , and
2806 2811 # `%paste` magic.
2807 2812 if self.trio_runner:
2808 2813 runner = self.trio_runner
2809 2814 elif self.should_run_async(
2810 2815 raw_cell,
2811 2816 transformed_cell=transformed_cell,
2812 2817 preprocessing_exc_tuple=preprocessing_exc_tuple,
2813 2818 ):
2814 2819 runner = self.loop_runner
2815 2820 else:
2816 2821 runner = _pseudo_sync_runner
2817 2822
2818 2823 try:
2819 2824 return runner(coro)
2820 2825 except BaseException as e:
2821 2826 info = ExecutionInfo(raw_cell, store_history, silent, shell_futures)
2822 2827 result = ExecutionResult(info)
2823 2828 result.error_in_exec = e
2824 2829 self.showtraceback(running_compiled_code=True)
2825 2830 return result
2826 2831
2827 2832 def should_run_async(
2828 2833 self, raw_cell: str, *, transformed_cell=None, preprocessing_exc_tuple=None
2829 2834 ) -> bool:
2830 2835 """Return whether a cell should be run asynchronously via a coroutine runner
2831 2836
2832 2837 Parameters
2833 2838 ----------
2834 2839 raw_cell: str
2835 2840 The code to be executed
2836 2841
2837 2842 Returns
2838 2843 -------
2839 2844 result: bool
2840 2845 Whether the code needs to be run with a coroutine runner or not
2841 2846
2842 2847 .. versionadded:: 7.0
2843 2848 """
2844 2849 if not self.autoawait:
2845 2850 return False
2846 2851 if preprocessing_exc_tuple is not None:
2847 2852 return False
2848 2853 assert preprocessing_exc_tuple is None
2849 2854 if transformed_cell is None:
2850 2855 warnings.warn(
2851 2856 "`should_run_async` will not call `transform_cell`"
2852 2857 " automatically in the future. Please pass the result to"
2853 2858 " `transformed_cell` argument and any exception that happen"
2854 2859 " during the"
2855 2860 "transform in `preprocessing_exc_tuple` in"
2856 2861 " IPython 7.17 and above.",
2857 2862 DeprecationWarning,
2858 2863 stacklevel=2,
2859 2864 )
2860 2865 try:
2861 2866 cell = self.transform_cell(raw_cell)
2862 2867 except Exception:
2863 2868 # any exception during transform will be raised
2864 2869 # prior to execution
2865 2870 return False
2866 2871 else:
2867 2872 cell = transformed_cell
2868 2873 return _should_be_async(cell)
2869 2874
2870 2875 async def run_cell_async(
2871 2876 self,
2872 2877 raw_cell: str,
2873 2878 store_history=False,
2874 2879 silent=False,
2875 2880 shell_futures=True,
2876 2881 *,
2877 2882 transformed_cell: Optional[str] = None,
2878 2883 preprocessing_exc_tuple: Optional[Any] = None
2879 2884 ) -> ExecutionResult:
2880 2885 """Run a complete IPython cell asynchronously.
2881 2886
2882 2887 Parameters
2883 2888 ----------
2884 2889 raw_cell : str
2885 2890 The code (including IPython code such as %magic functions) to run.
2886 2891 store_history : bool
2887 2892 If True, the raw and translated cell will be stored in IPython's
2888 2893 history. For user code calling back into IPython's machinery, this
2889 2894 should be set to False.
2890 2895 silent : bool
2891 2896 If True, avoid side-effects, such as implicit displayhooks and
2892 2897 and logging. silent=True forces store_history=False.
2893 2898 shell_futures : bool
2894 2899 If True, the code will share future statements with the interactive
2895 2900 shell. It will both be affected by previous __future__ imports, and
2896 2901 any __future__ imports in the code will affect the shell. If False,
2897 2902 __future__ imports are not shared in either direction.
2898 2903 transformed_cell: str
2899 2904 cell that was passed through transformers
2900 2905 preprocessing_exc_tuple:
2901 2906 trace if the transformation failed.
2902 2907
2903 2908 Returns
2904 2909 -------
2905 2910 result : :class:`ExecutionResult`
2906 2911
2907 2912 .. versionadded:: 7.0
2908 2913 """
2909 2914 info = ExecutionInfo(
2910 2915 raw_cell, store_history, silent, shell_futures)
2911 2916 result = ExecutionResult(info)
2912 2917
2913 2918 if (not raw_cell) or raw_cell.isspace():
2914 2919 self.last_execution_succeeded = True
2915 2920 self.last_execution_result = result
2916 2921 return result
2917 2922
2918 2923 if silent:
2919 2924 store_history = False
2920 2925
2921 2926 if store_history:
2922 2927 result.execution_count = self.execution_count
2923 2928
2924 2929 def error_before_exec(value):
2925 2930 if store_history:
2926 2931 self.execution_count += 1
2927 2932 result.error_before_exec = value
2928 2933 self.last_execution_succeeded = False
2929 2934 self.last_execution_result = result
2930 2935 return result
2931 2936
2932 2937 self.events.trigger('pre_execute')
2933 2938 if not silent:
2934 2939 self.events.trigger('pre_run_cell', info)
2935 2940
2936 2941 if transformed_cell is None:
2937 2942 warnings.warn(
2938 2943 "`run_cell_async` will not call `transform_cell`"
2939 2944 " automatically in the future. Please pass the result to"
2940 2945 " `transformed_cell` argument and any exception that happen"
2941 2946 " during the"
2942 2947 "transform in `preprocessing_exc_tuple` in"
2943 2948 " IPython 7.17 and above.",
2944 2949 DeprecationWarning,
2945 2950 stacklevel=2,
2946 2951 )
2947 2952 # If any of our input transformation (input_transformer_manager or
2948 2953 # prefilter_manager) raises an exception, we store it in this variable
2949 2954 # so that we can display the error after logging the input and storing
2950 2955 # it in the history.
2951 2956 try:
2952 2957 cell = self.transform_cell(raw_cell)
2953 2958 except Exception:
2954 2959 preprocessing_exc_tuple = sys.exc_info()
2955 2960 cell = raw_cell # cell has to exist so it can be stored/logged
2956 2961 else:
2957 2962 preprocessing_exc_tuple = None
2958 2963 else:
2959 2964 if preprocessing_exc_tuple is None:
2960 2965 cell = transformed_cell
2961 2966 else:
2962 2967 cell = raw_cell
2963 2968
2964 2969 # Store raw and processed history
2965 2970 if store_history:
2966 2971 self.history_manager.store_inputs(self.execution_count,
2967 2972 cell, raw_cell)
2968 2973 if not silent:
2969 2974 self.logger.log(cell, raw_cell)
2970 2975
2971 2976 # Display the exception if input processing failed.
2972 2977 if preprocessing_exc_tuple is not None:
2973 2978 self.showtraceback(preprocessing_exc_tuple)
2974 2979 if store_history:
2975 2980 self.execution_count += 1
2976 2981 return error_before_exec(preprocessing_exc_tuple[1])
2977 2982
2978 2983 # Our own compiler remembers the __future__ environment. If we want to
2979 2984 # run code with a separate __future__ environment, use the default
2980 2985 # compiler
2981 2986 compiler = self.compile if shell_futures else self.compiler_class()
2982 2987
2983 2988 _run_async = False
2984 2989
2985 2990 with self.builtin_trap:
2986 2991 cell_name = compiler.cache(cell, self.execution_count, raw_code=raw_cell)
2987 2992
2988 2993 with self.display_trap:
2989 2994 # Compile to bytecode
2990 2995 try:
2991 2996 code_ast = compiler.ast_parse(cell, filename=cell_name)
2992 2997 except self.custom_exceptions as e:
2993 2998 etype, value, tb = sys.exc_info()
2994 2999 self.CustomTB(etype, value, tb)
2995 3000 return error_before_exec(e)
2996 3001 except IndentationError as e:
2997 3002 self.showindentationerror()
2998 3003 return error_before_exec(e)
2999 3004 except (OverflowError, SyntaxError, ValueError, TypeError,
3000 3005 MemoryError) as e:
3001 3006 self.showsyntaxerror()
3002 3007 return error_before_exec(e)
3003 3008
3004 3009 # Apply AST transformations
3005 3010 try:
3006 3011 code_ast = self.transform_ast(code_ast)
3007 3012 except InputRejected as e:
3008 3013 self.showtraceback()
3009 3014 return error_before_exec(e)
3010 3015
3011 3016 # Give the displayhook a reference to our ExecutionResult so it
3012 3017 # can fill in the output value.
3013 3018 self.displayhook.exec_result = result
3014 3019
3015 3020 # Execute the user code
3016 3021 interactivity = "none" if silent else self.ast_node_interactivity
3017 3022
3018 3023 has_raised = await self.run_ast_nodes(code_ast.body, cell_name,
3019 3024 interactivity=interactivity, compiler=compiler, result=result)
3020 3025
3021 3026 self.last_execution_succeeded = not has_raised
3022 3027 self.last_execution_result = result
3023 3028
3024 3029 # Reset this so later displayed values do not modify the
3025 3030 # ExecutionResult
3026 3031 self.displayhook.exec_result = None
3027 3032
3028 3033 if store_history:
3029 3034 # Write output to the database. Does nothing unless
3030 3035 # history output logging is enabled.
3031 3036 self.history_manager.store_output(self.execution_count)
3032 3037 # Each cell is a *single* input, regardless of how many lines it has
3033 3038 self.execution_count += 1
3034 3039
3035 3040 return result
3036 3041
3037 3042 def transform_cell(self, raw_cell):
3038 3043 """Transform an input cell before parsing it.
3039 3044
3040 3045 Static transformations, implemented in IPython.core.inputtransformer2,
3041 3046 deal with things like ``%magic`` and ``!system`` commands.
3042 3047 These run on all input.
3043 3048 Dynamic transformations, for things like unescaped magics and the exit
3044 3049 autocall, depend on the state of the interpreter.
3045 3050 These only apply to single line inputs.
3046 3051
3047 3052 These string-based transformations are followed by AST transformations;
3048 3053 see :meth:`transform_ast`.
3049 3054 """
3050 3055 # Static input transformations
3051 3056 cell = self.input_transformer_manager.transform_cell(raw_cell)
3052 3057
3053 3058 if len(cell.splitlines()) == 1:
3054 3059 # Dynamic transformations - only applied for single line commands
3055 3060 with self.builtin_trap:
3056 3061 # use prefilter_lines to handle trailing newlines
3057 3062 # restore trailing newline for ast.parse
3058 3063 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
3059 3064
3060 3065 lines = cell.splitlines(keepends=True)
3061 3066 for transform in self.input_transformers_post:
3062 3067 lines = transform(lines)
3063 3068 cell = ''.join(lines)
3064 3069
3065 3070 return cell
3066 3071
3067 3072 def transform_ast(self, node):
3068 3073 """Apply the AST transformations from self.ast_transformers
3069 3074
3070 3075 Parameters
3071 3076 ----------
3072 3077 node : ast.Node
3073 3078 The root node to be transformed. Typically called with the ast.Module
3074 3079 produced by parsing user input.
3075 3080
3076 3081 Returns
3077 3082 -------
3078 3083 An ast.Node corresponding to the node it was called with. Note that it
3079 3084 may also modify the passed object, so don't rely on references to the
3080 3085 original AST.
3081 3086 """
3082 3087 for transformer in self.ast_transformers:
3083 3088 try:
3084 3089 node = transformer.visit(node)
3085 3090 except InputRejected:
3086 3091 # User-supplied AST transformers can reject an input by raising
3087 3092 # an InputRejected. Short-circuit in this case so that we
3088 3093 # don't unregister the transform.
3089 3094 raise
3090 3095 except Exception:
3091 3096 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
3092 3097 self.ast_transformers.remove(transformer)
3093 3098
3094 3099 if self.ast_transformers:
3095 3100 ast.fix_missing_locations(node)
3096 3101 return node
3097 3102
3098 3103 async def run_ast_nodes(
3099 3104 self,
3100 3105 nodelist: ListType[stmt],
3101 3106 cell_name: str,
3102 3107 interactivity="last_expr",
3103 3108 compiler=compile,
3104 3109 result=None,
3105 3110 ):
3106 3111 """Run a sequence of AST nodes. The execution mode depends on the
3107 3112 interactivity parameter.
3108 3113
3109 3114 Parameters
3110 3115 ----------
3111 3116 nodelist : list
3112 3117 A sequence of AST nodes to run.
3113 3118 cell_name : str
3114 3119 Will be passed to the compiler as the filename of the cell. Typically
3115 3120 the value returned by ip.compile.cache(cell).
3116 3121 interactivity : str
3117 3122 'all', 'last', 'last_expr' , 'last_expr_or_assign' or 'none',
3118 3123 specifying which nodes should be run interactively (displaying output
3119 3124 from expressions). 'last_expr' will run the last node interactively
3120 3125 only if it is an expression (i.e. expressions in loops or other blocks
3121 3126 are not displayed) 'last_expr_or_assign' will run the last expression
3122 3127 or the last assignment. Other values for this parameter will raise a
3123 3128 ValueError.
3124 3129
3125 3130 compiler : callable
3126 3131 A function with the same interface as the built-in compile(), to turn
3127 3132 the AST nodes into code objects. Default is the built-in compile().
3128 3133 result : ExecutionResult, optional
3129 3134 An object to store exceptions that occur during execution.
3130 3135
3131 3136 Returns
3132 3137 -------
3133 3138 True if an exception occurred while running code, False if it finished
3134 3139 running.
3135 3140 """
3136 3141 if not nodelist:
3137 3142 return
3138 3143
3139 3144
3140 3145 if interactivity == 'last_expr_or_assign':
3141 3146 if isinstance(nodelist[-1], _assign_nodes):
3142 3147 asg = nodelist[-1]
3143 3148 if isinstance(asg, ast.Assign) and len(asg.targets) == 1:
3144 3149 target = asg.targets[0]
3145 3150 elif isinstance(asg, _single_targets_nodes):
3146 3151 target = asg.target
3147 3152 else:
3148 3153 target = None
3149 3154 if isinstance(target, ast.Name):
3150 3155 nnode = ast.Expr(ast.Name(target.id, ast.Load()))
3151 3156 ast.fix_missing_locations(nnode)
3152 3157 nodelist.append(nnode)
3153 3158 interactivity = 'last_expr'
3154 3159
3155 3160 _async = False
3156 3161 if interactivity == 'last_expr':
3157 3162 if isinstance(nodelist[-1], ast.Expr):
3158 3163 interactivity = "last"
3159 3164 else:
3160 3165 interactivity = "none"
3161 3166
3162 3167 if interactivity == 'none':
3163 3168 to_run_exec, to_run_interactive = nodelist, []
3164 3169 elif interactivity == 'last':
3165 3170 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
3166 3171 elif interactivity == 'all':
3167 3172 to_run_exec, to_run_interactive = [], nodelist
3168 3173 else:
3169 3174 raise ValueError("Interactivity was %r" % interactivity)
3170 3175
3171 3176 try:
3172 3177
3173 3178 def compare(code):
3174 3179 is_async = inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE
3175 3180 return is_async
3176 3181
3177 3182 # refactor that to just change the mod constructor.
3178 3183 to_run = []
3179 3184 for node in to_run_exec:
3180 3185 to_run.append((node, "exec"))
3181 3186
3182 3187 for node in to_run_interactive:
3183 3188 to_run.append((node, "single"))
3184 3189
3185 3190 for node, mode in to_run:
3186 3191 if mode == "exec":
3187 3192 mod = Module([node], [])
3188 3193 elif mode == "single":
3189 3194 mod = ast.Interactive([node])
3190 3195 with compiler.extra_flags(
3191 3196 getattr(ast, "PyCF_ALLOW_TOP_LEVEL_AWAIT", 0x0)
3192 3197 if self.autoawait
3193 3198 else 0x0
3194 3199 ):
3195 3200 code = compiler(mod, cell_name, mode)
3196 3201 asy = compare(code)
3197 3202 if await self.run_code(code, result, async_=asy):
3198 3203 return True
3199 3204
3200 3205 # Flush softspace
3201 3206 if softspace(sys.stdout, 0):
3202 3207 print()
3203 3208
3204 3209 except:
3205 3210 # It's possible to have exceptions raised here, typically by
3206 3211 # compilation of odd code (such as a naked 'return' outside a
3207 3212 # function) that did parse but isn't valid. Typically the exception
3208 3213 # is a SyntaxError, but it's safest just to catch anything and show
3209 3214 # the user a traceback.
3210 3215
3211 3216 # We do only one try/except outside the loop to minimize the impact
3212 3217 # on runtime, and also because if any node in the node list is
3213 3218 # broken, we should stop execution completely.
3214 3219 if result:
3215 3220 result.error_before_exec = sys.exc_info()[1]
3216 3221 self.showtraceback()
3217 3222 return True
3218 3223
3219 3224 return False
3220 3225
3221 3226 async def run_code(self, code_obj, result=None, *, async_=False):
3222 3227 """Execute a code object.
3223 3228
3224 3229 When an exception occurs, self.showtraceback() is called to display a
3225 3230 traceback.
3226 3231
3227 3232 Parameters
3228 3233 ----------
3229 3234 code_obj : code object
3230 3235 A compiled code object, to be executed
3231 3236 result : ExecutionResult, optional
3232 3237 An object to store exceptions that occur during execution.
3233 3238 async_ : Bool (Experimental)
3234 3239 Attempt to run top-level asynchronous code in a default loop.
3235 3240
3236 3241 Returns
3237 3242 -------
3238 3243 False : successful execution.
3239 3244 True : an error occurred.
3240 3245 """
3241 3246 # special value to say that anything above is IPython and should be
3242 3247 # hidden.
3243 3248 __tracebackhide__ = "__ipython_bottom__"
3244 3249 # Set our own excepthook in case the user code tries to call it
3245 3250 # directly, so that the IPython crash handler doesn't get triggered
3246 3251 old_excepthook, sys.excepthook = sys.excepthook, self.excepthook
3247 3252
3248 3253 # we save the original sys.excepthook in the instance, in case config
3249 3254 # code (such as magics) needs access to it.
3250 3255 self.sys_excepthook = old_excepthook
3251 3256 outflag = True # happens in more places, so it's easier as default
3252 3257 try:
3253 3258 try:
3254 3259 self.hooks.pre_run_code_hook()
3255 3260 if async_:
3256 3261 await eval(code_obj, self.user_global_ns, self.user_ns)
3257 3262 else:
3258 3263 exec(code_obj, self.user_global_ns, self.user_ns)
3259 3264 finally:
3260 3265 # Reset our crash handler in place
3261 3266 sys.excepthook = old_excepthook
3262 3267 except SystemExit as e:
3263 3268 if result is not None:
3264 3269 result.error_in_exec = e
3265 3270 self.showtraceback(exception_only=True)
3266 3271 warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
3267 3272 except self.custom_exceptions:
3268 3273 etype, value, tb = sys.exc_info()
3269 3274 if result is not None:
3270 3275 result.error_in_exec = value
3271 3276 self.CustomTB(etype, value, tb)
3272 3277 except:
3273 3278 if result is not None:
3274 3279 result.error_in_exec = sys.exc_info()[1]
3275 3280 self.showtraceback(running_compiled_code=True)
3276 3281 else:
3277 3282 outflag = False
3278 3283 return outflag
3279 3284
3280 3285 # For backwards compatibility
3281 3286 runcode = run_code
3282 3287
3283 3288 def check_complete(self, code: str) -> Tuple[str, str]:
3284 3289 """Return whether a block of code is ready to execute, or should be continued
3285 3290
3286 3291 Parameters
3287 3292 ----------
3288 3293 source : string
3289 3294 Python input code, which can be multiline.
3290 3295
3291 3296 Returns
3292 3297 -------
3293 3298 status : str
3294 3299 One of 'complete', 'incomplete', or 'invalid' if source is not a
3295 3300 prefix of valid code.
3296 3301 indent : str
3297 3302 When status is 'incomplete', this is some whitespace to insert on
3298 3303 the next line of the prompt.
3299 3304 """
3300 3305 status, nspaces = self.input_transformer_manager.check_complete(code)
3301 3306 return status, ' ' * (nspaces or 0)
3302 3307
3303 3308 #-------------------------------------------------------------------------
3304 3309 # Things related to GUI support and pylab
3305 3310 #-------------------------------------------------------------------------
3306 3311
3307 3312 active_eventloop = None
3308 3313
3309 3314 def enable_gui(self, gui=None):
3310 3315 raise NotImplementedError('Implement enable_gui in a subclass')
3311 3316
3312 3317 def enable_matplotlib(self, gui=None):
3313 3318 """Enable interactive matplotlib and inline figure support.
3314 3319
3315 3320 This takes the following steps:
3316 3321
3317 3322 1. select the appropriate eventloop and matplotlib backend
3318 3323 2. set up matplotlib for interactive use with that backend
3319 3324 3. configure formatters for inline figure display
3320 3325 4. enable the selected gui eventloop
3321 3326
3322 3327 Parameters
3323 3328 ----------
3324 3329 gui : optional, string
3325 3330 If given, dictates the choice of matplotlib GUI backend to use
3326 3331 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3327 3332 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3328 3333 matplotlib (as dictated by the matplotlib build-time options plus the
3329 3334 user's matplotlibrc configuration file). Note that not all backends
3330 3335 make sense in all contexts, for example a terminal ipython can't
3331 3336 display figures inline.
3332 3337 """
3333 3338 from IPython.core import pylabtools as pt
3334 3339 from matplotlib_inline.backend_inline import configure_inline_support
3335 3340 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
3336 3341
3337 3342 if gui != 'inline':
3338 3343 # If we have our first gui selection, store it
3339 3344 if self.pylab_gui_select is None:
3340 3345 self.pylab_gui_select = gui
3341 3346 # Otherwise if they are different
3342 3347 elif gui != self.pylab_gui_select:
3343 3348 print('Warning: Cannot change to a different GUI toolkit: %s.'
3344 3349 ' Using %s instead.' % (gui, self.pylab_gui_select))
3345 3350 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
3346 3351
3347 3352 pt.activate_matplotlib(backend)
3348 3353 configure_inline_support(self, backend)
3349 3354
3350 3355 # Now we must activate the gui pylab wants to use, and fix %run to take
3351 3356 # plot updates into account
3352 3357 self.enable_gui(gui)
3353 3358 self.magics_manager.registry['ExecutionMagics'].default_runner = \
3354 3359 pt.mpl_runner(self.safe_execfile)
3355 3360
3356 3361 return gui, backend
3357 3362
3358 3363 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
3359 3364 """Activate pylab support at runtime.
3360 3365
3361 3366 This turns on support for matplotlib, preloads into the interactive
3362 3367 namespace all of numpy and pylab, and configures IPython to correctly
3363 3368 interact with the GUI event loop. The GUI backend to be used can be
3364 3369 optionally selected with the optional ``gui`` argument.
3365 3370
3366 3371 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
3367 3372
3368 3373 Parameters
3369 3374 ----------
3370 3375 gui : optional, string
3371 3376 If given, dictates the choice of matplotlib GUI backend to use
3372 3377 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3373 3378 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3374 3379 matplotlib (as dictated by the matplotlib build-time options plus the
3375 3380 user's matplotlibrc configuration file). Note that not all backends
3376 3381 make sense in all contexts, for example a terminal ipython can't
3377 3382 display figures inline.
3378 3383 import_all : optional, bool, default: True
3379 3384 Whether to do `from numpy import *` and `from pylab import *`
3380 3385 in addition to module imports.
3381 3386 welcome_message : deprecated
3382 3387 This argument is ignored, no welcome message will be displayed.
3383 3388 """
3384 3389 from IPython.core.pylabtools import import_pylab
3385 3390
3386 3391 gui, backend = self.enable_matplotlib(gui)
3387 3392
3388 3393 # We want to prevent the loading of pylab to pollute the user's
3389 3394 # namespace as shown by the %who* magics, so we execute the activation
3390 3395 # code in an empty namespace, and we update *both* user_ns and
3391 3396 # user_ns_hidden with this information.
3392 3397 ns = {}
3393 3398 import_pylab(ns, import_all)
3394 3399 # warn about clobbered names
3395 3400 ignored = {"__builtins__"}
3396 3401 both = set(ns).intersection(self.user_ns).difference(ignored)
3397 3402 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
3398 3403 self.user_ns.update(ns)
3399 3404 self.user_ns_hidden.update(ns)
3400 3405 return gui, backend, clobbered
3401 3406
3402 3407 #-------------------------------------------------------------------------
3403 3408 # Utilities
3404 3409 #-------------------------------------------------------------------------
3405 3410
3406 3411 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
3407 3412 """Expand python variables in a string.
3408 3413
3409 3414 The depth argument indicates how many frames above the caller should
3410 3415 be walked to look for the local namespace where to expand variables.
3411 3416
3412 3417 The global namespace for expansion is always the user's interactive
3413 3418 namespace.
3414 3419 """
3415 3420 ns = self.user_ns.copy()
3416 3421 try:
3417 3422 frame = sys._getframe(depth+1)
3418 3423 except ValueError:
3419 3424 # This is thrown if there aren't that many frames on the stack,
3420 3425 # e.g. if a script called run_line_magic() directly.
3421 3426 pass
3422 3427 else:
3423 3428 ns.update(frame.f_locals)
3424 3429
3425 3430 try:
3426 3431 # We have to use .vformat() here, because 'self' is a valid and common
3427 3432 # name, and expanding **ns for .format() would make it collide with
3428 3433 # the 'self' argument of the method.
3429 3434 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3430 3435 except Exception:
3431 3436 # if formatter couldn't format, just let it go untransformed
3432 3437 pass
3433 3438 return cmd
3434 3439
3435 3440 def mktempfile(self, data=None, prefix='ipython_edit_'):
3436 3441 """Make a new tempfile and return its filename.
3437 3442
3438 3443 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3439 3444 but it registers the created filename internally so ipython cleans it up
3440 3445 at exit time.
3441 3446
3442 3447 Optional inputs:
3443 3448
3444 3449 - data(None): if data is given, it gets written out to the temp file
3445 3450 immediately, and the file is closed again."""
3446 3451
3447 3452 dir_path = Path(tempfile.mkdtemp(prefix=prefix))
3448 3453 self.tempdirs.append(dir_path)
3449 3454
3450 3455 handle, filename = tempfile.mkstemp(".py", prefix, dir=str(dir_path))
3451 3456 os.close(handle) # On Windows, there can only be one open handle on a file
3452 3457
3453 3458 file_path = Path(filename)
3454 3459 self.tempfiles.append(file_path)
3455 3460
3456 3461 if data:
3457 3462 file_path.write_text(data)
3458 3463 return filename
3459 3464
3460 3465 def ask_yes_no(self, prompt, default=None, interrupt=None):
3461 3466 if self.quiet:
3462 3467 return True
3463 3468 return ask_yes_no(prompt,default,interrupt)
3464 3469
3465 3470 def show_usage(self):
3466 3471 """Show a usage message"""
3467 3472 page.page(IPython.core.usage.interactive_usage)
3468 3473
3469 3474 def extract_input_lines(self, range_str, raw=False):
3470 3475 """Return as a string a set of input history slices.
3471 3476
3472 3477 Parameters
3473 3478 ----------
3474 3479 range_str : str
3475 3480 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3476 3481 since this function is for use by magic functions which get their
3477 3482 arguments as strings. The number before the / is the session
3478 3483 number: ~n goes n back from the current session.
3479 3484
3480 3485 If empty string is given, returns history of current session
3481 3486 without the last input.
3482 3487
3483 3488 raw : bool, optional
3484 3489 By default, the processed input is used. If this is true, the raw
3485 3490 input history is used instead.
3486 3491
3487 3492 Notes
3488 3493 -----
3489 3494
3490 3495 Slices can be described with two notations:
3491 3496
3492 3497 * ``N:M`` -> standard python form, means including items N...(M-1).
3493 3498 * ``N-M`` -> include items N..M (closed endpoint).
3494 3499 """
3495 3500 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3496 3501 text = "\n".join(x for _, _, x in lines)
3497 3502
3498 3503 # Skip the last line, as it's probably the magic that called this
3499 3504 if not range_str:
3500 3505 if "\n" not in text:
3501 3506 text = ""
3502 3507 else:
3503 3508 text = text[: text.rfind("\n")]
3504 3509
3505 3510 return text
3506 3511
3507 3512 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False):
3508 3513 """Get a code string from history, file, url, or a string or macro.
3509 3514
3510 3515 This is mainly used by magic functions.
3511 3516
3512 3517 Parameters
3513 3518 ----------
3514 3519 target : str
3515 3520 A string specifying code to retrieve. This will be tried respectively
3516 3521 as: ranges of input history (see %history for syntax), url,
3517 3522 corresponding .py file, filename, or an expression evaluating to a
3518 3523 string or Macro in the user namespace.
3519 3524
3520 3525 If empty string is given, returns complete history of current
3521 3526 session, without the last line.
3522 3527
3523 3528 raw : bool
3524 3529 If true (default), retrieve raw history. Has no effect on the other
3525 3530 retrieval mechanisms.
3526 3531
3527 3532 py_only : bool (default False)
3528 3533 Only try to fetch python code, do not try alternative methods to decode file
3529 3534 if unicode fails.
3530 3535
3531 3536 Returns
3532 3537 -------
3533 3538 A string of code.
3534 3539
3535 3540 ValueError is raised if nothing is found, and TypeError if it evaluates
3536 3541 to an object of another type. In each case, .args[0] is a printable
3537 3542 message.
3538 3543 """
3539 3544 code = self.extract_input_lines(target, raw=raw) # Grab history
3540 3545 if code:
3541 3546 return code
3542 3547 try:
3543 3548 if target.startswith(('http://', 'https://')):
3544 3549 return openpy.read_py_url(target, skip_encoding_cookie=skip_encoding_cookie)
3545 3550 except UnicodeDecodeError as e:
3546 3551 if not py_only :
3547 3552 # Deferred import
3548 3553 from urllib.request import urlopen
3549 3554 response = urlopen(target)
3550 3555 return response.read().decode('latin1')
3551 3556 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3552 3557
3553 3558 potential_target = [target]
3554 3559 try :
3555 3560 potential_target.insert(0,get_py_filename(target))
3556 3561 except IOError:
3557 3562 pass
3558 3563
3559 3564 for tgt in potential_target :
3560 3565 if os.path.isfile(tgt): # Read file
3561 3566 try :
3562 3567 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3563 3568 except UnicodeDecodeError as e:
3564 3569 if not py_only :
3565 3570 with io_open(tgt,'r', encoding='latin1') as f :
3566 3571 return f.read()
3567 3572 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3568 3573 elif os.path.isdir(os.path.expanduser(tgt)):
3569 3574 raise ValueError("'%s' is a directory, not a regular file." % target)
3570 3575
3571 3576 if search_ns:
3572 3577 # Inspect namespace to load object source
3573 3578 object_info = self.object_inspect(target, detail_level=1)
3574 3579 if object_info['found'] and object_info['source']:
3575 3580 return object_info['source']
3576 3581
3577 3582 try: # User namespace
3578 3583 codeobj = eval(target, self.user_ns)
3579 3584 except Exception as e:
3580 3585 raise ValueError(("'%s' was not found in history, as a file, url, "
3581 3586 "nor in the user namespace.") % target) from e
3582 3587
3583 3588 if isinstance(codeobj, str):
3584 3589 return codeobj
3585 3590 elif isinstance(codeobj, Macro):
3586 3591 return codeobj.value
3587 3592
3588 3593 raise TypeError("%s is neither a string nor a macro." % target,
3589 3594 codeobj)
3590 3595
3591 3596 def _atexit_once(self):
3592 3597 """
3593 3598 At exist operation that need to be called at most once.
3594 3599 Second call to this function per instance will do nothing.
3595 3600 """
3596 3601
3597 3602 if not getattr(self, "_atexit_once_called", False):
3598 3603 self._atexit_once_called = True
3599 3604 # Clear all user namespaces to release all references cleanly.
3600 3605 self.reset(new_session=False)
3601 3606 # Close the history session (this stores the end time and line count)
3602 3607 # this must be *before* the tempfile cleanup, in case of temporary
3603 3608 # history db
3604 3609 self.history_manager.end_session()
3605 3610 self.history_manager = None
3606 3611
3607 3612 #-------------------------------------------------------------------------
3608 3613 # Things related to IPython exiting
3609 3614 #-------------------------------------------------------------------------
3610 3615 def atexit_operations(self):
3611 3616 """This will be executed at the time of exit.
3612 3617
3613 3618 Cleanup operations and saving of persistent data that is done
3614 3619 unconditionally by IPython should be performed here.
3615 3620
3616 3621 For things that may depend on startup flags or platform specifics (such
3617 3622 as having readline or not), register a separate atexit function in the
3618 3623 code that has the appropriate information, rather than trying to
3619 3624 clutter
3620 3625 """
3621 3626 self._atexit_once()
3622 3627
3623 3628 # Cleanup all tempfiles and folders left around
3624 3629 for tfile in self.tempfiles:
3625 3630 try:
3626 3631 tfile.unlink()
3627 3632 self.tempfiles.remove(tfile)
3628 3633 except FileNotFoundError:
3629 3634 pass
3630 3635 del self.tempfiles
3631 3636 for tdir in self.tempdirs:
3632 3637 try:
3633 3638 tdir.rmdir()
3634 3639 self.tempdirs.remove(tdir)
3635 3640 except FileNotFoundError:
3636 3641 pass
3637 3642 del self.tempdirs
3638 3643
3639 3644
3640 3645 # Run user hooks
3641 3646 self.hooks.shutdown_hook()
3642 3647
3643 3648 def cleanup(self):
3644 3649 self.restore_sys_module_state()
3645 3650
3646 3651
3647 3652 # Overridden in terminal subclass to change prompts
3648 3653 def switch_doctest_mode(self, mode):
3649 3654 pass
3650 3655
3651 3656
3652 3657 class InteractiveShellABC(metaclass=abc.ABCMeta):
3653 3658 """An abstract base class for InteractiveShell."""
3654 3659
3655 3660 InteractiveShellABC.register(InteractiveShell)
@@ -1,470 +1,452 b''
1 1 # encoding: utf-8
2 2 """
3 3 A mixin for :class:`~IPython.core.application.Application` classes that
4 4 launch InteractiveShell instances, load extensions, etc.
5 5 """
6 6
7 7 # Copyright (c) IPython Development Team.
8 8 # Distributed under the terms of the Modified BSD License.
9 9
10 10 import glob
11 11 from itertools import chain
12 12 import os
13 13 import sys
14 14
15 15 from traitlets.config.application import boolean_flag
16 16 from traitlets.config.configurable import Configurable
17 17 from traitlets.config.loader import Config
18 18 from IPython.core.application import SYSTEM_CONFIG_DIRS, ENV_CONFIG_DIRS
19 19 from IPython.core import pylabtools
20 20 from IPython.utils.contexts import preserve_keys
21 21 from IPython.utils.path import filefind
22 22 import traitlets
23 23 from traitlets import (
24 24 Unicode, Instance, List, Bool, CaselessStrEnum, observe,
25 25 DottedObjectName,
26 26 )
27 27 from IPython.terminal import pt_inputhooks
28 28
29 29 #-----------------------------------------------------------------------------
30 30 # Aliases and Flags
31 31 #-----------------------------------------------------------------------------
32 32
33 33 gui_keys = tuple(sorted(pt_inputhooks.backends) + sorted(pt_inputhooks.aliases))
34 34
35 35 backend_keys = sorted(pylabtools.backends.keys())
36 36 backend_keys.insert(0, 'auto')
37 37
38 38 shell_flags = {}
39 39
40 40 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
41 41 addflag('autoindent', 'InteractiveShell.autoindent',
42 42 'Turn on autoindenting.', 'Turn off autoindenting.'
43 43 )
44 44 addflag('automagic', 'InteractiveShell.automagic',
45 45 """Turn on the auto calling of magic commands. Type %%magic at the
46 46 IPython prompt for more information.""",
47 47 'Turn off the auto calling of magic commands.'
48 48 )
49 49 addflag('pdb', 'InteractiveShell.pdb',
50 50 "Enable auto calling the pdb debugger after every exception.",
51 51 "Disable auto calling the pdb debugger after every exception."
52 52 )
53 53 addflag('pprint', 'PlainTextFormatter.pprint',
54 54 "Enable auto pretty printing of results.",
55 55 "Disable auto pretty printing of results."
56 56 )
57 57 addflag('color-info', 'InteractiveShell.color_info',
58 58 """IPython can display information about objects via a set of functions,
59 59 and optionally can use colors for this, syntax highlighting
60 60 source code and various other elements. This is on by default, but can cause
61 61 problems with some pagers. If you see such problems, you can disable the
62 62 colours.""",
63 63 "Disable using colors for info related things."
64 64 )
65 65 addflag('ignore-cwd', 'InteractiveShellApp.ignore_cwd',
66 66 "Exclude the current working directory from sys.path",
67 67 "Include the current working directory in sys.path",
68 68 )
69 69 nosep_config = Config()
70 70 nosep_config.InteractiveShell.separate_in = ''
71 71 nosep_config.InteractiveShell.separate_out = ''
72 72 nosep_config.InteractiveShell.separate_out2 = ''
73 73
74 74 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
75 75 shell_flags['pylab'] = (
76 76 {'InteractiveShellApp' : {'pylab' : 'auto'}},
77 77 """Pre-load matplotlib and numpy for interactive use with
78 78 the default matplotlib backend."""
79 79 )
80 80 shell_flags['matplotlib'] = (
81 81 {'InteractiveShellApp' : {'matplotlib' : 'auto'}},
82 82 """Configure matplotlib for interactive use with
83 83 the default matplotlib backend."""
84 84 )
85 85
86 86 # it's possible we don't want short aliases for *all* of these:
87 87 shell_aliases = dict(
88 88 autocall='InteractiveShell.autocall',
89 89 colors='InteractiveShell.colors',
90 90 logfile='InteractiveShell.logfile',
91 91 logappend='InteractiveShell.logappend',
92 92 c='InteractiveShellApp.code_to_run',
93 93 m='InteractiveShellApp.module_to_run',
94 94 ext="InteractiveShellApp.extra_extensions",
95 95 gui='InteractiveShellApp.gui',
96 96 pylab='InteractiveShellApp.pylab',
97 97 matplotlib='InteractiveShellApp.matplotlib',
98 98 )
99 99 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
100 100
101 if traitlets.version_info < (5, 0):
102 # traitlets 4 doesn't handle lists on CLI
103 shell_aliases["ext"] = "InteractiveShellApp.extra_extension"
104
105
106 101 #-----------------------------------------------------------------------------
107 102 # Main classes and functions
108 103 #-----------------------------------------------------------------------------
109 104
110 105 class InteractiveShellApp(Configurable):
111 106 """A Mixin for applications that start InteractiveShell instances.
112 107
113 108 Provides configurables for loading extensions and executing files
114 109 as part of configuring a Shell environment.
115 110
116 111 The following methods should be called by the :meth:`initialize` method
117 112 of the subclass:
118 113
119 114 - :meth:`init_path`
120 115 - :meth:`init_shell` (to be implemented by the subclass)
121 116 - :meth:`init_gui_pylab`
122 117 - :meth:`init_extensions`
123 118 - :meth:`init_code`
124 119 """
125 120 extensions = List(Unicode(),
126 121 help="A list of dotted module names of IPython extensions to load."
127 122 ).tag(config=True)
128 123
129 extra_extension = Unicode(
130 "",
131 help="""
132 DEPRECATED. Dotted module name of a single extra IPython extension to load.
133
134 Only one extension can be added this way.
135
136 Only used with traitlets < 5.0, plural extra_extensions list is used in traitlets 5.
137 """,
138 ).tag(config=True)
139
140 124 extra_extensions = List(
141 125 DottedObjectName(),
142 126 help="""
143 127 Dotted module name(s) of one or more IPython extensions to load.
144 128
145 129 For specifying extra extensions to load on the command-line.
146 130
147 131 .. versionadded:: 7.10
148 132 """,
149 133 ).tag(config=True)
150 134
151 135 reraise_ipython_extension_failures = Bool(False,
152 136 help="Reraise exceptions encountered loading IPython extensions?",
153 137 ).tag(config=True)
154 138
155 139 # Extensions that are always loaded (not configurable)
156 140 default_extensions = List(Unicode(), [u'storemagic']).tag(config=False)
157 141
158 142 hide_initial_ns = Bool(True,
159 143 help="""Should variables loaded at startup (by startup files, exec_lines, etc.)
160 144 be hidden from tools like %who?"""
161 145 ).tag(config=True)
162 146
163 147 exec_files = List(Unicode(),
164 148 help="""List of files to run at IPython startup."""
165 149 ).tag(config=True)
166 150 exec_PYTHONSTARTUP = Bool(True,
167 151 help="""Run the file referenced by the PYTHONSTARTUP environment
168 152 variable at IPython startup."""
169 153 ).tag(config=True)
170 154 file_to_run = Unicode('',
171 155 help="""A file to be run""").tag(config=True)
172 156
173 157 exec_lines = List(Unicode(),
174 158 help="""lines of code to run at IPython startup."""
175 159 ).tag(config=True)
176 160 code_to_run = Unicode('',
177 161 help="Execute the given command string."
178 162 ).tag(config=True)
179 163 module_to_run = Unicode('',
180 164 help="Run the module as a script."
181 165 ).tag(config=True)
182 166 gui = CaselessStrEnum(gui_keys, allow_none=True,
183 167 help="Enable GUI event loop integration with any of {0}.".format(gui_keys)
184 168 ).tag(config=True)
185 169 matplotlib = CaselessStrEnum(backend_keys, allow_none=True,
186 170 help="""Configure matplotlib for interactive use with
187 171 the default matplotlib backend."""
188 172 ).tag(config=True)
189 173 pylab = CaselessStrEnum(backend_keys, allow_none=True,
190 174 help="""Pre-load matplotlib and numpy for interactive use,
191 175 selecting a particular matplotlib backend and loop integration.
192 176 """
193 177 ).tag(config=True)
194 178 pylab_import_all = Bool(True,
195 179 help="""If true, IPython will populate the user namespace with numpy, pylab, etc.
196 180 and an ``import *`` is done from numpy and pylab, when using pylab mode.
197 181
198 182 When False, pylab mode should not import any names into the user namespace.
199 183 """
200 184 ).tag(config=True)
201 185 ignore_cwd = Bool(
202 186 False,
203 187 help="""If True, IPython will not add the current working directory to sys.path.
204 188 When False, the current working directory is added to sys.path, allowing imports
205 189 of modules defined in the current directory."""
206 190 ).tag(config=True)
207 191 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
208 192 allow_none=True)
209 193 # whether interact-loop should start
210 194 interact = Bool(True)
211 195
212 196 user_ns = Instance(dict, args=None, allow_none=True)
213 197 @observe('user_ns')
214 198 def _user_ns_changed(self, change):
215 199 if self.shell is not None:
216 200 self.shell.user_ns = change['new']
217 201 self.shell.init_user_ns()
218 202
219 203 def init_path(self):
220 204 """Add current working directory, '', to sys.path
221 205
222 206 Unlike Python's default, we insert before the first `site-packages`
223 207 or `dist-packages` directory,
224 208 so that it is after the standard library.
225 209
226 210 .. versionchanged:: 7.2
227 211 Try to insert after the standard library, instead of first.
228 212 .. versionchanged:: 8.0
229 213 Allow optionally not including the current directory in sys.path
230 214 """
231 215 if '' in sys.path or self.ignore_cwd:
232 216 return
233 217 for idx, path in enumerate(sys.path):
234 218 parent, last_part = os.path.split(path)
235 219 if last_part in {'site-packages', 'dist-packages'}:
236 220 break
237 221 else:
238 222 # no site-packages or dist-packages found (?!)
239 223 # back to original behavior of inserting at the front
240 224 idx = 0
241 225 sys.path.insert(idx, '')
242 226
243 227 def init_shell(self):
244 228 raise NotImplementedError("Override in subclasses")
245 229
246 230 def init_gui_pylab(self):
247 231 """Enable GUI event loop integration, taking pylab into account."""
248 232 enable = False
249 233 shell = self.shell
250 234 if self.pylab:
251 235 enable = lambda key: shell.enable_pylab(key, import_all=self.pylab_import_all)
252 236 key = self.pylab
253 237 elif self.matplotlib:
254 238 enable = shell.enable_matplotlib
255 239 key = self.matplotlib
256 240 elif self.gui:
257 241 enable = shell.enable_gui
258 242 key = self.gui
259 243
260 244 if not enable:
261 245 return
262 246
263 247 try:
264 248 r = enable(key)
265 249 except ImportError:
266 250 self.log.warning("Eventloop or matplotlib integration failed. Is matplotlib installed?")
267 251 self.shell.showtraceback()
268 252 return
269 253 except Exception:
270 254 self.log.warning("GUI event loop or pylab initialization failed")
271 255 self.shell.showtraceback()
272 256 return
273 257
274 258 if isinstance(r, tuple):
275 259 gui, backend = r[:2]
276 260 self.log.info("Enabling GUI event loop integration, "
277 261 "eventloop=%s, matplotlib=%s", gui, backend)
278 262 if key == "auto":
279 263 print("Using matplotlib backend: %s" % backend)
280 264 else:
281 265 gui = r
282 266 self.log.info("Enabling GUI event loop integration, "
283 267 "eventloop=%s", gui)
284 268
285 269 def init_extensions(self):
286 270 """Load all IPython extensions in IPythonApp.extensions.
287 271
288 272 This uses the :meth:`ExtensionManager.load_extensions` to load all
289 273 the extensions listed in ``self.extensions``.
290 274 """
291 275 try:
292 276 self.log.debug("Loading IPython extensions...")
293 277 extensions = (
294 278 self.default_extensions + self.extensions + self.extra_extensions
295 279 )
296 if self.extra_extension:
297 extensions.append(self.extra_extension)
298 280 for ext in extensions:
299 281 try:
300 282 self.log.info("Loading IPython extension: %s" % ext)
301 283 self.shell.extension_manager.load_extension(ext)
302 284 except:
303 285 if self.reraise_ipython_extension_failures:
304 286 raise
305 287 msg = ("Error in loading extension: {ext}\n"
306 288 "Check your config files in {location}".format(
307 289 ext=ext,
308 290 location=self.profile_dir.location
309 291 ))
310 292 self.log.warning(msg, exc_info=True)
311 293 except:
312 294 if self.reraise_ipython_extension_failures:
313 295 raise
314 296 self.log.warning("Unknown error in loading extensions:", exc_info=True)
315 297
316 298 def init_code(self):
317 299 """run the pre-flight code, specified via exec_lines"""
318 300 self._run_startup_files()
319 301 self._run_exec_lines()
320 302 self._run_exec_files()
321 303
322 304 # Hide variables defined here from %who etc.
323 305 if self.hide_initial_ns:
324 306 self.shell.user_ns_hidden.update(self.shell.user_ns)
325 307
326 308 # command-line execution (ipython -i script.py, ipython -m module)
327 309 # should *not* be excluded from %whos
328 310 self._run_cmd_line_code()
329 311 self._run_module()
330 312
331 313 # flush output, so itwon't be attached to the first cell
332 314 sys.stdout.flush()
333 315 sys.stderr.flush()
334 316 self.shell._sys_modules_keys = set(sys.modules.keys())
335 317
336 318 def _run_exec_lines(self):
337 319 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
338 320 if not self.exec_lines:
339 321 return
340 322 try:
341 323 self.log.debug("Running code from IPythonApp.exec_lines...")
342 324 for line in self.exec_lines:
343 325 try:
344 326 self.log.info("Running code in user namespace: %s" %
345 327 line)
346 328 self.shell.run_cell(line, store_history=False)
347 329 except:
348 330 self.log.warning("Error in executing line in user "
349 331 "namespace: %s" % line)
350 332 self.shell.showtraceback()
351 333 except:
352 334 self.log.warning("Unknown error in handling IPythonApp.exec_lines:")
353 335 self.shell.showtraceback()
354 336
355 337 def _exec_file(self, fname, shell_futures=False):
356 338 try:
357 339 full_filename = filefind(fname, [u'.', self.ipython_dir])
358 340 except IOError:
359 341 self.log.warning("File not found: %r"%fname)
360 342 return
361 343 # Make sure that the running script gets a proper sys.argv as if it
362 344 # were run from a system shell.
363 345 save_argv = sys.argv
364 346 sys.argv = [full_filename] + self.extra_args[1:]
365 347 try:
366 348 if os.path.isfile(full_filename):
367 349 self.log.info("Running file in user namespace: %s" %
368 350 full_filename)
369 351 # Ensure that __file__ is always defined to match Python
370 352 # behavior.
371 353 with preserve_keys(self.shell.user_ns, '__file__'):
372 354 self.shell.user_ns['__file__'] = fname
373 355 if full_filename.endswith('.ipy') or full_filename.endswith('.ipynb'):
374 356 self.shell.safe_execfile_ipy(full_filename,
375 357 shell_futures=shell_futures)
376 358 else:
377 359 # default to python, even without extension
378 360 self.shell.safe_execfile(full_filename,
379 361 self.shell.user_ns,
380 362 shell_futures=shell_futures,
381 363 raise_exceptions=True)
382 364 finally:
383 365 sys.argv = save_argv
384 366
385 367 def _run_startup_files(self):
386 368 """Run files from profile startup directory"""
387 369 startup_dirs = [self.profile_dir.startup_dir] + [
388 370 os.path.join(p, 'startup') for p in chain(ENV_CONFIG_DIRS, SYSTEM_CONFIG_DIRS)
389 371 ]
390 372 startup_files = []
391 373
392 374 if self.exec_PYTHONSTARTUP and os.environ.get('PYTHONSTARTUP', False) and \
393 375 not (self.file_to_run or self.code_to_run or self.module_to_run):
394 376 python_startup = os.environ['PYTHONSTARTUP']
395 377 self.log.debug("Running PYTHONSTARTUP file %s...", python_startup)
396 378 try:
397 379 self._exec_file(python_startup)
398 380 except:
399 381 self.log.warning("Unknown error in handling PYTHONSTARTUP file %s:", python_startup)
400 382 self.shell.showtraceback()
401 383 for startup_dir in startup_dirs[::-1]:
402 384 startup_files += glob.glob(os.path.join(startup_dir, '*.py'))
403 385 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
404 386 if not startup_files:
405 387 return
406 388
407 389 self.log.debug("Running startup files from %s...", startup_dir)
408 390 try:
409 391 for fname in sorted(startup_files):
410 392 self._exec_file(fname)
411 393 except:
412 394 self.log.warning("Unknown error in handling startup files:")
413 395 self.shell.showtraceback()
414 396
415 397 def _run_exec_files(self):
416 398 """Run files from IPythonApp.exec_files"""
417 399 if not self.exec_files:
418 400 return
419 401
420 402 self.log.debug("Running files in IPythonApp.exec_files...")
421 403 try:
422 404 for fname in self.exec_files:
423 405 self._exec_file(fname)
424 406 except:
425 407 self.log.warning("Unknown error in handling IPythonApp.exec_files:")
426 408 self.shell.showtraceback()
427 409
428 410 def _run_cmd_line_code(self):
429 411 """Run code or file specified at the command-line"""
430 412 if self.code_to_run:
431 413 line = self.code_to_run
432 414 try:
433 415 self.log.info("Running code given at command line (c=): %s" %
434 416 line)
435 417 self.shell.run_cell(line, store_history=False)
436 418 except:
437 419 self.log.warning("Error in executing line in user namespace: %s" %
438 420 line)
439 421 self.shell.showtraceback()
440 422 if not self.interact:
441 423 self.exit(1)
442 424
443 425 # Like Python itself, ignore the second if the first of these is present
444 426 elif self.file_to_run:
445 427 fname = self.file_to_run
446 428 if os.path.isdir(fname):
447 429 fname = os.path.join(fname, "__main__.py")
448 430 if not os.path.exists(fname):
449 431 self.log.warning("File '%s' doesn't exist", fname)
450 432 if not self.interact:
451 433 self.exit(2)
452 434 try:
453 435 self._exec_file(fname, shell_futures=True)
454 436 except:
455 437 self.shell.showtraceback(tb_offset=4)
456 438 if not self.interact:
457 439 self.exit(1)
458 440
459 441 def _run_module(self):
460 442 """Run module specified at the command-line."""
461 443 if self.module_to_run:
462 444 # Make sure that the module gets a proper sys.argv as if it were
463 445 # run using `python -m`.
464 446 save_argv = sys.argv
465 447 sys.argv = [sys.executable] + self.extra_args
466 448 try:
467 449 self.shell.safe_run_module(self.module_to_run,
468 450 self.shell.user_ns)
469 451 finally:
470 452 sys.argv = save_argv
@@ -1,544 +1,532 b''
1 1 """Tests for the Formatters."""
2 2
3 3 import warnings
4 4 from math import pi
5 5
6 6 try:
7 7 import numpy
8 8 except:
9 9 numpy = None
10 10 import pytest
11 11
12 12 from IPython import get_ipython
13 13 from traitlets.config import Config
14 14 from IPython.core.formatters import (
15 15 PlainTextFormatter, HTMLFormatter, PDFFormatter, _mod_name_key,
16 16 DisplayFormatter, JSONFormatter,
17 17 )
18 18 from IPython.utils.io import capture_output
19 19
20 20 class A(object):
21 21 def __repr__(self):
22 22 return 'A()'
23 23
24 24 class B(A):
25 25 def __repr__(self):
26 26 return 'B()'
27 27
28 28 class C:
29 29 pass
30 30
31 31 class BadRepr(object):
32 32 def __repr__(self):
33 33 raise ValueError("bad repr")
34 34
35 35 class BadPretty(object):
36 36 _repr_pretty_ = None
37 37
38 38 class GoodPretty(object):
39 39 def _repr_pretty_(self, pp, cycle):
40 40 pp.text('foo')
41 41
42 42 def __repr__(self):
43 43 return 'GoodPretty()'
44 44
45 45 def foo_printer(obj, pp, cycle):
46 46 pp.text('foo')
47 47
48 48 def test_pretty():
49 49 f = PlainTextFormatter()
50 50 f.for_type(A, foo_printer)
51 51 assert f(A()) == "foo"
52 52 assert f(B()) == "B()"
53 53 assert f(GoodPretty()) == "foo"
54 54 # Just don't raise an exception for the following:
55 55 f(BadPretty())
56 56
57 57 f.pprint = False
58 58 assert f(A()) == "A()"
59 59 assert f(B()) == "B()"
60 60 assert f(GoodPretty()) == "GoodPretty()"
61 61
62 62
63 63 def test_deferred():
64 64 f = PlainTextFormatter()
65 65
66 66 def test_precision():
67 67 """test various values for float_precision."""
68 68 f = PlainTextFormatter()
69 69 assert f(pi) == repr(pi)
70 70 f.float_precision = 0
71 71 if numpy:
72 72 po = numpy.get_printoptions()
73 73 assert po["precision"] == 0
74 74 assert f(pi) == "3"
75 75 f.float_precision = 2
76 76 if numpy:
77 77 po = numpy.get_printoptions()
78 78 assert po["precision"] == 2
79 79 assert f(pi) == "3.14"
80 80 f.float_precision = "%g"
81 81 if numpy:
82 82 po = numpy.get_printoptions()
83 83 assert po["precision"] == 2
84 84 assert f(pi) == "3.14159"
85 85 f.float_precision = "%e"
86 86 assert f(pi) == "3.141593e+00"
87 87 f.float_precision = ""
88 88 if numpy:
89 89 po = numpy.get_printoptions()
90 90 assert po["precision"] == 8
91 91 assert f(pi) == repr(pi)
92 92
93 93
94 94 def test_bad_precision():
95 95 """test various invalid values for float_precision."""
96 96 f = PlainTextFormatter()
97 97 def set_fp(p):
98 98 f.float_precision = p
99 99
100 100 pytest.raises(ValueError, set_fp, "%")
101 101 pytest.raises(ValueError, set_fp, "%.3f%i")
102 102 pytest.raises(ValueError, set_fp, "foo")
103 103 pytest.raises(ValueError, set_fp, -1)
104 104
105 105 def test_for_type():
106 106 f = PlainTextFormatter()
107 107
108 108 # initial return, None
109 109 assert f.for_type(C, foo_printer) is None
110 110 # no func queries
111 111 assert f.for_type(C) is foo_printer
112 112 # shouldn't change anything
113 113 assert f.for_type(C) is foo_printer
114 114 # None should do the same
115 115 assert f.for_type(C, None) is foo_printer
116 116 assert f.for_type(C, None) is foo_printer
117 117
118 118 def test_for_type_string():
119 119 f = PlainTextFormatter()
120 120
121 121 type_str = '%s.%s' % (C.__module__, 'C')
122 122
123 123 # initial return, None
124 124 assert f.for_type(type_str, foo_printer) is None
125 125 # no func queries
126 126 assert f.for_type(type_str) is foo_printer
127 127 assert _mod_name_key(C) in f.deferred_printers
128 128 assert f.for_type(C) is foo_printer
129 129 assert _mod_name_key(C) not in f.deferred_printers
130 130 assert C in f.type_printers
131 131
132 132 def test_for_type_by_name():
133 133 f = PlainTextFormatter()
134 134
135 135 mod = C.__module__
136 136
137 137 # initial return, None
138 138 assert f.for_type_by_name(mod, "C", foo_printer) is None
139 139 # no func queries
140 140 assert f.for_type_by_name(mod, "C") is foo_printer
141 141 # shouldn't change anything
142 142 assert f.for_type_by_name(mod, "C") is foo_printer
143 143 # None should do the same
144 144 assert f.for_type_by_name(mod, "C", None) is foo_printer
145 145 assert f.for_type_by_name(mod, "C", None) is foo_printer
146 146
147 147
148 148 def test_lookup():
149 149 f = PlainTextFormatter()
150 150
151 151 f.for_type(C, foo_printer)
152 152 assert f.lookup(C()) is foo_printer
153 153 with pytest.raises(KeyError):
154 154 f.lookup(A())
155 155
156 156 def test_lookup_string():
157 157 f = PlainTextFormatter()
158 158 type_str = '%s.%s' % (C.__module__, 'C')
159 159
160 160 f.for_type(type_str, foo_printer)
161 161 assert f.lookup(C()) is foo_printer
162 162 # should move from deferred to imported dict
163 163 assert _mod_name_key(C) not in f.deferred_printers
164 164 assert C in f.type_printers
165 165
166 166 def test_lookup_by_type():
167 167 f = PlainTextFormatter()
168 168 f.for_type(C, foo_printer)
169 169 assert f.lookup_by_type(C) is foo_printer
170 170 with pytest.raises(KeyError):
171 171 f.lookup_by_type(A)
172 172
173 173 def test_lookup_by_type_string():
174 174 f = PlainTextFormatter()
175 175 type_str = '%s.%s' % (C.__module__, 'C')
176 176 f.for_type(type_str, foo_printer)
177 177
178 178 # verify insertion
179 179 assert _mod_name_key(C) in f.deferred_printers
180 180 assert C not in f.type_printers
181 181
182 182 assert f.lookup_by_type(type_str) is foo_printer
183 183 # lookup by string doesn't cause import
184 184 assert _mod_name_key(C) in f.deferred_printers
185 185 assert C not in f.type_printers
186 186
187 187 assert f.lookup_by_type(C) is foo_printer
188 188 # should move from deferred to imported dict
189 189 assert _mod_name_key(C) not in f.deferred_printers
190 190 assert C in f.type_printers
191 191
192 192 def test_in_formatter():
193 193 f = PlainTextFormatter()
194 194 f.for_type(C, foo_printer)
195 195 type_str = '%s.%s' % (C.__module__, 'C')
196 196 assert C in f
197 197 assert type_str in f
198 198
199 199 def test_string_in_formatter():
200 200 f = PlainTextFormatter()
201 201 type_str = '%s.%s' % (C.__module__, 'C')
202 202 f.for_type(type_str, foo_printer)
203 203 assert type_str in f
204 204 assert C in f
205 205
206 206 def test_pop():
207 207 f = PlainTextFormatter()
208 208 f.for_type(C, foo_printer)
209 209 assert f.lookup_by_type(C) is foo_printer
210 210 assert f.pop(C, None) is foo_printer
211 211 f.for_type(C, foo_printer)
212 212 assert f.pop(C) is foo_printer
213 213 with pytest.raises(KeyError):
214 214 f.lookup_by_type(C)
215 215 with pytest.raises(KeyError):
216 216 f.pop(C)
217 217 with pytest.raises(KeyError):
218 218 f.pop(A)
219 219 assert f.pop(A, None) is None
220 220
221 221 def test_pop_string():
222 222 f = PlainTextFormatter()
223 223 type_str = '%s.%s' % (C.__module__, 'C')
224 224
225 225 with pytest.raises(KeyError):
226 226 f.pop(type_str)
227 227
228 228 f.for_type(type_str, foo_printer)
229 229 f.pop(type_str)
230 230 with pytest.raises(KeyError):
231 231 f.lookup_by_type(C)
232 232 with pytest.raises(KeyError):
233 233 f.pop(type_str)
234 234
235 235 f.for_type(C, foo_printer)
236 236 assert f.pop(type_str, None) is foo_printer
237 237 with pytest.raises(KeyError):
238 238 f.lookup_by_type(C)
239 239 with pytest.raises(KeyError):
240 240 f.pop(type_str)
241 241 assert f.pop(type_str, None) is None
242 242
243 243
244 244 def test_error_method():
245 245 f = HTMLFormatter()
246 246 class BadHTML(object):
247 247 def _repr_html_(self):
248 248 raise ValueError("Bad HTML")
249 249 bad = BadHTML()
250 250 with capture_output() as captured:
251 251 result = f(bad)
252 252 assert result is None
253 253 assert "Traceback" in captured.stdout
254 254 assert "Bad HTML" in captured.stdout
255 255 assert "_repr_html_" in captured.stdout
256 256
257 257 def test_nowarn_notimplemented():
258 258 f = HTMLFormatter()
259 259 class HTMLNotImplemented(object):
260 260 def _repr_html_(self):
261 261 raise NotImplementedError
262 262 h = HTMLNotImplemented()
263 263 with capture_output() as captured:
264 264 result = f(h)
265 265 assert result is None
266 266 assert "" == captured.stderr
267 267 assert "" == captured.stdout
268 268
269 269
270 270 def test_warn_error_for_type():
271 271 f = HTMLFormatter()
272 272 f.for_type(int, lambda i: name_error)
273 273 with capture_output() as captured:
274 274 result = f(5)
275 275 assert result is None
276 276 assert "Traceback" in captured.stdout
277 277 assert "NameError" in captured.stdout
278 278 assert "name_error" in captured.stdout
279 279
280 280 def test_error_pretty_method():
281 281 f = PlainTextFormatter()
282 282 class BadPretty(object):
283 283 def _repr_pretty_(self):
284 284 return "hello"
285 285 bad = BadPretty()
286 286 with capture_output() as captured:
287 287 result = f(bad)
288 288 assert result is None
289 289 assert "Traceback" in captured.stdout
290 290 assert "_repr_pretty_" in captured.stdout
291 291 assert "given" in captured.stdout
292 292 assert "argument" in captured.stdout
293 293
294 294
295 295 def test_bad_repr_traceback():
296 296 f = PlainTextFormatter()
297 297 bad = BadRepr()
298 298 with capture_output() as captured:
299 299 result = f(bad)
300 300 # catches error, returns None
301 301 assert result is None
302 302 assert "Traceback" in captured.stdout
303 303 assert "__repr__" in captured.stdout
304 304 assert "ValueError" in captured.stdout
305 305
306 306
307 307 class MakePDF(object):
308 308 def _repr_pdf_(self):
309 309 return 'PDF'
310 310
311 311 def test_pdf_formatter():
312 312 pdf = MakePDF()
313 313 f = PDFFormatter()
314 314 assert f(pdf) == "PDF"
315 315
316 316
317 317 def test_print_method_bound():
318 318 f = HTMLFormatter()
319 319 class MyHTML(object):
320 320 def _repr_html_(self):
321 321 return "hello"
322 322 with capture_output() as captured:
323 323 result = f(MyHTML)
324 324 assert result is None
325 325 assert "FormatterWarning" not in captured.stderr
326 326
327 327 with capture_output() as captured:
328 328 result = f(MyHTML())
329 329 assert result == "hello"
330 330 assert captured.stderr == ""
331 331
332 332
333 333 def test_print_method_weird():
334 334
335 335 class TextMagicHat(object):
336 336 def __getattr__(self, key):
337 337 return key
338 338
339 339 f = HTMLFormatter()
340 340
341 341 text_hat = TextMagicHat()
342 342 assert text_hat._repr_html_ == "_repr_html_"
343 343 with capture_output() as captured:
344 344 result = f(text_hat)
345 345
346 346 assert result is None
347 347 assert "FormatterWarning" not in captured.stderr
348 348
349 349 class CallableMagicHat(object):
350 350 def __getattr__(self, key):
351 351 return lambda : key
352 352
353 353 call_hat = CallableMagicHat()
354 354 with capture_output() as captured:
355 355 result = f(call_hat)
356 356
357 357 assert result is None
358 358
359 359 class BadReprArgs(object):
360 360 def _repr_html_(self, extra, args):
361 361 return "html"
362 362
363 363 bad = BadReprArgs()
364 364 with capture_output() as captured:
365 365 result = f(bad)
366 366
367 367 assert result is None
368 368 assert "FormatterWarning" not in captured.stderr
369 369
370 370
371 371 def test_format_config():
372 372 """config objects don't pretend to support fancy reprs with lazy attrs"""
373 373 f = HTMLFormatter()
374 374 cfg = Config()
375 375 with capture_output() as captured:
376 376 result = f(cfg)
377 377 assert result is None
378 378 assert captured.stderr == ""
379 379
380 380 with capture_output() as captured:
381 381 result = f(Config)
382 382 assert result is None
383 383 assert captured.stderr == ""
384 384
385 385
386 386 def test_pretty_max_seq_length():
387 387 f = PlainTextFormatter(max_seq_length=1)
388 388 lis = list(range(3))
389 389 text = f(lis)
390 390 assert text == "[0, ...]"
391 391 f.max_seq_length = 0
392 392 text = f(lis)
393 393 assert text == "[0, 1, 2]"
394 394 text = f(list(range(1024)))
395 395 lines = text.splitlines()
396 396 assert len(lines) == 1024
397 397
398 398
399 399 def test_ipython_display_formatter():
400 400 """Objects with _ipython_display_ defined bypass other formatters"""
401 401 f = get_ipython().display_formatter
402 402 catcher = []
403 403 class SelfDisplaying(object):
404 404 def _ipython_display_(self):
405 405 catcher.append(self)
406 406
407 407 class NotSelfDisplaying(object):
408 408 def __repr__(self):
409 409 return "NotSelfDisplaying"
410 410
411 411 def _ipython_display_(self):
412 412 raise NotImplementedError
413 413
414 414 save_enabled = f.ipython_display_formatter.enabled
415 415 f.ipython_display_formatter.enabled = True
416 416
417 417 yes = SelfDisplaying()
418 418 no = NotSelfDisplaying()
419 419
420 420 d, md = f.format(no)
421 421 assert d == {"text/plain": repr(no)}
422 422 assert md == {}
423 423 assert catcher == []
424 424
425 425 d, md = f.format(yes)
426 426 assert d == {}
427 427 assert md == {}
428 428 assert catcher == [yes]
429 429
430 430 f.ipython_display_formatter.enabled = save_enabled
431 431
432 432
433 def test_json_as_string_deprecated():
434 class JSONString(object):
435 def _repr_json_(self):
436 return '{}'
437
438 f = JSONFormatter()
439 with warnings.catch_warnings(record=True) as w:
440 d = f(JSONString())
441 assert d == {}
442 assert len(w) == 1
443
444
445 433 def test_repr_mime():
446 434 class HasReprMime(object):
447 435 def _repr_mimebundle_(self, include=None, exclude=None):
448 436 return {
449 437 'application/json+test.v2': {
450 438 'x': 'y'
451 439 },
452 440 'plain/text' : '<HasReprMime>',
453 441 'image/png' : 'i-overwrite'
454 442 }
455 443
456 444 def _repr_png_(self):
457 445 return 'should-be-overwritten'
458 446 def _repr_html_(self):
459 447 return '<b>hi!</b>'
460 448
461 449 f = get_ipython().display_formatter
462 450 html_f = f.formatters['text/html']
463 451 save_enabled = html_f.enabled
464 452 html_f.enabled = True
465 453 obj = HasReprMime()
466 454 d, md = f.format(obj)
467 455 html_f.enabled = save_enabled
468 456
469 457 assert sorted(d) == [
470 458 "application/json+test.v2",
471 459 "image/png",
472 460 "plain/text",
473 461 "text/html",
474 462 "text/plain",
475 463 ]
476 464 assert md == {}
477 465
478 466 d, md = f.format(obj, include={"image/png"})
479 467 assert list(d.keys()) == [
480 468 "image/png"
481 469 ], "Include should filter out even things from repr_mimebundle"
482 470
483 471 assert d["image/png"] == "i-overwrite", "_repr_mimebundle_ take precedence"
484 472
485 473
486 474 def test_pass_correct_include_exclude():
487 475 class Tester(object):
488 476
489 477 def __init__(self, include=None, exclude=None):
490 478 self.include = include
491 479 self.exclude = exclude
492 480
493 481 def _repr_mimebundle_(self, include, exclude, **kwargs):
494 482 if include and (include != self.include):
495 483 raise ValueError('include got modified: display() may be broken.')
496 484 if exclude and (exclude != self.exclude):
497 485 raise ValueError('exclude got modified: display() may be broken.')
498 486
499 487 return None
500 488
501 489 include = {'a', 'b', 'c'}
502 490 exclude = {'c', 'e' , 'f'}
503 491
504 492 f = get_ipython().display_formatter
505 493 f.format(Tester(include=include, exclude=exclude), include=include, exclude=exclude)
506 494 f.format(Tester(exclude=exclude), exclude=exclude)
507 495 f.format(Tester(include=include), include=include)
508 496
509 497
510 498 def test_repr_mime_meta():
511 499 class HasReprMimeMeta(object):
512 500 def _repr_mimebundle_(self, include=None, exclude=None):
513 501 data = {
514 502 'image/png': 'base64-image-data',
515 503 }
516 504 metadata = {
517 505 'image/png': {
518 506 'width': 5,
519 507 'height': 10,
520 508 }
521 509 }
522 510 return (data, metadata)
523 511
524 512 f = get_ipython().display_formatter
525 513 obj = HasReprMimeMeta()
526 514 d, md = f.format(obj)
527 515 assert sorted(d) == ["image/png", "text/plain"]
528 516 assert md == {
529 517 "image/png": {
530 518 "width": 5,
531 519 "height": 10,
532 520 }
533 521 }
534 522
535 523
536 524 def test_repr_mime_failure():
537 525 class BadReprMime(object):
538 526 def _repr_mimebundle_(self, include=None, exclude=None):
539 527 raise RuntimeError
540 528
541 529 f = get_ipython().display_formatter
542 530 obj = BadReprMime()
543 531 d, md = f.format(obj)
544 532 assert "text/plain" in d
@@ -1,356 +1,340 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 The :class:`~IPython.core.application.Application` object for the command
5 5 line :command:`ipython` program.
6 6 """
7 7
8 8 # Copyright (c) IPython Development Team.
9 9 # Distributed under the terms of the Modified BSD License.
10 10
11 11
12 12 import logging
13 13 import os
14 14 import sys
15 15 import warnings
16 16
17 17 from traitlets.config.loader import Config
18 18 from traitlets.config.application import boolean_flag, catch_config_error
19 19 from IPython.core import release
20 20 from IPython.core import usage
21 21 from IPython.core.completer import IPCompleter
22 22 from IPython.core.crashhandler import CrashHandler
23 23 from IPython.core.formatters import PlainTextFormatter
24 24 from IPython.core.history import HistoryManager
25 25 from IPython.core.application import (
26 26 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
27 27 )
28 28 from IPython.core.magics import (
29 29 ScriptMagics, LoggingMagics
30 30 )
31 31 from IPython.core.shellapp import (
32 32 InteractiveShellApp, shell_flags, shell_aliases
33 33 )
34 34 from IPython.extensions.storemagic import StoreMagics
35 35 from .interactiveshell import TerminalInteractiveShell
36 36 from IPython.paths import get_ipython_dir
37 37 from traitlets import (
38 38 Bool, List, default, observe, Type
39 39 )
40 40
41 41 #-----------------------------------------------------------------------------
42 42 # Globals, utilities and helpers
43 43 #-----------------------------------------------------------------------------
44 44
45 45 _examples = """
46 46 ipython --matplotlib # enable matplotlib integration
47 47 ipython --matplotlib=qt # enable matplotlib integration with qt4 backend
48 48
49 49 ipython --log-level=DEBUG # set logging to DEBUG
50 50 ipython --profile=foo # start with profile foo
51 51
52 52 ipython profile create foo # create profile foo w/ default config files
53 53 ipython help profile # show the help for the profile subcmd
54 54
55 55 ipython locate # print the path to the IPython directory
56 56 ipython locate profile foo # print the path to the directory for profile `foo`
57 57 """
58 58
59 59 #-----------------------------------------------------------------------------
60 60 # Crash handler for this application
61 61 #-----------------------------------------------------------------------------
62 62
63 63 class IPAppCrashHandler(CrashHandler):
64 64 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
65 65
66 66 def __init__(self, app):
67 67 contact_name = release.author
68 68 contact_email = release.author_email
69 69 bug_tracker = 'https://github.com/ipython/ipython/issues'
70 70 super(IPAppCrashHandler,self).__init__(
71 71 app, contact_name, contact_email, bug_tracker
72 72 )
73 73
74 74 def make_report(self,traceback):
75 75 """Return a string containing a crash report."""
76 76
77 77 sec_sep = self.section_sep
78 78 # Start with parent report
79 79 report = [super(IPAppCrashHandler, self).make_report(traceback)]
80 80 # Add interactive-specific info we may have
81 81 rpt_add = report.append
82 82 try:
83 83 rpt_add(sec_sep+"History of session input:")
84 84 for line in self.app.shell.user_ns['_ih']:
85 85 rpt_add(line)
86 86 rpt_add('\n*** Last line of input (may not be in above history):\n')
87 87 rpt_add(self.app.shell._last_input_line+'\n')
88 88 except:
89 89 pass
90 90
91 91 return ''.join(report)
92 92
93 93 #-----------------------------------------------------------------------------
94 94 # Aliases and Flags
95 95 #-----------------------------------------------------------------------------
96 96 flags = dict(base_flags)
97 97 flags.update(shell_flags)
98 98 frontend_flags = {}
99 99 addflag = lambda *args: frontend_flags.update(boolean_flag(*args))
100 100 addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
101 101 'Turn on auto editing of files with syntax errors.',
102 102 'Turn off auto editing of files with syntax errors.'
103 103 )
104 104 addflag('simple-prompt', 'TerminalInteractiveShell.simple_prompt',
105 105 "Force simple minimal prompt using `raw_input`",
106 106 "Use a rich interactive prompt with prompt_toolkit",
107 107 )
108 108
109 109 addflag('banner', 'TerminalIPythonApp.display_banner',
110 110 "Display a banner upon starting IPython.",
111 111 "Don't display a banner upon starting IPython."
112 112 )
113 113 addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
114 114 """Set to confirm when you try to exit IPython with an EOF (Control-D
115 115 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
116 116 you can force a direct exit without any confirmation.""",
117 117 "Don't prompt the user when exiting."
118 118 )
119 119 addflag('term-title', 'TerminalInteractiveShell.term_title',
120 120 "Enable auto setting the terminal title.",
121 121 "Disable auto setting the terminal title."
122 122 )
123 123 classic_config = Config()
124 124 classic_config.InteractiveShell.cache_size = 0
125 125 classic_config.PlainTextFormatter.pprint = False
126 126 classic_config.TerminalInteractiveShell.prompts_class='IPython.terminal.prompts.ClassicPrompts'
127 127 classic_config.InteractiveShell.separate_in = ''
128 128 classic_config.InteractiveShell.separate_out = ''
129 129 classic_config.InteractiveShell.separate_out2 = ''
130 130 classic_config.InteractiveShell.colors = 'NoColor'
131 131 classic_config.InteractiveShell.xmode = 'Plain'
132 132
133 133 frontend_flags['classic']=(
134 134 classic_config,
135 135 "Gives IPython a similar feel to the classic Python prompt."
136 136 )
137 137 # # log doesn't make so much sense this way anymore
138 138 # paa('--log','-l',
139 139 # action='store_true', dest='InteractiveShell.logstart',
140 140 # help="Start logging to the default log file (./ipython_log.py).")
141 141 #
142 142 # # quick is harder to implement
143 143 frontend_flags['quick']=(
144 144 {'TerminalIPythonApp' : {'quick' : True}},
145 145 "Enable quick startup with no config files."
146 146 )
147 147
148 148 frontend_flags['i'] = (
149 149 {'TerminalIPythonApp' : {'force_interact' : True}},
150 150 """If running code from the command line, become interactive afterwards.
151 151 It is often useful to follow this with `--` to treat remaining flags as
152 152 script arguments.
153 153 """
154 154 )
155 155 flags.update(frontend_flags)
156 156
157 157 aliases = dict(base_aliases)
158 158 aliases.update(shell_aliases)
159 159
160 160 #-----------------------------------------------------------------------------
161 161 # Main classes and functions
162 162 #-----------------------------------------------------------------------------
163 163
164 164
165 165 class LocateIPythonApp(BaseIPythonApplication):
166 166 description = """print the path to the IPython dir"""
167 167 subcommands = dict(
168 168 profile=('IPython.core.profileapp.ProfileLocate',
169 169 "print the path to an IPython profile directory",
170 170 ),
171 171 )
172 172 def start(self):
173 173 if self.subapp is not None:
174 174 return self.subapp.start()
175 175 else:
176 176 print(self.ipython_dir)
177 177
178 178
179 179 class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):
180 180 name = u'ipython'
181 181 description = usage.cl_usage
182 182 crash_handler_class = IPAppCrashHandler
183 183 examples = _examples
184 184
185 185 flags = flags
186 186 aliases = aliases
187 187 classes = List()
188 188
189 189 interactive_shell_class = Type(
190 190 klass=object, # use default_value otherwise which only allow subclasses.
191 191 default_value=TerminalInteractiveShell,
192 192 help="Class to use to instantiate the TerminalInteractiveShell object. Useful for custom Frontends"
193 193 ).tag(config=True)
194 194
195 195 @default('classes')
196 196 def _classes_default(self):
197 197 """This has to be in a method, for TerminalIPythonApp to be available."""
198 198 return [
199 199 InteractiveShellApp, # ShellApp comes before TerminalApp, because
200 200 self.__class__, # it will also affect subclasses (e.g. QtConsole)
201 201 TerminalInteractiveShell,
202 202 HistoryManager,
203 203 ProfileDir,
204 204 PlainTextFormatter,
205 205 IPCompleter,
206 206 ScriptMagics,
207 207 LoggingMagics,
208 208 StoreMagics,
209 209 ]
210 210
211 211 subcommands = dict(
212 212 profile = ("IPython.core.profileapp.ProfileApp",
213 213 "Create and manage IPython profiles."
214 214 ),
215 215 kernel = ("ipykernel.kernelapp.IPKernelApp",
216 216 "Start a kernel without an attached frontend."
217 217 ),
218 218 locate=('IPython.terminal.ipapp.LocateIPythonApp',
219 219 LocateIPythonApp.description
220 220 ),
221 221 history=('IPython.core.historyapp.HistoryApp',
222 222 "Manage the IPython history database."
223 223 ),
224 224 )
225 225
226 226
227 227 # *do* autocreate requested profile, but don't create the config file.
228 228 auto_create=Bool(True)
229 229 # configurables
230 230 quick = Bool(False,
231 231 help="""Start IPython quickly by skipping the loading of config files."""
232 232 ).tag(config=True)
233 233 @observe('quick')
234 234 def _quick_changed(self, change):
235 235 if change['new']:
236 236 self.load_config_file = lambda *a, **kw: None
237 237
238 238 display_banner = Bool(True,
239 239 help="Whether to display a banner upon starting IPython."
240 240 ).tag(config=True)
241 241
242 242 # if there is code of files to run from the cmd line, don't interact
243 243 # unless the --i flag (App.force_interact) is true.
244 244 force_interact = Bool(False,
245 245 help="""If a command or file is given via the command-line,
246 246 e.g. 'ipython foo.py', start an interactive shell after executing the
247 247 file or command."""
248 248 ).tag(config=True)
249 249 @observe('force_interact')
250 250 def _force_interact_changed(self, change):
251 251 if change['new']:
252 252 self.interact = True
253 253
254 254 @observe('file_to_run', 'code_to_run', 'module_to_run')
255 255 def _file_to_run_changed(self, change):
256 256 new = change['new']
257 257 if new:
258 258 self.something_to_run = True
259 259 if new and not self.force_interact:
260 260 self.interact = False
261 261
262 262 # internal, not-configurable
263 263 something_to_run=Bool(False)
264 264
265 def parse_command_line(self, argv=None):
266 """override to allow old '-pylab' flag with deprecation warning"""
267
268 argv = sys.argv[1:] if argv is None else argv
269
270 if '-pylab' in argv:
271 # deprecated `-pylab` given,
272 # warn and transform into current syntax
273 argv = argv[:] # copy, don't clobber
274 idx = argv.index('-pylab')
275 warnings.warn("`-pylab` flag has been deprecated.\n"
276 " Use `--matplotlib <backend>` and import pylab manually.")
277 argv[idx] = '--pylab'
278
279 return super(TerminalIPythonApp, self).parse_command_line(argv)
280
281 265 @catch_config_error
282 266 def initialize(self, argv=None):
283 267 """Do actions after construct, but before starting the app."""
284 268 super(TerminalIPythonApp, self).initialize(argv)
285 269 if self.subapp is not None:
286 270 # don't bother initializing further, starting subapp
287 271 return
288 272 # print self.extra_args
289 273 if self.extra_args and not self.something_to_run:
290 274 self.file_to_run = self.extra_args[0]
291 275 self.init_path()
292 276 # create the shell
293 277 self.init_shell()
294 278 # and draw the banner
295 279 self.init_banner()
296 280 # Now a variety of things that happen after the banner is printed.
297 281 self.init_gui_pylab()
298 282 self.init_extensions()
299 283 self.init_code()
300 284
301 285 def init_shell(self):
302 286 """initialize the InteractiveShell instance"""
303 287 # Create an InteractiveShell instance.
304 288 # shell.display_banner should always be False for the terminal
305 289 # based app, because we call shell.show_banner() by hand below
306 290 # so the banner shows *before* all extension loading stuff.
307 291 self.shell = self.interactive_shell_class.instance(parent=self,
308 292 profile_dir=self.profile_dir,
309 293 ipython_dir=self.ipython_dir, user_ns=self.user_ns)
310 294 self.shell.configurables.append(self)
311 295
312 296 def init_banner(self):
313 297 """optionally display the banner"""
314 298 if self.display_banner and self.interact:
315 299 self.shell.show_banner()
316 300 # Make sure there is a space below the banner.
317 301 if self.log_level <= logging.INFO: print()
318 302
319 303 def _pylab_changed(self, name, old, new):
320 304 """Replace --pylab='inline' with --pylab='auto'"""
321 305 if new == 'inline':
322 306 warnings.warn("'inline' not available as pylab backend, "
323 307 "using 'auto' instead.")
324 308 self.pylab = 'auto'
325 309
326 310 def start(self):
327 311 if self.subapp is not None:
328 312 return self.subapp.start()
329 313 # perform any prexec steps:
330 314 if self.interact:
331 315 self.log.debug("Starting IPython's mainloop...")
332 316 self.shell.mainloop()
333 317 else:
334 318 self.log.debug("IPython not interactive...")
335 319 if not self.shell.last_execution_succeeded:
336 320 sys.exit(1)
337 321
338 322 def load_default_config(ipython_dir=None):
339 323 """Load the default config file from the default ipython_dir.
340 324
341 325 This is useful for embedded shells.
342 326 """
343 327 if ipython_dir is None:
344 328 ipython_dir = get_ipython_dir()
345 329
346 330 profile_dir = os.path.join(ipython_dir, 'profile_default')
347 331 app = TerminalIPythonApp()
348 332 app.config_file_paths.append(profile_dir)
349 333 app.load_config_file()
350 334 return app.config
351 335
352 336 launch_new_instance = TerminalIPythonApp.launch_instance
353 337
354 338
355 339 if __name__ == '__main__':
356 340 launch_new_instance()
@@ -1,440 +1,392 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
17 17 from IPython.utils.process import system
18 18 from IPython.utils.decorators import undoc
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Code
22 22 #-----------------------------------------------------------------------------
23 23 fs_encoding = sys.getfilesystemencoding()
24 24
25 25 def _writable_dir(path):
26 26 """Whether `path` is a directory, to which the user has write access."""
27 27 return os.path.isdir(path) and os.access(path, os.W_OK)
28 28
29 29 if sys.platform == 'win32':
30 30 def _get_long_path_name(path):
31 31 """Get a long path name (expand ~) on Windows using ctypes.
32 32
33 33 Examples
34 34 --------
35 35
36 36 >>> get_long_path_name('c:\\\\docume~1')
37 37 'c:\\\\Documents and Settings'
38 38
39 39 """
40 40 try:
41 41 import ctypes
42 42 except ImportError as e:
43 43 raise ImportError('you need to have ctypes installed for this to work') from e
44 44 _GetLongPathName = ctypes.windll.kernel32.GetLongPathNameW
45 45 _GetLongPathName.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p,
46 46 ctypes.c_uint ]
47 47
48 48 buf = ctypes.create_unicode_buffer(260)
49 49 rv = _GetLongPathName(path, buf, 260)
50 50 if rv == 0 or rv > 260:
51 51 return path
52 52 else:
53 53 return buf.value
54 54 else:
55 55 def _get_long_path_name(path):
56 56 """Dummy no-op."""
57 57 return path
58 58
59 59
60 60
61 61 def get_long_path_name(path):
62 62 """Expand a path into its long form.
63 63
64 64 On Windows this expands any ~ in the paths. On other platforms, it is
65 65 a null operation.
66 66 """
67 67 return _get_long_path_name(path)
68 68
69 69
70 def unquote_filename(name, win32=(sys.platform=='win32')):
71 """ On Windows, remove leading and trailing quotes from filenames.
72
73 This function has been deprecated and should not be used any more:
74 unquoting is now taken care of by :func:`IPython.utils.process.arg_split`.
75 """
76 warn("'unquote_filename' is deprecated since IPython 5.0 and should not "
77 "be used anymore", DeprecationWarning, stacklevel=2)
78 if win32:
79 if name.startswith(("'", '"')) and name.endswith(("'", '"')):
80 name = name[1:-1]
81 return name
82
83
84 70 def compress_user(path):
85 71 """Reverse of :func:`os.path.expanduser`
86 72 """
87 73 home = os.path.expanduser('~')
88 74 if path.startswith(home):
89 75 path = "~" + path[len(home):]
90 76 return path
91 77
92 def get_py_filename(name, force_win32=None):
78 def get_py_filename(name):
93 79 """Return a valid python filename in the current directory.
94 80
95 81 If the given name is not a file, it adds '.py' and searches again.
96 82 Raises IOError with an informative message if the file isn't found.
97 83 """
98 84
99 85 name = os.path.expanduser(name)
100 if force_win32 is not None:
101 warn("The 'force_win32' argument to 'get_py_filename' is deprecated "
102 "since IPython 5.0 and should not be used anymore",
103 DeprecationWarning, stacklevel=2)
104 86 if not os.path.isfile(name) and not name.endswith('.py'):
105 87 name += '.py'
106 88 if os.path.isfile(name):
107 89 return name
108 90 else:
109 91 raise IOError('File `%r` not found.' % name)
110 92
111 93
112 94 def filefind(filename: str, path_dirs=None) -> str:
113 95 """Find a file by looking through a sequence of paths.
114 96
115 97 This iterates through a sequence of paths looking for a file and returns
116 98 the full, absolute path of the first occurrence of the file. If no set of
117 99 path dirs is given, the filename is tested as is, after running through
118 100 :func:`expandvars` and :func:`expanduser`. Thus a simple call::
119 101
120 102 filefind('myfile.txt')
121 103
122 104 will find the file in the current working dir, but::
123 105
124 106 filefind('~/myfile.txt')
125 107
126 108 Will find the file in the users home directory. This function does not
127 109 automatically try any paths, such as the cwd or the user's home directory.
128 110
129 111 Parameters
130 112 ----------
131 113 filename : str
132 114 The filename to look for.
133 115 path_dirs : str, None or sequence of str
134 116 The sequence of paths to look for the file in. If None, the filename
135 117 need to be absolute or be in the cwd. If a string, the string is
136 118 put into a sequence and the searched. If a sequence, walk through
137 119 each element and join with ``filename``, calling :func:`expandvars`
138 120 and :func:`expanduser` before testing for existence.
139 121
140 122 Returns
141 123 -------
142 124 path : str
143 125 returns absolute path to file.
144 126
145 127 Raises
146 128 ------
147 129 IOError
148 130 """
149 131
150 132 # If paths are quoted, abspath gets confused, strip them...
151 133 filename = filename.strip('"').strip("'")
152 134 # If the input is an absolute path, just check it exists
153 135 if os.path.isabs(filename) and os.path.isfile(filename):
154 136 return filename
155 137
156 138 if path_dirs is None:
157 139 path_dirs = ("",)
158 140 elif isinstance(path_dirs, str):
159 141 path_dirs = (path_dirs,)
160 142
161 143 for path in path_dirs:
162 144 if path == '.': path = os.getcwd()
163 145 testname = expand_path(os.path.join(path, filename))
164 146 if os.path.isfile(testname):
165 147 return os.path.abspath(testname)
166 148
167 149 raise IOError("File %r does not exist in any of the search paths: %r" %
168 150 (filename, path_dirs) )
169 151
170 152
171 153 class HomeDirError(Exception):
172 154 pass
173 155
174 156
175 157 def get_home_dir(require_writable=False) -> str:
176 158 """Return the 'home' directory, as a unicode string.
177 159
178 160 Uses os.path.expanduser('~'), and checks for writability.
179 161
180 162 See stdlib docs for how this is determined.
181 163 For Python <3.8, $HOME is first priority on *ALL* platforms.
182 164 For Python >=3.8 on Windows, %HOME% is no longer considered.
183 165
184 166 Parameters
185 167 ----------
186 168 require_writable : bool [default: False]
187 169 if True:
188 170 guarantees the return value is a writable directory, otherwise
189 171 raises HomeDirError
190 172 if False:
191 173 The path is resolved, but it is not guaranteed to exist or be writable.
192 174 """
193 175
194 176 homedir = os.path.expanduser('~')
195 177 # Next line will make things work even when /home/ is a symlink to
196 178 # /usr/home as it is on FreeBSD, for example
197 179 homedir = os.path.realpath(homedir)
198 180
199 181 if not _writable_dir(homedir) and os.name == 'nt':
200 182 # expanduser failed, use the registry to get the 'My Documents' folder.
201 183 try:
202 184 import winreg as wreg
203 185 with wreg.OpenKey(
204 186 wreg.HKEY_CURRENT_USER,
205 187 r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
206 188 ) as key:
207 189 homedir = wreg.QueryValueEx(key,'Personal')[0]
208 190 except:
209 191 pass
210 192
211 193 if (not require_writable) or _writable_dir(homedir):
212 194 assert isinstance(homedir, str), "Homedir should be unicode not bytes"
213 195 return homedir
214 196 else:
215 197 raise HomeDirError('%s is not a writable dir, '
216 198 'set $HOME environment variable to override' % homedir)
217 199
218 200 def get_xdg_dir():
219 201 """Return the XDG_CONFIG_HOME, if it is defined and exists, else None.
220 202
221 203 This is only for non-OS X posix (Linux,Unix,etc.) systems.
222 204 """
223 205
224 206 env = os.environ
225 207
226 208 if os.name == 'posix' and sys.platform != 'darwin':
227 209 # Linux, Unix, AIX, etc.
228 210 # use ~/.config if empty OR not set
229 211 xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config')
230 212 if xdg and _writable_dir(xdg):
231 213 assert isinstance(xdg, str)
232 214 return xdg
233 215
234 216 return None
235 217
236 218
237 219 def get_xdg_cache_dir():
238 220 """Return the XDG_CACHE_HOME, if it is defined and exists, else None.
239 221
240 222 This is only for non-OS X posix (Linux,Unix,etc.) systems.
241 223 """
242 224
243 225 env = os.environ
244 226
245 227 if os.name == 'posix' and sys.platform != 'darwin':
246 228 # Linux, Unix, AIX, etc.
247 229 # use ~/.cache if empty OR not set
248 230 xdg = env.get("XDG_CACHE_HOME", None) or os.path.join(get_home_dir(), '.cache')
249 231 if xdg and _writable_dir(xdg):
250 232 assert isinstance(xdg, str)
251 233 return xdg
252 234
253 235 return None
254 236
255 237
256 @undoc
257 def get_ipython_dir():
258 warn("get_ipython_dir has moved to the IPython.paths module since IPython 4.0.", DeprecationWarning, stacklevel=2)
259 from IPython.paths import get_ipython_dir
260 return get_ipython_dir()
261
262 @undoc
263 def get_ipython_cache_dir():
264 warn("get_ipython_cache_dir has moved to the IPython.paths module since IPython 4.0.", DeprecationWarning, stacklevel=2)
265 from IPython.paths import get_ipython_cache_dir
266 return get_ipython_cache_dir()
267
268 @undoc
269 def get_ipython_package_dir():
270 warn("get_ipython_package_dir has moved to the IPython.paths module since IPython 4.0.", DeprecationWarning, stacklevel=2)
271 from IPython.paths import get_ipython_package_dir
272 return get_ipython_package_dir()
273
274 @undoc
275 def get_ipython_module_path(module_str):
276 warn("get_ipython_module_path has moved to the IPython.paths module since IPython 4.0.", DeprecationWarning, stacklevel=2)
277 from IPython.paths import get_ipython_module_path
278 return get_ipython_module_path(module_str)
279
280 @undoc
281 def locate_profile(profile='default'):
282 warn("locate_profile has moved to the IPython.paths module since IPython 4.0.", DeprecationWarning, stacklevel=2)
283 from IPython.paths import locate_profile
284 return locate_profile(profile=profile)
285
286 238 def expand_path(s):
287 239 """Expand $VARS and ~names in a string, like a shell
288 240
289 241 :Examples:
290 242
291 243 In [2]: os.environ['FOO']='test'
292 244
293 245 In [3]: expand_path('variable FOO is $FOO')
294 246 Out[3]: 'variable FOO is test'
295 247 """
296 248 # This is a pretty subtle hack. When expand user is given a UNC path
297 249 # on Windows (\\server\share$\%username%), os.path.expandvars, removes
298 250 # the $ to get (\\server\share\%username%). I think it considered $
299 251 # alone an empty var. But, we need the $ to remains there (it indicates
300 252 # a hidden share).
301 253 if os.name=='nt':
302 254 s = s.replace('$\\', 'IPYTHON_TEMP')
303 255 s = os.path.expandvars(os.path.expanduser(s))
304 256 if os.name=='nt':
305 257 s = s.replace('IPYTHON_TEMP', '$\\')
306 258 return s
307 259
308 260
309 261 def unescape_glob(string):
310 262 """Unescape glob pattern in `string`."""
311 263 def unescape(s):
312 264 for pattern in '*[]!?':
313 265 s = s.replace(r'\{0}'.format(pattern), pattern)
314 266 return s
315 267 return '\\'.join(map(unescape, string.split('\\\\')))
316 268
317 269
318 270 def shellglob(args):
319 271 """
320 272 Do glob expansion for each element in `args` and return a flattened list.
321 273
322 274 Unmatched glob pattern will remain as-is in the returned list.
323 275
324 276 """
325 277 expanded = []
326 278 # Do not unescape backslash in Windows as it is interpreted as
327 279 # path separator:
328 280 unescape = unescape_glob if sys.platform != 'win32' else lambda x: x
329 281 for a in args:
330 282 expanded.extend(glob.glob(a) or [unescape(a)])
331 283 return expanded
332 284
333 285
334 286 def target_outdated(target,deps):
335 287 """Determine whether a target is out of date.
336 288
337 289 target_outdated(target,deps) -> 1/0
338 290
339 291 deps: list of filenames which MUST exist.
340 292 target: single filename which may or may not exist.
341 293
342 294 If target doesn't exist or is older than any file listed in deps, return
343 295 true, otherwise return false.
344 296 """
345 297 try:
346 298 target_time = os.path.getmtime(target)
347 299 except os.error:
348 300 return 1
349 301 for dep in deps:
350 302 dep_time = os.path.getmtime(dep)
351 303 if dep_time > target_time:
352 304 #print "For target",target,"Dep failed:",dep # dbg
353 305 #print "times (dep,tar):",dep_time,target_time # dbg
354 306 return 1
355 307 return 0
356 308
357 309
358 310 def target_update(target,deps,cmd):
359 311 """Update a target with a given command given a list of dependencies.
360 312
361 313 target_update(target,deps,cmd) -> runs cmd if target is outdated.
362 314
363 315 This is just a wrapper around target_outdated() which calls the given
364 316 command if target is outdated."""
365 317
366 318 if target_outdated(target,deps):
367 319 system(cmd)
368 320
369 321
370 322 ENOLINK = 1998
371 323
372 324 def link(src, dst):
373 325 """Hard links ``src`` to ``dst``, returning 0 or errno.
374 326
375 327 Note that the special errno ``ENOLINK`` will be returned if ``os.link`` isn't
376 328 supported by the operating system.
377 329 """
378 330
379 331 if not hasattr(os, "link"):
380 332 return ENOLINK
381 333 link_errno = 0
382 334 try:
383 335 os.link(src, dst)
384 336 except OSError as e:
385 337 link_errno = e.errno
386 338 return link_errno
387 339
388 340
389 341 def link_or_copy(src, dst):
390 342 """Attempts to hardlink ``src`` to ``dst``, copying if the link fails.
391 343
392 344 Attempts to maintain the semantics of ``shutil.copy``.
393 345
394 346 Because ``os.link`` does not overwrite files, a unique temporary file
395 347 will be used if the target already exists, then that file will be moved
396 348 into place.
397 349 """
398 350
399 351 if os.path.isdir(dst):
400 352 dst = os.path.join(dst, os.path.basename(src))
401 353
402 354 link_errno = link(src, dst)
403 355 if link_errno == errno.EEXIST:
404 356 if os.stat(src).st_ino == os.stat(dst).st_ino:
405 357 # dst is already a hard link to the correct file, so we don't need
406 358 # to do anything else. If we try to link and rename the file
407 359 # anyway, we get duplicate files - see http://bugs.python.org/issue21876
408 360 return
409 361
410 362 new_dst = dst + "-temp-%04X" %(random.randint(1, 16**4), )
411 363 try:
412 364 link_or_copy(src, new_dst)
413 365 except:
414 366 try:
415 367 os.remove(new_dst)
416 368 except OSError:
417 369 pass
418 370 raise
419 371 os.rename(new_dst, dst)
420 372 elif link_errno != 0:
421 373 # Either link isn't supported, or the filesystem doesn't support
422 374 # linking, or 'src' and 'dst' are on different filesystems.
423 375 shutil.copy(src, dst)
424 376
425 377 def ensure_dir_exists(path, mode=0o755):
426 378 """ensure that a directory exists
427 379
428 380 If it doesn't exist, try to create it and protect against a race condition
429 381 if another process is doing the same.
430 382
431 383 The default permissions are 755, which differ from os.makedirs default of 777.
432 384 """
433 385 if not os.path.exists(path):
434 386 try:
435 387 os.makedirs(path, mode=mode)
436 388 except OSError as e:
437 389 if e.errno != errno.EEXIST:
438 390 raise
439 391 elif not os.path.isdir(path):
440 392 raise IOError("%r exists but is not a directory" % path)
@@ -1,122 +1,123 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 19 #-----------------------------------------------------------------------------
20 20 # Code
21 21 #-----------------------------------------------------------------------------
22 22
23 23 # If possible (Unix), use the resource module instead of time.clock()
24 24 try:
25 25 import resource
26 26 except ImportError:
27 27 resource = None
28 28
29 29 # Some implementations (like jyputerlite) don't have getrusage
30 30 if resource is not None and hasattr(resource, "getrusage"):
31 31 def clocku():
32 32 """clocku() -> floating point number
33 33
34 34 Return the *USER* CPU time in seconds since the start of the process.
35 35 This is done via a call to resource.getrusage, so it avoids the
36 36 wraparound problems in time.clock()."""
37 37
38 38 return resource.getrusage(resource.RUSAGE_SELF)[0]
39 39
40 40 def clocks():
41 41 """clocks() -> floating point number
42 42
43 43 Return the *SYSTEM* CPU time in seconds since the start of the process.
44 44 This is done via a call to resource.getrusage, so it avoids the
45 45 wraparound problems in time.clock()."""
46 46
47 47 return resource.getrusage(resource.RUSAGE_SELF)[1]
48 48
49 49 def clock():
50 50 """clock() -> floating point number
51 51
52 52 Return the *TOTAL USER+SYSTEM* CPU time in seconds since the start of
53 53 the process. This is done via a call to resource.getrusage, so it
54 54 avoids the wraparound problems in time.clock()."""
55 55
56 56 u,s = resource.getrusage(resource.RUSAGE_SELF)[:2]
57 57 return u+s
58 58
59 59 def clock2():
60 60 """clock2() -> (t_user,t_system)
61 61
62 62 Similar to clock(), but return a tuple of user/system times."""
63 63 return resource.getrusage(resource.RUSAGE_SELF)[:2]
64 64
65
65 66 else:
66 67 # There is no distinction of user/system time under windows, so we just use
67 68 # time.perff_counter() for everything...
68 69 clocku = clocks = clock = time.perf_counter
69 70 def clock2():
70 71 """Under windows, system CPU time can't be measured.
71 72
72 73 This just returns perf_counter() and zero."""
73 74 return time.perf_counter(),0.0
74 75
75 76
76 77 def timings_out(reps,func,*args,**kw):
77 78 """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
78 79
79 80 Execute a function reps times, return a tuple with the elapsed total
80 81 CPU time in seconds, the time per call and the function's output.
81 82
82 83 Under Unix, the return value is the sum of user+system time consumed by
83 84 the process, computed via the resource module. This prevents problems
84 85 related to the wraparound effect which the time.clock() function has.
85 86
86 87 Under Windows the return value is in wall clock seconds. See the
87 88 documentation for the time module for more details."""
88 89
89 90 reps = int(reps)
90 91 assert reps >=1, 'reps must be >= 1'
91 92 if reps==1:
92 93 start = clock()
93 94 out = func(*args,**kw)
94 95 tot_time = clock()-start
95 96 else:
96 97 rng = range(reps-1) # the last time is executed separately to store output
97 98 start = clock()
98 99 for dummy in rng: func(*args,**kw)
99 100 out = func(*args,**kw) # one last time
100 101 tot_time = clock()-start
101 102 av_time = tot_time / reps
102 103 return tot_time,av_time,out
103 104
104 105
105 106 def timings(reps,func,*args,**kw):
106 107 """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
107 108
108 109 Execute a function reps times, return a tuple with the elapsed total CPU
109 110 time in seconds and the time per call. These are just the first two values
110 111 in timings_out()."""
111 112
112 113 return timings_out(reps,func,*args,**kw)[0:2]
113 114
114 115
115 116 def timing(func,*args,**kw):
116 117 """timing(func,*args,**kw) -> t_total
117 118
118 119 Execute a function once, return the elapsed total CPU time in
119 120 seconds. This is just the first value in timings_out()."""
120 121
121 122 return timings_out(1,func,*args,**kw)[0]
122 123
@@ -1,185 +1,184 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Setup script for IPython.
3 3
4 4 Under Posix environments it works like a typical setup.py script.
5 5 Under Windows, the command sdist is not supported, since IPython
6 6 requires utilities which are not available under Windows."""
7 7
8 8 #-----------------------------------------------------------------------------
9 9 # Copyright (c) 2008-2011, IPython Development Team.
10 10 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
11 11 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
12 12 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
13 13 #
14 14 # Distributed under the terms of the Modified BSD License.
15 15 #
16 16 # The full license is in the file COPYING.rst, distributed with this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 import os
20 20 import sys
21 21 from itertools import chain
22 22
23 23 # **Python version check**
24 24 #
25 25 # This check is also made in IPython/__init__, don't forget to update both when
26 26 # changing Python version requirements.
27 27 if sys.version_info < (3, 8):
28 28 pip_message = 'This may be due to an out of date pip. Make sure you have pip >= 9.0.1.'
29 29 try:
30 30 import pip
31 31 pip_version = tuple([int(x) for x in pip.__version__.split('.')[:3]])
32 32 if pip_version < (9, 0, 1) :
33 33 pip_message = 'Your pip version is out of date, please install pip >= 9.0.1. '\
34 34 'pip {} detected.'.format(pip.__version__)
35 35 else:
36 36 # pip is new enough - it must be something else
37 37 pip_message = ''
38 38 except Exception:
39 39 pass
40 40
41 41
42 42 error = """
43 43 IPython 8+ supports Python 3.8 and above, following NEP 29.
44 44 When using Python 2.7, please install IPython 5.x LTS Long Term Support version.
45 45 Python 3.3 and 3.4 were supported up to IPython 6.x.
46 46 Python 3.5 was supported with IPython 7.0 to 7.9.
47 47 Python 3.6 was supported with IPython up to 7.16.
48 48 Python 3.7 was still supported with the 7.x branch.
49 49
50 50 See IPython `README.rst` file for more information:
51 51
52 52 https://github.com/ipython/ipython/blob/master/README.rst
53 53
54 54 Python {py} detected.
55 55 {pip}
56 56 """.format(py=sys.version_info, pip=pip_message )
57 57
58 58 print(error, file=sys.stderr)
59 59 sys.exit(1)
60 60
61 61 # At least we're on the python version we need, move on.
62 62
63 63 from setuptools import setup
64 64
65 65 # Our own imports
66 66 from setupbase import target_update
67 67
68 68 from setupbase import (
69 69 setup_args,
70 70 check_package_data_first,
71 71 find_data_files,
72 72 git_prebuild,
73 73 install_symlinked,
74 74 install_lib_symlink,
75 75 install_scripts_for_symlink,
76 76 unsymlink,
77 77 )
78 78
79 79 #-------------------------------------------------------------------------------
80 80 # Handle OS specific things
81 81 #-------------------------------------------------------------------------------
82 82
83 83 if os.name in ('nt','dos'):
84 84 os_name = 'windows'
85 85 else:
86 86 os_name = os.name
87 87
88 88 # Under Windows, 'sdist' has not been supported. Now that the docs build with
89 89 # Sphinx it might work, but let's not turn it on until someone confirms that it
90 90 # actually works.
91 91 if os_name == 'windows' and 'sdist' in sys.argv:
92 92 print('The sdist command is not available under Windows. Exiting.')
93 93 sys.exit(1)
94 94
95 95
96 96 #-------------------------------------------------------------------------------
97 97 # Things related to the IPython documentation
98 98 #-------------------------------------------------------------------------------
99 99
100 100 # update the manuals when building a source dist
101 101 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
102 102
103 103 # List of things to be updated. Each entry is a triplet of args for
104 104 # target_update()
105 105 to_update = [
106 106 (
107 107 "docs/man/ipython.1.gz",
108 108 ["docs/man/ipython.1"],
109 109 "cd docs/man && python -m gzip --best ipython.1",
110 110 ),
111 111 ]
112 112
113 113
114 114 [ target_update(*t) for t in to_update ]
115 115
116 116 #---------------------------------------------------------------------------
117 117 # Find all the packages, package data, and data_files
118 118 #---------------------------------------------------------------------------
119 119
120 120 data_files = find_data_files()
121 121
122 122 setup_args['data_files'] = data_files
123 123
124 124 #---------------------------------------------------------------------------
125 125 # custom distutils commands
126 126 #---------------------------------------------------------------------------
127 127 # imports here, so they are after setuptools import if there was one
128 128 from setuptools.command.sdist import sdist
129 129
130 130 setup_args['cmdclass'] = {
131 131 'build_py': \
132 132 check_package_data_first(git_prebuild('IPython')),
133 133 'sdist' : git_prebuild('IPython', sdist),
134 134 'symlink': install_symlinked,
135 135 'install_lib_symlink': install_lib_symlink,
136 136 'install_scripts_sym': install_scripts_for_symlink,
137 137 'unsymlink': unsymlink,
138 138 }
139 139
140 140
141 141 #---------------------------------------------------------------------------
142 142 # Handle scripts, dependencies, and setuptools specific things
143 143 #---------------------------------------------------------------------------
144 144
145 145 # setuptools requirements
146 146
147 147 extras_require = dict(
148 148 parallel=["ipyparallel"],
149 149 qtconsole=["qtconsole"],
150 150 doc=["Sphinx>=1.3"],
151 151 test=[
152 152 "pytest",
153 153 "testpath",
154 154 "pygments",
155 155 ],
156 156 test_extra=[
157 157 "pytest",
158 158 "testpath",
159 159 "curio",
160 160 "matplotlib!=3.2.0",
161 161 "nbformat",
162 162 "numpy>=1.17",
163 163 "pandas",
164 164 "pygments",
165 165 "trio",
166 166 ],
167 167 terminal=[],
168 168 kernel=["ipykernel"],
169 169 nbformat=["nbformat"],
170 170 notebook=["notebook", "ipywidgets"],
171 171 nbconvert=["nbconvert"],
172 172 )
173 173
174
175 174 everything = set(chain.from_iterable(extras_require.values()))
176 175 extras_require['all'] = list(sorted(everything))
177 176
178 177 setup_args["extras_require"] = extras_require
179 178
180 179 #---------------------------------------------------------------------------
181 180 # Do the actual setup now
182 181 #---------------------------------------------------------------------------
183 182
184 183 if __name__ == "__main__":
185 184 setup(**setup_args)
General Comments 0
You need to be logged in to leave comments. Login now