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