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