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