##// END OF EJS Templates
Restore lineno's for Input mapped files (#13560)...
JD Smith -
Show More
@@ -0,0 +1,50 b''
1 Restore line numbers for Input
2 ==================================
3
4 Line number information in tracebacks from input are restored.
5 Line numbers from input were removed during the transition to v8 enhanced traceback reporting.
6
7 So, instead of::
8
9 ---------------------------------------------------------------------------
10 ZeroDivisionError Traceback (most recent call last)
11 Input In [3], in <cell line: 1>()
12 ----> 1 myfunc(2)
13
14 Input In [2], in myfunc(z)
15 1 def myfunc(z):
16 ----> 2 foo.boo(z-1)
17
18 File ~/code/python/ipython/foo.py:3, in boo(x)
19 2 def boo(x):
20 ----> 3 return 1/(1-x)
21
22 ZeroDivisionError: division by zero
23
24 The error traceback now looks like::
25
26 ---------------------------------------------------------------------------
27 ZeroDivisionError Traceback (most recent call last)
28 Cell In [3], line 1
29 ----> 1 myfunc(2)
30
31 Cell In [2], line 2, in myfunc(z)
32 1 def myfunc(z):
33 ----> 2 foo.boo(z-1)
34
35 File ~/code/python/ipython/foo.py:3, in boo(x)
36 2 def boo(x):
37 ----> 3 return 1/(1-x)
38
39 ZeroDivisionError: division by zero
40
41 or, with xmode=Plain::
42
43 Traceback (most recent call last):
44 Cell In [12], line 1
45 myfunc(2)
46 Cell In [6], line 2 in myfunc
47 foo.boo(z-1)
48 File ~/code/python/ipython/foo.py:3 in boo
49 return 1/(1-x)
50 ZeroDivisionError: division by zero
@@ -1,3800 +1,3775 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 bdb
18 18 import builtins as builtin_mod
19 import dis
20 19 import functools
21 20 import inspect
22 21 import os
23 22 import re
24 23 import runpy
25 24 import subprocess
26 25 import sys
27 26 import tempfile
28 27 import traceback
29 28 import types
30 29 import warnings
31 30 from ast import stmt
32 31 from io import open as io_open
33 32 from logging import error
34 33 from pathlib import Path
35 34 from typing import Callable
36 35 from typing import List as ListType
37 36 from typing import Optional, Tuple
38 37 from warnings import warn
39 38
40 39 from pickleshare import PickleShareDB
41 40 from tempfile import TemporaryDirectory
42 41 from traitlets import (
43 42 Any,
44 43 Bool,
45 44 CaselessStrEnum,
46 45 Dict,
47 46 Enum,
48 47 Instance,
49 48 Integer,
50 49 List,
51 50 Type,
52 51 Unicode,
53 52 default,
54 53 observe,
55 54 validate,
56 55 )
57 56 from traitlets.config.configurable import SingletonConfigurable
58 57 from traitlets.utils.importstring import import_item
59 58
60 59 import IPython.core.hooks
61 60 from IPython.core import magic, oinspect, page, prefilter, ultratb
62 61 from IPython.core.alias import Alias, AliasManager
63 62 from IPython.core.autocall import ExitAutocall
64 63 from IPython.core.builtin_trap import BuiltinTrap
65 64 from IPython.core.compilerop import CachingCompiler, check_linecache_ipython
66 65 from IPython.core.debugger import InterruptiblePdb
67 66 from IPython.core.display_trap import DisplayTrap
68 67 from IPython.core.displayhook import DisplayHook
69 68 from IPython.core.displaypub import DisplayPublisher
70 69 from IPython.core.error import InputRejected, UsageError
71 70 from IPython.core.events import EventManager, available_events
72 71 from IPython.core.extensions import ExtensionManager
73 72 from IPython.core.formatters import DisplayFormatter
74 73 from IPython.core.history import HistoryManager
75 74 from IPython.core.inputtransformer2 import ESC_MAGIC, ESC_MAGIC2
76 75 from IPython.core.logger import Logger
77 76 from IPython.core.macro import Macro
78 77 from IPython.core.payload import PayloadManager
79 78 from IPython.core.prefilter import PrefilterManager
80 79 from IPython.core.profiledir import ProfileDir
81 80 from IPython.core.usage import default_banner
82 81 from IPython.display import display
83 82 from IPython.paths import get_ipython_dir
84 83 from IPython.testing.skipdoctest import skip_doctest
85 84 from IPython.utils import PyColorize, io, openpy, py3compat
86 85 from IPython.utils.decorators import undoc
87 86 from IPython.utils.io import ask_yes_no
88 87 from IPython.utils.ipstruct import Struct
89 88 from IPython.utils.path import ensure_dir_exists, get_home_dir, get_py_filename
90 89 from IPython.utils.process import getoutput, system
91 90 from IPython.utils.strdispatch import StrDispatch
92 91 from IPython.utils.syspathcontext import prepended_to_syspath
93 92 from IPython.utils.text import DollarFormatter, LSString, SList, format_screen
94 93
95 94 sphinxify: Optional[Callable]
96 95
97 96 try:
98 97 import docrepr.sphinxify as sphx
99 98
100 99 def sphinxify(oinfo):
101 100 wrapped_docstring = sphx.wrap_main_docstring(oinfo)
102 101
103 102 def sphinxify_docstring(docstring):
104 103 with TemporaryDirectory() as dirname:
105 104 return {
106 105 "text/html": sphx.sphinxify(wrapped_docstring, dirname),
107 106 "text/plain": docstring,
108 107 }
109 108
110 109 return sphinxify_docstring
111 110 except ImportError:
112 111 sphinxify = None
113 112
114 113
115 114 class ProvisionalWarning(DeprecationWarning):
116 115 """
117 116 Warning class for unstable features
118 117 """
119 118 pass
120 119
121 120 from ast import Module
122 121
123 122 _assign_nodes = (ast.AugAssign, ast.AnnAssign, ast.Assign)
124 123 _single_targets_nodes = (ast.AugAssign, ast.AnnAssign)
125 124
126 125 #-----------------------------------------------------------------------------
127 126 # Await Helpers
128 127 #-----------------------------------------------------------------------------
129 128
130 129 # we still need to run things using the asyncio eventloop, but there is no
131 130 # async integration
132 131 from .async_helpers import (
133 132 _asyncio_runner,
134 133 _curio_runner,
135 134 _pseudo_sync_runner,
136 135 _should_be_async,
137 136 _trio_runner,
138 137 )
139 138
140 139 #-----------------------------------------------------------------------------
141 140 # Globals
142 141 #-----------------------------------------------------------------------------
143 142
144 143 # compiled regexps for autoindent management
145 144 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
146 145
147 146 #-----------------------------------------------------------------------------
148 147 # Utilities
149 148 #-----------------------------------------------------------------------------
150 149
151 150 @undoc
152 151 def softspace(file, newvalue):
153 152 """Copied from code.py, to remove the dependency"""
154 153
155 154 oldvalue = 0
156 155 try:
157 156 oldvalue = file.softspace
158 157 except AttributeError:
159 158 pass
160 159 try:
161 160 file.softspace = newvalue
162 161 except (AttributeError, TypeError):
163 162 # "attribute-less object" or "read-only attributes"
164 163 pass
165 164 return oldvalue
166 165
167 166 @undoc
168 167 def no_op(*a, **kw):
169 168 pass
170 169
171 170
172 171 class SpaceInInput(Exception): pass
173 172
174 173
175 174 class SeparateUnicode(Unicode):
176 175 r"""A Unicode subclass to validate separate_in, separate_out, etc.
177 176
178 177 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
179 178 """
180 179
181 180 def validate(self, obj, value):
182 181 if value == '0': value = ''
183 182 value = value.replace('\\n','\n')
184 183 return super(SeparateUnicode, self).validate(obj, value)
185 184
186 185
187 186 @undoc
188 187 class DummyMod(object):
189 188 """A dummy module used for IPython's interactive module when
190 189 a namespace must be assigned to the module's __dict__."""
191 190 __spec__ = None
192 191
193 192
194 193 class ExecutionInfo(object):
195 194 """The arguments used for a call to :meth:`InteractiveShell.run_cell`
196 195
197 196 Stores information about what is going to happen.
198 197 """
199 198 raw_cell = None
200 199 store_history = False
201 200 silent = False
202 201 shell_futures = True
203 202 cell_id = None
204 203
205 204 def __init__(self, raw_cell, store_history, silent, shell_futures, cell_id):
206 205 self.raw_cell = raw_cell
207 206 self.store_history = store_history
208 207 self.silent = silent
209 208 self.shell_futures = shell_futures
210 209 self.cell_id = cell_id
211 210
212 211 def __repr__(self):
213 212 name = self.__class__.__qualname__
214 213 raw_cell = (
215 214 (self.raw_cell[:50] + "..") if len(self.raw_cell) > 50 else self.raw_cell
216 215 )
217 216 return '<%s object at %x, raw_cell="%s" store_history=%s silent=%s shell_futures=%s cell_id=%s>' % (
218 217 name,
219 218 id(self),
220 219 raw_cell,
221 220 self.store_history,
222 221 self.silent,
223 222 self.shell_futures,
224 223 self.cell_id,
225 224 )
226 225
227 226
228 227 class ExecutionResult(object):
229 228 """The result of a call to :meth:`InteractiveShell.run_cell`
230 229
231 230 Stores information about what took place.
232 231 """
233 232 execution_count = None
234 233 error_before_exec = None
235 234 error_in_exec: Optional[BaseException] = None
236 235 info = None
237 236 result = None
238 237
239 238 def __init__(self, info):
240 239 self.info = info
241 240
242 241 @property
243 242 def success(self):
244 243 return (self.error_before_exec is None) and (self.error_in_exec is None)
245 244
246 245 def raise_error(self):
247 246 """Reraises error if `success` is `False`, otherwise does nothing"""
248 247 if self.error_before_exec is not None:
249 248 raise self.error_before_exec
250 249 if self.error_in_exec is not None:
251 250 raise self.error_in_exec
252 251
253 252 def __repr__(self):
254 253 name = self.__class__.__qualname__
255 254 return '<%s object at %x, execution_count=%s error_before_exec=%s error_in_exec=%s info=%s result=%s>' %\
256 255 (name, id(self), self.execution_count, self.error_before_exec, self.error_in_exec, repr(self.info), repr(self.result))
257 256
258 257
259 258 class InteractiveShell(SingletonConfigurable):
260 259 """An enhanced, interactive shell for Python."""
261 260
262 261 _instance = None
263 262
264 263 ast_transformers = List([], help=
265 264 """
266 265 A list of ast.NodeTransformer subclass instances, which will be applied
267 266 to user input before code is run.
268 267 """
269 268 ).tag(config=True)
270 269
271 270 autocall = Enum((0,1,2), default_value=0, help=
272 271 """
273 272 Make IPython automatically call any callable object even if you didn't
274 273 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
275 274 automatically. The value can be '0' to disable the feature, '1' for
276 275 'smart' autocall, where it is not applied if there are no more
277 276 arguments on the line, and '2' for 'full' autocall, where all callable
278 277 objects are automatically called (even if no arguments are present).
279 278 """
280 279 ).tag(config=True)
281 280
282 281 autoindent = Bool(True, help=
283 282 """
284 283 Autoindent IPython code entered interactively.
285 284 """
286 285 ).tag(config=True)
287 286
288 287 autoawait = Bool(True, help=
289 288 """
290 289 Automatically run await statement in the top level repl.
291 290 """
292 291 ).tag(config=True)
293 292
294 293 loop_runner_map ={
295 294 'asyncio':(_asyncio_runner, True),
296 295 'curio':(_curio_runner, True),
297 296 'trio':(_trio_runner, True),
298 297 'sync': (_pseudo_sync_runner, False)
299 298 }
300 299
301 300 loop_runner = Any(default_value="IPython.core.interactiveshell._asyncio_runner",
302 301 allow_none=True,
303 302 help="""Select the loop runner that will be used to execute top-level asynchronous code"""
304 303 ).tag(config=True)
305 304
306 305 @default('loop_runner')
307 306 def _default_loop_runner(self):
308 307 return import_item("IPython.core.interactiveshell._asyncio_runner")
309 308
310 309 @validate('loop_runner')
311 310 def _import_runner(self, proposal):
312 311 if isinstance(proposal.value, str):
313 312 if proposal.value in self.loop_runner_map:
314 313 runner, autoawait = self.loop_runner_map[proposal.value]
315 314 self.autoawait = autoawait
316 315 return runner
317 316 runner = import_item(proposal.value)
318 317 if not callable(runner):
319 318 raise ValueError('loop_runner must be callable')
320 319 return runner
321 320 if not callable(proposal.value):
322 321 raise ValueError('loop_runner must be callable')
323 322 return proposal.value
324 323
325 324 automagic = Bool(True, help=
326 325 """
327 326 Enable magic commands to be called without the leading %.
328 327 """
329 328 ).tag(config=True)
330 329
331 330 banner1 = Unicode(default_banner,
332 331 help="""The part of the banner to be printed before the profile"""
333 332 ).tag(config=True)
334 333 banner2 = Unicode('',
335 334 help="""The part of the banner to be printed after the profile"""
336 335 ).tag(config=True)
337 336
338 337 cache_size = Integer(1000, help=
339 338 """
340 339 Set the size of the output cache. The default is 1000, you can
341 340 change it permanently in your config file. Setting it to 0 completely
342 341 disables the caching system, and the minimum value accepted is 3 (if
343 342 you provide a value less than 3, it is reset to 0 and a warning is
344 343 issued). This limit is defined because otherwise you'll spend more
345 344 time re-flushing a too small cache than working
346 345 """
347 346 ).tag(config=True)
348 347 color_info = Bool(True, help=
349 348 """
350 349 Use colors for displaying information about objects. Because this
351 350 information is passed through a pager (like 'less'), and some pagers
352 351 get confused with color codes, this capability can be turned off.
353 352 """
354 353 ).tag(config=True)
355 354 colors = CaselessStrEnum(('Neutral', 'NoColor','LightBG','Linux'),
356 355 default_value='Neutral',
357 356 help="Set the color scheme (NoColor, Neutral, Linux, or LightBG)."
358 357 ).tag(config=True)
359 358 debug = Bool(False).tag(config=True)
360 359 disable_failing_post_execute = Bool(False,
361 360 help="Don't call post-execute functions that have failed in the past."
362 361 ).tag(config=True)
363 362 display_formatter = Instance(DisplayFormatter, allow_none=True)
364 363 displayhook_class = Type(DisplayHook)
365 364 display_pub_class = Type(DisplayPublisher)
366 365 compiler_class = Type(CachingCompiler)
367 366
368 367 sphinxify_docstring = Bool(False, help=
369 368 """
370 369 Enables rich html representation of docstrings. (This requires the
371 370 docrepr module).
372 371 """).tag(config=True)
373 372
374 373 @observe("sphinxify_docstring")
375 374 def _sphinxify_docstring_changed(self, change):
376 375 if change['new']:
377 376 warn("`sphinxify_docstring` is provisional since IPython 5.0 and might change in future versions." , ProvisionalWarning)
378 377
379 378 enable_html_pager = Bool(False, help=
380 379 """
381 380 (Provisional API) enables html representation in mime bundles sent
382 381 to pagers.
383 382 """).tag(config=True)
384 383
385 384 @observe("enable_html_pager")
386 385 def _enable_html_pager_changed(self, change):
387 386 if change['new']:
388 387 warn("`enable_html_pager` is provisional since IPython 5.0 and might change in future versions.", ProvisionalWarning)
389 388
390 389 data_pub_class = None
391 390
392 391 exit_now = Bool(False)
393 392 exiter = Instance(ExitAutocall)
394 393 @default('exiter')
395 394 def _exiter_default(self):
396 395 return ExitAutocall(self)
397 396 # Monotonically increasing execution counter
398 397 execution_count = Integer(1)
399 398 filename = Unicode("<ipython console>")
400 399 ipython_dir= Unicode('').tag(config=True) # Set to get_ipython_dir() in __init__
401 400
402 401 # Used to transform cells before running them, and check whether code is complete
403 402 input_transformer_manager = Instance('IPython.core.inputtransformer2.TransformerManager',
404 403 ())
405 404
406 405 @property
407 406 def input_transformers_cleanup(self):
408 407 return self.input_transformer_manager.cleanup_transforms
409 408
410 409 input_transformers_post = List([],
411 410 help="A list of string input transformers, to be applied after IPython's "
412 411 "own input transformations."
413 412 )
414 413
415 414 @property
416 415 def input_splitter(self):
417 416 """Make this available for backward compatibility (pre-7.0 release) with existing code.
418 417
419 418 For example, ipykernel ipykernel currently uses
420 419 `shell.input_splitter.check_complete`
421 420 """
422 421 from warnings import warn
423 422 warn("`input_splitter` is deprecated since IPython 7.0, prefer `input_transformer_manager`.",
424 423 DeprecationWarning, stacklevel=2
425 424 )
426 425 return self.input_transformer_manager
427 426
428 427 logstart = Bool(False, help=
429 428 """
430 429 Start logging to the default log file in overwrite mode.
431 430 Use `logappend` to specify a log file to **append** logs to.
432 431 """
433 432 ).tag(config=True)
434 433 logfile = Unicode('', help=
435 434 """
436 435 The name of the logfile to use.
437 436 """
438 437 ).tag(config=True)
439 438 logappend = Unicode('', help=
440 439 """
441 440 Start logging to the given file in append mode.
442 441 Use `logfile` to specify a log file to **overwrite** logs to.
443 442 """
444 443 ).tag(config=True)
445 444 object_info_string_level = Enum((0,1,2), default_value=0,
446 445 ).tag(config=True)
447 446 pdb = Bool(False, help=
448 447 """
449 448 Automatically call the pdb debugger after every exception.
450 449 """
451 450 ).tag(config=True)
452 451 display_page = Bool(False,
453 452 help="""If True, anything that would be passed to the pager
454 453 will be displayed as regular output instead."""
455 454 ).tag(config=True)
456 455
457 456
458 457 show_rewritten_input = Bool(True,
459 458 help="Show rewritten input, e.g. for autocall."
460 459 ).tag(config=True)
461 460
462 461 quiet = Bool(False).tag(config=True)
463 462
464 463 history_length = Integer(10000,
465 464 help='Total length of command history'
466 465 ).tag(config=True)
467 466
468 467 history_load_length = Integer(1000, help=
469 468 """
470 469 The number of saved history entries to be loaded
471 470 into the history buffer at startup.
472 471 """
473 472 ).tag(config=True)
474 473
475 474 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none', 'last_expr_or_assign'],
476 475 default_value='last_expr',
477 476 help="""
478 477 'all', 'last', 'last_expr' or 'none', 'last_expr_or_assign' specifying
479 478 which nodes should be run interactively (displaying output from expressions).
480 479 """
481 480 ).tag(config=True)
482 481
483 482 # TODO: this part of prompt management should be moved to the frontends.
484 483 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
485 484 separate_in = SeparateUnicode('\n').tag(config=True)
486 485 separate_out = SeparateUnicode('').tag(config=True)
487 486 separate_out2 = SeparateUnicode('').tag(config=True)
488 487 wildcards_case_sensitive = Bool(True).tag(config=True)
489 488 xmode = CaselessStrEnum(('Context', 'Plain', 'Verbose', 'Minimal'),
490 489 default_value='Context',
491 490 help="Switch modes for the IPython exception handlers."
492 491 ).tag(config=True)
493 492
494 493 # Subcomponents of InteractiveShell
495 494 alias_manager = Instance('IPython.core.alias.AliasManager', allow_none=True)
496 495 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
497 496 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap', allow_none=True)
498 497 display_trap = Instance('IPython.core.display_trap.DisplayTrap', allow_none=True)
499 498 extension_manager = Instance('IPython.core.extensions.ExtensionManager', allow_none=True)
500 499 payload_manager = Instance('IPython.core.payload.PayloadManager', allow_none=True)
501 500 history_manager = Instance('IPython.core.history.HistoryAccessorBase', allow_none=True)
502 501 magics_manager = Instance('IPython.core.magic.MagicsManager', allow_none=True)
503 502
504 503 profile_dir = Instance('IPython.core.application.ProfileDir', allow_none=True)
505 504 @property
506 505 def profile(self):
507 506 if self.profile_dir is not None:
508 507 name = os.path.basename(self.profile_dir.location)
509 508 return name.replace('profile_','')
510 509
511 510
512 511 # Private interface
513 512 _post_execute = Dict()
514 513
515 514 # Tracks any GUI loop loaded for pylab
516 515 pylab_gui_select = None
517 516
518 517 last_execution_succeeded = Bool(True, help='Did last executed command succeeded')
519 518
520 519 last_execution_result = Instance('IPython.core.interactiveshell.ExecutionResult', help='Result of executing the last command', allow_none=True)
521 520
522 521 def __init__(self, ipython_dir=None, profile_dir=None,
523 522 user_module=None, user_ns=None,
524 523 custom_exceptions=((), None), **kwargs):
525 524 # This is where traits with a config_key argument are updated
526 525 # from the values on config.
527 526 super(InteractiveShell, self).__init__(**kwargs)
528 527 if 'PromptManager' in self.config:
529 528 warn('As of IPython 5.0 `PromptManager` config will have no effect'
530 529 ' and has been replaced by TerminalInteractiveShell.prompts_class')
531 530 self.configurables = [self]
532 531
533 532 # These are relatively independent and stateless
534 533 self.init_ipython_dir(ipython_dir)
535 534 self.init_profile_dir(profile_dir)
536 535 self.init_instance_attrs()
537 536 self.init_environment()
538 537
539 538 # Check if we're in a virtualenv, and set up sys.path.
540 539 self.init_virtualenv()
541 540
542 541 # Create namespaces (user_ns, user_global_ns, etc.)
543 542 self.init_create_namespaces(user_module, user_ns)
544 543 # This has to be done after init_create_namespaces because it uses
545 544 # something in self.user_ns, but before init_sys_modules, which
546 545 # is the first thing to modify sys.
547 546 # TODO: When we override sys.stdout and sys.stderr before this class
548 547 # is created, we are saving the overridden ones here. Not sure if this
549 548 # is what we want to do.
550 549 self.save_sys_module_state()
551 550 self.init_sys_modules()
552 551
553 552 # While we're trying to have each part of the code directly access what
554 553 # it needs without keeping redundant references to objects, we have too
555 554 # much legacy code that expects ip.db to exist.
556 555 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
557 556
558 557 self.init_history()
559 558 self.init_encoding()
560 559 self.init_prefilter()
561 560
562 561 self.init_syntax_highlighting()
563 562 self.init_hooks()
564 563 self.init_events()
565 564 self.init_pushd_popd_magic()
566 565 self.init_user_ns()
567 566 self.init_logger()
568 567 self.init_builtins()
569 568
570 569 # The following was in post_config_initialization
571 570 self.init_inspector()
572 571 self.raw_input_original = input
573 572 self.init_completer()
574 573 # TODO: init_io() needs to happen before init_traceback handlers
575 574 # because the traceback handlers hardcode the stdout/stderr streams.
576 575 # This logic in in debugger.Pdb and should eventually be changed.
577 576 self.init_io()
578 577 self.init_traceback_handlers(custom_exceptions)
579 578 self.init_prompts()
580 579 self.init_display_formatter()
581 580 self.init_display_pub()
582 581 self.init_data_pub()
583 582 self.init_displayhook()
584 583 self.init_magics()
585 584 self.init_alias()
586 585 self.init_logstart()
587 586 self.init_pdb()
588 587 self.init_extension_manager()
589 588 self.init_payload()
590 589 self.events.trigger('shell_initialized', self)
591 590 atexit.register(self.atexit_operations)
592 591
593 592 # The trio runner is used for running Trio in the foreground thread. It
594 593 # is different from `_trio_runner(async_fn)` in `async_helpers.py`
595 594 # which calls `trio.run()` for every cell. This runner runs all cells
596 595 # inside a single Trio event loop. If used, it is set from
597 596 # `ipykernel.kernelapp`.
598 597 self.trio_runner = None
599 598
600 599 def get_ipython(self):
601 600 """Return the currently running IPython instance."""
602 601 return self
603 602
604 603 #-------------------------------------------------------------------------
605 604 # Trait changed handlers
606 605 #-------------------------------------------------------------------------
607 606 @observe('ipython_dir')
608 607 def _ipython_dir_changed(self, change):
609 608 ensure_dir_exists(change['new'])
610 609
611 610 def set_autoindent(self,value=None):
612 611 """Set the autoindent flag.
613 612
614 613 If called with no arguments, it acts as a toggle."""
615 614 if value is None:
616 615 self.autoindent = not self.autoindent
617 616 else:
618 617 self.autoindent = value
619 618
620 619 def set_trio_runner(self, tr):
621 620 self.trio_runner = tr
622 621
623 622 #-------------------------------------------------------------------------
624 623 # init_* methods called by __init__
625 624 #-------------------------------------------------------------------------
626 625
627 626 def init_ipython_dir(self, ipython_dir):
628 627 if ipython_dir is not None:
629 628 self.ipython_dir = ipython_dir
630 629 return
631 630
632 631 self.ipython_dir = get_ipython_dir()
633 632
634 633 def init_profile_dir(self, profile_dir):
635 634 if profile_dir is not None:
636 635 self.profile_dir = profile_dir
637 636 return
638 637 self.profile_dir = ProfileDir.create_profile_dir_by_name(
639 638 self.ipython_dir, "default"
640 639 )
641 640
642 641 def init_instance_attrs(self):
643 642 self.more = False
644 643
645 644 # command compiler
646 645 self.compile = self.compiler_class()
647 646
648 647 # Make an empty namespace, which extension writers can rely on both
649 648 # existing and NEVER being used by ipython itself. This gives them a
650 649 # convenient location for storing additional information and state
651 650 # their extensions may require, without fear of collisions with other
652 651 # ipython names that may develop later.
653 652 self.meta = Struct()
654 653
655 654 # Temporary files used for various purposes. Deleted at exit.
656 655 # The files here are stored with Path from Pathlib
657 656 self.tempfiles = []
658 657 self.tempdirs = []
659 658
660 659 # keep track of where we started running (mainly for crash post-mortem)
661 660 # This is not being used anywhere currently.
662 661 self.starting_dir = os.getcwd()
663 662
664 663 # Indentation management
665 664 self.indent_current_nsp = 0
666 665
667 666 # Dict to track post-execution functions that have been registered
668 667 self._post_execute = {}
669 668
670 669 def init_environment(self):
671 670 """Any changes we need to make to the user's environment."""
672 671 pass
673 672
674 673 def init_encoding(self):
675 674 # Get system encoding at startup time. Certain terminals (like Emacs
676 675 # under Win32 have it set to None, and we need to have a known valid
677 676 # encoding to use in the raw_input() method
678 677 try:
679 678 self.stdin_encoding = sys.stdin.encoding or 'ascii'
680 679 except AttributeError:
681 680 self.stdin_encoding = 'ascii'
682 681
683 682
684 683 @observe('colors')
685 684 def init_syntax_highlighting(self, changes=None):
686 685 # Python source parser/formatter for syntax highlighting
687 686 pyformat = PyColorize.Parser(style=self.colors, parent=self).format
688 687 self.pycolorize = lambda src: pyformat(src,'str')
689 688
690 689 def refresh_style(self):
691 690 # No-op here, used in subclass
692 691 pass
693 692
694 693 def init_pushd_popd_magic(self):
695 694 # for pushd/popd management
696 695 self.home_dir = get_home_dir()
697 696
698 697 self.dir_stack = []
699 698
700 699 def init_logger(self):
701 700 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
702 701 logmode='rotate')
703 702
704 703 def init_logstart(self):
705 704 """Initialize logging in case it was requested at the command line.
706 705 """
707 706 if self.logappend:
708 707 self.magic('logstart %s append' % self.logappend)
709 708 elif self.logfile:
710 709 self.magic('logstart %s' % self.logfile)
711 710 elif self.logstart:
712 711 self.magic('logstart')
713 712
714 713
715 714 def init_builtins(self):
716 715 # A single, static flag that we set to True. Its presence indicates
717 716 # that an IPython shell has been created, and we make no attempts at
718 717 # removing on exit or representing the existence of more than one
719 718 # IPython at a time.
720 719 builtin_mod.__dict__['__IPYTHON__'] = True
721 720 builtin_mod.__dict__['display'] = display
722 721
723 722 self.builtin_trap = BuiltinTrap(shell=self)
724 723
725 724 @observe('colors')
726 725 def init_inspector(self, changes=None):
727 726 # Object inspector
728 727 self.inspector = oinspect.Inspector(oinspect.InspectColors,
729 728 PyColorize.ANSICodeColors,
730 729 self.colors,
731 730 self.object_info_string_level)
732 731
733 732 def init_io(self):
734 733 # implemented in subclasses, TerminalInteractiveShell does call
735 734 # colorama.init().
736 735 pass
737 736
738 737 def init_prompts(self):
739 738 # Set system prompts, so that scripts can decide if they are running
740 739 # interactively.
741 740 sys.ps1 = 'In : '
742 741 sys.ps2 = '...: '
743 742 sys.ps3 = 'Out: '
744 743
745 744 def init_display_formatter(self):
746 745 self.display_formatter = DisplayFormatter(parent=self)
747 746 self.configurables.append(self.display_formatter)
748 747
749 748 def init_display_pub(self):
750 749 self.display_pub = self.display_pub_class(parent=self, shell=self)
751 750 self.configurables.append(self.display_pub)
752 751
753 752 def init_data_pub(self):
754 753 if not self.data_pub_class:
755 754 self.data_pub = None
756 755 return
757 756 self.data_pub = self.data_pub_class(parent=self)
758 757 self.configurables.append(self.data_pub)
759 758
760 759 def init_displayhook(self):
761 760 # Initialize displayhook, set in/out prompts and printing system
762 761 self.displayhook = self.displayhook_class(
763 762 parent=self,
764 763 shell=self,
765 764 cache_size=self.cache_size,
766 765 )
767 766 self.configurables.append(self.displayhook)
768 767 # This is a context manager that installs/revmoes the displayhook at
769 768 # the appropriate time.
770 769 self.display_trap = DisplayTrap(hook=self.displayhook)
771 770
772 771 @staticmethod
773 772 def get_path_links(p: Path):
774 773 """Gets path links including all symlinks
775 774
776 775 Examples
777 776 --------
778 777 In [1]: from IPython.core.interactiveshell import InteractiveShell
779 778
780 779 In [2]: import sys, pathlib
781 780
782 781 In [3]: paths = InteractiveShell.get_path_links(pathlib.Path(sys.executable))
783 782
784 783 In [4]: len(paths) == len(set(paths))
785 784 Out[4]: True
786 785
787 786 In [5]: bool(paths)
788 787 Out[5]: True
789 788 """
790 789 paths = [p]
791 790 while p.is_symlink():
792 791 new_path = Path(os.readlink(p))
793 792 if not new_path.is_absolute():
794 793 new_path = p.parent / new_path
795 794 p = new_path
796 795 paths.append(p)
797 796 return paths
798 797
799 798 def init_virtualenv(self):
800 799 """Add the current virtualenv to sys.path so the user can import modules from it.
801 800 This isn't perfect: it doesn't use the Python interpreter with which the
802 801 virtualenv was built, and it ignores the --no-site-packages option. A
803 802 warning will appear suggesting the user installs IPython in the
804 803 virtualenv, but for many cases, it probably works well enough.
805 804
806 805 Adapted from code snippets online.
807 806
808 807 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
809 808 """
810 809 if 'VIRTUAL_ENV' not in os.environ:
811 810 # Not in a virtualenv
812 811 return
813 812 elif os.environ["VIRTUAL_ENV"] == "":
814 813 warn("Virtual env path set to '', please check if this is intended.")
815 814 return
816 815
817 816 p = Path(sys.executable)
818 817 p_venv = Path(os.environ["VIRTUAL_ENV"])
819 818
820 819 # fallback venv detection:
821 820 # stdlib venv may symlink sys.executable, so we can't use realpath.
822 821 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
823 822 # So we just check every item in the symlink tree (generally <= 3)
824 823 paths = self.get_path_links(p)
825 824
826 825 # In Cygwin paths like "c:\..." and '\cygdrive\c\...' are possible
827 826 if p_venv.parts[1] == "cygdrive":
828 827 drive_name = p_venv.parts[2]
829 828 p_venv = (drive_name + ":/") / Path(*p_venv.parts[3:])
830 829
831 830 if any(p_venv == p.parents[1] for p in paths):
832 831 # Our exe is inside or has access to the virtualenv, don't need to do anything.
833 832 return
834 833
835 834 if sys.platform == "win32":
836 835 virtual_env = str(Path(os.environ["VIRTUAL_ENV"], "Lib", "site-packages"))
837 836 else:
838 837 virtual_env_path = Path(
839 838 os.environ["VIRTUAL_ENV"], "lib", "python{}.{}", "site-packages"
840 839 )
841 840 p_ver = sys.version_info[:2]
842 841
843 842 # Predict version from py[thon]-x.x in the $VIRTUAL_ENV
844 843 re_m = re.search(r"\bpy(?:thon)?([23])\.(\d+)\b", os.environ["VIRTUAL_ENV"])
845 844 if re_m:
846 845 predicted_path = Path(str(virtual_env_path).format(*re_m.groups()))
847 846 if predicted_path.exists():
848 847 p_ver = re_m.groups()
849 848
850 849 virtual_env = str(virtual_env_path).format(*p_ver)
851 850
852 851 warn(
853 852 "Attempting to work in a virtualenv. If you encounter problems, "
854 853 "please install IPython inside the virtualenv."
855 854 )
856 855 import site
857 856 sys.path.insert(0, virtual_env)
858 857 site.addsitedir(virtual_env)
859 858
860 859 #-------------------------------------------------------------------------
861 860 # Things related to injections into the sys module
862 861 #-------------------------------------------------------------------------
863 862
864 863 def save_sys_module_state(self):
865 864 """Save the state of hooks in the sys module.
866 865
867 866 This has to be called after self.user_module is created.
868 867 """
869 868 self._orig_sys_module_state = {'stdin': sys.stdin,
870 869 'stdout': sys.stdout,
871 870 'stderr': sys.stderr,
872 871 'excepthook': sys.excepthook}
873 872 self._orig_sys_modules_main_name = self.user_module.__name__
874 873 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
875 874
876 875 def restore_sys_module_state(self):
877 876 """Restore the state of the sys module."""
878 877 try:
879 878 for k, v in self._orig_sys_module_state.items():
880 879 setattr(sys, k, v)
881 880 except AttributeError:
882 881 pass
883 882 # Reset what what done in self.init_sys_modules
884 883 if self._orig_sys_modules_main_mod is not None:
885 884 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
886 885
887 886 #-------------------------------------------------------------------------
888 887 # Things related to the banner
889 888 #-------------------------------------------------------------------------
890 889
891 890 @property
892 891 def banner(self):
893 892 banner = self.banner1
894 893 if self.profile and self.profile != 'default':
895 894 banner += '\nIPython profile: %s\n' % self.profile
896 895 if self.banner2:
897 896 banner += '\n' + self.banner2
898 897 return banner
899 898
900 899 def show_banner(self, banner=None):
901 900 if banner is None:
902 901 banner = self.banner
903 902 sys.stdout.write(banner)
904 903
905 904 #-------------------------------------------------------------------------
906 905 # Things related to hooks
907 906 #-------------------------------------------------------------------------
908 907
909 908 def init_hooks(self):
910 909 # hooks holds pointers used for user-side customizations
911 910 self.hooks = Struct()
912 911
913 912 self.strdispatchers = {}
914 913
915 914 # Set all default hooks, defined in the IPython.hooks module.
916 915 hooks = IPython.core.hooks
917 916 for hook_name in hooks.__all__:
918 917 # default hooks have priority 100, i.e. low; user hooks should have
919 918 # 0-100 priority
920 919 self.set_hook(hook_name, getattr(hooks, hook_name), 100)
921 920
922 921 if self.display_page:
923 922 self.set_hook('show_in_pager', page.as_hook(page.display_page), 90)
924 923
925 924 def set_hook(self, name, hook, priority=50, str_key=None, re_key=None):
926 925 """set_hook(name,hook) -> sets an internal IPython hook.
927 926
928 927 IPython exposes some of its internal API as user-modifiable hooks. By
929 928 adding your function to one of these hooks, you can modify IPython's
930 929 behavior to call at runtime your own routines."""
931 930
932 931 # At some point in the future, this should validate the hook before it
933 932 # accepts it. Probably at least check that the hook takes the number
934 933 # of args it's supposed to.
935 934
936 935 f = types.MethodType(hook,self)
937 936
938 937 # check if the hook is for strdispatcher first
939 938 if str_key is not None:
940 939 sdp = self.strdispatchers.get(name, StrDispatch())
941 940 sdp.add_s(str_key, f, priority )
942 941 self.strdispatchers[name] = sdp
943 942 return
944 943 if re_key is not None:
945 944 sdp = self.strdispatchers.get(name, StrDispatch())
946 945 sdp.add_re(re.compile(re_key), f, priority )
947 946 self.strdispatchers[name] = sdp
948 947 return
949 948
950 949 dp = getattr(self.hooks, name, None)
951 950 if name not in IPython.core.hooks.__all__:
952 951 print("Warning! Hook '%s' is not one of %s" % \
953 952 (name, IPython.core.hooks.__all__ ))
954 953
955 954 if name in IPython.core.hooks.deprecated:
956 955 alternative = IPython.core.hooks.deprecated[name]
957 956 raise ValueError(
958 957 "Hook {} has been deprecated since IPython 5.0. Use {} instead.".format(
959 958 name, alternative
960 959 )
961 960 )
962 961
963 962 if not dp:
964 963 dp = IPython.core.hooks.CommandChainDispatcher()
965 964
966 965 try:
967 966 dp.add(f,priority)
968 967 except AttributeError:
969 968 # it was not commandchain, plain old func - replace
970 969 dp = f
971 970
972 971 setattr(self.hooks,name, dp)
973 972
974 973 #-------------------------------------------------------------------------
975 974 # Things related to events
976 975 #-------------------------------------------------------------------------
977 976
978 977 def init_events(self):
979 978 self.events = EventManager(self, available_events)
980 979
981 980 self.events.register("pre_execute", self._clear_warning_registry)
982 981
983 982 def register_post_execute(self, func):
984 983 """DEPRECATED: Use ip.events.register('post_run_cell', func)
985 984
986 985 Register a function for calling after code execution.
987 986 """
988 987 raise ValueError(
989 988 "ip.register_post_execute is deprecated since IPython 1.0, use "
990 989 "ip.events.register('post_run_cell', func) instead."
991 990 )
992 991
993 992 def _clear_warning_registry(self):
994 993 # clear the warning registry, so that different code blocks with
995 994 # overlapping line number ranges don't cause spurious suppression of
996 995 # warnings (see gh-6611 for details)
997 996 if "__warningregistry__" in self.user_global_ns:
998 997 del self.user_global_ns["__warningregistry__"]
999 998
1000 999 #-------------------------------------------------------------------------
1001 1000 # Things related to the "main" module
1002 1001 #-------------------------------------------------------------------------
1003 1002
1004 1003 def new_main_mod(self, filename, modname):
1005 1004 """Return a new 'main' module object for user code execution.
1006 1005
1007 1006 ``filename`` should be the path of the script which will be run in the
1008 1007 module. Requests with the same filename will get the same module, with
1009 1008 its namespace cleared.
1010 1009
1011 1010 ``modname`` should be the module name - normally either '__main__' or
1012 1011 the basename of the file without the extension.
1013 1012
1014 1013 When scripts are executed via %run, we must keep a reference to their
1015 1014 __main__ module around so that Python doesn't
1016 1015 clear it, rendering references to module globals useless.
1017 1016
1018 1017 This method keeps said reference in a private dict, keyed by the
1019 1018 absolute path of the script. This way, for multiple executions of the
1020 1019 same script we only keep one copy of the namespace (the last one),
1021 1020 thus preventing memory leaks from old references while allowing the
1022 1021 objects from the last execution to be accessible.
1023 1022 """
1024 1023 filename = os.path.abspath(filename)
1025 1024 try:
1026 1025 main_mod = self._main_mod_cache[filename]
1027 1026 except KeyError:
1028 1027 main_mod = self._main_mod_cache[filename] = types.ModuleType(
1029 1028 modname,
1030 1029 doc="Module created for script run in IPython")
1031 1030 else:
1032 1031 main_mod.__dict__.clear()
1033 1032 main_mod.__name__ = modname
1034 1033
1035 1034 main_mod.__file__ = filename
1036 1035 # It seems pydoc (and perhaps others) needs any module instance to
1037 1036 # implement a __nonzero__ method
1038 1037 main_mod.__nonzero__ = lambda : True
1039 1038
1040 1039 return main_mod
1041 1040
1042 1041 def clear_main_mod_cache(self):
1043 1042 """Clear the cache of main modules.
1044 1043
1045 1044 Mainly for use by utilities like %reset.
1046 1045
1047 1046 Examples
1048 1047 --------
1049 1048 In [15]: import IPython
1050 1049
1051 1050 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
1052 1051
1053 1052 In [17]: len(_ip._main_mod_cache) > 0
1054 1053 Out[17]: True
1055 1054
1056 1055 In [18]: _ip.clear_main_mod_cache()
1057 1056
1058 1057 In [19]: len(_ip._main_mod_cache) == 0
1059 1058 Out[19]: True
1060 1059 """
1061 1060 self._main_mod_cache.clear()
1062 1061
1063 1062 #-------------------------------------------------------------------------
1064 1063 # Things related to debugging
1065 1064 #-------------------------------------------------------------------------
1066 1065
1067 1066 def init_pdb(self):
1068 1067 # Set calling of pdb on exceptions
1069 1068 # self.call_pdb is a property
1070 1069 self.call_pdb = self.pdb
1071 1070
1072 1071 def _get_call_pdb(self):
1073 1072 return self._call_pdb
1074 1073
1075 1074 def _set_call_pdb(self,val):
1076 1075
1077 1076 if val not in (0,1,False,True):
1078 1077 raise ValueError('new call_pdb value must be boolean')
1079 1078
1080 1079 # store value in instance
1081 1080 self._call_pdb = val
1082 1081
1083 1082 # notify the actual exception handlers
1084 1083 self.InteractiveTB.call_pdb = val
1085 1084
1086 1085 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
1087 1086 'Control auto-activation of pdb at exceptions')
1088 1087
1089 1088 def debugger(self,force=False):
1090 1089 """Call the pdb debugger.
1091 1090
1092 1091 Keywords:
1093 1092
1094 1093 - force(False): by default, this routine checks the instance call_pdb
1095 1094 flag and does not actually invoke the debugger if the flag is false.
1096 1095 The 'force' option forces the debugger to activate even if the flag
1097 1096 is false.
1098 1097 """
1099 1098
1100 1099 if not (force or self.call_pdb):
1101 1100 return
1102 1101
1103 1102 if not hasattr(sys,'last_traceback'):
1104 1103 error('No traceback has been produced, nothing to debug.')
1105 1104 return
1106 1105
1107 1106 self.InteractiveTB.debugger(force=True)
1108 1107
1109 1108 #-------------------------------------------------------------------------
1110 1109 # Things related to IPython's various namespaces
1111 1110 #-------------------------------------------------------------------------
1112 1111 default_user_namespaces = True
1113 1112
1114 1113 def init_create_namespaces(self, user_module=None, user_ns=None):
1115 1114 # Create the namespace where the user will operate. user_ns is
1116 1115 # normally the only one used, and it is passed to the exec calls as
1117 1116 # the locals argument. But we do carry a user_global_ns namespace
1118 1117 # given as the exec 'globals' argument, This is useful in embedding
1119 1118 # situations where the ipython shell opens in a context where the
1120 1119 # distinction between locals and globals is meaningful. For
1121 1120 # non-embedded contexts, it is just the same object as the user_ns dict.
1122 1121
1123 1122 # FIXME. For some strange reason, __builtins__ is showing up at user
1124 1123 # level as a dict instead of a module. This is a manual fix, but I
1125 1124 # should really track down where the problem is coming from. Alex
1126 1125 # Schmolck reported this problem first.
1127 1126
1128 1127 # A useful post by Alex Martelli on this topic:
1129 1128 # Re: inconsistent value from __builtins__
1130 1129 # Von: Alex Martelli <aleaxit@yahoo.com>
1131 1130 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
1132 1131 # Gruppen: comp.lang.python
1133 1132
1134 1133 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
1135 1134 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
1136 1135 # > <type 'dict'>
1137 1136 # > >>> print type(__builtins__)
1138 1137 # > <type 'module'>
1139 1138 # > Is this difference in return value intentional?
1140 1139
1141 1140 # Well, it's documented that '__builtins__' can be either a dictionary
1142 1141 # or a module, and it's been that way for a long time. Whether it's
1143 1142 # intentional (or sensible), I don't know. In any case, the idea is
1144 1143 # that if you need to access the built-in namespace directly, you
1145 1144 # should start with "import __builtin__" (note, no 's') which will
1146 1145 # definitely give you a module. Yeah, it's somewhat confusing:-(.
1147 1146
1148 1147 # These routines return a properly built module and dict as needed by
1149 1148 # the rest of the code, and can also be used by extension writers to
1150 1149 # generate properly initialized namespaces.
1151 1150 if (user_ns is not None) or (user_module is not None):
1152 1151 self.default_user_namespaces = False
1153 1152 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
1154 1153
1155 1154 # A record of hidden variables we have added to the user namespace, so
1156 1155 # we can list later only variables defined in actual interactive use.
1157 1156 self.user_ns_hidden = {}
1158 1157
1159 1158 # Now that FakeModule produces a real module, we've run into a nasty
1160 1159 # problem: after script execution (via %run), the module where the user
1161 1160 # code ran is deleted. Now that this object is a true module (needed
1162 1161 # so doctest and other tools work correctly), the Python module
1163 1162 # teardown mechanism runs over it, and sets to None every variable
1164 1163 # present in that module. Top-level references to objects from the
1165 1164 # script survive, because the user_ns is updated with them. However,
1166 1165 # calling functions defined in the script that use other things from
1167 1166 # the script will fail, because the function's closure had references
1168 1167 # to the original objects, which are now all None. So we must protect
1169 1168 # these modules from deletion by keeping a cache.
1170 1169 #
1171 1170 # To avoid keeping stale modules around (we only need the one from the
1172 1171 # last run), we use a dict keyed with the full path to the script, so
1173 1172 # only the last version of the module is held in the cache. Note,
1174 1173 # however, that we must cache the module *namespace contents* (their
1175 1174 # __dict__). Because if we try to cache the actual modules, old ones
1176 1175 # (uncached) could be destroyed while still holding references (such as
1177 1176 # those held by GUI objects that tend to be long-lived)>
1178 1177 #
1179 1178 # The %reset command will flush this cache. See the cache_main_mod()
1180 1179 # and clear_main_mod_cache() methods for details on use.
1181 1180
1182 1181 # This is the cache used for 'main' namespaces
1183 1182 self._main_mod_cache = {}
1184 1183
1185 1184 # A table holding all the namespaces IPython deals with, so that
1186 1185 # introspection facilities can search easily.
1187 1186 self.ns_table = {'user_global':self.user_module.__dict__,
1188 1187 'user_local':self.user_ns,
1189 1188 'builtin':builtin_mod.__dict__
1190 1189 }
1191 1190
1192 1191 @property
1193 1192 def user_global_ns(self):
1194 1193 return self.user_module.__dict__
1195 1194
1196 1195 def prepare_user_module(self, user_module=None, user_ns=None):
1197 1196 """Prepare the module and namespace in which user code will be run.
1198 1197
1199 1198 When IPython is started normally, both parameters are None: a new module
1200 1199 is created automatically, and its __dict__ used as the namespace.
1201 1200
1202 1201 If only user_module is provided, its __dict__ is used as the namespace.
1203 1202 If only user_ns is provided, a dummy module is created, and user_ns
1204 1203 becomes the global namespace. If both are provided (as they may be
1205 1204 when embedding), user_ns is the local namespace, and user_module
1206 1205 provides the global namespace.
1207 1206
1208 1207 Parameters
1209 1208 ----------
1210 1209 user_module : module, optional
1211 1210 The current user module in which IPython is being run. If None,
1212 1211 a clean module will be created.
1213 1212 user_ns : dict, optional
1214 1213 A namespace in which to run interactive commands.
1215 1214
1216 1215 Returns
1217 1216 -------
1218 1217 A tuple of user_module and user_ns, each properly initialised.
1219 1218 """
1220 1219 if user_module is None and user_ns is not None:
1221 1220 user_ns.setdefault("__name__", "__main__")
1222 1221 user_module = DummyMod()
1223 1222 user_module.__dict__ = user_ns
1224 1223
1225 1224 if user_module is None:
1226 1225 user_module = types.ModuleType("__main__",
1227 1226 doc="Automatically created module for IPython interactive environment")
1228 1227
1229 1228 # We must ensure that __builtin__ (without the final 's') is always
1230 1229 # available and pointing to the __builtin__ *module*. For more details:
1231 1230 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1232 1231 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1233 1232 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1234 1233
1235 1234 if user_ns is None:
1236 1235 user_ns = user_module.__dict__
1237 1236
1238 1237 return user_module, user_ns
1239 1238
1240 1239 def init_sys_modules(self):
1241 1240 # We need to insert into sys.modules something that looks like a
1242 1241 # module but which accesses the IPython namespace, for shelve and
1243 1242 # pickle to work interactively. Normally they rely on getting
1244 1243 # everything out of __main__, but for embedding purposes each IPython
1245 1244 # instance has its own private namespace, so we can't go shoving
1246 1245 # everything into __main__.
1247 1246
1248 1247 # note, however, that we should only do this for non-embedded
1249 1248 # ipythons, which really mimic the __main__.__dict__ with their own
1250 1249 # namespace. Embedded instances, on the other hand, should not do
1251 1250 # this because they need to manage the user local/global namespaces
1252 1251 # only, but they live within a 'normal' __main__ (meaning, they
1253 1252 # shouldn't overtake the execution environment of the script they're
1254 1253 # embedded in).
1255 1254
1256 1255 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1257 1256 main_name = self.user_module.__name__
1258 1257 sys.modules[main_name] = self.user_module
1259 1258
1260 1259 def init_user_ns(self):
1261 1260 """Initialize all user-visible namespaces to their minimum defaults.
1262 1261
1263 1262 Certain history lists are also initialized here, as they effectively
1264 1263 act as user namespaces.
1265 1264
1266 1265 Notes
1267 1266 -----
1268 1267 All data structures here are only filled in, they are NOT reset by this
1269 1268 method. If they were not empty before, data will simply be added to
1270 1269 them.
1271 1270 """
1272 1271 # This function works in two parts: first we put a few things in
1273 1272 # user_ns, and we sync that contents into user_ns_hidden so that these
1274 1273 # initial variables aren't shown by %who. After the sync, we add the
1275 1274 # rest of what we *do* want the user to see with %who even on a new
1276 1275 # session (probably nothing, so they really only see their own stuff)
1277 1276
1278 1277 # The user dict must *always* have a __builtin__ reference to the
1279 1278 # Python standard __builtin__ namespace, which must be imported.
1280 1279 # This is so that certain operations in prompt evaluation can be
1281 1280 # reliably executed with builtins. Note that we can NOT use
1282 1281 # __builtins__ (note the 's'), because that can either be a dict or a
1283 1282 # module, and can even mutate at runtime, depending on the context
1284 1283 # (Python makes no guarantees on it). In contrast, __builtin__ is
1285 1284 # always a module object, though it must be explicitly imported.
1286 1285
1287 1286 # For more details:
1288 1287 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1289 1288 ns = {}
1290 1289
1291 1290 # make global variables for user access to the histories
1292 1291 ns['_ih'] = self.history_manager.input_hist_parsed
1293 1292 ns['_oh'] = self.history_manager.output_hist
1294 1293 ns['_dh'] = self.history_manager.dir_hist
1295 1294
1296 1295 # user aliases to input and output histories. These shouldn't show up
1297 1296 # in %who, as they can have very large reprs.
1298 1297 ns['In'] = self.history_manager.input_hist_parsed
1299 1298 ns['Out'] = self.history_manager.output_hist
1300 1299
1301 1300 # Store myself as the public api!!!
1302 1301 ns['get_ipython'] = self.get_ipython
1303 1302
1304 1303 ns['exit'] = self.exiter
1305 1304 ns['quit'] = self.exiter
1306 1305
1307 1306 # Sync what we've added so far to user_ns_hidden so these aren't seen
1308 1307 # by %who
1309 1308 self.user_ns_hidden.update(ns)
1310 1309
1311 1310 # Anything put into ns now would show up in %who. Think twice before
1312 1311 # putting anything here, as we really want %who to show the user their
1313 1312 # stuff, not our variables.
1314 1313
1315 1314 # Finally, update the real user's namespace
1316 1315 self.user_ns.update(ns)
1317 1316
1318 1317 @property
1319 1318 def all_ns_refs(self):
1320 1319 """Get a list of references to all the namespace dictionaries in which
1321 1320 IPython might store a user-created object.
1322 1321
1323 1322 Note that this does not include the displayhook, which also caches
1324 1323 objects from the output."""
1325 1324 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1326 1325 [m.__dict__ for m in self._main_mod_cache.values()]
1327 1326
1328 1327 def reset(self, new_session=True, aggressive=False):
1329 1328 """Clear all internal namespaces, and attempt to release references to
1330 1329 user objects.
1331 1330
1332 1331 If new_session is True, a new history session will be opened.
1333 1332 """
1334 1333 # Clear histories
1335 1334 self.history_manager.reset(new_session)
1336 1335 # Reset counter used to index all histories
1337 1336 if new_session:
1338 1337 self.execution_count = 1
1339 1338
1340 1339 # Reset last execution result
1341 1340 self.last_execution_succeeded = True
1342 1341 self.last_execution_result = None
1343 1342
1344 1343 # Flush cached output items
1345 1344 if self.displayhook.do_full_cache:
1346 1345 self.displayhook.flush()
1347 1346
1348 1347 # The main execution namespaces must be cleared very carefully,
1349 1348 # skipping the deletion of the builtin-related keys, because doing so
1350 1349 # would cause errors in many object's __del__ methods.
1351 1350 if self.user_ns is not self.user_global_ns:
1352 1351 self.user_ns.clear()
1353 1352 ns = self.user_global_ns
1354 1353 drop_keys = set(ns.keys())
1355 1354 drop_keys.discard('__builtin__')
1356 1355 drop_keys.discard('__builtins__')
1357 1356 drop_keys.discard('__name__')
1358 1357 for k in drop_keys:
1359 1358 del ns[k]
1360 1359
1361 1360 self.user_ns_hidden.clear()
1362 1361
1363 1362 # Restore the user namespaces to minimal usability
1364 1363 self.init_user_ns()
1365 1364 if aggressive and not hasattr(self, "_sys_modules_keys"):
1366 1365 print("Cannot restore sys.module, no snapshot")
1367 1366 elif aggressive:
1368 1367 print("culling sys module...")
1369 1368 current_keys = set(sys.modules.keys())
1370 1369 for k in current_keys - self._sys_modules_keys:
1371 1370 if k.startswith("multiprocessing"):
1372 1371 continue
1373 1372 del sys.modules[k]
1374 1373
1375 1374 # Restore the default and user aliases
1376 1375 self.alias_manager.clear_aliases()
1377 1376 self.alias_manager.init_aliases()
1378 1377
1379 1378 # Now define aliases that only make sense on the terminal, because they
1380 1379 # need direct access to the console in a way that we can't emulate in
1381 1380 # GUI or web frontend
1382 1381 if os.name == 'posix':
1383 1382 for cmd in ('clear', 'more', 'less', 'man'):
1384 1383 if cmd not in self.magics_manager.magics['line']:
1385 1384 self.alias_manager.soft_define_alias(cmd, cmd)
1386 1385
1387 1386 # Flush the private list of module references kept for script
1388 1387 # execution protection
1389 1388 self.clear_main_mod_cache()
1390 1389
1391 1390 def del_var(self, varname, by_name=False):
1392 1391 """Delete a variable from the various namespaces, so that, as
1393 1392 far as possible, we're not keeping any hidden references to it.
1394 1393
1395 1394 Parameters
1396 1395 ----------
1397 1396 varname : str
1398 1397 The name of the variable to delete.
1399 1398 by_name : bool
1400 1399 If True, delete variables with the given name in each
1401 1400 namespace. If False (default), find the variable in the user
1402 1401 namespace, and delete references to it.
1403 1402 """
1404 1403 if varname in ('__builtin__', '__builtins__'):
1405 1404 raise ValueError("Refusing to delete %s" % varname)
1406 1405
1407 1406 ns_refs = self.all_ns_refs
1408 1407
1409 1408 if by_name: # Delete by name
1410 1409 for ns in ns_refs:
1411 1410 try:
1412 1411 del ns[varname]
1413 1412 except KeyError:
1414 1413 pass
1415 1414 else: # Delete by object
1416 1415 try:
1417 1416 obj = self.user_ns[varname]
1418 1417 except KeyError as e:
1419 1418 raise NameError("name '%s' is not defined" % varname) from e
1420 1419 # Also check in output history
1421 1420 ns_refs.append(self.history_manager.output_hist)
1422 1421 for ns in ns_refs:
1423 1422 to_delete = [n for n, o in ns.items() if o is obj]
1424 1423 for name in to_delete:
1425 1424 del ns[name]
1426 1425
1427 1426 # Ensure it is removed from the last execution result
1428 1427 if self.last_execution_result.result is obj:
1429 1428 self.last_execution_result = None
1430 1429
1431 1430 # displayhook keeps extra references, but not in a dictionary
1432 1431 for name in ('_', '__', '___'):
1433 1432 if getattr(self.displayhook, name) is obj:
1434 1433 setattr(self.displayhook, name, None)
1435 1434
1436 1435 def reset_selective(self, regex=None):
1437 1436 """Clear selective variables from internal namespaces based on a
1438 1437 specified regular expression.
1439 1438
1440 1439 Parameters
1441 1440 ----------
1442 1441 regex : string or compiled pattern, optional
1443 1442 A regular expression pattern that will be used in searching
1444 1443 variable names in the users namespaces.
1445 1444 """
1446 1445 if regex is not None:
1447 1446 try:
1448 1447 m = re.compile(regex)
1449 1448 except TypeError as e:
1450 1449 raise TypeError('regex must be a string or compiled pattern') from e
1451 1450 # Search for keys in each namespace that match the given regex
1452 1451 # If a match is found, delete the key/value pair.
1453 1452 for ns in self.all_ns_refs:
1454 1453 for var in ns:
1455 1454 if m.search(var):
1456 1455 del ns[var]
1457 1456
1458 1457 def push(self, variables, interactive=True):
1459 1458 """Inject a group of variables into the IPython user namespace.
1460 1459
1461 1460 Parameters
1462 1461 ----------
1463 1462 variables : dict, str or list/tuple of str
1464 1463 The variables to inject into the user's namespace. If a dict, a
1465 1464 simple update is done. If a str, the string is assumed to have
1466 1465 variable names separated by spaces. A list/tuple of str can also
1467 1466 be used to give the variable names. If just the variable names are
1468 1467 give (list/tuple/str) then the variable values looked up in the
1469 1468 callers frame.
1470 1469 interactive : bool
1471 1470 If True (default), the variables will be listed with the ``who``
1472 1471 magic.
1473 1472 """
1474 1473 vdict = None
1475 1474
1476 1475 # We need a dict of name/value pairs to do namespace updates.
1477 1476 if isinstance(variables, dict):
1478 1477 vdict = variables
1479 1478 elif isinstance(variables, (str, list, tuple)):
1480 1479 if isinstance(variables, str):
1481 1480 vlist = variables.split()
1482 1481 else:
1483 1482 vlist = variables
1484 1483 vdict = {}
1485 1484 cf = sys._getframe(1)
1486 1485 for name in vlist:
1487 1486 try:
1488 1487 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1489 1488 except:
1490 1489 print('Could not get variable %s from %s' %
1491 1490 (name,cf.f_code.co_name))
1492 1491 else:
1493 1492 raise ValueError('variables must be a dict/str/list/tuple')
1494 1493
1495 1494 # Propagate variables to user namespace
1496 1495 self.user_ns.update(vdict)
1497 1496
1498 1497 # And configure interactive visibility
1499 1498 user_ns_hidden = self.user_ns_hidden
1500 1499 if interactive:
1501 1500 for name in vdict:
1502 1501 user_ns_hidden.pop(name, None)
1503 1502 else:
1504 1503 user_ns_hidden.update(vdict)
1505 1504
1506 1505 def drop_by_id(self, variables):
1507 1506 """Remove a dict of variables from the user namespace, if they are the
1508 1507 same as the values in the dictionary.
1509 1508
1510 1509 This is intended for use by extensions: variables that they've added can
1511 1510 be taken back out if they are unloaded, without removing any that the
1512 1511 user has overwritten.
1513 1512
1514 1513 Parameters
1515 1514 ----------
1516 1515 variables : dict
1517 1516 A dictionary mapping object names (as strings) to the objects.
1518 1517 """
1519 1518 for name, obj in variables.items():
1520 1519 if name in self.user_ns and self.user_ns[name] is obj:
1521 1520 del self.user_ns[name]
1522 1521 self.user_ns_hidden.pop(name, None)
1523 1522
1524 1523 #-------------------------------------------------------------------------
1525 1524 # Things related to object introspection
1526 1525 #-------------------------------------------------------------------------
1527 1526
1528 1527 def _ofind(self, oname, namespaces=None):
1529 1528 """Find an object in the available namespaces.
1530 1529
1531 1530 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1532 1531
1533 1532 Has special code to detect magic functions.
1534 1533 """
1535 1534 oname = oname.strip()
1536 1535 if not oname.startswith(ESC_MAGIC) and \
1537 1536 not oname.startswith(ESC_MAGIC2) and \
1538 1537 not all(a.isidentifier() for a in oname.split(".")):
1539 1538 return {'found': False}
1540 1539
1541 1540 if namespaces is None:
1542 1541 # Namespaces to search in:
1543 1542 # Put them in a list. The order is important so that we
1544 1543 # find things in the same order that Python finds them.
1545 1544 namespaces = [ ('Interactive', self.user_ns),
1546 1545 ('Interactive (global)', self.user_global_ns),
1547 1546 ('Python builtin', builtin_mod.__dict__),
1548 1547 ]
1549 1548
1550 1549 ismagic = False
1551 1550 isalias = False
1552 1551 found = False
1553 1552 ospace = None
1554 1553 parent = None
1555 1554 obj = None
1556 1555
1557 1556
1558 1557 # Look for the given name by splitting it in parts. If the head is
1559 1558 # found, then we look for all the remaining parts as members, and only
1560 1559 # declare success if we can find them all.
1561 1560 oname_parts = oname.split('.')
1562 1561 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1563 1562 for nsname,ns in namespaces:
1564 1563 try:
1565 1564 obj = ns[oname_head]
1566 1565 except KeyError:
1567 1566 continue
1568 1567 else:
1569 1568 for idx, part in enumerate(oname_rest):
1570 1569 try:
1571 1570 parent = obj
1572 1571 # The last part is looked up in a special way to avoid
1573 1572 # descriptor invocation as it may raise or have side
1574 1573 # effects.
1575 1574 if idx == len(oname_rest) - 1:
1576 1575 obj = self._getattr_property(obj, part)
1577 1576 else:
1578 1577 obj = getattr(obj, part)
1579 1578 except:
1580 1579 # Blanket except b/c some badly implemented objects
1581 1580 # allow __getattr__ to raise exceptions other than
1582 1581 # AttributeError, which then crashes IPython.
1583 1582 break
1584 1583 else:
1585 1584 # If we finish the for loop (no break), we got all members
1586 1585 found = True
1587 1586 ospace = nsname
1588 1587 break # namespace loop
1589 1588
1590 1589 # Try to see if it's magic
1591 1590 if not found:
1592 1591 obj = None
1593 1592 if oname.startswith(ESC_MAGIC2):
1594 1593 oname = oname.lstrip(ESC_MAGIC2)
1595 1594 obj = self.find_cell_magic(oname)
1596 1595 elif oname.startswith(ESC_MAGIC):
1597 1596 oname = oname.lstrip(ESC_MAGIC)
1598 1597 obj = self.find_line_magic(oname)
1599 1598 else:
1600 1599 # search without prefix, so run? will find %run?
1601 1600 obj = self.find_line_magic(oname)
1602 1601 if obj is None:
1603 1602 obj = self.find_cell_magic(oname)
1604 1603 if obj is not None:
1605 1604 found = True
1606 1605 ospace = 'IPython internal'
1607 1606 ismagic = True
1608 1607 isalias = isinstance(obj, Alias)
1609 1608
1610 1609 # Last try: special-case some literals like '', [], {}, etc:
1611 1610 if not found and oname_head in ["''",'""','[]','{}','()']:
1612 1611 obj = eval(oname_head)
1613 1612 found = True
1614 1613 ospace = 'Interactive'
1615 1614
1616 1615 return {
1617 1616 'obj':obj,
1618 1617 'found':found,
1619 1618 'parent':parent,
1620 1619 'ismagic':ismagic,
1621 1620 'isalias':isalias,
1622 1621 'namespace':ospace
1623 1622 }
1624 1623
1625 1624 @staticmethod
1626 1625 def _getattr_property(obj, attrname):
1627 1626 """Property-aware getattr to use in object finding.
1628 1627
1629 1628 If attrname represents a property, return it unevaluated (in case it has
1630 1629 side effects or raises an error.
1631 1630
1632 1631 """
1633 1632 if not isinstance(obj, type):
1634 1633 try:
1635 1634 # `getattr(type(obj), attrname)` is not guaranteed to return
1636 1635 # `obj`, but does so for property:
1637 1636 #
1638 1637 # property.__get__(self, None, cls) -> self
1639 1638 #
1640 1639 # The universal alternative is to traverse the mro manually
1641 1640 # searching for attrname in class dicts.
1642 1641 attr = getattr(type(obj), attrname)
1643 1642 except AttributeError:
1644 1643 pass
1645 1644 else:
1646 1645 # This relies on the fact that data descriptors (with both
1647 1646 # __get__ & __set__ magic methods) take precedence over
1648 1647 # instance-level attributes:
1649 1648 #
1650 1649 # class A(object):
1651 1650 # @property
1652 1651 # def foobar(self): return 123
1653 1652 # a = A()
1654 1653 # a.__dict__['foobar'] = 345
1655 1654 # a.foobar # == 123
1656 1655 #
1657 1656 # So, a property may be returned right away.
1658 1657 if isinstance(attr, property):
1659 1658 return attr
1660 1659
1661 1660 # Nothing helped, fall back.
1662 1661 return getattr(obj, attrname)
1663 1662
1664 1663 def _object_find(self, oname, namespaces=None):
1665 1664 """Find an object and return a struct with info about it."""
1666 1665 return Struct(self._ofind(oname, namespaces))
1667 1666
1668 1667 def _inspect(self, meth, oname, namespaces=None, **kw):
1669 1668 """Generic interface to the inspector system.
1670 1669
1671 1670 This function is meant to be called by pdef, pdoc & friends.
1672 1671 """
1673 1672 info = self._object_find(oname, namespaces)
1674 1673 docformat = (
1675 1674 sphinxify(self.object_inspect(oname)) if self.sphinxify_docstring else None
1676 1675 )
1677 1676 if info.found:
1678 1677 pmethod = getattr(self.inspector, meth)
1679 1678 # TODO: only apply format_screen to the plain/text repr of the mime
1680 1679 # bundle.
1681 1680 formatter = format_screen if info.ismagic else docformat
1682 1681 if meth == 'pdoc':
1683 1682 pmethod(info.obj, oname, formatter)
1684 1683 elif meth == 'pinfo':
1685 1684 pmethod(
1686 1685 info.obj,
1687 1686 oname,
1688 1687 formatter,
1689 1688 info,
1690 1689 enable_html_pager=self.enable_html_pager,
1691 1690 **kw,
1692 1691 )
1693 1692 else:
1694 1693 pmethod(info.obj, oname)
1695 1694 else:
1696 1695 print('Object `%s` not found.' % oname)
1697 1696 return 'not found' # so callers can take other action
1698 1697
1699 1698 def object_inspect(self, oname, detail_level=0):
1700 1699 """Get object info about oname"""
1701 1700 with self.builtin_trap:
1702 1701 info = self._object_find(oname)
1703 1702 if info.found:
1704 1703 return self.inspector.info(info.obj, oname, info=info,
1705 1704 detail_level=detail_level
1706 1705 )
1707 1706 else:
1708 1707 return oinspect.object_info(name=oname, found=False)
1709 1708
1710 1709 def object_inspect_text(self, oname, detail_level=0):
1711 1710 """Get object info as formatted text"""
1712 1711 return self.object_inspect_mime(oname, detail_level)['text/plain']
1713 1712
1714 1713 def object_inspect_mime(self, oname, detail_level=0, omit_sections=()):
1715 1714 """Get object info as a mimebundle of formatted representations.
1716 1715
1717 1716 A mimebundle is a dictionary, keyed by mime-type.
1718 1717 It must always have the key `'text/plain'`.
1719 1718 """
1720 1719 with self.builtin_trap:
1721 1720 info = self._object_find(oname)
1722 1721 if info.found:
1723 1722 docformat = (
1724 1723 sphinxify(self.object_inspect(oname))
1725 1724 if self.sphinxify_docstring
1726 1725 else None
1727 1726 )
1728 1727 return self.inspector._get_info(
1729 1728 info.obj,
1730 1729 oname,
1731 1730 info=info,
1732 1731 detail_level=detail_level,
1733 1732 formatter=docformat,
1734 1733 omit_sections=omit_sections,
1735 1734 )
1736 1735 else:
1737 1736 raise KeyError(oname)
1738 1737
1739 1738 #-------------------------------------------------------------------------
1740 1739 # Things related to history management
1741 1740 #-------------------------------------------------------------------------
1742 1741
1743 1742 def init_history(self):
1744 1743 """Sets up the command history, and starts regular autosaves."""
1745 1744 self.history_manager = HistoryManager(shell=self, parent=self)
1746 1745 self.configurables.append(self.history_manager)
1747 1746
1748 1747 #-------------------------------------------------------------------------
1749 1748 # Things related to exception handling and tracebacks (not debugging)
1750 1749 #-------------------------------------------------------------------------
1751 1750
1752 1751 debugger_cls = InterruptiblePdb
1753 1752
1754 1753 def init_traceback_handlers(self, custom_exceptions):
1755 1754 # Syntax error handler.
1756 1755 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor', parent=self)
1757 1756
1758 1757 # The interactive one is initialized with an offset, meaning we always
1759 1758 # want to remove the topmost item in the traceback, which is our own
1760 1759 # internal code. Valid modes: ['Plain','Context','Verbose','Minimal']
1761 1760 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1762 1761 color_scheme='NoColor',
1763 1762 tb_offset = 1,
1764 1763 check_cache=check_linecache_ipython,
1765 1764 debugger_cls=self.debugger_cls, parent=self)
1766 1765
1767 1766 # The instance will store a pointer to the system-wide exception hook,
1768 1767 # so that runtime code (such as magics) can access it. This is because
1769 1768 # during the read-eval loop, it may get temporarily overwritten.
1770 1769 self.sys_excepthook = sys.excepthook
1771 1770
1772 1771 # and add any custom exception handlers the user may have specified
1773 1772 self.set_custom_exc(*custom_exceptions)
1774 1773
1775 1774 # Set the exception mode
1776 1775 self.InteractiveTB.set_mode(mode=self.xmode)
1777 1776
1778 1777 def set_custom_exc(self, exc_tuple, handler):
1779 1778 """set_custom_exc(exc_tuple, handler)
1780 1779
1781 1780 Set a custom exception handler, which will be called if any of the
1782 1781 exceptions in exc_tuple occur in the mainloop (specifically, in the
1783 1782 run_code() method).
1784 1783
1785 1784 Parameters
1786 1785 ----------
1787 1786 exc_tuple : tuple of exception classes
1788 1787 A *tuple* of exception classes, for which to call the defined
1789 1788 handler. It is very important that you use a tuple, and NOT A
1790 1789 LIST here, because of the way Python's except statement works. If
1791 1790 you only want to trap a single exception, use a singleton tuple::
1792 1791
1793 1792 exc_tuple == (MyCustomException,)
1794 1793
1795 1794 handler : callable
1796 1795 handler must have the following signature::
1797 1796
1798 1797 def my_handler(self, etype, value, tb, tb_offset=None):
1799 1798 ...
1800 1799 return structured_traceback
1801 1800
1802 1801 Your handler must return a structured traceback (a list of strings),
1803 1802 or None.
1804 1803
1805 1804 This will be made into an instance method (via types.MethodType)
1806 1805 of IPython itself, and it will be called if any of the exceptions
1807 1806 listed in the exc_tuple are caught. If the handler is None, an
1808 1807 internal basic one is used, which just prints basic info.
1809 1808
1810 1809 To protect IPython from crashes, if your handler ever raises an
1811 1810 exception or returns an invalid result, it will be immediately
1812 1811 disabled.
1813 1812
1814 1813 Notes
1815 1814 -----
1816 1815 WARNING: by putting in your own exception handler into IPython's main
1817 1816 execution loop, you run a very good chance of nasty crashes. This
1818 1817 facility should only be used if you really know what you are doing.
1819 1818 """
1820 1819
1821 1820 if not isinstance(exc_tuple, tuple):
1822 1821 raise TypeError("The custom exceptions must be given as a tuple.")
1823 1822
1824 1823 def dummy_handler(self, etype, value, tb, tb_offset=None):
1825 1824 print('*** Simple custom exception handler ***')
1826 1825 print('Exception type :', etype)
1827 1826 print('Exception value:', value)
1828 1827 print('Traceback :', tb)
1829 1828
1830 1829 def validate_stb(stb):
1831 1830 """validate structured traceback return type
1832 1831
1833 1832 return type of CustomTB *should* be a list of strings, but allow
1834 1833 single strings or None, which are harmless.
1835 1834
1836 1835 This function will *always* return a list of strings,
1837 1836 and will raise a TypeError if stb is inappropriate.
1838 1837 """
1839 1838 msg = "CustomTB must return list of strings, not %r" % stb
1840 1839 if stb is None:
1841 1840 return []
1842 1841 elif isinstance(stb, str):
1843 1842 return [stb]
1844 1843 elif not isinstance(stb, list):
1845 1844 raise TypeError(msg)
1846 1845 # it's a list
1847 1846 for line in stb:
1848 1847 # check every element
1849 1848 if not isinstance(line, str):
1850 1849 raise TypeError(msg)
1851 1850 return stb
1852 1851
1853 1852 if handler is None:
1854 1853 wrapped = dummy_handler
1855 1854 else:
1856 1855 def wrapped(self,etype,value,tb,tb_offset=None):
1857 1856 """wrap CustomTB handler, to protect IPython from user code
1858 1857
1859 1858 This makes it harder (but not impossible) for custom exception
1860 1859 handlers to crash IPython.
1861 1860 """
1862 1861 try:
1863 1862 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1864 1863 return validate_stb(stb)
1865 1864 except:
1866 1865 # clear custom handler immediately
1867 1866 self.set_custom_exc((), None)
1868 1867 print("Custom TB Handler failed, unregistering", file=sys.stderr)
1869 1868 # show the exception in handler first
1870 1869 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1871 1870 print(self.InteractiveTB.stb2text(stb))
1872 1871 print("The original exception:")
1873 1872 stb = self.InteractiveTB.structured_traceback(
1874 1873 (etype,value,tb), tb_offset=tb_offset
1875 1874 )
1876 1875 return stb
1877 1876
1878 1877 self.CustomTB = types.MethodType(wrapped,self)
1879 1878 self.custom_exceptions = exc_tuple
1880 1879
1881 1880 def excepthook(self, etype, value, tb):
1882 1881 """One more defense for GUI apps that call sys.excepthook.
1883 1882
1884 1883 GUI frameworks like wxPython trap exceptions and call
1885 1884 sys.excepthook themselves. I guess this is a feature that
1886 1885 enables them to keep running after exceptions that would
1887 1886 otherwise kill their mainloop. This is a bother for IPython
1888 1887 which expects to catch all of the program exceptions with a try:
1889 1888 except: statement.
1890 1889
1891 1890 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1892 1891 any app directly invokes sys.excepthook, it will look to the user like
1893 1892 IPython crashed. In order to work around this, we can disable the
1894 1893 CrashHandler and replace it with this excepthook instead, which prints a
1895 1894 regular traceback using our InteractiveTB. In this fashion, apps which
1896 1895 call sys.excepthook will generate a regular-looking exception from
1897 1896 IPython, and the CrashHandler will only be triggered by real IPython
1898 1897 crashes.
1899 1898
1900 1899 This hook should be used sparingly, only in places which are not likely
1901 1900 to be true IPython errors.
1902 1901 """
1903 1902 self.showtraceback((etype, value, tb), tb_offset=0)
1904 1903
1905 1904 def _get_exc_info(self, exc_tuple=None):
1906 1905 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1907 1906
1908 1907 Ensures sys.last_type,value,traceback hold the exc_info we found,
1909 1908 from whichever source.
1910 1909
1911 1910 raises ValueError if none of these contain any information
1912 1911 """
1913 1912 if exc_tuple is None:
1914 1913 etype, value, tb = sys.exc_info()
1915 1914 else:
1916 1915 etype, value, tb = exc_tuple
1917 1916
1918 1917 if etype is None:
1919 1918 if hasattr(sys, 'last_type'):
1920 1919 etype, value, tb = sys.last_type, sys.last_value, \
1921 1920 sys.last_traceback
1922 1921
1923 1922 if etype is None:
1924 1923 raise ValueError("No exception to find")
1925 1924
1926 1925 # Now store the exception info in sys.last_type etc.
1927 1926 # WARNING: these variables are somewhat deprecated and not
1928 1927 # necessarily safe to use in a threaded environment, but tools
1929 1928 # like pdb depend on their existence, so let's set them. If we
1930 1929 # find problems in the field, we'll need to revisit their use.
1931 1930 sys.last_type = etype
1932 1931 sys.last_value = value
1933 1932 sys.last_traceback = tb
1934 1933
1935 1934 return etype, value, tb
1936 1935
1937 1936 def show_usage_error(self, exc):
1938 1937 """Show a short message for UsageErrors
1939 1938
1940 1939 These are special exceptions that shouldn't show a traceback.
1941 1940 """
1942 1941 print("UsageError: %s" % exc, file=sys.stderr)
1943 1942
1944 1943 def get_exception_only(self, exc_tuple=None):
1945 1944 """
1946 1945 Return as a string (ending with a newline) the exception that
1947 1946 just occurred, without any traceback.
1948 1947 """
1949 1948 etype, value, tb = self._get_exc_info(exc_tuple)
1950 1949 msg = traceback.format_exception_only(etype, value)
1951 1950 return ''.join(msg)
1952 1951
1953 1952 def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None,
1954 1953 exception_only=False, running_compiled_code=False):
1955 1954 """Display the exception that just occurred.
1956 1955
1957 1956 If nothing is known about the exception, this is the method which
1958 1957 should be used throughout the code for presenting user tracebacks,
1959 1958 rather than directly invoking the InteractiveTB object.
1960 1959
1961 1960 A specific showsyntaxerror() also exists, but this method can take
1962 1961 care of calling it if needed, so unless you are explicitly catching a
1963 1962 SyntaxError exception, don't try to analyze the stack manually and
1964 1963 simply call this method."""
1965 1964
1966 1965 try:
1967 1966 try:
1968 1967 etype, value, tb = self._get_exc_info(exc_tuple)
1969 1968 except ValueError:
1970 1969 print('No traceback available to show.', file=sys.stderr)
1971 1970 return
1972 1971
1973 1972 if issubclass(etype, SyntaxError):
1974 1973 # Though this won't be called by syntax errors in the input
1975 1974 # line, there may be SyntaxError cases with imported code.
1976 1975 self.showsyntaxerror(filename, running_compiled_code)
1977 1976 elif etype is UsageError:
1978 1977 self.show_usage_error(value)
1979 1978 else:
1980 1979 if exception_only:
1981 1980 stb = ['An exception has occurred, use %tb to see '
1982 1981 'the full traceback.\n']
1983 1982 stb.extend(self.InteractiveTB.get_exception_only(etype,
1984 1983 value))
1985 1984 else:
1986 1985 try:
1987 1986 # Exception classes can customise their traceback - we
1988 1987 # use this in IPython.parallel for exceptions occurring
1989 1988 # in the engines. This should return a list of strings.
1990 1989 if hasattr(value, "_render_traceback_"):
1991 1990 stb = value._render_traceback_()
1992 1991 else:
1993 1992 stb = self.InteractiveTB.structured_traceback(
1994 1993 etype, value, tb, tb_offset=tb_offset
1995 1994 )
1996 1995
1997 1996 except Exception:
1998 1997 print(
1999 1998 "Unexpected exception formatting exception. Falling back to standard exception"
2000 1999 )
2001 2000 traceback.print_exc()
2002 2001 return None
2003 2002
2004 2003 self._showtraceback(etype, value, stb)
2005 2004 if self.call_pdb:
2006 2005 # drop into debugger
2007 2006 self.debugger(force=True)
2008 2007 return
2009 2008
2010 2009 # Actually show the traceback
2011 2010 self._showtraceback(etype, value, stb)
2012 2011
2013 2012 except KeyboardInterrupt:
2014 2013 print('\n' + self.get_exception_only(), file=sys.stderr)
2015 2014
2016 2015 def _showtraceback(self, etype, evalue, stb: str):
2017 2016 """Actually show a traceback.
2018 2017
2019 2018 Subclasses may override this method to put the traceback on a different
2020 2019 place, like a side channel.
2021 2020 """
2022 2021 val = self.InteractiveTB.stb2text(stb)
2023 2022 try:
2024 2023 print(val)
2025 2024 except UnicodeEncodeError:
2026 2025 print(val.encode("utf-8", "backslashreplace").decode())
2027 2026
2028 2027 def showsyntaxerror(self, filename=None, running_compiled_code=False):
2029 2028 """Display the syntax error that just occurred.
2030 2029
2031 2030 This doesn't display a stack trace because there isn't one.
2032 2031
2033 2032 If a filename is given, it is stuffed in the exception instead
2034 2033 of what was there before (because Python's parser always uses
2035 2034 "<string>" when reading from a string).
2036 2035
2037 2036 If the syntax error occurred when running a compiled code (i.e. running_compile_code=True),
2038 2037 longer stack trace will be displayed.
2039 2038 """
2040 2039 etype, value, last_traceback = self._get_exc_info()
2041 2040
2042 2041 if filename and issubclass(etype, SyntaxError):
2043 2042 try:
2044 2043 value.filename = filename
2045 2044 except:
2046 2045 # Not the format we expect; leave it alone
2047 2046 pass
2048 2047
2049 2048 # If the error occurred when executing compiled code, we should provide full stacktrace.
2050 2049 elist = traceback.extract_tb(last_traceback) if running_compiled_code else []
2051 2050 stb = self.SyntaxTB.structured_traceback(etype, value, elist)
2052 2051 self._showtraceback(etype, value, stb)
2053 2052
2054 2053 # This is overridden in TerminalInteractiveShell to show a message about
2055 2054 # the %paste magic.
2056 2055 def showindentationerror(self):
2057 2056 """Called by _run_cell when there's an IndentationError in code entered
2058 2057 at the prompt.
2059 2058
2060 2059 This is overridden in TerminalInteractiveShell to show a message about
2061 2060 the %paste magic."""
2062 2061 self.showsyntaxerror()
2063 2062
2064 2063 @skip_doctest
2065 2064 def set_next_input(self, s, replace=False):
2066 2065 """ Sets the 'default' input string for the next command line.
2067 2066
2068 2067 Example::
2069 2068
2070 2069 In [1]: _ip.set_next_input("Hello Word")
2071 2070 In [2]: Hello Word_ # cursor is here
2072 2071 """
2073 2072 self.rl_next_input = s
2074 2073
2075 2074 def _indent_current_str(self):
2076 2075 """return the current level of indentation as a string"""
2077 2076 return self.input_splitter.get_indent_spaces() * ' '
2078 2077
2079 2078 #-------------------------------------------------------------------------
2080 2079 # Things related to text completion
2081 2080 #-------------------------------------------------------------------------
2082 2081
2083 2082 def init_completer(self):
2084 2083 """Initialize the completion machinery.
2085 2084
2086 2085 This creates completion machinery that can be used by client code,
2087 2086 either interactively in-process (typically triggered by the readline
2088 2087 library), programmatically (such as in test suites) or out-of-process
2089 2088 (typically over the network by remote frontends).
2090 2089 """
2091 2090 from IPython.core.completer import IPCompleter
2092 2091 from IPython.core.completerlib import (
2093 2092 cd_completer,
2094 2093 magic_run_completer,
2095 2094 module_completer,
2096 2095 reset_completer,
2097 2096 )
2098 2097
2099 2098 self.Completer = IPCompleter(shell=self,
2100 2099 namespace=self.user_ns,
2101 2100 global_namespace=self.user_global_ns,
2102 2101 parent=self,
2103 2102 )
2104 2103 self.configurables.append(self.Completer)
2105 2104
2106 2105 # Add custom completers to the basic ones built into IPCompleter
2107 2106 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
2108 2107 self.strdispatchers['complete_command'] = sdisp
2109 2108 self.Completer.custom_completers = sdisp
2110 2109
2111 2110 self.set_hook('complete_command', module_completer, str_key = 'import')
2112 2111 self.set_hook('complete_command', module_completer, str_key = 'from')
2113 2112 self.set_hook('complete_command', module_completer, str_key = '%aimport')
2114 2113 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
2115 2114 self.set_hook('complete_command', cd_completer, str_key = '%cd')
2116 2115 self.set_hook('complete_command', reset_completer, str_key = '%reset')
2117 2116
2118 2117 @skip_doctest
2119 2118 def complete(self, text, line=None, cursor_pos=None):
2120 2119 """Return the completed text and a list of completions.
2121 2120
2122 2121 Parameters
2123 2122 ----------
2124 2123 text : string
2125 2124 A string of text to be completed on. It can be given as empty and
2126 2125 instead a line/position pair are given. In this case, the
2127 2126 completer itself will split the line like readline does.
2128 2127 line : string, optional
2129 2128 The complete line that text is part of.
2130 2129 cursor_pos : int, optional
2131 2130 The position of the cursor on the input line.
2132 2131
2133 2132 Returns
2134 2133 -------
2135 2134 text : string
2136 2135 The actual text that was completed.
2137 2136 matches : list
2138 2137 A sorted list with all possible completions.
2139 2138
2140 2139 Notes
2141 2140 -----
2142 2141 The optional arguments allow the completion to take more context into
2143 2142 account, and are part of the low-level completion API.
2144 2143
2145 2144 This is a wrapper around the completion mechanism, similar to what
2146 2145 readline does at the command line when the TAB key is hit. By
2147 2146 exposing it as a method, it can be used by other non-readline
2148 2147 environments (such as GUIs) for text completion.
2149 2148
2150 2149 Examples
2151 2150 --------
2152 2151 In [1]: x = 'hello'
2153 2152
2154 2153 In [2]: _ip.complete('x.l')
2155 2154 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2156 2155 """
2157 2156
2158 2157 # Inject names into __builtin__ so we can complete on the added names.
2159 2158 with self.builtin_trap:
2160 2159 return self.Completer.complete(text, line, cursor_pos)
2161 2160
2162 2161 def set_custom_completer(self, completer, pos=0) -> None:
2163 2162 """Adds a new custom completer function.
2164 2163
2165 2164 The position argument (defaults to 0) is the index in the completers
2166 2165 list where you want the completer to be inserted.
2167 2166
2168 2167 `completer` should have the following signature::
2169 2168
2170 2169 def completion(self: Completer, text: string) -> List[str]:
2171 2170 raise NotImplementedError
2172 2171
2173 2172 It will be bound to the current Completer instance and pass some text
2174 2173 and return a list with current completions to suggest to the user.
2175 2174 """
2176 2175
2177 2176 newcomp = types.MethodType(completer, self.Completer)
2178 2177 self.Completer.custom_matchers.insert(pos,newcomp)
2179 2178
2180 2179 def set_completer_frame(self, frame=None):
2181 2180 """Set the frame of the completer."""
2182 2181 if frame:
2183 2182 self.Completer.namespace = frame.f_locals
2184 2183 self.Completer.global_namespace = frame.f_globals
2185 2184 else:
2186 2185 self.Completer.namespace = self.user_ns
2187 2186 self.Completer.global_namespace = self.user_global_ns
2188 2187
2189 2188 #-------------------------------------------------------------------------
2190 2189 # Things related to magics
2191 2190 #-------------------------------------------------------------------------
2192 2191
2193 2192 def init_magics(self):
2194 2193 from IPython.core import magics as m
2195 2194 self.magics_manager = magic.MagicsManager(shell=self,
2196 2195 parent=self,
2197 2196 user_magics=m.UserMagics(self))
2198 2197 self.configurables.append(self.magics_manager)
2199 2198
2200 2199 # Expose as public API from the magics manager
2201 2200 self.register_magics = self.magics_manager.register
2202 2201
2203 2202 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2204 2203 m.ConfigMagics, m.DisplayMagics, m.ExecutionMagics,
2205 2204 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2206 2205 m.NamespaceMagics, m.OSMagics, m.PackagingMagics,
2207 2206 m.PylabMagics, m.ScriptMagics,
2208 2207 )
2209 2208 self.register_magics(m.AsyncMagics)
2210 2209
2211 2210 # Register Magic Aliases
2212 2211 mman = self.magics_manager
2213 2212 # FIXME: magic aliases should be defined by the Magics classes
2214 2213 # or in MagicsManager, not here
2215 2214 mman.register_alias('ed', 'edit')
2216 2215 mman.register_alias('hist', 'history')
2217 2216 mman.register_alias('rep', 'recall')
2218 2217 mman.register_alias('SVG', 'svg', 'cell')
2219 2218 mman.register_alias('HTML', 'html', 'cell')
2220 2219 mman.register_alias('file', 'writefile', 'cell')
2221 2220
2222 2221 # FIXME: Move the color initialization to the DisplayHook, which
2223 2222 # should be split into a prompt manager and displayhook. We probably
2224 2223 # even need a centralize colors management object.
2225 2224 self.run_line_magic('colors', self.colors)
2226 2225
2227 2226 # Defined here so that it's included in the documentation
2228 2227 @functools.wraps(magic.MagicsManager.register_function)
2229 2228 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2230 2229 self.magics_manager.register_function(
2231 2230 func, magic_kind=magic_kind, magic_name=magic_name
2232 2231 )
2233 2232
2234 2233 def _find_with_lazy_load(self, /, type_, magic_name: str):
2235 2234 """
2236 2235 Try to find a magic potentially lazy-loading it.
2237 2236
2238 2237 Parameters
2239 2238 ----------
2240 2239
2241 2240 type_: "line"|"cell"
2242 2241 the type of magics we are trying to find/lazy load.
2243 2242 magic_name: str
2244 2243 The name of the magic we are trying to find/lazy load
2245 2244
2246 2245
2247 2246 Note that this may have any side effects
2248 2247 """
2249 2248 finder = {"line": self.find_line_magic, "cell": self.find_cell_magic}[type_]
2250 2249 fn = finder(magic_name)
2251 2250 if fn is not None:
2252 2251 return fn
2253 2252 lazy = self.magics_manager.lazy_magics.get(magic_name)
2254 2253 if lazy is None:
2255 2254 return None
2256 2255
2257 2256 self.run_line_magic("load_ext", lazy)
2258 2257 res = finder(magic_name)
2259 2258 return res
2260 2259
2261 2260 def run_line_magic(self, magic_name: str, line, _stack_depth=1):
2262 2261 """Execute the given line magic.
2263 2262
2264 2263 Parameters
2265 2264 ----------
2266 2265 magic_name : str
2267 2266 Name of the desired magic function, without '%' prefix.
2268 2267 line : str
2269 2268 The rest of the input line as a single string.
2270 2269 _stack_depth : int
2271 2270 If run_line_magic() is called from magic() then _stack_depth=2.
2272 2271 This is added to ensure backward compatibility for use of 'get_ipython().magic()'
2273 2272 """
2274 2273 fn = self._find_with_lazy_load("line", magic_name)
2275 2274 if fn is None:
2276 2275 lazy = self.magics_manager.lazy_magics.get(magic_name)
2277 2276 if lazy:
2278 2277 self.run_line_magic("load_ext", lazy)
2279 2278 fn = self.find_line_magic(magic_name)
2280 2279 if fn is None:
2281 2280 cm = self.find_cell_magic(magic_name)
2282 2281 etpl = "Line magic function `%%%s` not found%s."
2283 2282 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2284 2283 'did you mean that instead?)' % magic_name )
2285 2284 raise UsageError(etpl % (magic_name, extra))
2286 2285 else:
2287 2286 # Note: this is the distance in the stack to the user's frame.
2288 2287 # This will need to be updated if the internal calling logic gets
2289 2288 # refactored, or else we'll be expanding the wrong variables.
2290 2289
2291 2290 # Determine stack_depth depending on where run_line_magic() has been called
2292 2291 stack_depth = _stack_depth
2293 2292 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2294 2293 # magic has opted out of var_expand
2295 2294 magic_arg_s = line
2296 2295 else:
2297 2296 magic_arg_s = self.var_expand(line, stack_depth)
2298 2297 # Put magic args in a list so we can call with f(*a) syntax
2299 2298 args = [magic_arg_s]
2300 2299 kwargs = {}
2301 2300 # Grab local namespace if we need it:
2302 2301 if getattr(fn, "needs_local_scope", False):
2303 2302 kwargs['local_ns'] = self.get_local_scope(stack_depth)
2304 2303 with self.builtin_trap:
2305 2304 result = fn(*args, **kwargs)
2306 2305 return result
2307 2306
2308 2307 def get_local_scope(self, stack_depth):
2309 2308 """Get local scope at given stack depth.
2310 2309
2311 2310 Parameters
2312 2311 ----------
2313 2312 stack_depth : int
2314 2313 Depth relative to calling frame
2315 2314 """
2316 2315 return sys._getframe(stack_depth + 1).f_locals
2317 2316
2318 2317 def run_cell_magic(self, magic_name, line, cell):
2319 2318 """Execute the given cell magic.
2320 2319
2321 2320 Parameters
2322 2321 ----------
2323 2322 magic_name : str
2324 2323 Name of the desired magic function, without '%' prefix.
2325 2324 line : str
2326 2325 The rest of the first input line as a single string.
2327 2326 cell : str
2328 2327 The body of the cell as a (possibly multiline) string.
2329 2328 """
2330 2329 fn = self._find_with_lazy_load("cell", magic_name)
2331 2330 if fn is None:
2332 2331 lm = self.find_line_magic(magic_name)
2333 2332 etpl = "Cell magic `%%{0}` not found{1}."
2334 2333 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2335 2334 'did you mean that instead?)'.format(magic_name))
2336 2335 raise UsageError(etpl.format(magic_name, extra))
2337 2336 elif cell == '':
2338 2337 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2339 2338 if self.find_line_magic(magic_name) is not None:
2340 2339 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2341 2340 raise UsageError(message)
2342 2341 else:
2343 2342 # Note: this is the distance in the stack to the user's frame.
2344 2343 # This will need to be updated if the internal calling logic gets
2345 2344 # refactored, or else we'll be expanding the wrong variables.
2346 2345 stack_depth = 2
2347 2346 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2348 2347 # magic has opted out of var_expand
2349 2348 magic_arg_s = line
2350 2349 else:
2351 2350 magic_arg_s = self.var_expand(line, stack_depth)
2352 2351 kwargs = {}
2353 2352 if getattr(fn, "needs_local_scope", False):
2354 2353 kwargs['local_ns'] = self.user_ns
2355 2354
2356 2355 with self.builtin_trap:
2357 2356 args = (magic_arg_s, cell)
2358 2357 result = fn(*args, **kwargs)
2359 2358 return result
2360 2359
2361 2360 def find_line_magic(self, magic_name):
2362 2361 """Find and return a line magic by name.
2363 2362
2364 2363 Returns None if the magic isn't found."""
2365 2364 return self.magics_manager.magics['line'].get(magic_name)
2366 2365
2367 2366 def find_cell_magic(self, magic_name):
2368 2367 """Find and return a cell magic by name.
2369 2368
2370 2369 Returns None if the magic isn't found."""
2371 2370 return self.magics_manager.magics['cell'].get(magic_name)
2372 2371
2373 2372 def find_magic(self, magic_name, magic_kind='line'):
2374 2373 """Find and return a magic of the given type by name.
2375 2374
2376 2375 Returns None if the magic isn't found."""
2377 2376 return self.magics_manager.magics[magic_kind].get(magic_name)
2378 2377
2379 2378 def magic(self, arg_s):
2380 2379 """
2381 2380 DEPRECATED
2382 2381
2383 2382 Deprecated since IPython 0.13 (warning added in
2384 2383 8.1), use run_line_magic(magic_name, parameter_s).
2385 2384
2386 2385 Call a magic function by name.
2387 2386
2388 2387 Input: a string containing the name of the magic function to call and
2389 2388 any additional arguments to be passed to the magic.
2390 2389
2391 2390 magic('name -opt foo bar') is equivalent to typing at the ipython
2392 2391 prompt:
2393 2392
2394 2393 In[1]: %name -opt foo bar
2395 2394
2396 2395 To call a magic without arguments, simply use magic('name').
2397 2396
2398 2397 This provides a proper Python function to call IPython's magics in any
2399 2398 valid Python code you can type at the interpreter, including loops and
2400 2399 compound statements.
2401 2400 """
2402 2401 warnings.warn(
2403 2402 "`magic(...)` is deprecated since IPython 0.13 (warning added in "
2404 2403 "8.1), use run_line_magic(magic_name, parameter_s).",
2405 2404 DeprecationWarning,
2406 2405 stacklevel=2,
2407 2406 )
2408 2407 # TODO: should we issue a loud deprecation warning here?
2409 2408 magic_name, _, magic_arg_s = arg_s.partition(' ')
2410 2409 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2411 2410 return self.run_line_magic(magic_name, magic_arg_s, _stack_depth=2)
2412 2411
2413 2412 #-------------------------------------------------------------------------
2414 2413 # Things related to macros
2415 2414 #-------------------------------------------------------------------------
2416 2415
2417 2416 def define_macro(self, name, themacro):
2418 2417 """Define a new macro
2419 2418
2420 2419 Parameters
2421 2420 ----------
2422 2421 name : str
2423 2422 The name of the macro.
2424 2423 themacro : str or Macro
2425 2424 The action to do upon invoking the macro. If a string, a new
2426 2425 Macro object is created by passing the string to it.
2427 2426 """
2428 2427
2429 2428 from IPython.core import macro
2430 2429
2431 2430 if isinstance(themacro, str):
2432 2431 themacro = macro.Macro(themacro)
2433 2432 if not isinstance(themacro, macro.Macro):
2434 2433 raise ValueError('A macro must be a string or a Macro instance.')
2435 2434 self.user_ns[name] = themacro
2436 2435
2437 2436 #-------------------------------------------------------------------------
2438 2437 # Things related to the running of system commands
2439 2438 #-------------------------------------------------------------------------
2440 2439
2441 2440 def system_piped(self, cmd):
2442 2441 """Call the given cmd in a subprocess, piping stdout/err
2443 2442
2444 2443 Parameters
2445 2444 ----------
2446 2445 cmd : str
2447 2446 Command to execute (can not end in '&', as background processes are
2448 2447 not supported. Should not be a command that expects input
2449 2448 other than simple text.
2450 2449 """
2451 2450 if cmd.rstrip().endswith('&'):
2452 2451 # this is *far* from a rigorous test
2453 2452 # We do not support backgrounding processes because we either use
2454 2453 # pexpect or pipes to read from. Users can always just call
2455 2454 # os.system() or use ip.system=ip.system_raw
2456 2455 # if they really want a background process.
2457 2456 raise OSError("Background processes not supported.")
2458 2457
2459 2458 # we explicitly do NOT return the subprocess status code, because
2460 2459 # a non-None value would trigger :func:`sys.displayhook` calls.
2461 2460 # Instead, we store the exit_code in user_ns.
2462 2461 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2463 2462
2464 2463 def system_raw(self, cmd):
2465 2464 """Call the given cmd in a subprocess using os.system on Windows or
2466 2465 subprocess.call using the system shell on other platforms.
2467 2466
2468 2467 Parameters
2469 2468 ----------
2470 2469 cmd : str
2471 2470 Command to execute.
2472 2471 """
2473 2472 cmd = self.var_expand(cmd, depth=1)
2474 2473 # warn if there is an IPython magic alternative.
2475 2474 main_cmd = cmd.split()[0]
2476 2475 has_magic_alternatives = ("pip", "conda", "cd")
2477 2476
2478 2477 if main_cmd in has_magic_alternatives:
2479 2478 warnings.warn(
2480 2479 (
2481 2480 "You executed the system command !{0} which may not work "
2482 2481 "as expected. Try the IPython magic %{0} instead."
2483 2482 ).format(main_cmd)
2484 2483 )
2485 2484
2486 2485 # protect os.system from UNC paths on Windows, which it can't handle:
2487 2486 if sys.platform == 'win32':
2488 2487 from IPython.utils._process_win32 import AvoidUNCPath
2489 2488 with AvoidUNCPath() as path:
2490 2489 if path is not None:
2491 2490 cmd = '"pushd %s &&"%s' % (path, cmd)
2492 2491 try:
2493 2492 ec = os.system(cmd)
2494 2493 except KeyboardInterrupt:
2495 2494 print('\n' + self.get_exception_only(), file=sys.stderr)
2496 2495 ec = -2
2497 2496 else:
2498 2497 # For posix the result of the subprocess.call() below is an exit
2499 2498 # code, which by convention is zero for success, positive for
2500 2499 # program failure. Exit codes above 128 are reserved for signals,
2501 2500 # and the formula for converting a signal to an exit code is usually
2502 2501 # signal_number+128. To more easily differentiate between exit
2503 2502 # codes and signals, ipython uses negative numbers. For instance
2504 2503 # since control-c is signal 2 but exit code 130, ipython's
2505 2504 # _exit_code variable will read -2. Note that some shells like
2506 2505 # csh and fish don't follow sh/bash conventions for exit codes.
2507 2506 executable = os.environ.get('SHELL', None)
2508 2507 try:
2509 2508 # Use env shell instead of default /bin/sh
2510 2509 ec = subprocess.call(cmd, shell=True, executable=executable)
2511 2510 except KeyboardInterrupt:
2512 2511 # intercept control-C; a long traceback is not useful here
2513 2512 print('\n' + self.get_exception_only(), file=sys.stderr)
2514 2513 ec = 130
2515 2514 if ec > 128:
2516 2515 ec = -(ec - 128)
2517 2516
2518 2517 # We explicitly do NOT return the subprocess status code, because
2519 2518 # a non-None value would trigger :func:`sys.displayhook` calls.
2520 2519 # Instead, we store the exit_code in user_ns. Note the semantics
2521 2520 # of _exit_code: for control-c, _exit_code == -signal.SIGNIT,
2522 2521 # but raising SystemExit(_exit_code) will give status 254!
2523 2522 self.user_ns['_exit_code'] = ec
2524 2523
2525 2524 # use piped system by default, because it is better behaved
2526 2525 system = system_piped
2527 2526
2528 2527 def getoutput(self, cmd, split=True, depth=0):
2529 2528 """Get output (possibly including stderr) from a subprocess.
2530 2529
2531 2530 Parameters
2532 2531 ----------
2533 2532 cmd : str
2534 2533 Command to execute (can not end in '&', as background processes are
2535 2534 not supported.
2536 2535 split : bool, optional
2537 2536 If True, split the output into an IPython SList. Otherwise, an
2538 2537 IPython LSString is returned. These are objects similar to normal
2539 2538 lists and strings, with a few convenience attributes for easier
2540 2539 manipulation of line-based output. You can use '?' on them for
2541 2540 details.
2542 2541 depth : int, optional
2543 2542 How many frames above the caller are the local variables which should
2544 2543 be expanded in the command string? The default (0) assumes that the
2545 2544 expansion variables are in the stack frame calling this function.
2546 2545 """
2547 2546 if cmd.rstrip().endswith('&'):
2548 2547 # this is *far* from a rigorous test
2549 2548 raise OSError("Background processes not supported.")
2550 2549 out = getoutput(self.var_expand(cmd, depth=depth+1))
2551 2550 if split:
2552 2551 out = SList(out.splitlines())
2553 2552 else:
2554 2553 out = LSString(out)
2555 2554 return out
2556 2555
2557 2556 #-------------------------------------------------------------------------
2558 2557 # Things related to aliases
2559 2558 #-------------------------------------------------------------------------
2560 2559
2561 2560 def init_alias(self):
2562 2561 self.alias_manager = AliasManager(shell=self, parent=self)
2563 2562 self.configurables.append(self.alias_manager)
2564 2563
2565 2564 #-------------------------------------------------------------------------
2566 2565 # Things related to extensions
2567 2566 #-------------------------------------------------------------------------
2568 2567
2569 2568 def init_extension_manager(self):
2570 2569 self.extension_manager = ExtensionManager(shell=self, parent=self)
2571 2570 self.configurables.append(self.extension_manager)
2572 2571
2573 2572 #-------------------------------------------------------------------------
2574 2573 # Things related to payloads
2575 2574 #-------------------------------------------------------------------------
2576 2575
2577 2576 def init_payload(self):
2578 2577 self.payload_manager = PayloadManager(parent=self)
2579 2578 self.configurables.append(self.payload_manager)
2580 2579
2581 2580 #-------------------------------------------------------------------------
2582 2581 # Things related to the prefilter
2583 2582 #-------------------------------------------------------------------------
2584 2583
2585 2584 def init_prefilter(self):
2586 2585 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2587 2586 self.configurables.append(self.prefilter_manager)
2588 2587 # Ultimately this will be refactored in the new interpreter code, but
2589 2588 # for now, we should expose the main prefilter method (there's legacy
2590 2589 # code out there that may rely on this).
2591 2590 self.prefilter = self.prefilter_manager.prefilter_lines
2592 2591
2593 2592 def auto_rewrite_input(self, cmd):
2594 2593 """Print to the screen the rewritten form of the user's command.
2595 2594
2596 2595 This shows visual feedback by rewriting input lines that cause
2597 2596 automatic calling to kick in, like::
2598 2597
2599 2598 /f x
2600 2599
2601 2600 into::
2602 2601
2603 2602 ------> f(x)
2604 2603
2605 2604 after the user's input prompt. This helps the user understand that the
2606 2605 input line was transformed automatically by IPython.
2607 2606 """
2608 2607 if not self.show_rewritten_input:
2609 2608 return
2610 2609
2611 2610 # This is overridden in TerminalInteractiveShell to use fancy prompts
2612 2611 print("------> " + cmd)
2613 2612
2614 2613 #-------------------------------------------------------------------------
2615 2614 # Things related to extracting values/expressions from kernel and user_ns
2616 2615 #-------------------------------------------------------------------------
2617 2616
2618 2617 def _user_obj_error(self):
2619 2618 """return simple exception dict
2620 2619
2621 2620 for use in user_expressions
2622 2621 """
2623 2622
2624 2623 etype, evalue, tb = self._get_exc_info()
2625 2624 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2626 2625
2627 2626 exc_info = {
2628 2627 "status": "error",
2629 2628 "traceback": stb,
2630 2629 "ename": etype.__name__,
2631 2630 "evalue": py3compat.safe_unicode(evalue),
2632 2631 }
2633 2632
2634 2633 return exc_info
2635 2634
2636 2635 def _format_user_obj(self, obj):
2637 2636 """format a user object to display dict
2638 2637
2639 2638 for use in user_expressions
2640 2639 """
2641 2640
2642 2641 data, md = self.display_formatter.format(obj)
2643 2642 value = {
2644 2643 'status' : 'ok',
2645 2644 'data' : data,
2646 2645 'metadata' : md,
2647 2646 }
2648 2647 return value
2649 2648
2650 2649 def user_expressions(self, expressions):
2651 2650 """Evaluate a dict of expressions in the user's namespace.
2652 2651
2653 2652 Parameters
2654 2653 ----------
2655 2654 expressions : dict
2656 2655 A dict with string keys and string values. The expression values
2657 2656 should be valid Python expressions, each of which will be evaluated
2658 2657 in the user namespace.
2659 2658
2660 2659 Returns
2661 2660 -------
2662 2661 A dict, keyed like the input expressions dict, with the rich mime-typed
2663 2662 display_data of each value.
2664 2663 """
2665 2664 out = {}
2666 2665 user_ns = self.user_ns
2667 2666 global_ns = self.user_global_ns
2668 2667
2669 2668 for key, expr in expressions.items():
2670 2669 try:
2671 2670 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2672 2671 except:
2673 2672 value = self._user_obj_error()
2674 2673 out[key] = value
2675 2674 return out
2676 2675
2677 2676 #-------------------------------------------------------------------------
2678 2677 # Things related to the running of code
2679 2678 #-------------------------------------------------------------------------
2680 2679
2681 2680 def ex(self, cmd):
2682 2681 """Execute a normal python statement in user namespace."""
2683 2682 with self.builtin_trap:
2684 2683 exec(cmd, self.user_global_ns, self.user_ns)
2685 2684
2686 2685 def ev(self, expr):
2687 2686 """Evaluate python expression expr in user namespace.
2688 2687
2689 2688 Returns the result of evaluation
2690 2689 """
2691 2690 with self.builtin_trap:
2692 2691 return eval(expr, self.user_global_ns, self.user_ns)
2693 2692
2694 2693 def safe_execfile(self, fname, *where, exit_ignore=False, raise_exceptions=False, shell_futures=False):
2695 2694 """A safe version of the builtin execfile().
2696 2695
2697 2696 This version will never throw an exception, but instead print
2698 2697 helpful error messages to the screen. This only works on pure
2699 2698 Python files with the .py extension.
2700 2699
2701 2700 Parameters
2702 2701 ----------
2703 2702 fname : string
2704 2703 The name of the file to be executed.
2705 2704 *where : tuple
2706 2705 One or two namespaces, passed to execfile() as (globals,locals).
2707 2706 If only one is given, it is passed as both.
2708 2707 exit_ignore : bool (False)
2709 2708 If True, then silence SystemExit for non-zero status (it is always
2710 2709 silenced for zero status, as it is so common).
2711 2710 raise_exceptions : bool (False)
2712 2711 If True raise exceptions everywhere. Meant for testing.
2713 2712 shell_futures : bool (False)
2714 2713 If True, the code will share future statements with the interactive
2715 2714 shell. It will both be affected by previous __future__ imports, and
2716 2715 any __future__ imports in the code will affect the shell. If False,
2717 2716 __future__ imports are not shared in either direction.
2718 2717
2719 2718 """
2720 2719 fname = Path(fname).expanduser().resolve()
2721 2720
2722 2721 # Make sure we can open the file
2723 2722 try:
2724 2723 with fname.open("rb"):
2725 2724 pass
2726 2725 except:
2727 2726 warn('Could not open file <%s> for safe execution.' % fname)
2728 2727 return
2729 2728
2730 2729 # Find things also in current directory. This is needed to mimic the
2731 2730 # behavior of running a script from the system command line, where
2732 2731 # Python inserts the script's directory into sys.path
2733 2732 dname = str(fname.parent)
2734 2733
2735 2734 with prepended_to_syspath(dname), self.builtin_trap:
2736 2735 try:
2737 2736 glob, loc = (where + (None, ))[:2]
2738 2737 py3compat.execfile(
2739 2738 fname, glob, loc,
2740 2739 self.compile if shell_futures else None)
2741 2740 except SystemExit as status:
2742 2741 # If the call was made with 0 or None exit status (sys.exit(0)
2743 2742 # or sys.exit() ), don't bother showing a traceback, as both of
2744 2743 # these are considered normal by the OS:
2745 2744 # > python -c'import sys;sys.exit(0)'; echo $?
2746 2745 # 0
2747 2746 # > python -c'import sys;sys.exit()'; echo $?
2748 2747 # 0
2749 2748 # For other exit status, we show the exception unless
2750 2749 # explicitly silenced, but only in short form.
2751 2750 if status.code:
2752 2751 if raise_exceptions:
2753 2752 raise
2754 2753 if not exit_ignore:
2755 2754 self.showtraceback(exception_only=True)
2756 2755 except:
2757 2756 if raise_exceptions:
2758 2757 raise
2759 2758 # tb offset is 2 because we wrap execfile
2760 2759 self.showtraceback(tb_offset=2)
2761 2760
2762 2761 def safe_execfile_ipy(self, fname, shell_futures=False, raise_exceptions=False):
2763 2762 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2764 2763
2765 2764 Parameters
2766 2765 ----------
2767 2766 fname : str
2768 2767 The name of the file to execute. The filename must have a
2769 2768 .ipy or .ipynb extension.
2770 2769 shell_futures : bool (False)
2771 2770 If True, the code will share future statements with the interactive
2772 2771 shell. It will both be affected by previous __future__ imports, and
2773 2772 any __future__ imports in the code will affect the shell. If False,
2774 2773 __future__ imports are not shared in either direction.
2775 2774 raise_exceptions : bool (False)
2776 2775 If True raise exceptions everywhere. Meant for testing.
2777 2776 """
2778 2777 fname = Path(fname).expanduser().resolve()
2779 2778
2780 2779 # Make sure we can open the file
2781 2780 try:
2782 2781 with fname.open("rb"):
2783 2782 pass
2784 2783 except:
2785 2784 warn('Could not open file <%s> for safe execution.' % fname)
2786 2785 return
2787 2786
2788 2787 # Find things also in current directory. This is needed to mimic the
2789 2788 # behavior of running a script from the system command line, where
2790 2789 # Python inserts the script's directory into sys.path
2791 2790 dname = str(fname.parent)
2792 2791
2793 2792 def get_cells():
2794 2793 """generator for sequence of code blocks to run"""
2795 2794 if fname.suffix == ".ipynb":
2796 2795 from nbformat import read
2797 2796 nb = read(fname, as_version=4)
2798 2797 if not nb.cells:
2799 2798 return
2800 2799 for cell in nb.cells:
2801 2800 if cell.cell_type == 'code':
2802 2801 yield cell.source
2803 2802 else:
2804 2803 yield fname.read_text(encoding="utf-8")
2805 2804
2806 2805 with prepended_to_syspath(dname):
2807 2806 try:
2808 2807 for cell in get_cells():
2809 2808 result = self.run_cell(cell, silent=True, shell_futures=shell_futures)
2810 2809 if raise_exceptions:
2811 2810 result.raise_error()
2812 2811 elif not result.success:
2813 2812 break
2814 2813 except:
2815 2814 if raise_exceptions:
2816 2815 raise
2817 2816 self.showtraceback()
2818 2817 warn('Unknown failure executing file: <%s>' % fname)
2819 2818
2820 2819 def safe_run_module(self, mod_name, where):
2821 2820 """A safe version of runpy.run_module().
2822 2821
2823 2822 This version will never throw an exception, but instead print
2824 2823 helpful error messages to the screen.
2825 2824
2826 2825 `SystemExit` exceptions with status code 0 or None are ignored.
2827 2826
2828 2827 Parameters
2829 2828 ----------
2830 2829 mod_name : string
2831 2830 The name of the module to be executed.
2832 2831 where : dict
2833 2832 The globals namespace.
2834 2833 """
2835 2834 try:
2836 2835 try:
2837 2836 where.update(
2838 2837 runpy.run_module(str(mod_name), run_name="__main__",
2839 2838 alter_sys=True)
2840 2839 )
2841 2840 except SystemExit as status:
2842 2841 if status.code:
2843 2842 raise
2844 2843 except:
2845 2844 self.showtraceback()
2846 2845 warn('Unknown failure executing module: <%s>' % mod_name)
2847 2846
2848 2847 def run_cell(
2849 2848 self,
2850 2849 raw_cell,
2851 2850 store_history=False,
2852 2851 silent=False,
2853 2852 shell_futures=True,
2854 2853 cell_id=None,
2855 2854 ):
2856 2855 """Run a complete IPython cell.
2857 2856
2858 2857 Parameters
2859 2858 ----------
2860 2859 raw_cell : str
2861 2860 The code (including IPython code such as %magic functions) to run.
2862 2861 store_history : bool
2863 2862 If True, the raw and translated cell will be stored in IPython's
2864 2863 history. For user code calling back into IPython's machinery, this
2865 2864 should be set to False.
2866 2865 silent : bool
2867 2866 If True, avoid side-effects, such as implicit displayhooks and
2868 2867 and logging. silent=True forces store_history=False.
2869 2868 shell_futures : bool
2870 2869 If True, the code will share future statements with the interactive
2871 2870 shell. It will both be affected by previous __future__ imports, and
2872 2871 any __future__ imports in the code will affect the shell. If False,
2873 2872 __future__ imports are not shared in either direction.
2874 2873
2875 2874 Returns
2876 2875 -------
2877 2876 result : :class:`ExecutionResult`
2878 2877 """
2879 2878 result = None
2880 2879 try:
2881 2880 result = self._run_cell(
2882 2881 raw_cell, store_history, silent, shell_futures, cell_id
2883 2882 )
2884 2883 finally:
2885 2884 self.events.trigger('post_execute')
2886 2885 if not silent:
2887 2886 self.events.trigger('post_run_cell', result)
2888 2887 return result
2889 2888
2890 2889 def _run_cell(
2891 2890 self,
2892 2891 raw_cell: str,
2893 2892 store_history: bool,
2894 2893 silent: bool,
2895 2894 shell_futures: bool,
2896 2895 cell_id: str,
2897 2896 ) -> ExecutionResult:
2898 2897 """Internal method to run a complete IPython cell."""
2899 2898
2900 2899 # we need to avoid calling self.transform_cell multiple time on the same thing
2901 2900 # so we need to store some results:
2902 2901 preprocessing_exc_tuple = None
2903 2902 try:
2904 2903 transformed_cell = self.transform_cell(raw_cell)
2905 2904 except Exception:
2906 2905 transformed_cell = raw_cell
2907 2906 preprocessing_exc_tuple = sys.exc_info()
2908 2907
2909 2908 assert transformed_cell is not None
2910 2909 coro = self.run_cell_async(
2911 2910 raw_cell,
2912 2911 store_history=store_history,
2913 2912 silent=silent,
2914 2913 shell_futures=shell_futures,
2915 2914 transformed_cell=transformed_cell,
2916 2915 preprocessing_exc_tuple=preprocessing_exc_tuple,
2917 2916 cell_id=cell_id,
2918 2917 )
2919 2918
2920 2919 # run_cell_async is async, but may not actually need an eventloop.
2921 2920 # when this is the case, we want to run it using the pseudo_sync_runner
2922 2921 # so that code can invoke eventloops (for example via the %run , and
2923 2922 # `%paste` magic.
2924 2923 if self.trio_runner:
2925 2924 runner = self.trio_runner
2926 2925 elif self.should_run_async(
2927 2926 raw_cell,
2928 2927 transformed_cell=transformed_cell,
2929 2928 preprocessing_exc_tuple=preprocessing_exc_tuple,
2930 2929 ):
2931 2930 runner = self.loop_runner
2932 2931 else:
2933 2932 runner = _pseudo_sync_runner
2934 2933
2935 2934 try:
2936 2935 return runner(coro)
2937 2936 except BaseException as e:
2938 2937 info = ExecutionInfo(
2939 2938 raw_cell, store_history, silent, shell_futures, cell_id
2940 2939 )
2941 2940 result = ExecutionResult(info)
2942 2941 result.error_in_exec = e
2943 2942 self.showtraceback(running_compiled_code=True)
2944 2943 return result
2945 2944
2946 2945 def should_run_async(
2947 2946 self, raw_cell: str, *, transformed_cell=None, preprocessing_exc_tuple=None
2948 2947 ) -> bool:
2949 2948 """Return whether a cell should be run asynchronously via a coroutine runner
2950 2949
2951 2950 Parameters
2952 2951 ----------
2953 2952 raw_cell : str
2954 2953 The code to be executed
2955 2954
2956 2955 Returns
2957 2956 -------
2958 2957 result: bool
2959 2958 Whether the code needs to be run with a coroutine runner or not
2960 2959 .. versionadded:: 7.0
2961 2960 """
2962 2961 if not self.autoawait:
2963 2962 return False
2964 2963 if preprocessing_exc_tuple is not None:
2965 2964 return False
2966 2965 assert preprocessing_exc_tuple is None
2967 2966 if transformed_cell is None:
2968 2967 warnings.warn(
2969 2968 "`should_run_async` will not call `transform_cell`"
2970 2969 " automatically in the future. Please pass the result to"
2971 2970 " `transformed_cell` argument and any exception that happen"
2972 2971 " during the"
2973 2972 "transform in `preprocessing_exc_tuple` in"
2974 2973 " IPython 7.17 and above.",
2975 2974 DeprecationWarning,
2976 2975 stacklevel=2,
2977 2976 )
2978 2977 try:
2979 2978 cell = self.transform_cell(raw_cell)
2980 2979 except Exception:
2981 2980 # any exception during transform will be raised
2982 2981 # prior to execution
2983 2982 return False
2984 2983 else:
2985 2984 cell = transformed_cell
2986 2985 return _should_be_async(cell)
2987 2986
2988 2987 async def run_cell_async(
2989 2988 self,
2990 2989 raw_cell: str,
2991 2990 store_history=False,
2992 2991 silent=False,
2993 2992 shell_futures=True,
2994 2993 *,
2995 2994 transformed_cell: Optional[str] = None,
2996 2995 preprocessing_exc_tuple: Optional[Any] = None,
2997 2996 cell_id=None,
2998 2997 ) -> ExecutionResult:
2999 2998 """Run a complete IPython cell asynchronously.
3000 2999
3001 3000 Parameters
3002 3001 ----------
3003 3002 raw_cell : str
3004 3003 The code (including IPython code such as %magic functions) to run.
3005 3004 store_history : bool
3006 3005 If True, the raw and translated cell will be stored in IPython's
3007 3006 history. For user code calling back into IPython's machinery, this
3008 3007 should be set to False.
3009 3008 silent : bool
3010 3009 If True, avoid side-effects, such as implicit displayhooks and
3011 3010 and logging. silent=True forces store_history=False.
3012 3011 shell_futures : bool
3013 3012 If True, the code will share future statements with the interactive
3014 3013 shell. It will both be affected by previous __future__ imports, and
3015 3014 any __future__ imports in the code will affect the shell. If False,
3016 3015 __future__ imports are not shared in either direction.
3017 3016 transformed_cell: str
3018 3017 cell that was passed through transformers
3019 3018 preprocessing_exc_tuple:
3020 3019 trace if the transformation failed.
3021 3020
3022 3021 Returns
3023 3022 -------
3024 3023 result : :class:`ExecutionResult`
3025 3024
3026 3025 .. versionadded:: 7.0
3027 3026 """
3028 3027 info = ExecutionInfo(raw_cell, store_history, silent, shell_futures, cell_id)
3029 3028 result = ExecutionResult(info)
3030 3029
3031 3030 if (not raw_cell) or raw_cell.isspace():
3032 3031 self.last_execution_succeeded = True
3033 3032 self.last_execution_result = result
3034 3033 return result
3035 3034
3036 3035 if silent:
3037 3036 store_history = False
3038 3037
3039 3038 if store_history:
3040 3039 result.execution_count = self.execution_count
3041 3040
3042 3041 def error_before_exec(value):
3043 3042 if store_history:
3044 3043 self.execution_count += 1
3045 3044 result.error_before_exec = value
3046 3045 self.last_execution_succeeded = False
3047 3046 self.last_execution_result = result
3048 3047 return result
3049 3048
3050 3049 self.events.trigger('pre_execute')
3051 3050 if not silent:
3052 3051 self.events.trigger('pre_run_cell', info)
3053 3052
3054 3053 if transformed_cell is None:
3055 3054 warnings.warn(
3056 3055 "`run_cell_async` will not call `transform_cell`"
3057 3056 " automatically in the future. Please pass the result to"
3058 3057 " `transformed_cell` argument and any exception that happen"
3059 3058 " during the"
3060 3059 "transform in `preprocessing_exc_tuple` in"
3061 3060 " IPython 7.17 and above.",
3062 3061 DeprecationWarning,
3063 3062 stacklevel=2,
3064 3063 )
3065 3064 # If any of our input transformation (input_transformer_manager or
3066 3065 # prefilter_manager) raises an exception, we store it in this variable
3067 3066 # so that we can display the error after logging the input and storing
3068 3067 # it in the history.
3069 3068 try:
3070 3069 cell = self.transform_cell(raw_cell)
3071 3070 except Exception:
3072 3071 preprocessing_exc_tuple = sys.exc_info()
3073 3072 cell = raw_cell # cell has to exist so it can be stored/logged
3074 3073 else:
3075 3074 preprocessing_exc_tuple = None
3076 3075 else:
3077 3076 if preprocessing_exc_tuple is None:
3078 3077 cell = transformed_cell
3079 3078 else:
3080 3079 cell = raw_cell
3081 3080
3082 3081 # Store raw and processed history
3083 3082 if store_history and raw_cell.strip(" %") != "paste":
3084 3083 self.history_manager.store_inputs(self.execution_count, cell, raw_cell)
3085 3084 if not silent:
3086 3085 self.logger.log(cell, raw_cell)
3087 3086
3088 3087 # Display the exception if input processing failed.
3089 3088 if preprocessing_exc_tuple is not None:
3090 3089 self.showtraceback(preprocessing_exc_tuple)
3091 3090 if store_history:
3092 3091 self.execution_count += 1
3093 3092 return error_before_exec(preprocessing_exc_tuple[1])
3094 3093
3095 3094 # Our own compiler remembers the __future__ environment. If we want to
3096 3095 # run code with a separate __future__ environment, use the default
3097 3096 # compiler
3098 3097 compiler = self.compile if shell_futures else self.compiler_class()
3099 3098
3100 3099 _run_async = False
3101 3100
3102 3101 with self.builtin_trap:
3103 3102 cell_name = compiler.cache(cell, self.execution_count, raw_code=raw_cell)
3104 3103
3105 3104 with self.display_trap:
3106 3105 # Compile to bytecode
3107 3106 try:
3108 3107 code_ast = compiler.ast_parse(cell, filename=cell_name)
3109 3108 except self.custom_exceptions as e:
3110 3109 etype, value, tb = sys.exc_info()
3111 3110 self.CustomTB(etype, value, tb)
3112 3111 return error_before_exec(e)
3113 3112 except IndentationError as e:
3114 3113 self.showindentationerror()
3115 3114 return error_before_exec(e)
3116 3115 except (OverflowError, SyntaxError, ValueError, TypeError,
3117 3116 MemoryError) as e:
3118 3117 self.showsyntaxerror()
3119 3118 return error_before_exec(e)
3120 3119
3121 3120 # Apply AST transformations
3122 3121 try:
3123 3122 code_ast = self.transform_ast(code_ast)
3124 3123 except InputRejected as e:
3125 3124 self.showtraceback()
3126 3125 return error_before_exec(e)
3127 3126
3128 3127 # Give the displayhook a reference to our ExecutionResult so it
3129 3128 # can fill in the output value.
3130 3129 self.displayhook.exec_result = result
3131 3130
3132 3131 # Execute the user code
3133 3132 interactivity = "none" if silent else self.ast_node_interactivity
3134 3133
3135 3134 has_raised = await self.run_ast_nodes(code_ast.body, cell_name,
3136 3135 interactivity=interactivity, compiler=compiler, result=result)
3137 3136
3138 3137 self.last_execution_succeeded = not has_raised
3139 3138 self.last_execution_result = result
3140 3139
3141 3140 # Reset this so later displayed values do not modify the
3142 3141 # ExecutionResult
3143 3142 self.displayhook.exec_result = None
3144 3143
3145 3144 if store_history:
3146 3145 # Write output to the database. Does nothing unless
3147 3146 # history output logging is enabled.
3148 3147 self.history_manager.store_output(self.execution_count)
3149 3148 # Each cell is a *single* input, regardless of how many lines it has
3150 3149 self.execution_count += 1
3151 3150
3152 3151 return result
3153 3152
3154 3153 def transform_cell(self, raw_cell):
3155 3154 """Transform an input cell before parsing it.
3156 3155
3157 3156 Static transformations, implemented in IPython.core.inputtransformer2,
3158 3157 deal with things like ``%magic`` and ``!system`` commands.
3159 3158 These run on all input.
3160 3159 Dynamic transformations, for things like unescaped magics and the exit
3161 3160 autocall, depend on the state of the interpreter.
3162 3161 These only apply to single line inputs.
3163 3162
3164 3163 These string-based transformations are followed by AST transformations;
3165 3164 see :meth:`transform_ast`.
3166 3165 """
3167 3166 # Static input transformations
3168 3167 cell = self.input_transformer_manager.transform_cell(raw_cell)
3169 3168
3170 3169 if len(cell.splitlines()) == 1:
3171 3170 # Dynamic transformations - only applied for single line commands
3172 3171 with self.builtin_trap:
3173 3172 # use prefilter_lines to handle trailing newlines
3174 3173 # restore trailing newline for ast.parse
3175 3174 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
3176 3175
3177 3176 lines = cell.splitlines(keepends=True)
3178 3177 for transform in self.input_transformers_post:
3179 3178 lines = transform(lines)
3180 3179 cell = ''.join(lines)
3181 3180
3182 3181 return cell
3183 3182
3184 3183 def transform_ast(self, node):
3185 3184 """Apply the AST transformations from self.ast_transformers
3186 3185
3187 3186 Parameters
3188 3187 ----------
3189 3188 node : ast.Node
3190 3189 The root node to be transformed. Typically called with the ast.Module
3191 3190 produced by parsing user input.
3192 3191
3193 3192 Returns
3194 3193 -------
3195 3194 An ast.Node corresponding to the node it was called with. Note that it
3196 3195 may also modify the passed object, so don't rely on references to the
3197 3196 original AST.
3198 3197 """
3199 3198 for transformer in self.ast_transformers:
3200 3199 try:
3201 3200 node = transformer.visit(node)
3202 3201 except InputRejected:
3203 3202 # User-supplied AST transformers can reject an input by raising
3204 3203 # an InputRejected. Short-circuit in this case so that we
3205 3204 # don't unregister the transform.
3206 3205 raise
3207 3206 except Exception:
3208 3207 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
3209 3208 self.ast_transformers.remove(transformer)
3210 3209
3211 3210 if self.ast_transformers:
3212 3211 ast.fix_missing_locations(node)
3213 3212 return node
3214 3213
3215 def _update_code_co_name(self, code):
3216 """Python 3.10 changed the behaviour so that whenever a code object
3217 is assembled in the compile(ast) the co_firstlineno would be == 1.
3218
3219 This makes pydevd/debugpy think that all cells invoked are the same
3220 since it caches information based on (co_firstlineno, co_name, co_filename).
3221
3222 Given that, this function changes the code 'co_name' to be unique
3223 based on the first real lineno of the code (which also has a nice
3224 side effect of customizing the name so that it's not always <module>).
3225
3226 See: https://github.com/ipython/ipykernel/issues/841
3227 """
3228 if not hasattr(code, "replace"):
3229 # It may not be available on older versions of Python (only
3230 # available for 3.8 onwards).
3231 return code
3232 try:
3233 first_real_line = next(dis.findlinestarts(code))[1]
3234 except StopIteration:
3235 return code
3236 return code.replace(co_name="<cell line: %s>" % (first_real_line,))
3237
3238 3214 async def run_ast_nodes(
3239 3215 self,
3240 3216 nodelist: ListType[stmt],
3241 3217 cell_name: str,
3242 3218 interactivity="last_expr",
3243 3219 compiler=compile,
3244 3220 result=None,
3245 3221 ):
3246 3222 """Run a sequence of AST nodes. The execution mode depends on the
3247 3223 interactivity parameter.
3248 3224
3249 3225 Parameters
3250 3226 ----------
3251 3227 nodelist : list
3252 3228 A sequence of AST nodes to run.
3253 3229 cell_name : str
3254 3230 Will be passed to the compiler as the filename of the cell. Typically
3255 3231 the value returned by ip.compile.cache(cell).
3256 3232 interactivity : str
3257 3233 'all', 'last', 'last_expr' , 'last_expr_or_assign' or 'none',
3258 3234 specifying which nodes should be run interactively (displaying output
3259 3235 from expressions). 'last_expr' will run the last node interactively
3260 3236 only if it is an expression (i.e. expressions in loops or other blocks
3261 3237 are not displayed) 'last_expr_or_assign' will run the last expression
3262 3238 or the last assignment. Other values for this parameter will raise a
3263 3239 ValueError.
3264 3240
3265 3241 compiler : callable
3266 3242 A function with the same interface as the built-in compile(), to turn
3267 3243 the AST nodes into code objects. Default is the built-in compile().
3268 3244 result : ExecutionResult, optional
3269 3245 An object to store exceptions that occur during execution.
3270 3246
3271 3247 Returns
3272 3248 -------
3273 3249 True if an exception occurred while running code, False if it finished
3274 3250 running.
3275 3251 """
3276 3252 if not nodelist:
3277 3253 return
3278 3254
3279 3255
3280 3256 if interactivity == 'last_expr_or_assign':
3281 3257 if isinstance(nodelist[-1], _assign_nodes):
3282 3258 asg = nodelist[-1]
3283 3259 if isinstance(asg, ast.Assign) and len(asg.targets) == 1:
3284 3260 target = asg.targets[0]
3285 3261 elif isinstance(asg, _single_targets_nodes):
3286 3262 target = asg.target
3287 3263 else:
3288 3264 target = None
3289 3265 if isinstance(target, ast.Name):
3290 3266 nnode = ast.Expr(ast.Name(target.id, ast.Load()))
3291 3267 ast.fix_missing_locations(nnode)
3292 3268 nodelist.append(nnode)
3293 3269 interactivity = 'last_expr'
3294 3270
3295 3271 _async = False
3296 3272 if interactivity == 'last_expr':
3297 3273 if isinstance(nodelist[-1], ast.Expr):
3298 3274 interactivity = "last"
3299 3275 else:
3300 3276 interactivity = "none"
3301 3277
3302 3278 if interactivity == 'none':
3303 3279 to_run_exec, to_run_interactive = nodelist, []
3304 3280 elif interactivity == 'last':
3305 3281 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
3306 3282 elif interactivity == 'all':
3307 3283 to_run_exec, to_run_interactive = [], nodelist
3308 3284 else:
3309 3285 raise ValueError("Interactivity was %r" % interactivity)
3310 3286
3311 3287 try:
3312 3288
3313 3289 def compare(code):
3314 3290 is_async = inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE
3315 3291 return is_async
3316 3292
3317 3293 # refactor that to just change the mod constructor.
3318 3294 to_run = []
3319 3295 for node in to_run_exec:
3320 3296 to_run.append((node, "exec"))
3321 3297
3322 3298 for node in to_run_interactive:
3323 3299 to_run.append((node, "single"))
3324 3300
3325 3301 for node, mode in to_run:
3326 3302 if mode == "exec":
3327 3303 mod = Module([node], [])
3328 3304 elif mode == "single":
3329 3305 mod = ast.Interactive([node])
3330 3306 with compiler.extra_flags(
3331 3307 getattr(ast, "PyCF_ALLOW_TOP_LEVEL_AWAIT", 0x0)
3332 3308 if self.autoawait
3333 3309 else 0x0
3334 3310 ):
3335 3311 code = compiler(mod, cell_name, mode)
3336 code = self._update_code_co_name(code)
3337 3312 asy = compare(code)
3338 3313 if await self.run_code(code, result, async_=asy):
3339 3314 return True
3340 3315
3341 3316 # Flush softspace
3342 3317 if softspace(sys.stdout, 0):
3343 3318 print()
3344 3319
3345 3320 except:
3346 3321 # It's possible to have exceptions raised here, typically by
3347 3322 # compilation of odd code (such as a naked 'return' outside a
3348 3323 # function) that did parse but isn't valid. Typically the exception
3349 3324 # is a SyntaxError, but it's safest just to catch anything and show
3350 3325 # the user a traceback.
3351 3326
3352 3327 # We do only one try/except outside the loop to minimize the impact
3353 3328 # on runtime, and also because if any node in the node list is
3354 3329 # broken, we should stop execution completely.
3355 3330 if result:
3356 3331 result.error_before_exec = sys.exc_info()[1]
3357 3332 self.showtraceback()
3358 3333 return True
3359 3334
3360 3335 return False
3361 3336
3362 3337 async def run_code(self, code_obj, result=None, *, async_=False):
3363 3338 """Execute a code object.
3364 3339
3365 3340 When an exception occurs, self.showtraceback() is called to display a
3366 3341 traceback.
3367 3342
3368 3343 Parameters
3369 3344 ----------
3370 3345 code_obj : code object
3371 3346 A compiled code object, to be executed
3372 3347 result : ExecutionResult, optional
3373 3348 An object to store exceptions that occur during execution.
3374 3349 async_ : Bool (Experimental)
3375 3350 Attempt to run top-level asynchronous code in a default loop.
3376 3351
3377 3352 Returns
3378 3353 -------
3379 3354 False : successful execution.
3380 3355 True : an error occurred.
3381 3356 """
3382 3357 # special value to say that anything above is IPython and should be
3383 3358 # hidden.
3384 3359 __tracebackhide__ = "__ipython_bottom__"
3385 3360 # Set our own excepthook in case the user code tries to call it
3386 3361 # directly, so that the IPython crash handler doesn't get triggered
3387 3362 old_excepthook, sys.excepthook = sys.excepthook, self.excepthook
3388 3363
3389 3364 # we save the original sys.excepthook in the instance, in case config
3390 3365 # code (such as magics) needs access to it.
3391 3366 self.sys_excepthook = old_excepthook
3392 3367 outflag = True # happens in more places, so it's easier as default
3393 3368 try:
3394 3369 try:
3395 3370 if async_:
3396 3371 await eval(code_obj, self.user_global_ns, self.user_ns)
3397 3372 else:
3398 3373 exec(code_obj, self.user_global_ns, self.user_ns)
3399 3374 finally:
3400 3375 # Reset our crash handler in place
3401 3376 sys.excepthook = old_excepthook
3402 3377 except SystemExit as e:
3403 3378 if result is not None:
3404 3379 result.error_in_exec = e
3405 3380 self.showtraceback(exception_only=True)
3406 3381 warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
3407 3382 except bdb.BdbQuit:
3408 3383 etype, value, tb = sys.exc_info()
3409 3384 if result is not None:
3410 3385 result.error_in_exec = value
3411 3386 # the BdbQuit stops here
3412 3387 except self.custom_exceptions:
3413 3388 etype, value, tb = sys.exc_info()
3414 3389 if result is not None:
3415 3390 result.error_in_exec = value
3416 3391 self.CustomTB(etype, value, tb)
3417 3392 except:
3418 3393 if result is not None:
3419 3394 result.error_in_exec = sys.exc_info()[1]
3420 3395 self.showtraceback(running_compiled_code=True)
3421 3396 else:
3422 3397 outflag = False
3423 3398 return outflag
3424 3399
3425 3400 # For backwards compatibility
3426 3401 runcode = run_code
3427 3402
3428 3403 def check_complete(self, code: str) -> Tuple[str, str]:
3429 3404 """Return whether a block of code is ready to execute, or should be continued
3430 3405
3431 3406 Parameters
3432 3407 ----------
3433 3408 code : string
3434 3409 Python input code, which can be multiline.
3435 3410
3436 3411 Returns
3437 3412 -------
3438 3413 status : str
3439 3414 One of 'complete', 'incomplete', or 'invalid' if source is not a
3440 3415 prefix of valid code.
3441 3416 indent : str
3442 3417 When status is 'incomplete', this is some whitespace to insert on
3443 3418 the next line of the prompt.
3444 3419 """
3445 3420 status, nspaces = self.input_transformer_manager.check_complete(code)
3446 3421 return status, ' ' * (nspaces or 0)
3447 3422
3448 3423 #-------------------------------------------------------------------------
3449 3424 # Things related to GUI support and pylab
3450 3425 #-------------------------------------------------------------------------
3451 3426
3452 3427 active_eventloop = None
3453 3428
3454 3429 def enable_gui(self, gui=None):
3455 3430 raise NotImplementedError('Implement enable_gui in a subclass')
3456 3431
3457 3432 def enable_matplotlib(self, gui=None):
3458 3433 """Enable interactive matplotlib and inline figure support.
3459 3434
3460 3435 This takes the following steps:
3461 3436
3462 3437 1. select the appropriate eventloop and matplotlib backend
3463 3438 2. set up matplotlib for interactive use with that backend
3464 3439 3. configure formatters for inline figure display
3465 3440 4. enable the selected gui eventloop
3466 3441
3467 3442 Parameters
3468 3443 ----------
3469 3444 gui : optional, string
3470 3445 If given, dictates the choice of matplotlib GUI backend to use
3471 3446 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3472 3447 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3473 3448 matplotlib (as dictated by the matplotlib build-time options plus the
3474 3449 user's matplotlibrc configuration file). Note that not all backends
3475 3450 make sense in all contexts, for example a terminal ipython can't
3476 3451 display figures inline.
3477 3452 """
3478 3453 from matplotlib_inline.backend_inline import configure_inline_support
3479 3454
3480 3455 from IPython.core import pylabtools as pt
3481 3456 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
3482 3457
3483 3458 if gui != 'inline':
3484 3459 # If we have our first gui selection, store it
3485 3460 if self.pylab_gui_select is None:
3486 3461 self.pylab_gui_select = gui
3487 3462 # Otherwise if they are different
3488 3463 elif gui != self.pylab_gui_select:
3489 3464 print('Warning: Cannot change to a different GUI toolkit: %s.'
3490 3465 ' Using %s instead.' % (gui, self.pylab_gui_select))
3491 3466 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
3492 3467
3493 3468 pt.activate_matplotlib(backend)
3494 3469 configure_inline_support(self, backend)
3495 3470
3496 3471 # Now we must activate the gui pylab wants to use, and fix %run to take
3497 3472 # plot updates into account
3498 3473 self.enable_gui(gui)
3499 3474 self.magics_manager.registry['ExecutionMagics'].default_runner = \
3500 3475 pt.mpl_runner(self.safe_execfile)
3501 3476
3502 3477 return gui, backend
3503 3478
3504 3479 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
3505 3480 """Activate pylab support at runtime.
3506 3481
3507 3482 This turns on support for matplotlib, preloads into the interactive
3508 3483 namespace all of numpy and pylab, and configures IPython to correctly
3509 3484 interact with the GUI event loop. The GUI backend to be used can be
3510 3485 optionally selected with the optional ``gui`` argument.
3511 3486
3512 3487 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
3513 3488
3514 3489 Parameters
3515 3490 ----------
3516 3491 gui : optional, string
3517 3492 If given, dictates the choice of matplotlib GUI backend to use
3518 3493 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3519 3494 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3520 3495 matplotlib (as dictated by the matplotlib build-time options plus the
3521 3496 user's matplotlibrc configuration file). Note that not all backends
3522 3497 make sense in all contexts, for example a terminal ipython can't
3523 3498 display figures inline.
3524 3499 import_all : optional, bool, default: True
3525 3500 Whether to do `from numpy import *` and `from pylab import *`
3526 3501 in addition to module imports.
3527 3502 welcome_message : deprecated
3528 3503 This argument is ignored, no welcome message will be displayed.
3529 3504 """
3530 3505 from IPython.core.pylabtools import import_pylab
3531 3506
3532 3507 gui, backend = self.enable_matplotlib(gui)
3533 3508
3534 3509 # We want to prevent the loading of pylab to pollute the user's
3535 3510 # namespace as shown by the %who* magics, so we execute the activation
3536 3511 # code in an empty namespace, and we update *both* user_ns and
3537 3512 # user_ns_hidden with this information.
3538 3513 ns = {}
3539 3514 import_pylab(ns, import_all)
3540 3515 # warn about clobbered names
3541 3516 ignored = {"__builtins__"}
3542 3517 both = set(ns).intersection(self.user_ns).difference(ignored)
3543 3518 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
3544 3519 self.user_ns.update(ns)
3545 3520 self.user_ns_hidden.update(ns)
3546 3521 return gui, backend, clobbered
3547 3522
3548 3523 #-------------------------------------------------------------------------
3549 3524 # Utilities
3550 3525 #-------------------------------------------------------------------------
3551 3526
3552 3527 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
3553 3528 """Expand python variables in a string.
3554 3529
3555 3530 The depth argument indicates how many frames above the caller should
3556 3531 be walked to look for the local namespace where to expand variables.
3557 3532
3558 3533 The global namespace for expansion is always the user's interactive
3559 3534 namespace.
3560 3535 """
3561 3536 ns = self.user_ns.copy()
3562 3537 try:
3563 3538 frame = sys._getframe(depth+1)
3564 3539 except ValueError:
3565 3540 # This is thrown if there aren't that many frames on the stack,
3566 3541 # e.g. if a script called run_line_magic() directly.
3567 3542 pass
3568 3543 else:
3569 3544 ns.update(frame.f_locals)
3570 3545
3571 3546 try:
3572 3547 # We have to use .vformat() here, because 'self' is a valid and common
3573 3548 # name, and expanding **ns for .format() would make it collide with
3574 3549 # the 'self' argument of the method.
3575 3550 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3576 3551 except Exception:
3577 3552 # if formatter couldn't format, just let it go untransformed
3578 3553 pass
3579 3554 return cmd
3580 3555
3581 3556 def mktempfile(self, data=None, prefix='ipython_edit_'):
3582 3557 """Make a new tempfile and return its filename.
3583 3558
3584 3559 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3585 3560 but it registers the created filename internally so ipython cleans it up
3586 3561 at exit time.
3587 3562
3588 3563 Optional inputs:
3589 3564
3590 3565 - data(None): if data is given, it gets written out to the temp file
3591 3566 immediately, and the file is closed again."""
3592 3567
3593 3568 dir_path = Path(tempfile.mkdtemp(prefix=prefix))
3594 3569 self.tempdirs.append(dir_path)
3595 3570
3596 3571 handle, filename = tempfile.mkstemp(".py", prefix, dir=str(dir_path))
3597 3572 os.close(handle) # On Windows, there can only be one open handle on a file
3598 3573
3599 3574 file_path = Path(filename)
3600 3575 self.tempfiles.append(file_path)
3601 3576
3602 3577 if data:
3603 3578 file_path.write_text(data, encoding="utf-8")
3604 3579 return filename
3605 3580
3606 3581 def ask_yes_no(self, prompt, default=None, interrupt=None):
3607 3582 if self.quiet:
3608 3583 return True
3609 3584 return ask_yes_no(prompt,default,interrupt)
3610 3585
3611 3586 def show_usage(self):
3612 3587 """Show a usage message"""
3613 3588 page.page(IPython.core.usage.interactive_usage)
3614 3589
3615 3590 def extract_input_lines(self, range_str, raw=False):
3616 3591 """Return as a string a set of input history slices.
3617 3592
3618 3593 Parameters
3619 3594 ----------
3620 3595 range_str : str
3621 3596 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3622 3597 since this function is for use by magic functions which get their
3623 3598 arguments as strings. The number before the / is the session
3624 3599 number: ~n goes n back from the current session.
3625 3600
3626 3601 If empty string is given, returns history of current session
3627 3602 without the last input.
3628 3603
3629 3604 raw : bool, optional
3630 3605 By default, the processed input is used. If this is true, the raw
3631 3606 input history is used instead.
3632 3607
3633 3608 Notes
3634 3609 -----
3635 3610 Slices can be described with two notations:
3636 3611
3637 3612 * ``N:M`` -> standard python form, means including items N...(M-1).
3638 3613 * ``N-M`` -> include items N..M (closed endpoint).
3639 3614 """
3640 3615 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3641 3616 text = "\n".join(x for _, _, x in lines)
3642 3617
3643 3618 # Skip the last line, as it's probably the magic that called this
3644 3619 if not range_str:
3645 3620 if "\n" not in text:
3646 3621 text = ""
3647 3622 else:
3648 3623 text = text[: text.rfind("\n")]
3649 3624
3650 3625 return text
3651 3626
3652 3627 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False):
3653 3628 """Get a code string from history, file, url, or a string or macro.
3654 3629
3655 3630 This is mainly used by magic functions.
3656 3631
3657 3632 Parameters
3658 3633 ----------
3659 3634 target : str
3660 3635 A string specifying code to retrieve. This will be tried respectively
3661 3636 as: ranges of input history (see %history for syntax), url,
3662 3637 corresponding .py file, filename, or an expression evaluating to a
3663 3638 string or Macro in the user namespace.
3664 3639
3665 3640 If empty string is given, returns complete history of current
3666 3641 session, without the last line.
3667 3642
3668 3643 raw : bool
3669 3644 If true (default), retrieve raw history. Has no effect on the other
3670 3645 retrieval mechanisms.
3671 3646
3672 3647 py_only : bool (default False)
3673 3648 Only try to fetch python code, do not try alternative methods to decode file
3674 3649 if unicode fails.
3675 3650
3676 3651 Returns
3677 3652 -------
3678 3653 A string of code.
3679 3654 ValueError is raised if nothing is found, and TypeError if it evaluates
3680 3655 to an object of another type. In each case, .args[0] is a printable
3681 3656 message.
3682 3657 """
3683 3658 code = self.extract_input_lines(target, raw=raw) # Grab history
3684 3659 if code:
3685 3660 return code
3686 3661 try:
3687 3662 if target.startswith(('http://', 'https://')):
3688 3663 return openpy.read_py_url(target, skip_encoding_cookie=skip_encoding_cookie)
3689 3664 except UnicodeDecodeError as e:
3690 3665 if not py_only :
3691 3666 # Deferred import
3692 3667 from urllib.request import urlopen
3693 3668 response = urlopen(target)
3694 3669 return response.read().decode('latin1')
3695 3670 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3696 3671
3697 3672 potential_target = [target]
3698 3673 try :
3699 3674 potential_target.insert(0,get_py_filename(target))
3700 3675 except IOError:
3701 3676 pass
3702 3677
3703 3678 for tgt in potential_target :
3704 3679 if os.path.isfile(tgt): # Read file
3705 3680 try :
3706 3681 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3707 3682 except UnicodeDecodeError as e:
3708 3683 if not py_only :
3709 3684 with io_open(tgt,'r', encoding='latin1') as f :
3710 3685 return f.read()
3711 3686 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3712 3687 elif os.path.isdir(os.path.expanduser(tgt)):
3713 3688 raise ValueError("'%s' is a directory, not a regular file." % target)
3714 3689
3715 3690 if search_ns:
3716 3691 # Inspect namespace to load object source
3717 3692 object_info = self.object_inspect(target, detail_level=1)
3718 3693 if object_info['found'] and object_info['source']:
3719 3694 return object_info['source']
3720 3695
3721 3696 try: # User namespace
3722 3697 codeobj = eval(target, self.user_ns)
3723 3698 except Exception as e:
3724 3699 raise ValueError(("'%s' was not found in history, as a file, url, "
3725 3700 "nor in the user namespace.") % target) from e
3726 3701
3727 3702 if isinstance(codeobj, str):
3728 3703 return codeobj
3729 3704 elif isinstance(codeobj, Macro):
3730 3705 return codeobj.value
3731 3706
3732 3707 raise TypeError("%s is neither a string nor a macro." % target,
3733 3708 codeobj)
3734 3709
3735 3710 def _atexit_once(self):
3736 3711 """
3737 3712 At exist operation that need to be called at most once.
3738 3713 Second call to this function per instance will do nothing.
3739 3714 """
3740 3715
3741 3716 if not getattr(self, "_atexit_once_called", False):
3742 3717 self._atexit_once_called = True
3743 3718 # Clear all user namespaces to release all references cleanly.
3744 3719 self.reset(new_session=False)
3745 3720 # Close the history session (this stores the end time and line count)
3746 3721 # this must be *before* the tempfile cleanup, in case of temporary
3747 3722 # history db
3748 3723 self.history_manager.end_session()
3749 3724 self.history_manager = None
3750 3725
3751 3726 #-------------------------------------------------------------------------
3752 3727 # Things related to IPython exiting
3753 3728 #-------------------------------------------------------------------------
3754 3729 def atexit_operations(self):
3755 3730 """This will be executed at the time of exit.
3756 3731
3757 3732 Cleanup operations and saving of persistent data that is done
3758 3733 unconditionally by IPython should be performed here.
3759 3734
3760 3735 For things that may depend on startup flags or platform specifics (such
3761 3736 as having readline or not), register a separate atexit function in the
3762 3737 code that has the appropriate information, rather than trying to
3763 3738 clutter
3764 3739 """
3765 3740 self._atexit_once()
3766 3741
3767 3742 # Cleanup all tempfiles and folders left around
3768 3743 for tfile in self.tempfiles:
3769 3744 try:
3770 3745 tfile.unlink()
3771 3746 self.tempfiles.remove(tfile)
3772 3747 except FileNotFoundError:
3773 3748 pass
3774 3749 del self.tempfiles
3775 3750 for tdir in self.tempdirs:
3776 3751 try:
3777 3752 tdir.rmdir()
3778 3753 self.tempdirs.remove(tdir)
3779 3754 except FileNotFoundError:
3780 3755 pass
3781 3756 del self.tempdirs
3782 3757
3783 3758 # Restore user's cursor
3784 3759 if hasattr(self, "editing_mode") and self.editing_mode == "vi":
3785 3760 sys.stdout.write("\x1b[0 q")
3786 3761 sys.stdout.flush()
3787 3762
3788 3763 def cleanup(self):
3789 3764 self.restore_sys_module_state()
3790 3765
3791 3766
3792 3767 # Overridden in terminal subclass to change prompts
3793 3768 def switch_doctest_mode(self, mode):
3794 3769 pass
3795 3770
3796 3771
3797 3772 class InteractiveShellABC(metaclass=abc.ABCMeta):
3798 3773 """An abstract base class for InteractiveShell."""
3799 3774
3800 3775 InteractiveShellABC.register(InteractiveShell)
@@ -1,250 +1,250 b''
1 1 """Tests for the key interactiveshell module, where the main ipython class is defined.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Module imports
5 5 #-----------------------------------------------------------------------------
6 6
7 7 # third party
8 8 import pytest
9 9
10 10 # our own packages
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Test functions
14 14 #-----------------------------------------------------------------------------
15 15
16 16 def test_reset():
17 17 """reset must clear most namespaces."""
18 18
19 19 # Check that reset runs without error
20 20 ip.reset()
21 21
22 22 # Once we've reset it (to clear of any junk that might have been there from
23 23 # other tests, we can count how many variables are in the user's namespace
24 24 nvars_user_ns = len(ip.user_ns)
25 25 nvars_hidden = len(ip.user_ns_hidden)
26 26
27 27 # Now add a few variables to user_ns, and check that reset clears them
28 28 ip.user_ns['x'] = 1
29 29 ip.user_ns['y'] = 1
30 30 ip.reset()
31 31
32 32 # Finally, check that all namespaces have only as many variables as we
33 33 # expect to find in them:
34 34 assert len(ip.user_ns) == nvars_user_ns
35 35 assert len(ip.user_ns_hidden) == nvars_hidden
36 36
37 37
38 38 # Tests for reporting of exceptions in various modes, handling of SystemExit,
39 39 # and %tb functionality. This is really a mix of testing ultraTB and interactiveshell.
40 40
41 41 def doctest_tb_plain():
42 42 """
43 43 In [18]: xmode plain
44 44 Exception reporting mode: Plain
45 45
46 46 In [19]: run simpleerr.py
47 47 Traceback (most recent call last):
48 File ...:... in <module>
48 File ...:...
49 49 bar(mode)
50 50 File ...:... in bar
51 51 div0()
52 52 File ...:... in div0
53 53 x/y
54 54 ZeroDivisionError: ...
55 55 """
56 56
57 57
58 58 def doctest_tb_context():
59 59 """
60 60 In [3]: xmode context
61 61 Exception reporting mode: Context
62 62
63 63 In [4]: run simpleerr.py
64 64 ---------------------------------------------------------------------------
65 65 ZeroDivisionError Traceback (most recent call last)
66 66 <BLANKLINE>
67 ... in <module>
67 ...
68 68 30 except IndexError:
69 69 31 mode = 'div'
70 70 ---> 33 bar(mode)
71 71 <BLANKLINE>
72 72 ... in bar(mode)
73 73 15 "bar"
74 74 16 if mode=='div':
75 75 ---> 17 div0()
76 76 18 elif mode=='exit':
77 77 19 try:
78 78 <BLANKLINE>
79 79 ... in div0()
80 80 6 x = 1
81 81 7 y = 0
82 82 ----> 8 x/y
83 83 <BLANKLINE>
84 84 ZeroDivisionError: ..."""
85 85
86 86
87 87 def doctest_tb_verbose():
88 88 """
89 89 In [5]: xmode verbose
90 90 Exception reporting mode: Verbose
91 91
92 92 In [6]: run simpleerr.py
93 93 ---------------------------------------------------------------------------
94 94 ZeroDivisionError Traceback (most recent call last)
95 95 <BLANKLINE>
96 ... in <module>
96 ...
97 97 30 except IndexError:
98 98 31 mode = 'div'
99 99 ---> 33 bar(mode)
100 100 mode = 'div'
101 101 <BLANKLINE>
102 102 ... in bar(mode='div')
103 103 15 "bar"
104 104 16 if mode=='div':
105 105 ---> 17 div0()
106 106 18 elif mode=='exit':
107 107 19 try:
108 108 <BLANKLINE>
109 109 ... in div0()
110 110 6 x = 1
111 111 7 y = 0
112 112 ----> 8 x/y
113 113 x = 1
114 114 y = 0
115 115 <BLANKLINE>
116 116 ZeroDivisionError: ...
117 117 """
118 118
119 119
120 120 def doctest_tb_sysexit():
121 121 """
122 122 In [17]: %xmode plain
123 123 Exception reporting mode: Plain
124 124
125 125 In [18]: %run simpleerr.py exit
126 126 An exception has occurred, use %tb to see the full traceback.
127 127 SystemExit: (1, 'Mode = exit')
128 128
129 129 In [19]: %run simpleerr.py exit 2
130 130 An exception has occurred, use %tb to see the full traceback.
131 131 SystemExit: (2, 'Mode = exit')
132 132
133 133 In [20]: %tb
134 134 Traceback (most recent call last):
135 135 File ...:... in execfile
136 136 exec(compiler(f.read(), fname, "exec"), glob, loc)
137 File ...:... in <module>
137 File ...:...
138 138 bar(mode)
139 139 File ...:... in bar
140 140 sysexit(stat, mode)
141 141 File ...:... in sysexit
142 142 raise SystemExit(stat, f"Mode = {mode}")
143 143 SystemExit: (2, 'Mode = exit')
144 144
145 145 In [21]: %xmode context
146 146 Exception reporting mode: Context
147 147
148 148 In [22]: %tb
149 149 ---------------------------------------------------------------------------
150 150 SystemExit Traceback (most recent call last)
151 151 File ..., in execfile(fname, glob, loc, compiler)
152 152 ... with open(fname, "rb") as f:
153 153 ... compiler = compiler or compile
154 154 ---> ... exec(compiler(f.read(), fname, "exec"), glob, loc)
155 ...<module>
155 ...
156 156 30 except IndexError:
157 157 31 mode = 'div'
158 158 ---> 33 bar(mode)
159 159 <BLANKLINE>
160 160 ...bar(mode)
161 161 21 except:
162 162 22 stat = 1
163 163 ---> 23 sysexit(stat, mode)
164 164 24 else:
165 165 25 raise ValueError('Unknown mode')
166 166 <BLANKLINE>
167 167 ...sysexit(stat, mode)
168 168 10 def sysexit(stat, mode):
169 169 ---> 11 raise SystemExit(stat, f"Mode = {mode}")
170 170 <BLANKLINE>
171 171 SystemExit: (2, 'Mode = exit')
172 172 """
173 173
174 174
175 175 def doctest_tb_sysexit_verbose():
176 176 """
177 177 In [18]: %run simpleerr.py exit
178 178 An exception has occurred, use %tb to see the full traceback.
179 179 SystemExit: (1, 'Mode = exit')
180 180
181 181 In [19]: %run simpleerr.py exit 2
182 182 An exception has occurred, use %tb to see the full traceback.
183 183 SystemExit: (2, 'Mode = exit')
184 184
185 185 In [23]: %xmode verbose
186 186 Exception reporting mode: Verbose
187 187
188 188 In [24]: %tb
189 189 ---------------------------------------------------------------------------
190 190 SystemExit Traceback (most recent call last)
191 191 <BLANKLINE>
192 ... in <module>
192 ...
193 193 30 except IndexError:
194 194 31 mode = 'div'
195 195 ---> 33 bar(mode)
196 196 mode = 'exit'
197 197 <BLANKLINE>
198 198 ... in bar(mode='exit')
199 199 ... except:
200 200 ... stat = 1
201 201 ---> ... sysexit(stat, mode)
202 202 mode = 'exit'
203 203 stat = 2
204 204 ... else:
205 205 ... raise ValueError('Unknown mode')
206 206 <BLANKLINE>
207 207 ... in sysexit(stat=2, mode='exit')
208 208 10 def sysexit(stat, mode):
209 209 ---> 11 raise SystemExit(stat, f"Mode = {mode}")
210 210 stat = 2
211 211 <BLANKLINE>
212 212 SystemExit: (2, 'Mode = exit')
213 213 """
214 214
215 215
216 216 def test_run_cell():
217 217 import textwrap
218 218
219 219 ip.run_cell("a = 10\na+=1")
220 220 ip.run_cell("assert a == 11\nassert 1")
221 221
222 222 assert ip.user_ns["a"] == 11
223 223 complex = textwrap.dedent(
224 224 """
225 225 if 1:
226 226 print "hello"
227 227 if 1:
228 228 print "world"
229 229
230 230 if 2:
231 231 print "foo"
232 232
233 233 if 3:
234 234 print "bar"
235 235
236 236 if 4:
237 237 print "bar"
238 238
239 239 """
240 240 )
241 241 # Simply verifies that this kind of input is run
242 242 ip.run_cell(complex)
243 243
244 244
245 245 def test_db():
246 246 """Test the internal database used for variable persistence."""
247 247 ip.db["__unittest_"] = 12
248 248 assert ip.db["__unittest_"] == 12
249 249 del ip.db["__unittest_"]
250 250 assert "__unittest_" not in ip.db
@@ -1,1207 +1,1201 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Verbose and colourful traceback formatting.
4 4
5 5 **ColorTB**
6 6
7 7 I've always found it a bit hard to visually parse tracebacks in Python. The
8 8 ColorTB class is a solution to that problem. It colors the different parts of a
9 9 traceback in a manner similar to what you would expect from a syntax-highlighting
10 10 text editor.
11 11
12 12 Installation instructions for ColorTB::
13 13
14 14 import sys,ultratb
15 15 sys.excepthook = ultratb.ColorTB()
16 16
17 17 **VerboseTB**
18 18
19 19 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
20 20 of useful info when a traceback occurs. Ping originally had it spit out HTML
21 21 and intended it for CGI programmers, but why should they have all the fun? I
22 22 altered it to spit out colored text to the terminal. It's a bit overwhelming,
23 23 but kind of neat, and maybe useful for long-running programs that you believe
24 24 are bug-free. If a crash *does* occur in that type of program you want details.
25 25 Give it a shot--you'll love it or you'll hate it.
26 26
27 27 .. note::
28 28
29 29 The Verbose mode prints the variables currently visible where the exception
30 30 happened (shortening their strings if too long). This can potentially be
31 31 very slow, if you happen to have a huge data structure whose string
32 32 representation is complex to compute. Your computer may appear to freeze for
33 33 a while with cpu usage at 100%. If this occurs, you can cancel the traceback
34 34 with Ctrl-C (maybe hitting it more than once).
35 35
36 36 If you encounter this kind of situation often, you may want to use the
37 37 Verbose_novars mode instead of the regular Verbose, which avoids formatting
38 38 variables (but otherwise includes the information and context given by
39 39 Verbose).
40 40
41 41 .. note::
42 42
43 43 The verbose mode print all variables in the stack, which means it can
44 44 potentially leak sensitive information like access keys, or unencrypted
45 45 password.
46 46
47 47 Installation instructions for VerboseTB::
48 48
49 49 import sys,ultratb
50 50 sys.excepthook = ultratb.VerboseTB()
51 51
52 52 Note: Much of the code in this module was lifted verbatim from the standard
53 53 library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'.
54 54
55 55 Color schemes
56 56 -------------
57 57
58 58 The colors are defined in the class TBTools through the use of the
59 59 ColorSchemeTable class. Currently the following exist:
60 60
61 61 - NoColor: allows all of this module to be used in any terminal (the color
62 62 escapes are just dummy blank strings).
63 63
64 64 - Linux: is meant to look good in a terminal like the Linux console (black
65 65 or very dark background).
66 66
67 67 - LightBG: similar to Linux but swaps dark/light colors to be more readable
68 68 in light background terminals.
69 69
70 70 - Neutral: a neutral color scheme that should be readable on both light and
71 71 dark background
72 72
73 73 You can implement other color schemes easily, the syntax is fairly
74 74 self-explanatory. Please send back new schemes you develop to the author for
75 75 possible inclusion in future releases.
76 76
77 77 Inheritance diagram:
78 78
79 79 .. inheritance-diagram:: IPython.core.ultratb
80 80 :parts: 3
81 81 """
82 82
83 83 #*****************************************************************************
84 84 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
85 85 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
86 86 #
87 87 # Distributed under the terms of the BSD License. The full license is in
88 88 # the file COPYING, distributed as part of this software.
89 89 #*****************************************************************************
90 90
91 91
92 92 import inspect
93 93 import linecache
94 94 import pydoc
95 95 import sys
96 96 import time
97 97 import traceback
98 98 from types import TracebackType
99 99 from typing import Tuple, List, Any, Optional
100 100
101 101 import stack_data
102 102 from pygments.formatters.terminal256 import Terminal256Formatter
103 103 from pygments.styles import get_style_by_name
104 104
105 105 # IPython's own modules
106 106 from IPython import get_ipython
107 107 from IPython.core import debugger
108 108 from IPython.core.display_trap import DisplayTrap
109 109 from IPython.core.excolors import exception_colors
110 110 from IPython.utils import path as util_path
111 111 from IPython.utils import py3compat
112 112 from IPython.utils.terminal import get_terminal_size
113 113
114 114 import IPython.utils.colorable as colorable
115 115
116 116 # Globals
117 117 # amount of space to put line numbers before verbose tracebacks
118 118 INDENT_SIZE = 8
119 119
120 120 # Default color scheme. This is used, for example, by the traceback
121 121 # formatter. When running in an actual IPython instance, the user's rc.colors
122 122 # value is used, but having a module global makes this functionality available
123 123 # to users of ultratb who are NOT running inside ipython.
124 124 DEFAULT_SCHEME = 'NoColor'
125 125
126 126 # ---------------------------------------------------------------------------
127 127 # Code begins
128 128
129 129 # Helper function -- largely belongs to VerboseTB, but we need the same
130 130 # functionality to produce a pseudo verbose TB for SyntaxErrors, so that they
131 131 # can be recognized properly by ipython.el's py-traceback-line-re
132 132 # (SyntaxErrors have to be treated specially because they have no traceback)
133 133
134 134
135 135 def _format_traceback_lines(lines, Colors, has_colors: bool, lvals):
136 136 """
137 137 Format tracebacks lines with pointing arrow, leading numbers...
138 138
139 139 Parameters
140 140 ----------
141 141 lines : list[Line]
142 142 Colors
143 143 ColorScheme used.
144 144 lvals : str
145 145 Values of local variables, already colored, to inject just after the error line.
146 146 """
147 147 numbers_width = INDENT_SIZE - 1
148 148 res = []
149 149
150 150 for stack_line in lines:
151 151 if stack_line is stack_data.LINE_GAP:
152 152 res.append('%s (...)%s\n' % (Colors.linenoEm, Colors.Normal))
153 153 continue
154 154
155 155 line = stack_line.render(pygmented=has_colors).rstrip('\n') + '\n'
156 156 lineno = stack_line.lineno
157 157 if stack_line.is_current:
158 158 # This is the line with the error
159 159 pad = numbers_width - len(str(lineno))
160 160 num = '%s%s' % (debugger.make_arrow(pad), str(lineno))
161 161 start_color = Colors.linenoEm
162 162 else:
163 163 num = '%*s' % (numbers_width, lineno)
164 164 start_color = Colors.lineno
165 165
166 166 line = '%s%s%s %s' % (start_color, num, Colors.Normal, line)
167 167
168 168 res.append(line)
169 169 if lvals and stack_line.is_current:
170 170 res.append(lvals + '\n')
171 171 return res
172 172
173 173
174 174 def _format_filename(file, ColorFilename, ColorNormal, *, lineno=None):
175 175 """
176 176 Format filename lines with `In [n]` if it's the nth code cell or `File *.py` if it's a module.
177 177
178 178 Parameters
179 179 ----------
180 180 file : str
181 181 ColorFilename
182 182 ColorScheme's filename coloring to be used.
183 183 ColorNormal
184 184 ColorScheme's normal coloring to be used.
185 185 """
186 186 ipinst = get_ipython()
187 187
188 188 if ipinst is not None and file in ipinst.compile._filename_map:
189 189 file = "[%s]" % ipinst.compile._filename_map[file]
190 tpl_link = f"Input {ColorFilename}In {{file}}{ColorNormal}"
190 if lineno is None:
191 tpl_link = f"Cell {ColorFilename}In {{file}}{ColorNormal}"
192 else:
193 tpl_link = f"Cell {ColorFilename}In {{file}}, line {{lineno}}{ColorNormal}"
191 194 else:
192 195 file = util_path.compress_user(
193 196 py3compat.cast_unicode(file, util_path.fs_encoding)
194 197 )
195 198 if lineno is None:
196 199 tpl_link = f"File {ColorFilename}{{file}}{ColorNormal}"
197 200 else:
198 201 tpl_link = f"File {ColorFilename}{{file}}:{{lineno}}{ColorNormal}"
199 202
200 203 return tpl_link.format(file=file, lineno=lineno)
201 204
202 205 #---------------------------------------------------------------------------
203 206 # Module classes
204 207 class TBTools(colorable.Colorable):
205 208 """Basic tools used by all traceback printer classes."""
206 209
207 210 # Number of frames to skip when reporting tracebacks
208 211 tb_offset = 0
209 212
210 213 def __init__(
211 214 self,
212 215 color_scheme="NoColor",
213 216 call_pdb=False,
214 217 ostream=None,
215 218 parent=None,
216 219 config=None,
217 220 *,
218 221 debugger_cls=None,
219 222 ):
220 223 # Whether to call the interactive pdb debugger after printing
221 224 # tracebacks or not
222 225 super(TBTools, self).__init__(parent=parent, config=config)
223 226 self.call_pdb = call_pdb
224 227
225 228 # Output stream to write to. Note that we store the original value in
226 229 # a private attribute and then make the public ostream a property, so
227 230 # that we can delay accessing sys.stdout until runtime. The way
228 231 # things are written now, the sys.stdout object is dynamically managed
229 232 # so a reference to it should NEVER be stored statically. This
230 233 # property approach confines this detail to a single location, and all
231 234 # subclasses can simply access self.ostream for writing.
232 235 self._ostream = ostream
233 236
234 237 # Create color table
235 238 self.color_scheme_table = exception_colors()
236 239
237 240 self.set_colors(color_scheme)
238 241 self.old_scheme = color_scheme # save initial value for toggles
239 242 self.debugger_cls = debugger_cls or debugger.Pdb
240 243
241 244 if call_pdb:
242 245 self.pdb = self.debugger_cls()
243 246 else:
244 247 self.pdb = None
245 248
246 249 def _get_ostream(self):
247 250 """Output stream that exceptions are written to.
248 251
249 252 Valid values are:
250 253
251 254 - None: the default, which means that IPython will dynamically resolve
252 255 to sys.stdout. This ensures compatibility with most tools, including
253 256 Windows (where plain stdout doesn't recognize ANSI escapes).
254 257
255 258 - Any object with 'write' and 'flush' attributes.
256 259 """
257 260 return sys.stdout if self._ostream is None else self._ostream
258 261
259 262 def _set_ostream(self, val):
260 263 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
261 264 self._ostream = val
262 265
263 266 ostream = property(_get_ostream, _set_ostream)
264 267
265 268 @staticmethod
266 269 def _get_chained_exception(exception_value):
267 270 cause = getattr(exception_value, "__cause__", None)
268 271 if cause:
269 272 return cause
270 273 if getattr(exception_value, "__suppress_context__", False):
271 274 return None
272 275 return getattr(exception_value, "__context__", None)
273 276
274 277 def get_parts_of_chained_exception(
275 278 self, evalue
276 279 ) -> Optional[Tuple[type, BaseException, TracebackType]]:
277 280
278 281 chained_evalue = self._get_chained_exception(evalue)
279 282
280 283 if chained_evalue:
281 284 return chained_evalue.__class__, chained_evalue, chained_evalue.__traceback__
282 285 return None
283 286
284 287 def prepare_chained_exception_message(self, cause) -> List[Any]:
285 288 direct_cause = "\nThe above exception was the direct cause of the following exception:\n"
286 289 exception_during_handling = "\nDuring handling of the above exception, another exception occurred:\n"
287 290
288 291 if cause:
289 292 message = [[direct_cause]]
290 293 else:
291 294 message = [[exception_during_handling]]
292 295 return message
293 296
294 297 @property
295 298 def has_colors(self) -> bool:
296 299 return self.color_scheme_table.active_scheme_name.lower() != "nocolor"
297 300
298 301 def set_colors(self, *args, **kw):
299 302 """Shorthand access to the color table scheme selector method."""
300 303
301 304 # Set own color table
302 305 self.color_scheme_table.set_active_scheme(*args, **kw)
303 306 # for convenience, set Colors to the active scheme
304 307 self.Colors = self.color_scheme_table.active_colors
305 308 # Also set colors of debugger
306 309 if hasattr(self, 'pdb') and self.pdb is not None:
307 310 self.pdb.set_colors(*args, **kw)
308 311
309 312 def color_toggle(self):
310 313 """Toggle between the currently active color scheme and NoColor."""
311 314
312 315 if self.color_scheme_table.active_scheme_name == 'NoColor':
313 316 self.color_scheme_table.set_active_scheme(self.old_scheme)
314 317 self.Colors = self.color_scheme_table.active_colors
315 318 else:
316 319 self.old_scheme = self.color_scheme_table.active_scheme_name
317 320 self.color_scheme_table.set_active_scheme('NoColor')
318 321 self.Colors = self.color_scheme_table.active_colors
319 322
320 323 def stb2text(self, stb):
321 324 """Convert a structured traceback (a list) to a string."""
322 325 return '\n'.join(stb)
323 326
324 327 def text(self, etype, value, tb, tb_offset: Optional[int] = None, context=5):
325 328 """Return formatted traceback.
326 329
327 330 Subclasses may override this if they add extra arguments.
328 331 """
329 332 tb_list = self.structured_traceback(etype, value, tb,
330 333 tb_offset, context)
331 334 return self.stb2text(tb_list)
332 335
333 336 def structured_traceback(
334 337 self, etype, evalue, tb, tb_offset: Optional[int] = None, context=5, mode=None
335 338 ):
336 339 """Return a list of traceback frames.
337 340
338 341 Must be implemented by each class.
339 342 """
340 343 raise NotImplementedError()
341 344
342 345
343 346 #---------------------------------------------------------------------------
344 347 class ListTB(TBTools):
345 348 """Print traceback information from a traceback list, with optional color.
346 349
347 350 Calling requires 3 arguments: (etype, evalue, elist)
348 351 as would be obtained by::
349 352
350 353 etype, evalue, tb = sys.exc_info()
351 354 if tb:
352 355 elist = traceback.extract_tb(tb)
353 356 else:
354 357 elist = None
355 358
356 359 It can thus be used by programs which need to process the traceback before
357 360 printing (such as console replacements based on the code module from the
358 361 standard library).
359 362
360 363 Because they are meant to be called without a full traceback (only a
361 364 list), instances of this class can't call the interactive pdb debugger."""
362 365
363 366
364 367 def __call__(self, etype, value, elist):
365 368 self.ostream.flush()
366 369 self.ostream.write(self.text(etype, value, elist))
367 370 self.ostream.write('\n')
368 371
369 372 def _extract_tb(self, tb):
370 373 if tb:
371 374 return traceback.extract_tb(tb)
372 375 else:
373 376 return None
374 377
375 378 def structured_traceback(
376 379 self,
377 380 etype: type,
378 381 evalue: BaseException,
379 382 etb: Optional[TracebackType] = None,
380 383 tb_offset: Optional[int] = None,
381 384 context=5,
382 385 ):
383 386 """Return a color formatted string with the traceback info.
384 387
385 388 Parameters
386 389 ----------
387 390 etype : exception type
388 391 Type of the exception raised.
389 392 evalue : object
390 393 Data stored in the exception
391 394 etb : list | TracebackType | None
392 395 If list: List of frames, see class docstring for details.
393 396 If Traceback: Traceback of the exception.
394 397 tb_offset : int, optional
395 398 Number of frames in the traceback to skip. If not given, the
396 399 instance evalue is used (set in constructor).
397 400 context : int, optional
398 401 Number of lines of context information to print.
399 402
400 403 Returns
401 404 -------
402 405 String with formatted exception.
403 406 """
404 407 # This is a workaround to get chained_exc_ids in recursive calls
405 408 # etb should not be a tuple if structured_traceback is not recursive
406 409 if isinstance(etb, tuple):
407 410 etb, chained_exc_ids = etb
408 411 else:
409 412 chained_exc_ids = set()
410 413
411 414 if isinstance(etb, list):
412 415 elist = etb
413 416 elif etb is not None:
414 417 elist = self._extract_tb(etb)
415 418 else:
416 419 elist = []
417 420 tb_offset = self.tb_offset if tb_offset is None else tb_offset
418 421 assert isinstance(tb_offset, int)
419 422 Colors = self.Colors
420 423 out_list = []
421 424 if elist:
422 425
423 426 if tb_offset and len(elist) > tb_offset:
424 427 elist = elist[tb_offset:]
425 428
426 429 out_list.append('Traceback %s(most recent call last)%s:' %
427 430 (Colors.normalEm, Colors.Normal) + '\n')
428 431 out_list.extend(self._format_list(elist))
429 432 # The exception info should be a single entry in the list.
430 433 lines = ''.join(self._format_exception_only(etype, evalue))
431 434 out_list.append(lines)
432 435
433 436 exception = self.get_parts_of_chained_exception(evalue)
434 437
435 438 if exception and not id(exception[1]) in chained_exc_ids:
436 439 chained_exception_message = self.prepare_chained_exception_message(
437 440 evalue.__cause__)[0]
438 441 etype, evalue, etb = exception
439 442 # Trace exception to avoid infinite 'cause' loop
440 443 chained_exc_ids.add(id(exception[1]))
441 444 chained_exceptions_tb_offset = 0
442 445 out_list = (
443 446 self.structured_traceback(
444 447 etype, evalue, (etb, chained_exc_ids),
445 448 chained_exceptions_tb_offset, context)
446 449 + chained_exception_message
447 450 + out_list)
448 451
449 452 return out_list
450 453
451 454 def _format_list(self, extracted_list):
452 455 """Format a list of traceback entry tuples for printing.
453 456
454 457 Given a list of tuples as returned by extract_tb() or
455 458 extract_stack(), return a list of strings ready for printing.
456 459 Each string in the resulting list corresponds to the item with the
457 460 same index in the argument list. Each string ends in a newline;
458 461 the strings may contain internal newlines as well, for those items
459 462 whose source text line is not None.
460 463
461 464 Lifted almost verbatim from traceback.py
462 465 """
463 466
464 467 Colors = self.Colors
465 468 list = []
466 for filename, lineno, name, line in extracted_list[:-1]:
467 item = " %s in %s%s%s\n" % (
468 _format_filename(
469 filename, Colors.filename, Colors.Normal, lineno=lineno
470 ),
471 Colors.name,
472 name,
473 Colors.Normal,
474 )
475 if line:
476 item += ' %s\n' % line.strip()
477 list.append(item)
469 for ind, (filename, lineno, name, line) in enumerate(extracted_list):
470 normalCol, nameCol, fileCol, lineCol = (
478 471 # Emphasize the last entry
479 filename, lineno, name, line = extracted_list[-1]
480 item = "%s %s in %s%s%s%s\n" % (
481 Colors.normalEm,
482 _format_filename(
483 filename, Colors.filenameEm, Colors.normalEm, lineno=lineno
484 ),
485 Colors.nameEm,
486 name,
487 Colors.normalEm,
488 Colors.Normal,
472 (Colors.normalEm, Colors.nameEm, Colors.filenameEm, Colors.line)
473 if ind == len(extracted_list) - 1
474 else (Colors.Normal, Colors.name, Colors.filename, "")
489 475 )
476
477 fns = _format_filename(filename, fileCol, normalCol, lineno=lineno)
478 item = f"{normalCol} {fns}"
479
480 if name != "<module>":
481 item += f" in {nameCol}{name}{normalCol}\n"
482 else:
483 item += "\n"
490 484 if line:
491 item += '%s %s%s\n' % (Colors.line, line.strip(),
492 Colors.Normal)
485 item += f"{lineCol} {line.strip()}{normalCol}\n"
493 486 list.append(item)
487
494 488 return list
495 489
496 490 def _format_exception_only(self, etype, value):
497 491 """Format the exception part of a traceback.
498 492
499 493 The arguments are the exception type and value such as given by
500 494 sys.exc_info()[:2]. The return value is a list of strings, each ending
501 495 in a newline. Normally, the list contains a single string; however,
502 496 for SyntaxError exceptions, it contains several lines that (when
503 497 printed) display detailed information about where the syntax error
504 498 occurred. The message indicating which exception occurred is the
505 499 always last string in the list.
506 500
507 501 Also lifted nearly verbatim from traceback.py
508 502 """
509 503 have_filedata = False
510 504 Colors = self.Colors
511 505 list = []
512 506 stype = py3compat.cast_unicode(Colors.excName + etype.__name__ + Colors.Normal)
513 507 if value is None:
514 508 # Not sure if this can still happen in Python 2.6 and above
515 509 list.append(stype + '\n')
516 510 else:
517 511 if issubclass(etype, SyntaxError):
518 512 have_filedata = True
519 513 if not value.filename: value.filename = "<string>"
520 514 if value.lineno:
521 515 lineno = value.lineno
522 516 textline = linecache.getline(value.filename, value.lineno)
523 517 else:
524 518 lineno = "unknown"
525 519 textline = ""
526 520 list.append(
527 521 "%s %s%s\n"
528 522 % (
529 523 Colors.normalEm,
530 524 _format_filename(
531 525 value.filename,
532 526 Colors.filenameEm,
533 527 Colors.normalEm,
534 528 lineno=(None if lineno == "unknown" else lineno),
535 529 ),
536 530 Colors.Normal,
537 531 )
538 532 )
539 533 if textline == "":
540 534 textline = py3compat.cast_unicode(value.text, "utf-8")
541 535
542 536 if textline is not None:
543 537 i = 0
544 538 while i < len(textline) and textline[i].isspace():
545 539 i += 1
546 540 list.append('%s %s%s\n' % (Colors.line,
547 541 textline.strip(),
548 542 Colors.Normal))
549 543 if value.offset is not None:
550 544 s = ' '
551 545 for c in textline[i:value.offset - 1]:
552 546 if c.isspace():
553 547 s += c
554 548 else:
555 549 s += ' '
556 550 list.append('%s%s^%s\n' % (Colors.caret, s,
557 551 Colors.Normal))
558 552
559 553 try:
560 554 s = value.msg
561 555 except Exception:
562 556 s = self._some_str(value)
563 557 if s:
564 558 list.append('%s%s:%s %s\n' % (stype, Colors.excName,
565 559 Colors.Normal, s))
566 560 else:
567 561 list.append('%s\n' % stype)
568 562
569 563 # sync with user hooks
570 564 if have_filedata:
571 565 ipinst = get_ipython()
572 566 if ipinst is not None:
573 567 ipinst.hooks.synchronize_with_editor(value.filename, value.lineno, 0)
574 568
575 569 return list
576 570
577 571 def get_exception_only(self, etype, value):
578 572 """Only print the exception type and message, without a traceback.
579 573
580 574 Parameters
581 575 ----------
582 576 etype : exception type
583 577 value : exception value
584 578 """
585 579 return ListTB.structured_traceback(self, etype, value)
586 580
587 581 def show_exception_only(self, etype, evalue):
588 582 """Only print the exception type and message, without a traceback.
589 583
590 584 Parameters
591 585 ----------
592 586 etype : exception type
593 587 evalue : exception value
594 588 """
595 589 # This method needs to use __call__ from *this* class, not the one from
596 590 # a subclass whose signature or behavior may be different
597 591 ostream = self.ostream
598 592 ostream.flush()
599 593 ostream.write('\n'.join(self.get_exception_only(etype, evalue)))
600 594 ostream.flush()
601 595
602 596 def _some_str(self, value):
603 597 # Lifted from traceback.py
604 598 try:
605 599 return py3compat.cast_unicode(str(value))
606 600 except:
607 601 return u'<unprintable %s object>' % type(value).__name__
608 602
609 603
610 604 #----------------------------------------------------------------------------
611 605 class VerboseTB(TBTools):
612 606 """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
613 607 of HTML. Requires inspect and pydoc. Crazy, man.
614 608
615 609 Modified version which optionally strips the topmost entries from the
616 610 traceback, to be used with alternate interpreters (because their own code
617 611 would appear in the traceback)."""
618 612
619 613 def __init__(
620 614 self,
621 615 color_scheme: str = "Linux",
622 616 call_pdb: bool = False,
623 617 ostream=None,
624 618 tb_offset: int = 0,
625 619 long_header: bool = False,
626 620 include_vars: bool = True,
627 621 check_cache=None,
628 622 debugger_cls=None,
629 623 parent=None,
630 624 config=None,
631 625 ):
632 626 """Specify traceback offset, headers and color scheme.
633 627
634 628 Define how many frames to drop from the tracebacks. Calling it with
635 629 tb_offset=1 allows use of this handler in interpreters which will have
636 630 their own code at the top of the traceback (VerboseTB will first
637 631 remove that frame before printing the traceback info)."""
638 632 TBTools.__init__(
639 633 self,
640 634 color_scheme=color_scheme,
641 635 call_pdb=call_pdb,
642 636 ostream=ostream,
643 637 parent=parent,
644 638 config=config,
645 639 debugger_cls=debugger_cls,
646 640 )
647 641 self.tb_offset = tb_offset
648 642 self.long_header = long_header
649 643 self.include_vars = include_vars
650 644 # By default we use linecache.checkcache, but the user can provide a
651 645 # different check_cache implementation. This is used by the IPython
652 646 # kernel to provide tracebacks for interactive code that is cached,
653 647 # by a compiler instance that flushes the linecache but preserves its
654 648 # own code cache.
655 649 if check_cache is None:
656 650 check_cache = linecache.checkcache
657 651 self.check_cache = check_cache
658 652
659 653 self.skip_hidden = True
660 654
661 655 def format_record(self, frame_info):
662 656 """Format a single stack frame"""
663 657 Colors = self.Colors # just a shorthand + quicker name lookup
664 658 ColorsNormal = Colors.Normal # used a lot
665 659
666 660 if isinstance(frame_info, stack_data.RepeatedFrames):
667 661 return ' %s[... skipping similar frames: %s]%s\n' % (
668 662 Colors.excName, frame_info.description, ColorsNormal)
669 663
670 664 indent = " " * INDENT_SIZE
671 665 em_normal = "%s\n%s%s" % (Colors.valEm, indent, ColorsNormal)
672 666 tpl_call = f"in {Colors.vName}{{file}}{Colors.valEm}{{scope}}{ColorsNormal}"
673 667 tpl_call_fail = "in %s%%s%s(***failed resolving arguments***)%s" % (
674 668 Colors.vName,
675 669 Colors.valEm,
676 670 ColorsNormal,
677 671 )
678 672 tpl_name_val = "%%s %s= %%s%s" % (Colors.valEm, ColorsNormal)
679 673
680 674 link = _format_filename(
681 675 frame_info.filename,
682 676 Colors.filenameEm,
683 677 ColorsNormal,
684 678 lineno=frame_info.lineno,
685 679 )
686 680 args, varargs, varkw, locals_ = inspect.getargvalues(frame_info.frame)
687 681
688 682 func = frame_info.executing.code_qualname()
689 683 if func == "<module>":
690 call = tpl_call.format(file=func, scope="")
684 call = ""
691 685 else:
692 686 # Decide whether to include variable details or not
693 687 var_repr = eqrepr if self.include_vars else nullrepr
694 688 try:
695 689 scope = inspect.formatargvalues(
696 690 args, varargs, varkw, locals_, formatvalue=var_repr
697 691 )
698 692 call = tpl_call.format(file=func, scope=scope)
699 693 except KeyError:
700 694 # This happens in situations like errors inside generator
701 695 # expressions, where local variables are listed in the
702 696 # line, but can't be extracted from the frame. I'm not
703 697 # 100% sure this isn't actually a bug in inspect itself,
704 698 # but since there's no info for us to compute with, the
705 699 # best we can do is report the failure and move on. Here
706 700 # we must *not* call any traceback construction again,
707 701 # because that would mess up use of %debug later on. So we
708 702 # simply report the failure and move on. The only
709 703 # limitation will be that this frame won't have locals
710 704 # listed in the call signature. Quite subtle problem...
711 705 # I can't think of a good way to validate this in a unit
712 706 # test, but running a script consisting of:
713 707 # dict( (k,v.strip()) for (k,v) in range(10) )
714 708 # will illustrate the error, if this exception catch is
715 709 # disabled.
716 710 call = tpl_call_fail % func
717 711
718 712 lvals = ''
719 713 lvals_list = []
720 714 if self.include_vars:
721 715 try:
722 716 # we likely want to fix stackdata at some point, but
723 717 # still need a workaround.
724 718 fibp = frame_info.variables_in_executing_piece
725 719 for var in fibp:
726 720 lvals_list.append(tpl_name_val % (var.name, repr(var.value)))
727 721 except Exception:
728 722 lvals_list.append(
729 723 "Exception trying to inspect frame. No more locals available."
730 724 )
731 725 if lvals_list:
732 726 lvals = '%s%s' % (indent, em_normal.join(lvals_list))
733 727
734 result = "%s, %s\n" % (link, call)
728 result = f'{link}{", " if call else ""}{call}\n'
735 729
736 730 result += ''.join(_format_traceback_lines(frame_info.lines, Colors, self.has_colors, lvals))
737 731 return result
738 732
739 733 def prepare_header(self, etype, long_version=False):
740 734 colors = self.Colors # just a shorthand + quicker name lookup
741 735 colorsnormal = colors.Normal # used a lot
742 736 exc = '%s%s%s' % (colors.excName, etype, colorsnormal)
743 737 width = min(75, get_terminal_size()[0])
744 738 if long_version:
745 739 # Header with the exception type, python version, and date
746 740 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
747 741 date = time.ctime(time.time())
748 742
749 743 head = '%s%s%s\n%s%s%s\n%s' % (colors.topline, '-' * width, colorsnormal,
750 744 exc, ' ' * (width - len(str(etype)) - len(pyver)),
751 745 pyver, date.rjust(width) )
752 746 head += "\nA problem occurred executing Python code. Here is the sequence of function" \
753 747 "\ncalls leading up to the error, with the most recent (innermost) call last."
754 748 else:
755 749 # Simplified header
756 750 head = '%s%s' % (exc, 'Traceback (most recent call last)'. \
757 751 rjust(width - len(str(etype))) )
758 752
759 753 return head
760 754
761 755 def format_exception(self, etype, evalue):
762 756 colors = self.Colors # just a shorthand + quicker name lookup
763 757 colorsnormal = colors.Normal # used a lot
764 758 # Get (safely) a string form of the exception info
765 759 try:
766 760 etype_str, evalue_str = map(str, (etype, evalue))
767 761 except:
768 762 # User exception is improperly defined.
769 763 etype, evalue = str, sys.exc_info()[:2]
770 764 etype_str, evalue_str = map(str, (etype, evalue))
771 765 # ... and format it
772 766 return ['%s%s%s: %s' % (colors.excName, etype_str,
773 767 colorsnormal, py3compat.cast_unicode(evalue_str))]
774 768
775 769 def format_exception_as_a_whole(
776 770 self,
777 771 etype: type,
778 772 evalue: BaseException,
779 773 etb: Optional[TracebackType],
780 774 number_of_lines_of_context,
781 775 tb_offset: Optional[int],
782 776 ):
783 777 """Formats the header, traceback and exception message for a single exception.
784 778
785 779 This may be called multiple times by Python 3 exception chaining
786 780 (PEP 3134).
787 781 """
788 782 # some locals
789 783 orig_etype = etype
790 784 try:
791 785 etype = etype.__name__
792 786 except AttributeError:
793 787 pass
794 788
795 789 tb_offset = self.tb_offset if tb_offset is None else tb_offset
796 790 assert isinstance(tb_offset, int)
797 791 head = self.prepare_header(etype, self.long_header)
798 792 records = (
799 793 self.get_records(etb, number_of_lines_of_context, tb_offset) if etb else []
800 794 )
801 795
802 796 frames = []
803 797 skipped = 0
804 798 lastrecord = len(records) - 1
805 799 for i, r in enumerate(records):
806 800 if not isinstance(r, stack_data.RepeatedFrames) and self.skip_hidden:
807 801 if r.frame.f_locals.get("__tracebackhide__", 0) and i != lastrecord:
808 802 skipped += 1
809 803 continue
810 804 if skipped:
811 805 Colors = self.Colors # just a shorthand + quicker name lookup
812 806 ColorsNormal = Colors.Normal # used a lot
813 807 frames.append(
814 808 " %s[... skipping hidden %s frame]%s\n"
815 809 % (Colors.excName, skipped, ColorsNormal)
816 810 )
817 811 skipped = 0
818 812 frames.append(self.format_record(r))
819 813 if skipped:
820 814 Colors = self.Colors # just a shorthand + quicker name lookup
821 815 ColorsNormal = Colors.Normal # used a lot
822 816 frames.append(
823 817 " %s[... skipping hidden %s frame]%s\n"
824 818 % (Colors.excName, skipped, ColorsNormal)
825 819 )
826 820
827 821 formatted_exception = self.format_exception(etype, evalue)
828 822 if records:
829 823 frame_info = records[-1]
830 824 ipinst = get_ipython()
831 825 if ipinst is not None:
832 826 ipinst.hooks.synchronize_with_editor(frame_info.filename, frame_info.lineno, 0)
833 827
834 828 return [[head] + frames + [''.join(formatted_exception[0])]]
835 829
836 830 def get_records(
837 831 self, etb: TracebackType, number_of_lines_of_context: int, tb_offset: int
838 832 ):
839 833 assert etb is not None
840 834 context = number_of_lines_of_context - 1
841 835 after = context // 2
842 836 before = context - after
843 837 if self.has_colors:
844 838 style = get_style_by_name("default")
845 839 style = stack_data.style_with_executing_node(style, "bg:ansiyellow")
846 840 formatter = Terminal256Formatter(style=style)
847 841 else:
848 842 formatter = None
849 843 options = stack_data.Options(
850 844 before=before,
851 845 after=after,
852 846 pygments_formatter=formatter,
853 847 )
854 848 return list(stack_data.FrameInfo.stack_data(etb, options=options))[tb_offset:]
855 849
856 850 def structured_traceback(
857 851 self,
858 852 etype: type,
859 853 evalue: Optional[BaseException],
860 854 etb: Optional[TracebackType],
861 855 tb_offset: Optional[int] = None,
862 856 number_of_lines_of_context: int = 5,
863 857 ):
864 858 """Return a nice text document describing the traceback."""
865 859 formatted_exception = self.format_exception_as_a_whole(etype, evalue, etb, number_of_lines_of_context,
866 860 tb_offset)
867 861
868 862 colors = self.Colors # just a shorthand + quicker name lookup
869 863 colorsnormal = colors.Normal # used a lot
870 864 head = '%s%s%s' % (colors.topline, '-' * min(75, get_terminal_size()[0]), colorsnormal)
871 865 structured_traceback_parts = [head]
872 866 chained_exceptions_tb_offset = 0
873 867 lines_of_context = 3
874 868 formatted_exceptions = formatted_exception
875 869 exception = self.get_parts_of_chained_exception(evalue)
876 870 if exception:
877 871 assert evalue is not None
878 872 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
879 873 etype, evalue, etb = exception
880 874 else:
881 875 evalue = None
882 876 chained_exc_ids = set()
883 877 while evalue:
884 878 formatted_exceptions += self.format_exception_as_a_whole(etype, evalue, etb, lines_of_context,
885 879 chained_exceptions_tb_offset)
886 880 exception = self.get_parts_of_chained_exception(evalue)
887 881
888 882 if exception and not id(exception[1]) in chained_exc_ids:
889 883 chained_exc_ids.add(id(exception[1])) # trace exception to avoid infinite 'cause' loop
890 884 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
891 885 etype, evalue, etb = exception
892 886 else:
893 887 evalue = None
894 888
895 889 # we want to see exceptions in a reversed order:
896 890 # the first exception should be on top
897 891 for formatted_exception in reversed(formatted_exceptions):
898 892 structured_traceback_parts += formatted_exception
899 893
900 894 return structured_traceback_parts
901 895
902 896 def debugger(self, force: bool = False):
903 897 """Call up the pdb debugger if desired, always clean up the tb
904 898 reference.
905 899
906 900 Keywords:
907 901
908 902 - force(False): by default, this routine checks the instance call_pdb
909 903 flag and does not actually invoke the debugger if the flag is false.
910 904 The 'force' option forces the debugger to activate even if the flag
911 905 is false.
912 906
913 907 If the call_pdb flag is set, the pdb interactive debugger is
914 908 invoked. In all cases, the self.tb reference to the current traceback
915 909 is deleted to prevent lingering references which hamper memory
916 910 management.
917 911
918 912 Note that each call to pdb() does an 'import readline', so if your app
919 913 requires a special setup for the readline completers, you'll have to
920 914 fix that by hand after invoking the exception handler."""
921 915
922 916 if force or self.call_pdb:
923 917 if self.pdb is None:
924 918 self.pdb = self.debugger_cls()
925 919 # the system displayhook may have changed, restore the original
926 920 # for pdb
927 921 display_trap = DisplayTrap(hook=sys.__displayhook__)
928 922 with display_trap:
929 923 self.pdb.reset()
930 924 # Find the right frame so we don't pop up inside ipython itself
931 925 if hasattr(self, 'tb') and self.tb is not None:
932 926 etb = self.tb
933 927 else:
934 928 etb = self.tb = sys.last_traceback
935 929 while self.tb is not None and self.tb.tb_next is not None:
936 930 assert self.tb.tb_next is not None
937 931 self.tb = self.tb.tb_next
938 932 if etb and etb.tb_next:
939 933 etb = etb.tb_next
940 934 self.pdb.botframe = etb.tb_frame
941 935 self.pdb.interaction(None, etb)
942 936
943 937 if hasattr(self, 'tb'):
944 938 del self.tb
945 939
946 940 def handler(self, info=None):
947 941 (etype, evalue, etb) = info or sys.exc_info()
948 942 self.tb = etb
949 943 ostream = self.ostream
950 944 ostream.flush()
951 945 ostream.write(self.text(etype, evalue, etb))
952 946 ostream.write('\n')
953 947 ostream.flush()
954 948
955 949 # Changed so an instance can just be called as VerboseTB_inst() and print
956 950 # out the right info on its own.
957 951 def __call__(self, etype=None, evalue=None, etb=None):
958 952 """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
959 953 if etb is None:
960 954 self.handler()
961 955 else:
962 956 self.handler((etype, evalue, etb))
963 957 try:
964 958 self.debugger()
965 959 except KeyboardInterrupt:
966 960 print("\nKeyboardInterrupt")
967 961
968 962
969 963 #----------------------------------------------------------------------------
970 964 class FormattedTB(VerboseTB, ListTB):
971 965 """Subclass ListTB but allow calling with a traceback.
972 966
973 967 It can thus be used as a sys.excepthook for Python > 2.1.
974 968
975 969 Also adds 'Context' and 'Verbose' modes, not available in ListTB.
976 970
977 971 Allows a tb_offset to be specified. This is useful for situations where
978 972 one needs to remove a number of topmost frames from the traceback (such as
979 973 occurs with python programs that themselves execute other python code,
980 974 like Python shells). """
981 975
982 976 mode: str
983 977
984 978 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
985 979 ostream=None,
986 980 tb_offset=0, long_header=False, include_vars=False,
987 981 check_cache=None, debugger_cls=None,
988 982 parent=None, config=None):
989 983
990 984 # NEVER change the order of this list. Put new modes at the end:
991 985 self.valid_modes = ['Plain', 'Context', 'Verbose', 'Minimal']
992 986 self.verbose_modes = self.valid_modes[1:3]
993 987
994 988 VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
995 989 ostream=ostream, tb_offset=tb_offset,
996 990 long_header=long_header, include_vars=include_vars,
997 991 check_cache=check_cache, debugger_cls=debugger_cls,
998 992 parent=parent, config=config)
999 993
1000 994 # Different types of tracebacks are joined with different separators to
1001 995 # form a single string. They are taken from this dict
1002 996 self._join_chars = dict(Plain='', Context='\n', Verbose='\n',
1003 997 Minimal='')
1004 998 # set_mode also sets the tb_join_char attribute
1005 999 self.set_mode(mode)
1006 1000
1007 1001 def structured_traceback(self, etype, value, tb, tb_offset=None, number_of_lines_of_context=5):
1008 1002 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1009 1003 mode = self.mode
1010 1004 if mode in self.verbose_modes:
1011 1005 # Verbose modes need a full traceback
1012 1006 return VerboseTB.structured_traceback(
1013 1007 self, etype, value, tb, tb_offset, number_of_lines_of_context
1014 1008 )
1015 1009 elif mode == 'Minimal':
1016 1010 return ListTB.get_exception_only(self, etype, value)
1017 1011 else:
1018 1012 # We must check the source cache because otherwise we can print
1019 1013 # out-of-date source code.
1020 1014 self.check_cache()
1021 1015 # Now we can extract and format the exception
1022 1016 return ListTB.structured_traceback(
1023 1017 self, etype, value, tb, tb_offset, number_of_lines_of_context
1024 1018 )
1025 1019
1026 1020 def stb2text(self, stb):
1027 1021 """Convert a structured traceback (a list) to a string."""
1028 1022 return self.tb_join_char.join(stb)
1029 1023
1030 1024 def set_mode(self, mode: Optional[str] = None):
1031 1025 """Switch to the desired mode.
1032 1026
1033 1027 If mode is not specified, cycles through the available modes."""
1034 1028
1035 1029 if not mode:
1036 1030 new_idx = (self.valid_modes.index(self.mode) + 1 ) % \
1037 1031 len(self.valid_modes)
1038 1032 self.mode = self.valid_modes[new_idx]
1039 1033 elif mode not in self.valid_modes:
1040 1034 raise ValueError(
1041 1035 "Unrecognized mode in FormattedTB: <" + mode + ">\n"
1042 1036 "Valid modes: " + str(self.valid_modes)
1043 1037 )
1044 1038 else:
1045 1039 assert isinstance(mode, str)
1046 1040 self.mode = mode
1047 1041 # include variable details only in 'Verbose' mode
1048 1042 self.include_vars = (self.mode == self.valid_modes[2])
1049 1043 # Set the join character for generating text tracebacks
1050 1044 self.tb_join_char = self._join_chars[self.mode]
1051 1045
1052 1046 # some convenient shortcuts
1053 1047 def plain(self):
1054 1048 self.set_mode(self.valid_modes[0])
1055 1049
1056 1050 def context(self):
1057 1051 self.set_mode(self.valid_modes[1])
1058 1052
1059 1053 def verbose(self):
1060 1054 self.set_mode(self.valid_modes[2])
1061 1055
1062 1056 def minimal(self):
1063 1057 self.set_mode(self.valid_modes[3])
1064 1058
1065 1059
1066 1060 #----------------------------------------------------------------------------
1067 1061 class AutoFormattedTB(FormattedTB):
1068 1062 """A traceback printer which can be called on the fly.
1069 1063
1070 1064 It will find out about exceptions by itself.
1071 1065
1072 1066 A brief example::
1073 1067
1074 1068 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1075 1069 try:
1076 1070 ...
1077 1071 except:
1078 1072 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1079 1073 """
1080 1074
1081 1075 def __call__(self, etype=None, evalue=None, etb=None,
1082 1076 out=None, tb_offset=None):
1083 1077 """Print out a formatted exception traceback.
1084 1078
1085 1079 Optional arguments:
1086 1080 - out: an open file-like object to direct output to.
1087 1081
1088 1082 - tb_offset: the number of frames to skip over in the stack, on a
1089 1083 per-call basis (this overrides temporarily the instance's tb_offset
1090 1084 given at initialization time."""
1091 1085
1092 1086 if out is None:
1093 1087 out = self.ostream
1094 1088 out.flush()
1095 1089 out.write(self.text(etype, evalue, etb, tb_offset))
1096 1090 out.write('\n')
1097 1091 out.flush()
1098 1092 # FIXME: we should remove the auto pdb behavior from here and leave
1099 1093 # that to the clients.
1100 1094 try:
1101 1095 self.debugger()
1102 1096 except KeyboardInterrupt:
1103 1097 print("\nKeyboardInterrupt")
1104 1098
1105 1099 def structured_traceback(self, etype=None, value=None, tb=None,
1106 1100 tb_offset=None, number_of_lines_of_context=5):
1107 1101
1108 1102 etype: type
1109 1103 value: BaseException
1110 1104 # tb: TracebackType or tupleof tb types ?
1111 1105 if etype is None:
1112 1106 etype, value, tb = sys.exc_info()
1113 1107 if isinstance(tb, tuple):
1114 1108 # tb is a tuple if this is a chained exception.
1115 1109 self.tb = tb[0]
1116 1110 else:
1117 1111 self.tb = tb
1118 1112 return FormattedTB.structured_traceback(
1119 1113 self, etype, value, tb, tb_offset, number_of_lines_of_context)
1120 1114
1121 1115
1122 1116 #---------------------------------------------------------------------------
1123 1117
1124 1118 # A simple class to preserve Nathan's original functionality.
1125 1119 class ColorTB(FormattedTB):
1126 1120 """Shorthand to initialize a FormattedTB in Linux colors mode."""
1127 1121
1128 1122 def __init__(self, color_scheme='Linux', call_pdb=0, **kwargs):
1129 1123 FormattedTB.__init__(self, color_scheme=color_scheme,
1130 1124 call_pdb=call_pdb, **kwargs)
1131 1125
1132 1126
1133 1127 class SyntaxTB(ListTB):
1134 1128 """Extension which holds some state: the last exception value"""
1135 1129
1136 1130 def __init__(self, color_scheme='NoColor', parent=None, config=None):
1137 1131 ListTB.__init__(self, color_scheme, parent=parent, config=config)
1138 1132 self.last_syntax_error = None
1139 1133
1140 1134 def __call__(self, etype, value, elist):
1141 1135 self.last_syntax_error = value
1142 1136
1143 1137 ListTB.__call__(self, etype, value, elist)
1144 1138
1145 1139 def structured_traceback(self, etype, value, elist, tb_offset=None,
1146 1140 context=5):
1147 1141 # If the source file has been edited, the line in the syntax error can
1148 1142 # be wrong (retrieved from an outdated cache). This replaces it with
1149 1143 # the current value.
1150 1144 if isinstance(value, SyntaxError) \
1151 1145 and isinstance(value.filename, str) \
1152 1146 and isinstance(value.lineno, int):
1153 1147 linecache.checkcache(value.filename)
1154 1148 newtext = linecache.getline(value.filename, value.lineno)
1155 1149 if newtext:
1156 1150 value.text = newtext
1157 1151 self.last_syntax_error = value
1158 1152 return super(SyntaxTB, self).structured_traceback(etype, value, elist,
1159 1153 tb_offset=tb_offset, context=context)
1160 1154
1161 1155 def clear_err_state(self):
1162 1156 """Return the current error state and clear it"""
1163 1157 e = self.last_syntax_error
1164 1158 self.last_syntax_error = None
1165 1159 return e
1166 1160
1167 1161 def stb2text(self, stb):
1168 1162 """Convert a structured traceback (a list) to a string."""
1169 1163 return ''.join(stb)
1170 1164
1171 1165
1172 1166 # some internal-use functions
1173 1167 def text_repr(value):
1174 1168 """Hopefully pretty robust repr equivalent."""
1175 1169 # this is pretty horrible but should always return *something*
1176 1170 try:
1177 1171 return pydoc.text.repr(value)
1178 1172 except KeyboardInterrupt:
1179 1173 raise
1180 1174 except:
1181 1175 try:
1182 1176 return repr(value)
1183 1177 except KeyboardInterrupt:
1184 1178 raise
1185 1179 except:
1186 1180 try:
1187 1181 # all still in an except block so we catch
1188 1182 # getattr raising
1189 1183 name = getattr(value, '__name__', None)
1190 1184 if name:
1191 1185 # ick, recursion
1192 1186 return text_repr(name)
1193 1187 klass = getattr(value, '__class__', None)
1194 1188 if klass:
1195 1189 return '%s instance' % text_repr(klass)
1196 1190 except KeyboardInterrupt:
1197 1191 raise
1198 1192 except:
1199 1193 return 'UNRECOVERABLE REPR FAILURE'
1200 1194
1201 1195
1202 1196 def eqrepr(value, repr=text_repr):
1203 1197 return '=%s' % repr(value)
1204 1198
1205 1199
1206 1200 def nullrepr(value, repr=text_repr):
1207 1201 return ''
General Comments 0
You need to be logged in to leave comments. Login now