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