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