##// END OF EJS Templates
Merge pull request #13506 from Carreau/lazy-magics...
Matthias Bussonnier -
r27505:ca8b6d57 merge
parent child Browse files
Show More
@@ -1,3664 +1,3695 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Main IPython class."""
3 3
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 7 # Copyright (C) 2008-2011 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13
14 14 import abc
15 15 import ast
16 16 import atexit
17 17 import builtins as builtin_mod
18 18 import functools
19 19 import inspect
20 20 import os
21 21 import re
22 22 import runpy
23 23 import sys
24 24 import tempfile
25 25 import traceback
26 26 import types
27 27 import subprocess
28 28 import warnings
29 29 from io import open as io_open
30 30
31 31 from pathlib import Path
32 32 from pickleshare import PickleShareDB
33 33
34 34 from traitlets.config.configurable import SingletonConfigurable
35 35 from traitlets.utils.importstring import import_item
36 36 from IPython.core import oinspect
37 37 from IPython.core import magic
38 38 from IPython.core import page
39 39 from IPython.core import prefilter
40 40 from IPython.core import ultratb
41 41 from IPython.core.alias import Alias, AliasManager
42 42 from IPython.core.autocall import ExitAutocall
43 43 from IPython.core.builtin_trap import BuiltinTrap
44 44 from IPython.core.events import EventManager, available_events
45 45 from IPython.core.compilerop import CachingCompiler, check_linecache_ipython
46 46 from IPython.core.debugger import InterruptiblePdb
47 47 from IPython.core.display_trap import DisplayTrap
48 48 from IPython.core.displayhook import DisplayHook
49 49 from IPython.core.displaypub import DisplayPublisher
50 50 from IPython.core.error import InputRejected, UsageError
51 51 from IPython.core.extensions import ExtensionManager
52 52 from IPython.core.formatters import DisplayFormatter
53 53 from IPython.core.history import HistoryManager
54 54 from IPython.core.inputtransformer2 import ESC_MAGIC, ESC_MAGIC2
55 55 from IPython.core.logger import Logger
56 56 from IPython.core.macro import Macro
57 57 from IPython.core.payload import PayloadManager
58 58 from IPython.core.prefilter import PrefilterManager
59 59 from IPython.core.profiledir import ProfileDir
60 60 from IPython.core.usage import default_banner
61 61 from IPython.display import display
62 62 from IPython.testing.skipdoctest import skip_doctest
63 63 from IPython.utils import PyColorize
64 64 from IPython.utils import io
65 65 from IPython.utils import py3compat
66 66 from IPython.utils import openpy
67 67 from IPython.utils.decorators import undoc
68 68 from IPython.utils.io import ask_yes_no
69 69 from IPython.utils.ipstruct import Struct
70 70 from IPython.paths import get_ipython_dir
71 71 from IPython.utils.path import get_home_dir, get_py_filename, ensure_dir_exists
72 72 from IPython.utils.process import system, getoutput
73 73 from IPython.utils.strdispatch import StrDispatch
74 74 from IPython.utils.syspathcontext import prepended_to_syspath
75 75 from IPython.utils.text import format_screen, LSString, SList, DollarFormatter
76 76 from IPython.utils.tempdir import TemporaryDirectory
77 77 from traitlets import (
78 78 Integer, Bool, CaselessStrEnum, Enum, List, Dict, Unicode, Instance, Type,
79 79 observe, default, validate, Any
80 80 )
81 81 from warnings import warn
82 82 from logging import error
83 83 import IPython.core.hooks
84 84
85 85 from typing import List as ListType, Tuple, Optional, Callable
86 86 from ast import stmt
87 87
88 88 sphinxify: Optional[Callable]
89 89
90 90 try:
91 91 import docrepr.sphinxify as sphx
92 92
93 93 def sphinxify(oinfo):
94 94 wrapped_docstring = sphx.wrap_main_docstring(oinfo)
95 95
96 96 def sphinxify_docstring(docstring):
97 97 with TemporaryDirectory() as dirname:
98 98 return {
99 99 "text/html": sphx.sphinxify(wrapped_docstring, dirname),
100 100 "text/plain": docstring,
101 101 }
102 102
103 103 return sphinxify_docstring
104 104 except ImportError:
105 105 sphinxify = None
106 106
107 107
108 108 class ProvisionalWarning(DeprecationWarning):
109 109 """
110 110 Warning class for unstable features
111 111 """
112 112 pass
113 113
114 114 from ast import Module
115 115
116 116 _assign_nodes = (ast.AugAssign, ast.AnnAssign, ast.Assign)
117 117 _single_targets_nodes = (ast.AugAssign, ast.AnnAssign)
118 118
119 119 #-----------------------------------------------------------------------------
120 120 # Await Helpers
121 121 #-----------------------------------------------------------------------------
122 122
123 123 # we still need to run things using the asyncio eventloop, but there is no
124 124 # async integration
125 125 from .async_helpers import _asyncio_runner, _pseudo_sync_runner
126 126 from .async_helpers import _curio_runner, _trio_runner, _should_be_async
127 127
128 128 #-----------------------------------------------------------------------------
129 129 # Globals
130 130 #-----------------------------------------------------------------------------
131 131
132 132 # compiled regexps for autoindent management
133 133 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
134 134
135 135 #-----------------------------------------------------------------------------
136 136 # Utilities
137 137 #-----------------------------------------------------------------------------
138 138
139 139 @undoc
140 140 def softspace(file, newvalue):
141 141 """Copied from code.py, to remove the dependency"""
142 142
143 143 oldvalue = 0
144 144 try:
145 145 oldvalue = file.softspace
146 146 except AttributeError:
147 147 pass
148 148 try:
149 149 file.softspace = newvalue
150 150 except (AttributeError, TypeError):
151 151 # "attribute-less object" or "read-only attributes"
152 152 pass
153 153 return oldvalue
154 154
155 155 @undoc
156 156 def no_op(*a, **kw):
157 157 pass
158 158
159 159
160 160 class SpaceInInput(Exception): pass
161 161
162 162
163 163 class SeparateUnicode(Unicode):
164 164 r"""A Unicode subclass to validate separate_in, separate_out, etc.
165 165
166 166 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
167 167 """
168 168
169 169 def validate(self, obj, value):
170 170 if value == '0': value = ''
171 171 value = value.replace('\\n','\n')
172 172 return super(SeparateUnicode, self).validate(obj, value)
173 173
174 174
175 175 @undoc
176 176 class DummyMod(object):
177 177 """A dummy module used for IPython's interactive module when
178 178 a namespace must be assigned to the module's __dict__."""
179 179 __spec__ = None
180 180
181 181
182 182 class ExecutionInfo(object):
183 183 """The arguments used for a call to :meth:`InteractiveShell.run_cell`
184 184
185 185 Stores information about what is going to happen.
186 186 """
187 187 raw_cell = None
188 188 store_history = False
189 189 silent = False
190 190 shell_futures = True
191 191
192 192 def __init__(self, raw_cell, store_history, silent, shell_futures):
193 193 self.raw_cell = raw_cell
194 194 self.store_history = store_history
195 195 self.silent = silent
196 196 self.shell_futures = shell_futures
197 197
198 198 def __repr__(self):
199 199 name = self.__class__.__qualname__
200 200 raw_cell = ((self.raw_cell[:50] + '..')
201 201 if len(self.raw_cell) > 50 else self.raw_cell)
202 202 return '<%s object at %x, raw_cell="%s" store_history=%s silent=%s shell_futures=%s>' %\
203 203 (name, id(self), raw_cell, self.store_history, self.silent, self.shell_futures)
204 204
205 205
206 206 class ExecutionResult(object):
207 207 """The result of a call to :meth:`InteractiveShell.run_cell`
208 208
209 209 Stores information about what took place.
210 210 """
211 211 execution_count = None
212 212 error_before_exec = None
213 213 error_in_exec: Optional[BaseException] = None
214 214 info = None
215 215 result = None
216 216
217 217 def __init__(self, info):
218 218 self.info = info
219 219
220 220 @property
221 221 def success(self):
222 222 return (self.error_before_exec is None) and (self.error_in_exec is None)
223 223
224 224 def raise_error(self):
225 225 """Reraises error if `success` is `False`, otherwise does nothing"""
226 226 if self.error_before_exec is not None:
227 227 raise self.error_before_exec
228 228 if self.error_in_exec is not None:
229 229 raise self.error_in_exec
230 230
231 231 def __repr__(self):
232 232 name = self.__class__.__qualname__
233 233 return '<%s object at %x, execution_count=%s error_before_exec=%s error_in_exec=%s info=%s result=%s>' %\
234 234 (name, id(self), self.execution_count, self.error_before_exec, self.error_in_exec, repr(self.info), repr(self.result))
235 235
236 236
237 237 class InteractiveShell(SingletonConfigurable):
238 238 """An enhanced, interactive shell for Python."""
239 239
240 240 _instance = None
241 241
242 242 ast_transformers = List([], help=
243 243 """
244 244 A list of ast.NodeTransformer subclass instances, which will be applied
245 245 to user input before code is run.
246 246 """
247 247 ).tag(config=True)
248 248
249 249 autocall = Enum((0,1,2), default_value=0, help=
250 250 """
251 251 Make IPython automatically call any callable object even if you didn't
252 252 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
253 253 automatically. The value can be '0' to disable the feature, '1' for
254 254 'smart' autocall, where it is not applied if there are no more
255 255 arguments on the line, and '2' for 'full' autocall, where all callable
256 256 objects are automatically called (even if no arguments are present).
257 257 """
258 258 ).tag(config=True)
259 259
260 260 autoindent = Bool(True, help=
261 261 """
262 262 Autoindent IPython code entered interactively.
263 263 """
264 264 ).tag(config=True)
265 265
266 266 autoawait = Bool(True, help=
267 267 """
268 268 Automatically run await statement in the top level repl.
269 269 """
270 270 ).tag(config=True)
271 271
272 272 loop_runner_map ={
273 273 'asyncio':(_asyncio_runner, True),
274 274 'curio':(_curio_runner, True),
275 275 'trio':(_trio_runner, True),
276 276 'sync': (_pseudo_sync_runner, False)
277 277 }
278 278
279 279 loop_runner = Any(default_value="IPython.core.interactiveshell._asyncio_runner",
280 280 allow_none=True,
281 281 help="""Select the loop runner that will be used to execute top-level asynchronous code"""
282 282 ).tag(config=True)
283 283
284 284 @default('loop_runner')
285 285 def _default_loop_runner(self):
286 286 return import_item("IPython.core.interactiveshell._asyncio_runner")
287 287
288 288 @validate('loop_runner')
289 289 def _import_runner(self, proposal):
290 290 if isinstance(proposal.value, str):
291 291 if proposal.value in self.loop_runner_map:
292 292 runner, autoawait = self.loop_runner_map[proposal.value]
293 293 self.autoawait = autoawait
294 294 return runner
295 295 runner = import_item(proposal.value)
296 296 if not callable(runner):
297 297 raise ValueError('loop_runner must be callable')
298 298 return runner
299 299 if not callable(proposal.value):
300 300 raise ValueError('loop_runner must be callable')
301 301 return proposal.value
302 302
303 303 automagic = Bool(True, help=
304 304 """
305 305 Enable magic commands to be called without the leading %.
306 306 """
307 307 ).tag(config=True)
308 308
309 309 banner1 = Unicode(default_banner,
310 310 help="""The part of the banner to be printed before the profile"""
311 311 ).tag(config=True)
312 312 banner2 = Unicode('',
313 313 help="""The part of the banner to be printed after the profile"""
314 314 ).tag(config=True)
315 315
316 316 cache_size = Integer(1000, help=
317 317 """
318 318 Set the size of the output cache. The default is 1000, you can
319 319 change it permanently in your config file. Setting it to 0 completely
320 320 disables the caching system, and the minimum value accepted is 3 (if
321 321 you provide a value less than 3, it is reset to 0 and a warning is
322 322 issued). This limit is defined because otherwise you'll spend more
323 323 time re-flushing a too small cache than working
324 324 """
325 325 ).tag(config=True)
326 326 color_info = Bool(True, help=
327 327 """
328 328 Use colors for displaying information about objects. Because this
329 329 information is passed through a pager (like 'less'), and some pagers
330 330 get confused with color codes, this capability can be turned off.
331 331 """
332 332 ).tag(config=True)
333 333 colors = CaselessStrEnum(('Neutral', 'NoColor','LightBG','Linux'),
334 334 default_value='Neutral',
335 335 help="Set the color scheme (NoColor, Neutral, Linux, or LightBG)."
336 336 ).tag(config=True)
337 337 debug = Bool(False).tag(config=True)
338 338 disable_failing_post_execute = Bool(False,
339 339 help="Don't call post-execute functions that have failed in the past."
340 340 ).tag(config=True)
341 341 display_formatter = Instance(DisplayFormatter, allow_none=True)
342 342 displayhook_class = Type(DisplayHook)
343 343 display_pub_class = Type(DisplayPublisher)
344 344 compiler_class = Type(CachingCompiler)
345 345
346 346 sphinxify_docstring = Bool(False, help=
347 347 """
348 348 Enables rich html representation of docstrings. (This requires the
349 349 docrepr module).
350 350 """).tag(config=True)
351 351
352 352 @observe("sphinxify_docstring")
353 353 def _sphinxify_docstring_changed(self, change):
354 354 if change['new']:
355 355 warn("`sphinxify_docstring` is provisional since IPython 5.0 and might change in future versions." , ProvisionalWarning)
356 356
357 357 enable_html_pager = Bool(False, help=
358 358 """
359 359 (Provisional API) enables html representation in mime bundles sent
360 360 to pagers.
361 361 """).tag(config=True)
362 362
363 363 @observe("enable_html_pager")
364 364 def _enable_html_pager_changed(self, change):
365 365 if change['new']:
366 366 warn("`enable_html_pager` is provisional since IPython 5.0 and might change in future versions.", ProvisionalWarning)
367 367
368 368 data_pub_class = None
369 369
370 370 exit_now = Bool(False)
371 371 exiter = Instance(ExitAutocall)
372 372 @default('exiter')
373 373 def _exiter_default(self):
374 374 return ExitAutocall(self)
375 375 # Monotonically increasing execution counter
376 376 execution_count = Integer(1)
377 377 filename = Unicode("<ipython console>")
378 378 ipython_dir= Unicode('').tag(config=True) # Set to get_ipython_dir() in __init__
379 379
380 380 # Used to transform cells before running them, and check whether code is complete
381 381 input_transformer_manager = Instance('IPython.core.inputtransformer2.TransformerManager',
382 382 ())
383 383
384 384 @property
385 385 def input_transformers_cleanup(self):
386 386 return self.input_transformer_manager.cleanup_transforms
387 387
388 388 input_transformers_post = List([],
389 389 help="A list of string input transformers, to be applied after IPython's "
390 390 "own input transformations."
391 391 )
392 392
393 393 @property
394 394 def input_splitter(self):
395 395 """Make this available for backward compatibility (pre-7.0 release) with existing code.
396 396
397 397 For example, ipykernel ipykernel currently uses
398 398 `shell.input_splitter.check_complete`
399 399 """
400 400 from warnings import warn
401 401 warn("`input_splitter` is deprecated since IPython 7.0, prefer `input_transformer_manager`.",
402 402 DeprecationWarning, stacklevel=2
403 403 )
404 404 return self.input_transformer_manager
405 405
406 406 logstart = Bool(False, help=
407 407 """
408 408 Start logging to the default log file in overwrite mode.
409 409 Use `logappend` to specify a log file to **append** logs to.
410 410 """
411 411 ).tag(config=True)
412 412 logfile = Unicode('', help=
413 413 """
414 414 The name of the logfile to use.
415 415 """
416 416 ).tag(config=True)
417 417 logappend = Unicode('', help=
418 418 """
419 419 Start logging to the given file in append mode.
420 420 Use `logfile` to specify a log file to **overwrite** logs to.
421 421 """
422 422 ).tag(config=True)
423 423 object_info_string_level = Enum((0,1,2), default_value=0,
424 424 ).tag(config=True)
425 425 pdb = Bool(False, help=
426 426 """
427 427 Automatically call the pdb debugger after every exception.
428 428 """
429 429 ).tag(config=True)
430 430 display_page = Bool(False,
431 431 help="""If True, anything that would be passed to the pager
432 432 will be displayed as regular output instead."""
433 433 ).tag(config=True)
434 434
435 435
436 436 show_rewritten_input = Bool(True,
437 437 help="Show rewritten input, e.g. for autocall."
438 438 ).tag(config=True)
439 439
440 440 quiet = Bool(False).tag(config=True)
441 441
442 442 history_length = Integer(10000,
443 443 help='Total length of command history'
444 444 ).tag(config=True)
445 445
446 446 history_load_length = Integer(1000, help=
447 447 """
448 448 The number of saved history entries to be loaded
449 449 into the history buffer at startup.
450 450 """
451 451 ).tag(config=True)
452 452
453 453 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none', 'last_expr_or_assign'],
454 454 default_value='last_expr',
455 455 help="""
456 456 'all', 'last', 'last_expr' or 'none', 'last_expr_or_assign' specifying
457 457 which nodes should be run interactively (displaying output from expressions).
458 458 """
459 459 ).tag(config=True)
460 460
461 461 # TODO: this part of prompt management should be moved to the frontends.
462 462 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
463 463 separate_in = SeparateUnicode('\n').tag(config=True)
464 464 separate_out = SeparateUnicode('').tag(config=True)
465 465 separate_out2 = SeparateUnicode('').tag(config=True)
466 466 wildcards_case_sensitive = Bool(True).tag(config=True)
467 467 xmode = CaselessStrEnum(('Context', 'Plain', 'Verbose', 'Minimal'),
468 468 default_value='Context',
469 469 help="Switch modes for the IPython exception handlers."
470 470 ).tag(config=True)
471 471
472 472 # Subcomponents of InteractiveShell
473 473 alias_manager = Instance('IPython.core.alias.AliasManager', allow_none=True)
474 474 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
475 475 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap', allow_none=True)
476 476 display_trap = Instance('IPython.core.display_trap.DisplayTrap', allow_none=True)
477 477 extension_manager = Instance('IPython.core.extensions.ExtensionManager', allow_none=True)
478 478 payload_manager = Instance('IPython.core.payload.PayloadManager', allow_none=True)
479 479 history_manager = Instance('IPython.core.history.HistoryAccessorBase', allow_none=True)
480 480 magics_manager = Instance('IPython.core.magic.MagicsManager', allow_none=True)
481 481
482 482 profile_dir = Instance('IPython.core.application.ProfileDir', allow_none=True)
483 483 @property
484 484 def profile(self):
485 485 if self.profile_dir is not None:
486 486 name = os.path.basename(self.profile_dir.location)
487 487 return name.replace('profile_','')
488 488
489 489
490 490 # Private interface
491 491 _post_execute = Dict()
492 492
493 493 # Tracks any GUI loop loaded for pylab
494 494 pylab_gui_select = None
495 495
496 496 last_execution_succeeded = Bool(True, help='Did last executed command succeeded')
497 497
498 498 last_execution_result = Instance('IPython.core.interactiveshell.ExecutionResult', help='Result of executing the last command', allow_none=True)
499 499
500 500 def __init__(self, ipython_dir=None, profile_dir=None,
501 501 user_module=None, user_ns=None,
502 502 custom_exceptions=((), None), **kwargs):
503
504 503 # This is where traits with a config_key argument are updated
505 504 # from the values on config.
506 505 super(InteractiveShell, self).__init__(**kwargs)
507 506 if 'PromptManager' in self.config:
508 507 warn('As of IPython 5.0 `PromptManager` config will have no effect'
509 508 ' and has been replaced by TerminalInteractiveShell.prompts_class')
510 509 self.configurables = [self]
511 510
512 511 # These are relatively independent and stateless
513 512 self.init_ipython_dir(ipython_dir)
514 513 self.init_profile_dir(profile_dir)
515 514 self.init_instance_attrs()
516 515 self.init_environment()
517 516
518 517 # Check if we're in a virtualenv, and set up sys.path.
519 518 self.init_virtualenv()
520 519
521 520 # Create namespaces (user_ns, user_global_ns, etc.)
522 521 self.init_create_namespaces(user_module, user_ns)
523 522 # This has to be done after init_create_namespaces because it uses
524 523 # something in self.user_ns, but before init_sys_modules, which
525 524 # is the first thing to modify sys.
526 525 # TODO: When we override sys.stdout and sys.stderr before this class
527 526 # is created, we are saving the overridden ones here. Not sure if this
528 527 # is what we want to do.
529 528 self.save_sys_module_state()
530 529 self.init_sys_modules()
531 530
532 531 # While we're trying to have each part of the code directly access what
533 532 # it needs without keeping redundant references to objects, we have too
534 533 # much legacy code that expects ip.db to exist.
535 534 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
536 535
537 536 self.init_history()
538 537 self.init_encoding()
539 538 self.init_prefilter()
540 539
541 540 self.init_syntax_highlighting()
542 541 self.init_hooks()
543 542 self.init_events()
544 543 self.init_pushd_popd_magic()
545 544 self.init_user_ns()
546 545 self.init_logger()
547 546 self.init_builtins()
548 547
549 548 # The following was in post_config_initialization
550 549 self.init_inspector()
551 550 self.raw_input_original = input
552 551 self.init_completer()
553 552 # TODO: init_io() needs to happen before init_traceback handlers
554 553 # because the traceback handlers hardcode the stdout/stderr streams.
555 554 # This logic in in debugger.Pdb and should eventually be changed.
556 555 self.init_io()
557 556 self.init_traceback_handlers(custom_exceptions)
558 557 self.init_prompts()
559 558 self.init_display_formatter()
560 559 self.init_display_pub()
561 560 self.init_data_pub()
562 561 self.init_displayhook()
563 562 self.init_magics()
564 563 self.init_alias()
565 564 self.init_logstart()
566 565 self.init_pdb()
567 566 self.init_extension_manager()
568 567 self.init_payload()
569 568 self.events.trigger('shell_initialized', self)
570 569 atexit.register(self.atexit_operations)
571 570
572 571 # The trio runner is used for running Trio in the foreground thread. It
573 572 # is different from `_trio_runner(async_fn)` in `async_helpers.py`
574 573 # which calls `trio.run()` for every cell. This runner runs all cells
575 574 # inside a single Trio event loop. If used, it is set from
576 575 # `ipykernel.kernelapp`.
577 576 self.trio_runner = None
578 577
579 578 def get_ipython(self):
580 579 """Return the currently running IPython instance."""
581 580 return self
582 581
583 582 #-------------------------------------------------------------------------
584 583 # Trait changed handlers
585 584 #-------------------------------------------------------------------------
586 585 @observe('ipython_dir')
587 586 def _ipython_dir_changed(self, change):
588 587 ensure_dir_exists(change['new'])
589 588
590 589 def set_autoindent(self,value=None):
591 590 """Set the autoindent flag.
592 591
593 592 If called with no arguments, it acts as a toggle."""
594 593 if value is None:
595 594 self.autoindent = not self.autoindent
596 595 else:
597 596 self.autoindent = value
598 597
599 598 def set_trio_runner(self, tr):
600 599 self.trio_runner = tr
601 600
602 601 #-------------------------------------------------------------------------
603 602 # init_* methods called by __init__
604 603 #-------------------------------------------------------------------------
605 604
606 605 def init_ipython_dir(self, ipython_dir):
607 606 if ipython_dir is not None:
608 607 self.ipython_dir = ipython_dir
609 608 return
610 609
611 610 self.ipython_dir = get_ipython_dir()
612 611
613 612 def init_profile_dir(self, profile_dir):
614 613 if profile_dir is not None:
615 614 self.profile_dir = profile_dir
616 615 return
617 616 self.profile_dir = ProfileDir.create_profile_dir_by_name(
618 617 self.ipython_dir, "default"
619 618 )
620 619
621 620 def init_instance_attrs(self):
622 621 self.more = False
623 622
624 623 # command compiler
625 624 self.compile = self.compiler_class()
626 625
627 626 # Make an empty namespace, which extension writers can rely on both
628 627 # existing and NEVER being used by ipython itself. This gives them a
629 628 # convenient location for storing additional information and state
630 629 # their extensions may require, without fear of collisions with other
631 630 # ipython names that may develop later.
632 631 self.meta = Struct()
633 632
634 633 # Temporary files used for various purposes. Deleted at exit.
635 634 # The files here are stored with Path from Pathlib
636 635 self.tempfiles = []
637 636 self.tempdirs = []
638 637
639 638 # keep track of where we started running (mainly for crash post-mortem)
640 639 # This is not being used anywhere currently.
641 640 self.starting_dir = os.getcwd()
642 641
643 642 # Indentation management
644 643 self.indent_current_nsp = 0
645 644
646 645 # Dict to track post-execution functions that have been registered
647 646 self._post_execute = {}
648 647
649 648 def init_environment(self):
650 649 """Any changes we need to make to the user's environment."""
651 650 pass
652 651
653 652 def init_encoding(self):
654 653 # Get system encoding at startup time. Certain terminals (like Emacs
655 654 # under Win32 have it set to None, and we need to have a known valid
656 655 # encoding to use in the raw_input() method
657 656 try:
658 657 self.stdin_encoding = sys.stdin.encoding or 'ascii'
659 658 except AttributeError:
660 659 self.stdin_encoding = 'ascii'
661 660
662 661
663 662 @observe('colors')
664 663 def init_syntax_highlighting(self, changes=None):
665 664 # Python source parser/formatter for syntax highlighting
666 665 pyformat = PyColorize.Parser(style=self.colors, parent=self).format
667 666 self.pycolorize = lambda src: pyformat(src,'str')
668 667
669 668 def refresh_style(self):
670 669 # No-op here, used in subclass
671 670 pass
672 671
673 672 def init_pushd_popd_magic(self):
674 673 # for pushd/popd management
675 674 self.home_dir = get_home_dir()
676 675
677 676 self.dir_stack = []
678 677
679 678 def init_logger(self):
680 679 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
681 680 logmode='rotate')
682 681
683 682 def init_logstart(self):
684 683 """Initialize logging in case it was requested at the command line.
685 684 """
686 685 if self.logappend:
687 686 self.magic('logstart %s append' % self.logappend)
688 687 elif self.logfile:
689 688 self.magic('logstart %s' % self.logfile)
690 689 elif self.logstart:
691 690 self.magic('logstart')
692 691
693 692
694 693 def init_builtins(self):
695 694 # A single, static flag that we set to True. Its presence indicates
696 695 # that an IPython shell has been created, and we make no attempts at
697 696 # removing on exit or representing the existence of more than one
698 697 # IPython at a time.
699 698 builtin_mod.__dict__['__IPYTHON__'] = True
700 699 builtin_mod.__dict__['display'] = display
701 700
702 701 self.builtin_trap = BuiltinTrap(shell=self)
703 702
704 703 @observe('colors')
705 704 def init_inspector(self, changes=None):
706 705 # Object inspector
707 706 self.inspector = oinspect.Inspector(oinspect.InspectColors,
708 707 PyColorize.ANSICodeColors,
709 708 self.colors,
710 709 self.object_info_string_level)
711 710
712 711 def init_io(self):
713 712 # implemented in subclasses, TerminalInteractiveShell does call
714 713 # colorama.init().
715 714 pass
716 715
717 716 def init_prompts(self):
718 717 # Set system prompts, so that scripts can decide if they are running
719 718 # interactively.
720 719 sys.ps1 = 'In : '
721 720 sys.ps2 = '...: '
722 721 sys.ps3 = 'Out: '
723 722
724 723 def init_display_formatter(self):
725 724 self.display_formatter = DisplayFormatter(parent=self)
726 725 self.configurables.append(self.display_formatter)
727 726
728 727 def init_display_pub(self):
729 728 self.display_pub = self.display_pub_class(parent=self, shell=self)
730 729 self.configurables.append(self.display_pub)
731 730
732 731 def init_data_pub(self):
733 732 if not self.data_pub_class:
734 733 self.data_pub = None
735 734 return
736 735 self.data_pub = self.data_pub_class(parent=self)
737 736 self.configurables.append(self.data_pub)
738 737
739 738 def init_displayhook(self):
740 739 # Initialize displayhook, set in/out prompts and printing system
741 740 self.displayhook = self.displayhook_class(
742 741 parent=self,
743 742 shell=self,
744 743 cache_size=self.cache_size,
745 744 )
746 745 self.configurables.append(self.displayhook)
747 746 # This is a context manager that installs/revmoes the displayhook at
748 747 # the appropriate time.
749 748 self.display_trap = DisplayTrap(hook=self.displayhook)
750 749
751 750 def init_virtualenv(self):
752 751 """Add the current virtualenv to sys.path so the user can import modules from it.
753 752 This isn't perfect: it doesn't use the Python interpreter with which the
754 753 virtualenv was built, and it ignores the --no-site-packages option. A
755 754 warning will appear suggesting the user installs IPython in the
756 755 virtualenv, but for many cases, it probably works well enough.
757 756
758 757 Adapted from code snippets online.
759 758
760 759 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
761 760 """
762 761 if 'VIRTUAL_ENV' not in os.environ:
763 762 # Not in a virtualenv
764 763 return
765 764 elif os.environ["VIRTUAL_ENV"] == "":
766 765 warn("Virtual env path set to '', please check if this is intended.")
767 766 return
768 767
769 768 p = Path(sys.executable)
770 769 p_venv = Path(os.environ["VIRTUAL_ENV"])
771 770
772 771 # fallback venv detection:
773 772 # stdlib venv may symlink sys.executable, so we can't use realpath.
774 773 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
775 774 # So we just check every item in the symlink tree (generally <= 3)
776 775 paths = [p]
777 776 while p.is_symlink():
778 777 p = Path(os.readlink(p))
779 778 paths.append(p.resolve())
780 779
781 780 # In Cygwin paths like "c:\..." and '\cygdrive\c\...' are possible
782 781 if p_venv.parts[1] == "cygdrive":
783 782 drive_name = p_venv.parts[2]
784 783 p_venv = (drive_name + ":/") / Path(*p_venv.parts[3:])
785 784
786 785 if any(p_venv == p.parents[1] for p in paths):
787 786 # Our exe is inside or has access to the virtualenv, don't need to do anything.
788 787 return
789 788
790 789 if sys.platform == "win32":
791 790 virtual_env = str(Path(os.environ["VIRTUAL_ENV"], "Lib", "site-packages"))
792 791 else:
793 792 virtual_env_path = Path(
794 793 os.environ["VIRTUAL_ENV"], "lib", "python{}.{}", "site-packages"
795 794 )
796 795 p_ver = sys.version_info[:2]
797 796
798 797 # Predict version from py[thon]-x.x in the $VIRTUAL_ENV
799 798 re_m = re.search(r"\bpy(?:thon)?([23])\.(\d+)\b", os.environ["VIRTUAL_ENV"])
800 799 if re_m:
801 800 predicted_path = Path(str(virtual_env_path).format(*re_m.groups()))
802 801 if predicted_path.exists():
803 802 p_ver = re_m.groups()
804 803
805 804 virtual_env = str(virtual_env_path).format(*p_ver)
806 805
807 806 warn(
808 807 "Attempting to work in a virtualenv. If you encounter problems, "
809 808 "please install IPython inside the virtualenv."
810 809 )
811 810 import site
812 811 sys.path.insert(0, virtual_env)
813 812 site.addsitedir(virtual_env)
814 813
815 814 #-------------------------------------------------------------------------
816 815 # Things related to injections into the sys module
817 816 #-------------------------------------------------------------------------
818 817
819 818 def save_sys_module_state(self):
820 819 """Save the state of hooks in the sys module.
821 820
822 821 This has to be called after self.user_module is created.
823 822 """
824 823 self._orig_sys_module_state = {'stdin': sys.stdin,
825 824 'stdout': sys.stdout,
826 825 'stderr': sys.stderr,
827 826 'excepthook': sys.excepthook}
828 827 self._orig_sys_modules_main_name = self.user_module.__name__
829 828 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
830 829
831 830 def restore_sys_module_state(self):
832 831 """Restore the state of the sys module."""
833 832 try:
834 833 for k, v in self._orig_sys_module_state.items():
835 834 setattr(sys, k, v)
836 835 except AttributeError:
837 836 pass
838 837 # Reset what what done in self.init_sys_modules
839 838 if self._orig_sys_modules_main_mod is not None:
840 839 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
841 840
842 841 #-------------------------------------------------------------------------
843 842 # Things related to the banner
844 843 #-------------------------------------------------------------------------
845 844
846 845 @property
847 846 def banner(self):
848 847 banner = self.banner1
849 848 if self.profile and self.profile != 'default':
850 849 banner += '\nIPython profile: %s\n' % self.profile
851 850 if self.banner2:
852 851 banner += '\n' + self.banner2
853 852 return banner
854 853
855 854 def show_banner(self, banner=None):
856 855 if banner is None:
857 856 banner = self.banner
858 857 sys.stdout.write(banner)
859 858
860 859 #-------------------------------------------------------------------------
861 860 # Things related to hooks
862 861 #-------------------------------------------------------------------------
863 862
864 863 def init_hooks(self):
865 864 # hooks holds pointers used for user-side customizations
866 865 self.hooks = Struct()
867 866
868 867 self.strdispatchers = {}
869 868
870 869 # Set all default hooks, defined in the IPython.hooks module.
871 870 hooks = IPython.core.hooks
872 871 for hook_name in hooks.__all__:
873 872 # default hooks have priority 100, i.e. low; user hooks should have
874 873 # 0-100 priority
875 874 self.set_hook(hook_name, getattr(hooks, hook_name), 100)
876 875
877 876 if self.display_page:
878 877 self.set_hook('show_in_pager', page.as_hook(page.display_page), 90)
879 878
880 879 def set_hook(self, name, hook, priority=50, str_key=None, re_key=None):
881 880 """set_hook(name,hook) -> sets an internal IPython hook.
882 881
883 882 IPython exposes some of its internal API as user-modifiable hooks. By
884 883 adding your function to one of these hooks, you can modify IPython's
885 884 behavior to call at runtime your own routines."""
886 885
887 886 # At some point in the future, this should validate the hook before it
888 887 # accepts it. Probably at least check that the hook takes the number
889 888 # of args it's supposed to.
890 889
891 890 f = types.MethodType(hook,self)
892 891
893 892 # check if the hook is for strdispatcher first
894 893 if str_key is not None:
895 894 sdp = self.strdispatchers.get(name, StrDispatch())
896 895 sdp.add_s(str_key, f, priority )
897 896 self.strdispatchers[name] = sdp
898 897 return
899 898 if re_key is not None:
900 899 sdp = self.strdispatchers.get(name, StrDispatch())
901 900 sdp.add_re(re.compile(re_key), f, priority )
902 901 self.strdispatchers[name] = sdp
903 902 return
904 903
905 904 dp = getattr(self.hooks, name, None)
906 905 if name not in IPython.core.hooks.__all__:
907 906 print("Warning! Hook '%s' is not one of %s" % \
908 907 (name, IPython.core.hooks.__all__ ))
909 908
910 909 if name in IPython.core.hooks.deprecated:
911 910 alternative = IPython.core.hooks.deprecated[name]
912 911 raise ValueError(
913 912 "Hook {} has been deprecated since IPython 5.0. Use {} instead.".format(
914 913 name, alternative
915 914 )
916 915 )
917 916
918 917 if not dp:
919 918 dp = IPython.core.hooks.CommandChainDispatcher()
920 919
921 920 try:
922 921 dp.add(f,priority)
923 922 except AttributeError:
924 923 # it was not commandchain, plain old func - replace
925 924 dp = f
926 925
927 926 setattr(self.hooks,name, dp)
928 927
929 928 #-------------------------------------------------------------------------
930 929 # Things related to events
931 930 #-------------------------------------------------------------------------
932 931
933 932 def init_events(self):
934 933 self.events = EventManager(self, available_events)
935 934
936 935 self.events.register("pre_execute", self._clear_warning_registry)
937 936
938 937 def register_post_execute(self, func):
939 938 """DEPRECATED: Use ip.events.register('post_run_cell', func)
940 939
941 940 Register a function for calling after code execution.
942 941 """
943 942 raise ValueError(
944 943 "ip.register_post_execute is deprecated since IPython 1.0, use "
945 944 "ip.events.register('post_run_cell', func) instead."
946 945 )
947 946
948 947 def _clear_warning_registry(self):
949 948 # clear the warning registry, so that different code blocks with
950 949 # overlapping line number ranges don't cause spurious suppression of
951 950 # warnings (see gh-6611 for details)
952 951 if "__warningregistry__" in self.user_global_ns:
953 952 del self.user_global_ns["__warningregistry__"]
954 953
955 954 #-------------------------------------------------------------------------
956 955 # Things related to the "main" module
957 956 #-------------------------------------------------------------------------
958 957
959 958 def new_main_mod(self, filename, modname):
960 959 """Return a new 'main' module object for user code execution.
961 960
962 961 ``filename`` should be the path of the script which will be run in the
963 962 module. Requests with the same filename will get the same module, with
964 963 its namespace cleared.
965 964
966 965 ``modname`` should be the module name - normally either '__main__' or
967 966 the basename of the file without the extension.
968 967
969 968 When scripts are executed via %run, we must keep a reference to their
970 969 __main__ module around so that Python doesn't
971 970 clear it, rendering references to module globals useless.
972 971
973 972 This method keeps said reference in a private dict, keyed by the
974 973 absolute path of the script. This way, for multiple executions of the
975 974 same script we only keep one copy of the namespace (the last one),
976 975 thus preventing memory leaks from old references while allowing the
977 976 objects from the last execution to be accessible.
978 977 """
979 978 filename = os.path.abspath(filename)
980 979 try:
981 980 main_mod = self._main_mod_cache[filename]
982 981 except KeyError:
983 982 main_mod = self._main_mod_cache[filename] = types.ModuleType(
984 983 modname,
985 984 doc="Module created for script run in IPython")
986 985 else:
987 986 main_mod.__dict__.clear()
988 987 main_mod.__name__ = modname
989 988
990 989 main_mod.__file__ = filename
991 990 # It seems pydoc (and perhaps others) needs any module instance to
992 991 # implement a __nonzero__ method
993 992 main_mod.__nonzero__ = lambda : True
994 993
995 994 return main_mod
996 995
997 996 def clear_main_mod_cache(self):
998 997 """Clear the cache of main modules.
999 998
1000 999 Mainly for use by utilities like %reset.
1001 1000
1002 1001 Examples
1003 1002 --------
1004 1003 In [15]: import IPython
1005 1004
1006 1005 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
1007 1006
1008 1007 In [17]: len(_ip._main_mod_cache) > 0
1009 1008 Out[17]: True
1010 1009
1011 1010 In [18]: _ip.clear_main_mod_cache()
1012 1011
1013 1012 In [19]: len(_ip._main_mod_cache) == 0
1014 1013 Out[19]: True
1015 1014 """
1016 1015 self._main_mod_cache.clear()
1017 1016
1018 1017 #-------------------------------------------------------------------------
1019 1018 # Things related to debugging
1020 1019 #-------------------------------------------------------------------------
1021 1020
1022 1021 def init_pdb(self):
1023 1022 # Set calling of pdb on exceptions
1024 1023 # self.call_pdb is a property
1025 1024 self.call_pdb = self.pdb
1026 1025
1027 1026 def _get_call_pdb(self):
1028 1027 return self._call_pdb
1029 1028
1030 1029 def _set_call_pdb(self,val):
1031 1030
1032 1031 if val not in (0,1,False,True):
1033 1032 raise ValueError('new call_pdb value must be boolean')
1034 1033
1035 1034 # store value in instance
1036 1035 self._call_pdb = val
1037 1036
1038 1037 # notify the actual exception handlers
1039 1038 self.InteractiveTB.call_pdb = val
1040 1039
1041 1040 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
1042 1041 'Control auto-activation of pdb at exceptions')
1043 1042
1044 1043 def debugger(self,force=False):
1045 1044 """Call the pdb debugger.
1046 1045
1047 1046 Keywords:
1048 1047
1049 1048 - force(False): by default, this routine checks the instance call_pdb
1050 1049 flag and does not actually invoke the debugger if the flag is false.
1051 1050 The 'force' option forces the debugger to activate even if the flag
1052 1051 is false.
1053 1052 """
1054 1053
1055 1054 if not (force or self.call_pdb):
1056 1055 return
1057 1056
1058 1057 if not hasattr(sys,'last_traceback'):
1059 1058 error('No traceback has been produced, nothing to debug.')
1060 1059 return
1061 1060
1062 1061 self.InteractiveTB.debugger(force=True)
1063 1062
1064 1063 #-------------------------------------------------------------------------
1065 1064 # Things related to IPython's various namespaces
1066 1065 #-------------------------------------------------------------------------
1067 1066 default_user_namespaces = True
1068 1067
1069 1068 def init_create_namespaces(self, user_module=None, user_ns=None):
1070 1069 # Create the namespace where the user will operate. user_ns is
1071 1070 # normally the only one used, and it is passed to the exec calls as
1072 1071 # the locals argument. But we do carry a user_global_ns namespace
1073 1072 # given as the exec 'globals' argument, This is useful in embedding
1074 1073 # situations where the ipython shell opens in a context where the
1075 1074 # distinction between locals and globals is meaningful. For
1076 1075 # non-embedded contexts, it is just the same object as the user_ns dict.
1077 1076
1078 1077 # FIXME. For some strange reason, __builtins__ is showing up at user
1079 1078 # level as a dict instead of a module. This is a manual fix, but I
1080 1079 # should really track down where the problem is coming from. Alex
1081 1080 # Schmolck reported this problem first.
1082 1081
1083 1082 # A useful post by Alex Martelli on this topic:
1084 1083 # Re: inconsistent value from __builtins__
1085 1084 # Von: Alex Martelli <aleaxit@yahoo.com>
1086 1085 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
1087 1086 # Gruppen: comp.lang.python
1088 1087
1089 1088 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
1090 1089 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
1091 1090 # > <type 'dict'>
1092 1091 # > >>> print type(__builtins__)
1093 1092 # > <type 'module'>
1094 1093 # > Is this difference in return value intentional?
1095 1094
1096 1095 # Well, it's documented that '__builtins__' can be either a dictionary
1097 1096 # or a module, and it's been that way for a long time. Whether it's
1098 1097 # intentional (or sensible), I don't know. In any case, the idea is
1099 1098 # that if you need to access the built-in namespace directly, you
1100 1099 # should start with "import __builtin__" (note, no 's') which will
1101 1100 # definitely give you a module. Yeah, it's somewhat confusing:-(.
1102 1101
1103 1102 # These routines return a properly built module and dict as needed by
1104 1103 # the rest of the code, and can also be used by extension writers to
1105 1104 # generate properly initialized namespaces.
1106 1105 if (user_ns is not None) or (user_module is not None):
1107 1106 self.default_user_namespaces = False
1108 1107 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
1109 1108
1110 1109 # A record of hidden variables we have added to the user namespace, so
1111 1110 # we can list later only variables defined in actual interactive use.
1112 1111 self.user_ns_hidden = {}
1113 1112
1114 1113 # Now that FakeModule produces a real module, we've run into a nasty
1115 1114 # problem: after script execution (via %run), the module where the user
1116 1115 # code ran is deleted. Now that this object is a true module (needed
1117 1116 # so doctest and other tools work correctly), the Python module
1118 1117 # teardown mechanism runs over it, and sets to None every variable
1119 1118 # present in that module. Top-level references to objects from the
1120 1119 # script survive, because the user_ns is updated with them. However,
1121 1120 # calling functions defined in the script that use other things from
1122 1121 # the script will fail, because the function's closure had references
1123 1122 # to the original objects, which are now all None. So we must protect
1124 1123 # these modules from deletion by keeping a cache.
1125 1124 #
1126 1125 # To avoid keeping stale modules around (we only need the one from the
1127 1126 # last run), we use a dict keyed with the full path to the script, so
1128 1127 # only the last version of the module is held in the cache. Note,
1129 1128 # however, that we must cache the module *namespace contents* (their
1130 1129 # __dict__). Because if we try to cache the actual modules, old ones
1131 1130 # (uncached) could be destroyed while still holding references (such as
1132 1131 # those held by GUI objects that tend to be long-lived)>
1133 1132 #
1134 1133 # The %reset command will flush this cache. See the cache_main_mod()
1135 1134 # and clear_main_mod_cache() methods for details on use.
1136 1135
1137 1136 # This is the cache used for 'main' namespaces
1138 1137 self._main_mod_cache = {}
1139 1138
1140 1139 # A table holding all the namespaces IPython deals with, so that
1141 1140 # introspection facilities can search easily.
1142 1141 self.ns_table = {'user_global':self.user_module.__dict__,
1143 1142 'user_local':self.user_ns,
1144 1143 'builtin':builtin_mod.__dict__
1145 1144 }
1146 1145
1147 1146 @property
1148 1147 def user_global_ns(self):
1149 1148 return self.user_module.__dict__
1150 1149
1151 1150 def prepare_user_module(self, user_module=None, user_ns=None):
1152 1151 """Prepare the module and namespace in which user code will be run.
1153 1152
1154 1153 When IPython is started normally, both parameters are None: a new module
1155 1154 is created automatically, and its __dict__ used as the namespace.
1156 1155
1157 1156 If only user_module is provided, its __dict__ is used as the namespace.
1158 1157 If only user_ns is provided, a dummy module is created, and user_ns
1159 1158 becomes the global namespace. If both are provided (as they may be
1160 1159 when embedding), user_ns is the local namespace, and user_module
1161 1160 provides the global namespace.
1162 1161
1163 1162 Parameters
1164 1163 ----------
1165 1164 user_module : module, optional
1166 1165 The current user module in which IPython is being run. If None,
1167 1166 a clean module will be created.
1168 1167 user_ns : dict, optional
1169 1168 A namespace in which to run interactive commands.
1170 1169
1171 1170 Returns
1172 1171 -------
1173 1172 A tuple of user_module and user_ns, each properly initialised.
1174 1173 """
1175 1174 if user_module is None and user_ns is not None:
1176 1175 user_ns.setdefault("__name__", "__main__")
1177 1176 user_module = DummyMod()
1178 1177 user_module.__dict__ = user_ns
1179 1178
1180 1179 if user_module is None:
1181 1180 user_module = types.ModuleType("__main__",
1182 1181 doc="Automatically created module for IPython interactive environment")
1183 1182
1184 1183 # We must ensure that __builtin__ (without the final 's') is always
1185 1184 # available and pointing to the __builtin__ *module*. For more details:
1186 1185 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1187 1186 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1188 1187 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1189 1188
1190 1189 if user_ns is None:
1191 1190 user_ns = user_module.__dict__
1192 1191
1193 1192 return user_module, user_ns
1194 1193
1195 1194 def init_sys_modules(self):
1196 1195 # We need to insert into sys.modules something that looks like a
1197 1196 # module but which accesses the IPython namespace, for shelve and
1198 1197 # pickle to work interactively. Normally they rely on getting
1199 1198 # everything out of __main__, but for embedding purposes each IPython
1200 1199 # instance has its own private namespace, so we can't go shoving
1201 1200 # everything into __main__.
1202 1201
1203 1202 # note, however, that we should only do this for non-embedded
1204 1203 # ipythons, which really mimic the __main__.__dict__ with their own
1205 1204 # namespace. Embedded instances, on the other hand, should not do
1206 1205 # this because they need to manage the user local/global namespaces
1207 1206 # only, but they live within a 'normal' __main__ (meaning, they
1208 1207 # shouldn't overtake the execution environment of the script they're
1209 1208 # embedded in).
1210 1209
1211 1210 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1212 1211 main_name = self.user_module.__name__
1213 1212 sys.modules[main_name] = self.user_module
1214 1213
1215 1214 def init_user_ns(self):
1216 1215 """Initialize all user-visible namespaces to their minimum defaults.
1217 1216
1218 1217 Certain history lists are also initialized here, as they effectively
1219 1218 act as user namespaces.
1220 1219
1221 1220 Notes
1222 1221 -----
1223 1222 All data structures here are only filled in, they are NOT reset by this
1224 1223 method. If they were not empty before, data will simply be added to
1225 1224 them.
1226 1225 """
1227 1226 # This function works in two parts: first we put a few things in
1228 1227 # user_ns, and we sync that contents into user_ns_hidden so that these
1229 1228 # initial variables aren't shown by %who. After the sync, we add the
1230 1229 # rest of what we *do* want the user to see with %who even on a new
1231 1230 # session (probably nothing, so they really only see their own stuff)
1232 1231
1233 1232 # The user dict must *always* have a __builtin__ reference to the
1234 1233 # Python standard __builtin__ namespace, which must be imported.
1235 1234 # This is so that certain operations in prompt evaluation can be
1236 1235 # reliably executed with builtins. Note that we can NOT use
1237 1236 # __builtins__ (note the 's'), because that can either be a dict or a
1238 1237 # module, and can even mutate at runtime, depending on the context
1239 1238 # (Python makes no guarantees on it). In contrast, __builtin__ is
1240 1239 # always a module object, though it must be explicitly imported.
1241 1240
1242 1241 # For more details:
1243 1242 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1244 1243 ns = {}
1245 1244
1246 1245 # make global variables for user access to the histories
1247 1246 ns['_ih'] = self.history_manager.input_hist_parsed
1248 1247 ns['_oh'] = self.history_manager.output_hist
1249 1248 ns['_dh'] = self.history_manager.dir_hist
1250 1249
1251 1250 # user aliases to input and output histories. These shouldn't show up
1252 1251 # in %who, as they can have very large reprs.
1253 1252 ns['In'] = self.history_manager.input_hist_parsed
1254 1253 ns['Out'] = self.history_manager.output_hist
1255 1254
1256 1255 # Store myself as the public api!!!
1257 1256 ns['get_ipython'] = self.get_ipython
1258 1257
1259 1258 ns['exit'] = self.exiter
1260 1259 ns['quit'] = self.exiter
1261 1260
1262 1261 # Sync what we've added so far to user_ns_hidden so these aren't seen
1263 1262 # by %who
1264 1263 self.user_ns_hidden.update(ns)
1265 1264
1266 1265 # Anything put into ns now would show up in %who. Think twice before
1267 1266 # putting anything here, as we really want %who to show the user their
1268 1267 # stuff, not our variables.
1269 1268
1270 1269 # Finally, update the real user's namespace
1271 1270 self.user_ns.update(ns)
1272 1271
1273 1272 @property
1274 1273 def all_ns_refs(self):
1275 1274 """Get a list of references to all the namespace dictionaries in which
1276 1275 IPython might store a user-created object.
1277 1276
1278 1277 Note that this does not include the displayhook, which also caches
1279 1278 objects from the output."""
1280 1279 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1281 1280 [m.__dict__ for m in self._main_mod_cache.values()]
1282 1281
1283 1282 def reset(self, new_session=True, aggressive=False):
1284 1283 """Clear all internal namespaces, and attempt to release references to
1285 1284 user objects.
1286 1285
1287 1286 If new_session is True, a new history session will be opened.
1288 1287 """
1289 1288 # Clear histories
1290 1289 self.history_manager.reset(new_session)
1291 1290 # Reset counter used to index all histories
1292 1291 if new_session:
1293 1292 self.execution_count = 1
1294 1293
1295 1294 # Reset last execution result
1296 1295 self.last_execution_succeeded = True
1297 1296 self.last_execution_result = None
1298 1297
1299 1298 # Flush cached output items
1300 1299 if self.displayhook.do_full_cache:
1301 1300 self.displayhook.flush()
1302 1301
1303 1302 # The main execution namespaces must be cleared very carefully,
1304 1303 # skipping the deletion of the builtin-related keys, because doing so
1305 1304 # would cause errors in many object's __del__ methods.
1306 1305 if self.user_ns is not self.user_global_ns:
1307 1306 self.user_ns.clear()
1308 1307 ns = self.user_global_ns
1309 1308 drop_keys = set(ns.keys())
1310 1309 drop_keys.discard('__builtin__')
1311 1310 drop_keys.discard('__builtins__')
1312 1311 drop_keys.discard('__name__')
1313 1312 for k in drop_keys:
1314 1313 del ns[k]
1315 1314
1316 1315 self.user_ns_hidden.clear()
1317 1316
1318 1317 # Restore the user namespaces to minimal usability
1319 1318 self.init_user_ns()
1320 1319 if aggressive and not hasattr(self, "_sys_modules_keys"):
1321 1320 print("Cannot restore sys.module, no snapshot")
1322 1321 elif aggressive:
1323 1322 print("culling sys module...")
1324 1323 current_keys = set(sys.modules.keys())
1325 1324 for k in current_keys - self._sys_modules_keys:
1326 1325 if k.startswith("multiprocessing"):
1327 1326 continue
1328 1327 del sys.modules[k]
1329 1328
1330 1329 # Restore the default and user aliases
1331 1330 self.alias_manager.clear_aliases()
1332 1331 self.alias_manager.init_aliases()
1333 1332
1334 1333 # Now define aliases that only make sense on the terminal, because they
1335 1334 # need direct access to the console in a way that we can't emulate in
1336 1335 # GUI or web frontend
1337 1336 if os.name == 'posix':
1338 1337 for cmd in ('clear', 'more', 'less', 'man'):
1339 1338 if cmd not in self.magics_manager.magics['line']:
1340 1339 self.alias_manager.soft_define_alias(cmd, cmd)
1341 1340
1342 1341 # Flush the private list of module references kept for script
1343 1342 # execution protection
1344 1343 self.clear_main_mod_cache()
1345 1344
1346 1345 def del_var(self, varname, by_name=False):
1347 1346 """Delete a variable from the various namespaces, so that, as
1348 1347 far as possible, we're not keeping any hidden references to it.
1349 1348
1350 1349 Parameters
1351 1350 ----------
1352 1351 varname : str
1353 1352 The name of the variable to delete.
1354 1353 by_name : bool
1355 1354 If True, delete variables with the given name in each
1356 1355 namespace. If False (default), find the variable in the user
1357 1356 namespace, and delete references to it.
1358 1357 """
1359 1358 if varname in ('__builtin__', '__builtins__'):
1360 1359 raise ValueError("Refusing to delete %s" % varname)
1361 1360
1362 1361 ns_refs = self.all_ns_refs
1363 1362
1364 1363 if by_name: # Delete by name
1365 1364 for ns in ns_refs:
1366 1365 try:
1367 1366 del ns[varname]
1368 1367 except KeyError:
1369 1368 pass
1370 1369 else: # Delete by object
1371 1370 try:
1372 1371 obj = self.user_ns[varname]
1373 1372 except KeyError as e:
1374 1373 raise NameError("name '%s' is not defined" % varname) from e
1375 1374 # Also check in output history
1376 1375 ns_refs.append(self.history_manager.output_hist)
1377 1376 for ns in ns_refs:
1378 1377 to_delete = [n for n, o in ns.items() if o is obj]
1379 1378 for name in to_delete:
1380 1379 del ns[name]
1381 1380
1382 1381 # Ensure it is removed from the last execution result
1383 1382 if self.last_execution_result.result is obj:
1384 1383 self.last_execution_result = None
1385 1384
1386 1385 # displayhook keeps extra references, but not in a dictionary
1387 1386 for name in ('_', '__', '___'):
1388 1387 if getattr(self.displayhook, name) is obj:
1389 1388 setattr(self.displayhook, name, None)
1390 1389
1391 1390 def reset_selective(self, regex=None):
1392 1391 """Clear selective variables from internal namespaces based on a
1393 1392 specified regular expression.
1394 1393
1395 1394 Parameters
1396 1395 ----------
1397 1396 regex : string or compiled pattern, optional
1398 1397 A regular expression pattern that will be used in searching
1399 1398 variable names in the users namespaces.
1400 1399 """
1401 1400 if regex is not None:
1402 1401 try:
1403 1402 m = re.compile(regex)
1404 1403 except TypeError as e:
1405 1404 raise TypeError('regex must be a string or compiled pattern') from e
1406 1405 # Search for keys in each namespace that match the given regex
1407 1406 # If a match is found, delete the key/value pair.
1408 1407 for ns in self.all_ns_refs:
1409 1408 for var in ns:
1410 1409 if m.search(var):
1411 1410 del ns[var]
1412 1411
1413 1412 def push(self, variables, interactive=True):
1414 1413 """Inject a group of variables into the IPython user namespace.
1415 1414
1416 1415 Parameters
1417 1416 ----------
1418 1417 variables : dict, str or list/tuple of str
1419 1418 The variables to inject into the user's namespace. If a dict, a
1420 1419 simple update is done. If a str, the string is assumed to have
1421 1420 variable names separated by spaces. A list/tuple of str can also
1422 1421 be used to give the variable names. If just the variable names are
1423 1422 give (list/tuple/str) then the variable values looked up in the
1424 1423 callers frame.
1425 1424 interactive : bool
1426 1425 If True (default), the variables will be listed with the ``who``
1427 1426 magic.
1428 1427 """
1429 1428 vdict = None
1430 1429
1431 1430 # We need a dict of name/value pairs to do namespace updates.
1432 1431 if isinstance(variables, dict):
1433 1432 vdict = variables
1434 1433 elif isinstance(variables, (str, list, tuple)):
1435 1434 if isinstance(variables, str):
1436 1435 vlist = variables.split()
1437 1436 else:
1438 1437 vlist = variables
1439 1438 vdict = {}
1440 1439 cf = sys._getframe(1)
1441 1440 for name in vlist:
1442 1441 try:
1443 1442 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1444 1443 except:
1445 1444 print('Could not get variable %s from %s' %
1446 1445 (name,cf.f_code.co_name))
1447 1446 else:
1448 1447 raise ValueError('variables must be a dict/str/list/tuple')
1449 1448
1450 1449 # Propagate variables to user namespace
1451 1450 self.user_ns.update(vdict)
1452 1451
1453 1452 # And configure interactive visibility
1454 1453 user_ns_hidden = self.user_ns_hidden
1455 1454 if interactive:
1456 1455 for name in vdict:
1457 1456 user_ns_hidden.pop(name, None)
1458 1457 else:
1459 1458 user_ns_hidden.update(vdict)
1460 1459
1461 1460 def drop_by_id(self, variables):
1462 1461 """Remove a dict of variables from the user namespace, if they are the
1463 1462 same as the values in the dictionary.
1464 1463
1465 1464 This is intended for use by extensions: variables that they've added can
1466 1465 be taken back out if they are unloaded, without removing any that the
1467 1466 user has overwritten.
1468 1467
1469 1468 Parameters
1470 1469 ----------
1471 1470 variables : dict
1472 1471 A dictionary mapping object names (as strings) to the objects.
1473 1472 """
1474 1473 for name, obj in variables.items():
1475 1474 if name in self.user_ns and self.user_ns[name] is obj:
1476 1475 del self.user_ns[name]
1477 1476 self.user_ns_hidden.pop(name, None)
1478 1477
1479 1478 #-------------------------------------------------------------------------
1480 1479 # Things related to object introspection
1481 1480 #-------------------------------------------------------------------------
1482 1481
1483 1482 def _ofind(self, oname, namespaces=None):
1484 1483 """Find an object in the available namespaces.
1485 1484
1486 1485 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1487 1486
1488 1487 Has special code to detect magic functions.
1489 1488 """
1490 1489 oname = oname.strip()
1491 1490 if not oname.startswith(ESC_MAGIC) and \
1492 1491 not oname.startswith(ESC_MAGIC2) and \
1493 1492 not all(a.isidentifier() for a in oname.split(".")):
1494 1493 return {'found': False}
1495 1494
1496 1495 if namespaces is None:
1497 1496 # Namespaces to search in:
1498 1497 # Put them in a list. The order is important so that we
1499 1498 # find things in the same order that Python finds them.
1500 1499 namespaces = [ ('Interactive', self.user_ns),
1501 1500 ('Interactive (global)', self.user_global_ns),
1502 1501 ('Python builtin', builtin_mod.__dict__),
1503 1502 ]
1504 1503
1505 1504 ismagic = False
1506 1505 isalias = False
1507 1506 found = False
1508 1507 ospace = None
1509 1508 parent = None
1510 1509 obj = None
1511 1510
1512 1511
1513 1512 # Look for the given name by splitting it in parts. If the head is
1514 1513 # found, then we look for all the remaining parts as members, and only
1515 1514 # declare success if we can find them all.
1516 1515 oname_parts = oname.split('.')
1517 1516 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1518 1517 for nsname,ns in namespaces:
1519 1518 try:
1520 1519 obj = ns[oname_head]
1521 1520 except KeyError:
1522 1521 continue
1523 1522 else:
1524 1523 for idx, part in enumerate(oname_rest):
1525 1524 try:
1526 1525 parent = obj
1527 1526 # The last part is looked up in a special way to avoid
1528 1527 # descriptor invocation as it may raise or have side
1529 1528 # effects.
1530 1529 if idx == len(oname_rest) - 1:
1531 1530 obj = self._getattr_property(obj, part)
1532 1531 else:
1533 1532 obj = getattr(obj, part)
1534 1533 except:
1535 1534 # Blanket except b/c some badly implemented objects
1536 1535 # allow __getattr__ to raise exceptions other than
1537 1536 # AttributeError, which then crashes IPython.
1538 1537 break
1539 1538 else:
1540 1539 # If we finish the for loop (no break), we got all members
1541 1540 found = True
1542 1541 ospace = nsname
1543 1542 break # namespace loop
1544 1543
1545 1544 # Try to see if it's magic
1546 1545 if not found:
1547 1546 obj = None
1548 1547 if oname.startswith(ESC_MAGIC2):
1549 1548 oname = oname.lstrip(ESC_MAGIC2)
1550 1549 obj = self.find_cell_magic(oname)
1551 1550 elif oname.startswith(ESC_MAGIC):
1552 1551 oname = oname.lstrip(ESC_MAGIC)
1553 1552 obj = self.find_line_magic(oname)
1554 1553 else:
1555 1554 # search without prefix, so run? will find %run?
1556 1555 obj = self.find_line_magic(oname)
1557 1556 if obj is None:
1558 1557 obj = self.find_cell_magic(oname)
1559 1558 if obj is not None:
1560 1559 found = True
1561 1560 ospace = 'IPython internal'
1562 1561 ismagic = True
1563 1562 isalias = isinstance(obj, Alias)
1564 1563
1565 1564 # Last try: special-case some literals like '', [], {}, etc:
1566 1565 if not found and oname_head in ["''",'""','[]','{}','()']:
1567 1566 obj = eval(oname_head)
1568 1567 found = True
1569 1568 ospace = 'Interactive'
1570 1569
1571 1570 return {
1572 1571 'obj':obj,
1573 1572 'found':found,
1574 1573 'parent':parent,
1575 1574 'ismagic':ismagic,
1576 1575 'isalias':isalias,
1577 1576 'namespace':ospace
1578 1577 }
1579 1578
1580 1579 @staticmethod
1581 1580 def _getattr_property(obj, attrname):
1582 1581 """Property-aware getattr to use in object finding.
1583 1582
1584 1583 If attrname represents a property, return it unevaluated (in case it has
1585 1584 side effects or raises an error.
1586 1585
1587 1586 """
1588 1587 if not isinstance(obj, type):
1589 1588 try:
1590 1589 # `getattr(type(obj), attrname)` is not guaranteed to return
1591 1590 # `obj`, but does so for property:
1592 1591 #
1593 1592 # property.__get__(self, None, cls) -> self
1594 1593 #
1595 1594 # The universal alternative is to traverse the mro manually
1596 1595 # searching for attrname in class dicts.
1597 1596 attr = getattr(type(obj), attrname)
1598 1597 except AttributeError:
1599 1598 pass
1600 1599 else:
1601 1600 # This relies on the fact that data descriptors (with both
1602 1601 # __get__ & __set__ magic methods) take precedence over
1603 1602 # instance-level attributes:
1604 1603 #
1605 1604 # class A(object):
1606 1605 # @property
1607 1606 # def foobar(self): return 123
1608 1607 # a = A()
1609 1608 # a.__dict__['foobar'] = 345
1610 1609 # a.foobar # == 123
1611 1610 #
1612 1611 # So, a property may be returned right away.
1613 1612 if isinstance(attr, property):
1614 1613 return attr
1615 1614
1616 1615 # Nothing helped, fall back.
1617 1616 return getattr(obj, attrname)
1618 1617
1619 1618 def _object_find(self, oname, namespaces=None):
1620 1619 """Find an object and return a struct with info about it."""
1621 1620 return Struct(self._ofind(oname, namespaces))
1622 1621
1623 1622 def _inspect(self, meth, oname, namespaces=None, **kw):
1624 1623 """Generic interface to the inspector system.
1625 1624
1626 1625 This function is meant to be called by pdef, pdoc & friends.
1627 1626 """
1628 1627 info = self._object_find(oname, namespaces)
1629 1628 docformat = (
1630 1629 sphinxify(self.object_inspect(oname)) if self.sphinxify_docstring else None
1631 1630 )
1632 1631 if info.found:
1633 1632 pmethod = getattr(self.inspector, meth)
1634 1633 # TODO: only apply format_screen to the plain/text repr of the mime
1635 1634 # bundle.
1636 1635 formatter = format_screen if info.ismagic else docformat
1637 1636 if meth == 'pdoc':
1638 1637 pmethod(info.obj, oname, formatter)
1639 1638 elif meth == 'pinfo':
1640 1639 pmethod(
1641 1640 info.obj,
1642 1641 oname,
1643 1642 formatter,
1644 1643 info,
1645 1644 enable_html_pager=self.enable_html_pager,
1646 **kw
1645 **kw,
1647 1646 )
1648 1647 else:
1649 1648 pmethod(info.obj, oname)
1650 1649 else:
1651 1650 print('Object `%s` not found.' % oname)
1652 1651 return 'not found' # so callers can take other action
1653 1652
1654 1653 def object_inspect(self, oname, detail_level=0):
1655 1654 """Get object info about oname"""
1656 1655 with self.builtin_trap:
1657 1656 info = self._object_find(oname)
1658 1657 if info.found:
1659 1658 return self.inspector.info(info.obj, oname, info=info,
1660 1659 detail_level=detail_level
1661 1660 )
1662 1661 else:
1663 1662 return oinspect.object_info(name=oname, found=False)
1664 1663
1665 1664 def object_inspect_text(self, oname, detail_level=0):
1666 1665 """Get object info as formatted text"""
1667 1666 return self.object_inspect_mime(oname, detail_level)['text/plain']
1668 1667
1669 1668 def object_inspect_mime(self, oname, detail_level=0, omit_sections=()):
1670 1669 """Get object info as a mimebundle of formatted representations.
1671 1670
1672 1671 A mimebundle is a dictionary, keyed by mime-type.
1673 1672 It must always have the key `'text/plain'`.
1674 1673 """
1675 1674 with self.builtin_trap:
1676 1675 info = self._object_find(oname)
1677 1676 if info.found:
1678 1677 docformat = (
1679 1678 sphinxify(self.object_inspect(oname))
1680 1679 if self.sphinxify_docstring
1681 1680 else None
1682 1681 )
1683 1682 return self.inspector._get_info(
1684 1683 info.obj,
1685 1684 oname,
1686 1685 info=info,
1687 1686 detail_level=detail_level,
1688 1687 formatter=docformat,
1689 1688 omit_sections=omit_sections,
1690 1689 )
1691 1690 else:
1692 1691 raise KeyError(oname)
1693 1692
1694 1693 #-------------------------------------------------------------------------
1695 1694 # Things related to history management
1696 1695 #-------------------------------------------------------------------------
1697 1696
1698 1697 def init_history(self):
1699 1698 """Sets up the command history, and starts regular autosaves."""
1700 1699 self.history_manager = HistoryManager(shell=self, parent=self)
1701 1700 self.configurables.append(self.history_manager)
1702 1701
1703 1702 #-------------------------------------------------------------------------
1704 1703 # Things related to exception handling and tracebacks (not debugging)
1705 1704 #-------------------------------------------------------------------------
1706 1705
1707 1706 debugger_cls = InterruptiblePdb
1708 1707
1709 1708 def init_traceback_handlers(self, custom_exceptions):
1710 1709 # Syntax error handler.
1711 1710 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor', parent=self)
1712 1711
1713 1712 # The interactive one is initialized with an offset, meaning we always
1714 1713 # want to remove the topmost item in the traceback, which is our own
1715 1714 # internal code. Valid modes: ['Plain','Context','Verbose','Minimal']
1716 1715 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1717 1716 color_scheme='NoColor',
1718 1717 tb_offset = 1,
1719 1718 check_cache=check_linecache_ipython,
1720 1719 debugger_cls=self.debugger_cls, parent=self)
1721 1720
1722 1721 # The instance will store a pointer to the system-wide exception hook,
1723 1722 # so that runtime code (such as magics) can access it. This is because
1724 1723 # during the read-eval loop, it may get temporarily overwritten.
1725 1724 self.sys_excepthook = sys.excepthook
1726 1725
1727 1726 # and add any custom exception handlers the user may have specified
1728 1727 self.set_custom_exc(*custom_exceptions)
1729 1728
1730 1729 # Set the exception mode
1731 1730 self.InteractiveTB.set_mode(mode=self.xmode)
1732 1731
1733 1732 def set_custom_exc(self, exc_tuple, handler):
1734 1733 """set_custom_exc(exc_tuple, handler)
1735 1734
1736 1735 Set a custom exception handler, which will be called if any of the
1737 1736 exceptions in exc_tuple occur in the mainloop (specifically, in the
1738 1737 run_code() method).
1739 1738
1740 1739 Parameters
1741 1740 ----------
1742 1741 exc_tuple : tuple of exception classes
1743 1742 A *tuple* of exception classes, for which to call the defined
1744 1743 handler. It is very important that you use a tuple, and NOT A
1745 1744 LIST here, because of the way Python's except statement works. If
1746 1745 you only want to trap a single exception, use a singleton tuple::
1747 1746
1748 1747 exc_tuple == (MyCustomException,)
1749 1748
1750 1749 handler : callable
1751 1750 handler must have the following signature::
1752 1751
1753 1752 def my_handler(self, etype, value, tb, tb_offset=None):
1754 1753 ...
1755 1754 return structured_traceback
1756 1755
1757 1756 Your handler must return a structured traceback (a list of strings),
1758 1757 or None.
1759 1758
1760 1759 This will be made into an instance method (via types.MethodType)
1761 1760 of IPython itself, and it will be called if any of the exceptions
1762 1761 listed in the exc_tuple are caught. If the handler is None, an
1763 1762 internal basic one is used, which just prints basic info.
1764 1763
1765 1764 To protect IPython from crashes, if your handler ever raises an
1766 1765 exception or returns an invalid result, it will be immediately
1767 1766 disabled.
1768 1767
1769 1768 Notes
1770 1769 -----
1771 1770 WARNING: by putting in your own exception handler into IPython's main
1772 1771 execution loop, you run a very good chance of nasty crashes. This
1773 1772 facility should only be used if you really know what you are doing.
1774 1773 """
1775 1774
1776 1775 if not isinstance(exc_tuple, tuple):
1777 1776 raise TypeError("The custom exceptions must be given as a tuple.")
1778 1777
1779 1778 def dummy_handler(self, etype, value, tb, tb_offset=None):
1780 1779 print('*** Simple custom exception handler ***')
1781 1780 print('Exception type :', etype)
1782 1781 print('Exception value:', value)
1783 1782 print('Traceback :', tb)
1784 1783
1785 1784 def validate_stb(stb):
1786 1785 """validate structured traceback return type
1787 1786
1788 1787 return type of CustomTB *should* be a list of strings, but allow
1789 1788 single strings or None, which are harmless.
1790 1789
1791 1790 This function will *always* return a list of strings,
1792 1791 and will raise a TypeError if stb is inappropriate.
1793 1792 """
1794 1793 msg = "CustomTB must return list of strings, not %r" % stb
1795 1794 if stb is None:
1796 1795 return []
1797 1796 elif isinstance(stb, str):
1798 1797 return [stb]
1799 1798 elif not isinstance(stb, list):
1800 1799 raise TypeError(msg)
1801 1800 # it's a list
1802 1801 for line in stb:
1803 1802 # check every element
1804 1803 if not isinstance(line, str):
1805 1804 raise TypeError(msg)
1806 1805 return stb
1807 1806
1808 1807 if handler is None:
1809 1808 wrapped = dummy_handler
1810 1809 else:
1811 1810 def wrapped(self,etype,value,tb,tb_offset=None):
1812 1811 """wrap CustomTB handler, to protect IPython from user code
1813 1812
1814 1813 This makes it harder (but not impossible) for custom exception
1815 1814 handlers to crash IPython.
1816 1815 """
1817 1816 try:
1818 1817 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1819 1818 return validate_stb(stb)
1820 1819 except:
1821 1820 # clear custom handler immediately
1822 1821 self.set_custom_exc((), None)
1823 1822 print("Custom TB Handler failed, unregistering", file=sys.stderr)
1824 1823 # show the exception in handler first
1825 1824 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1826 1825 print(self.InteractiveTB.stb2text(stb))
1827 1826 print("The original exception:")
1828 1827 stb = self.InteractiveTB.structured_traceback(
1829 1828 (etype,value,tb), tb_offset=tb_offset
1830 1829 )
1831 1830 return stb
1832 1831
1833 1832 self.CustomTB = types.MethodType(wrapped,self)
1834 1833 self.custom_exceptions = exc_tuple
1835 1834
1836 1835 def excepthook(self, etype, value, tb):
1837 1836 """One more defense for GUI apps that call sys.excepthook.
1838 1837
1839 1838 GUI frameworks like wxPython trap exceptions and call
1840 1839 sys.excepthook themselves. I guess this is a feature that
1841 1840 enables them to keep running after exceptions that would
1842 1841 otherwise kill their mainloop. This is a bother for IPython
1843 1842 which expects to catch all of the program exceptions with a try:
1844 1843 except: statement.
1845 1844
1846 1845 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1847 1846 any app directly invokes sys.excepthook, it will look to the user like
1848 1847 IPython crashed. In order to work around this, we can disable the
1849 1848 CrashHandler and replace it with this excepthook instead, which prints a
1850 1849 regular traceback using our InteractiveTB. In this fashion, apps which
1851 1850 call sys.excepthook will generate a regular-looking exception from
1852 1851 IPython, and the CrashHandler will only be triggered by real IPython
1853 1852 crashes.
1854 1853
1855 1854 This hook should be used sparingly, only in places which are not likely
1856 1855 to be true IPython errors.
1857 1856 """
1858 1857 self.showtraceback((etype, value, tb), tb_offset=0)
1859 1858
1860 1859 def _get_exc_info(self, exc_tuple=None):
1861 1860 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1862 1861
1863 1862 Ensures sys.last_type,value,traceback hold the exc_info we found,
1864 1863 from whichever source.
1865 1864
1866 1865 raises ValueError if none of these contain any information
1867 1866 """
1868 1867 if exc_tuple is None:
1869 1868 etype, value, tb = sys.exc_info()
1870 1869 else:
1871 1870 etype, value, tb = exc_tuple
1872 1871
1873 1872 if etype is None:
1874 1873 if hasattr(sys, 'last_type'):
1875 1874 etype, value, tb = sys.last_type, sys.last_value, \
1876 1875 sys.last_traceback
1877 1876
1878 1877 if etype is None:
1879 1878 raise ValueError("No exception to find")
1880 1879
1881 1880 # Now store the exception info in sys.last_type etc.
1882 1881 # WARNING: these variables are somewhat deprecated and not
1883 1882 # necessarily safe to use in a threaded environment, but tools
1884 1883 # like pdb depend on their existence, so let's set them. If we
1885 1884 # find problems in the field, we'll need to revisit their use.
1886 1885 sys.last_type = etype
1887 1886 sys.last_value = value
1888 1887 sys.last_traceback = tb
1889 1888
1890 1889 return etype, value, tb
1891 1890
1892 1891 def show_usage_error(self, exc):
1893 1892 """Show a short message for UsageErrors
1894 1893
1895 1894 These are special exceptions that shouldn't show a traceback.
1896 1895 """
1897 1896 print("UsageError: %s" % exc, file=sys.stderr)
1898 1897
1899 1898 def get_exception_only(self, exc_tuple=None):
1900 1899 """
1901 1900 Return as a string (ending with a newline) the exception that
1902 1901 just occurred, without any traceback.
1903 1902 """
1904 1903 etype, value, tb = self._get_exc_info(exc_tuple)
1905 1904 msg = traceback.format_exception_only(etype, value)
1906 1905 return ''.join(msg)
1907 1906
1908 1907 def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None,
1909 1908 exception_only=False, running_compiled_code=False):
1910 1909 """Display the exception that just occurred.
1911 1910
1912 1911 If nothing is known about the exception, this is the method which
1913 1912 should be used throughout the code for presenting user tracebacks,
1914 1913 rather than directly invoking the InteractiveTB object.
1915 1914
1916 1915 A specific showsyntaxerror() also exists, but this method can take
1917 1916 care of calling it if needed, so unless you are explicitly catching a
1918 1917 SyntaxError exception, don't try to analyze the stack manually and
1919 1918 simply call this method."""
1920 1919
1921 1920 try:
1922 1921 try:
1923 1922 etype, value, tb = self._get_exc_info(exc_tuple)
1924 1923 except ValueError:
1925 1924 print('No traceback available to show.', file=sys.stderr)
1926 1925 return
1927 1926
1928 1927 if issubclass(etype, SyntaxError):
1929 1928 # Though this won't be called by syntax errors in the input
1930 1929 # line, there may be SyntaxError cases with imported code.
1931 1930 self.showsyntaxerror(filename, running_compiled_code)
1932 1931 elif etype is UsageError:
1933 1932 self.show_usage_error(value)
1934 1933 else:
1935 1934 if exception_only:
1936 1935 stb = ['An exception has occurred, use %tb to see '
1937 1936 'the full traceback.\n']
1938 1937 stb.extend(self.InteractiveTB.get_exception_only(etype,
1939 1938 value))
1940 1939 else:
1941 1940 try:
1942 1941 # Exception classes can customise their traceback - we
1943 1942 # use this in IPython.parallel for exceptions occurring
1944 1943 # in the engines. This should return a list of strings.
1945 1944 stb = value._render_traceback_()
1946 1945 except Exception:
1947 1946 stb = self.InteractiveTB.structured_traceback(etype,
1948 1947 value, tb, tb_offset=tb_offset)
1949 1948
1950 1949 self._showtraceback(etype, value, stb)
1951 1950 if self.call_pdb:
1952 1951 # drop into debugger
1953 1952 self.debugger(force=True)
1954 1953 return
1955 1954
1956 1955 # Actually show the traceback
1957 1956 self._showtraceback(etype, value, stb)
1958 1957
1959 1958 except KeyboardInterrupt:
1960 1959 print('\n' + self.get_exception_only(), file=sys.stderr)
1961 1960
1962 1961 def _showtraceback(self, etype, evalue, stb: str):
1963 1962 """Actually show a traceback.
1964 1963
1965 1964 Subclasses may override this method to put the traceback on a different
1966 1965 place, like a side channel.
1967 1966 """
1968 1967 val = self.InteractiveTB.stb2text(stb)
1969 1968 try:
1970 1969 print(val)
1971 1970 except UnicodeEncodeError:
1972 1971 print(val.encode("utf-8", "backslashreplace").decode())
1973 1972
1974 1973 def showsyntaxerror(self, filename=None, running_compiled_code=False):
1975 1974 """Display the syntax error that just occurred.
1976 1975
1977 1976 This doesn't display a stack trace because there isn't one.
1978 1977
1979 1978 If a filename is given, it is stuffed in the exception instead
1980 1979 of what was there before (because Python's parser always uses
1981 1980 "<string>" when reading from a string).
1982 1981
1983 1982 If the syntax error occurred when running a compiled code (i.e. running_compile_code=True),
1984 1983 longer stack trace will be displayed.
1985 1984 """
1986 1985 etype, value, last_traceback = self._get_exc_info()
1987 1986
1988 1987 if filename and issubclass(etype, SyntaxError):
1989 1988 try:
1990 1989 value.filename = filename
1991 1990 except:
1992 1991 # Not the format we expect; leave it alone
1993 1992 pass
1994 1993
1995 1994 # If the error occurred when executing compiled code, we should provide full stacktrace.
1996 1995 elist = traceback.extract_tb(last_traceback) if running_compiled_code else []
1997 1996 stb = self.SyntaxTB.structured_traceback(etype, value, elist)
1998 1997 self._showtraceback(etype, value, stb)
1999 1998
2000 1999 # This is overridden in TerminalInteractiveShell to show a message about
2001 2000 # the %paste magic.
2002 2001 def showindentationerror(self):
2003 2002 """Called by _run_cell when there's an IndentationError in code entered
2004 2003 at the prompt.
2005 2004
2006 2005 This is overridden in TerminalInteractiveShell to show a message about
2007 2006 the %paste magic."""
2008 2007 self.showsyntaxerror()
2009 2008
2010 2009 @skip_doctest
2011 2010 def set_next_input(self, s, replace=False):
2012 2011 """ Sets the 'default' input string for the next command line.
2013 2012
2014 2013 Example::
2015 2014
2016 2015 In [1]: _ip.set_next_input("Hello Word")
2017 2016 In [2]: Hello Word_ # cursor is here
2018 2017 """
2019 2018 self.rl_next_input = s
2020 2019
2021 2020 def _indent_current_str(self):
2022 2021 """return the current level of indentation as a string"""
2023 2022 return self.input_splitter.get_indent_spaces() * ' '
2024 2023
2025 2024 #-------------------------------------------------------------------------
2026 2025 # Things related to text completion
2027 2026 #-------------------------------------------------------------------------
2028 2027
2029 2028 def init_completer(self):
2030 2029 """Initialize the completion machinery.
2031 2030
2032 2031 This creates completion machinery that can be used by client code,
2033 2032 either interactively in-process (typically triggered by the readline
2034 2033 library), programmatically (such as in test suites) or out-of-process
2035 2034 (typically over the network by remote frontends).
2036 2035 """
2037 2036 from IPython.core.completer import IPCompleter
2038 2037 from IPython.core.completerlib import (module_completer,
2039 2038 magic_run_completer, cd_completer, reset_completer)
2040 2039
2041 2040 self.Completer = IPCompleter(shell=self,
2042 2041 namespace=self.user_ns,
2043 2042 global_namespace=self.user_global_ns,
2044 2043 parent=self,
2045 2044 )
2046 2045 self.configurables.append(self.Completer)
2047 2046
2048 2047 # Add custom completers to the basic ones built into IPCompleter
2049 2048 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
2050 2049 self.strdispatchers['complete_command'] = sdisp
2051 2050 self.Completer.custom_completers = sdisp
2052 2051
2053 2052 self.set_hook('complete_command', module_completer, str_key = 'import')
2054 2053 self.set_hook('complete_command', module_completer, str_key = 'from')
2055 2054 self.set_hook('complete_command', module_completer, str_key = '%aimport')
2056 2055 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
2057 2056 self.set_hook('complete_command', cd_completer, str_key = '%cd')
2058 2057 self.set_hook('complete_command', reset_completer, str_key = '%reset')
2059 2058
2060 2059 @skip_doctest
2061 2060 def complete(self, text, line=None, cursor_pos=None):
2062 2061 """Return the completed text and a list of completions.
2063 2062
2064 2063 Parameters
2065 2064 ----------
2066 2065 text : string
2067 2066 A string of text to be completed on. It can be given as empty and
2068 2067 instead a line/position pair are given. In this case, the
2069 2068 completer itself will split the line like readline does.
2070 2069 line : string, optional
2071 2070 The complete line that text is part of.
2072 2071 cursor_pos : int, optional
2073 2072 The position of the cursor on the input line.
2074 2073
2075 2074 Returns
2076 2075 -------
2077 2076 text : string
2078 2077 The actual text that was completed.
2079 2078 matches : list
2080 2079 A sorted list with all possible completions.
2081 2080
2082 2081 Notes
2083 2082 -----
2084 2083 The optional arguments allow the completion to take more context into
2085 2084 account, and are part of the low-level completion API.
2086 2085
2087 2086 This is a wrapper around the completion mechanism, similar to what
2088 2087 readline does at the command line when the TAB key is hit. By
2089 2088 exposing it as a method, it can be used by other non-readline
2090 2089 environments (such as GUIs) for text completion.
2091 2090
2092 2091 Examples
2093 2092 --------
2094 2093 In [1]: x = 'hello'
2095 2094
2096 2095 In [2]: _ip.complete('x.l')
2097 2096 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2098 2097 """
2099 2098
2100 2099 # Inject names into __builtin__ so we can complete on the added names.
2101 2100 with self.builtin_trap:
2102 2101 return self.Completer.complete(text, line, cursor_pos)
2103 2102
2104 2103 def set_custom_completer(self, completer, pos=0) -> None:
2105 2104 """Adds a new custom completer function.
2106 2105
2107 2106 The position argument (defaults to 0) is the index in the completers
2108 2107 list where you want the completer to be inserted.
2109 2108
2110 2109 `completer` should have the following signature::
2111 2110
2112 2111 def completion(self: Completer, text: string) -> List[str]:
2113 2112 raise NotImplementedError
2114 2113
2115 2114 It will be bound to the current Completer instance and pass some text
2116 2115 and return a list with current completions to suggest to the user.
2117 2116 """
2118 2117
2119 2118 newcomp = types.MethodType(completer, self.Completer)
2120 2119 self.Completer.custom_matchers.insert(pos,newcomp)
2121 2120
2122 2121 def set_completer_frame(self, frame=None):
2123 2122 """Set the frame of the completer."""
2124 2123 if frame:
2125 2124 self.Completer.namespace = frame.f_locals
2126 2125 self.Completer.global_namespace = frame.f_globals
2127 2126 else:
2128 2127 self.Completer.namespace = self.user_ns
2129 2128 self.Completer.global_namespace = self.user_global_ns
2130 2129
2131 2130 #-------------------------------------------------------------------------
2132 2131 # Things related to magics
2133 2132 #-------------------------------------------------------------------------
2134 2133
2135 2134 def init_magics(self):
2136 2135 from IPython.core import magics as m
2137 2136 self.magics_manager = magic.MagicsManager(shell=self,
2138 2137 parent=self,
2139 2138 user_magics=m.UserMagics(self))
2140 2139 self.configurables.append(self.magics_manager)
2141 2140
2142 2141 # Expose as public API from the magics manager
2143 2142 self.register_magics = self.magics_manager.register
2144 2143
2145 2144 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2146 2145 m.ConfigMagics, m.DisplayMagics, m.ExecutionMagics,
2147 2146 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2148 2147 m.NamespaceMagics, m.OSMagics, m.PackagingMagics,
2149 2148 m.PylabMagics, m.ScriptMagics,
2150 2149 )
2151 2150 self.register_magics(m.AsyncMagics)
2152 2151
2153 2152 # Register Magic Aliases
2154 2153 mman = self.magics_manager
2155 2154 # FIXME: magic aliases should be defined by the Magics classes
2156 2155 # or in MagicsManager, not here
2157 2156 mman.register_alias('ed', 'edit')
2158 2157 mman.register_alias('hist', 'history')
2159 2158 mman.register_alias('rep', 'recall')
2160 2159 mman.register_alias('SVG', 'svg', 'cell')
2161 2160 mman.register_alias('HTML', 'html', 'cell')
2162 2161 mman.register_alias('file', 'writefile', 'cell')
2163 2162
2164 2163 # FIXME: Move the color initialization to the DisplayHook, which
2165 2164 # should be split into a prompt manager and displayhook. We probably
2166 2165 # even need a centralize colors management object.
2167 2166 self.run_line_magic('colors', self.colors)
2168 2167
2169 2168 # Defined here so that it's included in the documentation
2170 2169 @functools.wraps(magic.MagicsManager.register_function)
2171 2170 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2172 2171 self.magics_manager.register_function(
2173 2172 func, magic_kind=magic_kind, magic_name=magic_name
2174 2173 )
2175 2174
2176 def run_line_magic(self, magic_name, line, _stack_depth=1):
2175 def _find_with_lazy_load(self, /, type_, magic_name: str):
2176 """
2177 Try to find a magic potentially lazy-loading it.
2178
2179 Parameters
2180 ----------
2181
2182 type_: "line"|"cell"
2183 the type of magics we are trying to find/lazy load.
2184 magic_name: str
2185 The name of the magic we are trying to find/lazy load
2186
2187
2188 Note that this may have any side effects
2189 """
2190 finder = {"line": self.find_line_magic, "cell": self.find_cell_magic}[type_]
2191 fn = finder(magic_name)
2192 if fn is not None:
2193 return fn
2194 lazy = self.magics_manager.lazy_magics.get(magic_name)
2195 if lazy is None:
2196 return None
2197
2198 self.run_line_magic("load_ext", lazy)
2199 res = finder(magic_name)
2200 return res
2201
2202 def run_line_magic(self, magic_name: str, line, _stack_depth=1):
2177 2203 """Execute the given line magic.
2178 2204
2179 2205 Parameters
2180 2206 ----------
2181 2207 magic_name : str
2182 2208 Name of the desired magic function, without '%' prefix.
2183 2209 line : str
2184 2210 The rest of the input line as a single string.
2185 2211 _stack_depth : int
2186 2212 If run_line_magic() is called from magic() then _stack_depth=2.
2187 2213 This is added to ensure backward compatibility for use of 'get_ipython().magic()'
2188 2214 """
2189 fn = self.find_line_magic(magic_name)
2215 fn = self._find_with_lazy_load("line", magic_name)
2216 if fn is None:
2217 lazy = self.magics_manager.lazy_magics.get(magic_name)
2218 if lazy:
2219 self.run_line_magic("load_ext", lazy)
2220 fn = self.find_line_magic(magic_name)
2190 2221 if fn is None:
2191 2222 cm = self.find_cell_magic(magic_name)
2192 2223 etpl = "Line magic function `%%%s` not found%s."
2193 2224 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2194 2225 'did you mean that instead?)' % magic_name )
2195 2226 raise UsageError(etpl % (magic_name, extra))
2196 2227 else:
2197 2228 # Note: this is the distance in the stack to the user's frame.
2198 2229 # This will need to be updated if the internal calling logic gets
2199 2230 # refactored, or else we'll be expanding the wrong variables.
2200 2231
2201 2232 # Determine stack_depth depending on where run_line_magic() has been called
2202 2233 stack_depth = _stack_depth
2203 2234 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2204 2235 # magic has opted out of var_expand
2205 2236 magic_arg_s = line
2206 2237 else:
2207 2238 magic_arg_s = self.var_expand(line, stack_depth)
2208 2239 # Put magic args in a list so we can call with f(*a) syntax
2209 2240 args = [magic_arg_s]
2210 2241 kwargs = {}
2211 2242 # Grab local namespace if we need it:
2212 2243 if getattr(fn, "needs_local_scope", False):
2213 2244 kwargs['local_ns'] = self.get_local_scope(stack_depth)
2214 2245 with self.builtin_trap:
2215 2246 result = fn(*args, **kwargs)
2216 2247 return result
2217 2248
2218 2249 def get_local_scope(self, stack_depth):
2219 2250 """Get local scope at given stack depth.
2220 2251
2221 2252 Parameters
2222 2253 ----------
2223 2254 stack_depth : int
2224 2255 Depth relative to calling frame
2225 2256 """
2226 2257 return sys._getframe(stack_depth + 1).f_locals
2227 2258
2228 2259 def run_cell_magic(self, magic_name, line, cell):
2229 2260 """Execute the given cell magic.
2230 2261
2231 2262 Parameters
2232 2263 ----------
2233 2264 magic_name : str
2234 2265 Name of the desired magic function, without '%' prefix.
2235 2266 line : str
2236 2267 The rest of the first input line as a single string.
2237 2268 cell : str
2238 2269 The body of the cell as a (possibly multiline) string.
2239 2270 """
2240 fn = self.find_cell_magic(magic_name)
2271 fn = self._find_with_lazy_load("cell", magic_name)
2241 2272 if fn is None:
2242 2273 lm = self.find_line_magic(magic_name)
2243 2274 etpl = "Cell magic `%%{0}` not found{1}."
2244 2275 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2245 2276 'did you mean that instead?)'.format(magic_name))
2246 2277 raise UsageError(etpl.format(magic_name, extra))
2247 2278 elif cell == '':
2248 2279 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2249 2280 if self.find_line_magic(magic_name) is not None:
2250 2281 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2251 2282 raise UsageError(message)
2252 2283 else:
2253 2284 # Note: this is the distance in the stack to the user's frame.
2254 2285 # This will need to be updated if the internal calling logic gets
2255 2286 # refactored, or else we'll be expanding the wrong variables.
2256 2287 stack_depth = 2
2257 2288 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2258 2289 # magic has opted out of var_expand
2259 2290 magic_arg_s = line
2260 2291 else:
2261 2292 magic_arg_s = self.var_expand(line, stack_depth)
2262 2293 kwargs = {}
2263 2294 if getattr(fn, "needs_local_scope", False):
2264 2295 kwargs['local_ns'] = self.user_ns
2265 2296
2266 2297 with self.builtin_trap:
2267 2298 args = (magic_arg_s, cell)
2268 2299 result = fn(*args, **kwargs)
2269 2300 return result
2270 2301
2271 2302 def find_line_magic(self, magic_name):
2272 2303 """Find and return a line magic by name.
2273 2304
2274 2305 Returns None if the magic isn't found."""
2275 2306 return self.magics_manager.magics['line'].get(magic_name)
2276 2307
2277 2308 def find_cell_magic(self, magic_name):
2278 2309 """Find and return a cell magic by name.
2279 2310
2280 2311 Returns None if the magic isn't found."""
2281 2312 return self.magics_manager.magics['cell'].get(magic_name)
2282 2313
2283 2314 def find_magic(self, magic_name, magic_kind='line'):
2284 2315 """Find and return a magic of the given type by name.
2285 2316
2286 2317 Returns None if the magic isn't found."""
2287 2318 return self.magics_manager.magics[magic_kind].get(magic_name)
2288 2319
2289 2320 def magic(self, arg_s):
2290 2321 """
2291 2322 DEPRECATED
2292 2323
2293 2324 Deprecated since IPython 0.13 (warning added in
2294 2325 8.1), use run_line_magic(magic_name, parameter_s).
2295 2326
2296 2327 Call a magic function by name.
2297 2328
2298 2329 Input: a string containing the name of the magic function to call and
2299 2330 any additional arguments to be passed to the magic.
2300 2331
2301 2332 magic('name -opt foo bar') is equivalent to typing at the ipython
2302 2333 prompt:
2303 2334
2304 2335 In[1]: %name -opt foo bar
2305 2336
2306 2337 To call a magic without arguments, simply use magic('name').
2307 2338
2308 2339 This provides a proper Python function to call IPython's magics in any
2309 2340 valid Python code you can type at the interpreter, including loops and
2310 2341 compound statements.
2311 2342 """
2312 2343 warnings.warn(
2313 2344 "`magic(...)` is deprecated since IPython 0.13 (warning added in "
2314 2345 "8.1), use run_line_magic(magic_name, parameter_s).",
2315 2346 DeprecationWarning,
2316 2347 stacklevel=2,
2317 2348 )
2318 2349 # TODO: should we issue a loud deprecation warning here?
2319 2350 magic_name, _, magic_arg_s = arg_s.partition(' ')
2320 2351 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2321 2352 return self.run_line_magic(magic_name, magic_arg_s, _stack_depth=2)
2322 2353
2323 2354 #-------------------------------------------------------------------------
2324 2355 # Things related to macros
2325 2356 #-------------------------------------------------------------------------
2326 2357
2327 2358 def define_macro(self, name, themacro):
2328 2359 """Define a new macro
2329 2360
2330 2361 Parameters
2331 2362 ----------
2332 2363 name : str
2333 2364 The name of the macro.
2334 2365 themacro : str or Macro
2335 2366 The action to do upon invoking the macro. If a string, a new
2336 2367 Macro object is created by passing the string to it.
2337 2368 """
2338 2369
2339 2370 from IPython.core import macro
2340 2371
2341 2372 if isinstance(themacro, str):
2342 2373 themacro = macro.Macro(themacro)
2343 2374 if not isinstance(themacro, macro.Macro):
2344 2375 raise ValueError('A macro must be a string or a Macro instance.')
2345 2376 self.user_ns[name] = themacro
2346 2377
2347 2378 #-------------------------------------------------------------------------
2348 2379 # Things related to the running of system commands
2349 2380 #-------------------------------------------------------------------------
2350 2381
2351 2382 def system_piped(self, cmd):
2352 2383 """Call the given cmd in a subprocess, piping stdout/err
2353 2384
2354 2385 Parameters
2355 2386 ----------
2356 2387 cmd : str
2357 2388 Command to execute (can not end in '&', as background processes are
2358 2389 not supported. Should not be a command that expects input
2359 2390 other than simple text.
2360 2391 """
2361 2392 if cmd.rstrip().endswith('&'):
2362 2393 # this is *far* from a rigorous test
2363 2394 # We do not support backgrounding processes because we either use
2364 2395 # pexpect or pipes to read from. Users can always just call
2365 2396 # os.system() or use ip.system=ip.system_raw
2366 2397 # if they really want a background process.
2367 2398 raise OSError("Background processes not supported.")
2368 2399
2369 2400 # we explicitly do NOT return the subprocess status code, because
2370 2401 # a non-None value would trigger :func:`sys.displayhook` calls.
2371 2402 # Instead, we store the exit_code in user_ns.
2372 2403 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2373 2404
2374 2405 def system_raw(self, cmd):
2375 2406 """Call the given cmd in a subprocess using os.system on Windows or
2376 2407 subprocess.call using the system shell on other platforms.
2377 2408
2378 2409 Parameters
2379 2410 ----------
2380 2411 cmd : str
2381 2412 Command to execute.
2382 2413 """
2383 2414 cmd = self.var_expand(cmd, depth=1)
2384 2415 # warn if there is an IPython magic alternative.
2385 2416 main_cmd = cmd.split()[0]
2386 2417 has_magic_alternatives = ("pip", "conda", "cd", "ls")
2387 2418
2388 2419 # had to check if the command was an alias expanded because of `ls`
2389 2420 is_alias_expanded = self.alias_manager.is_alias(main_cmd) and (
2390 2421 self.alias_manager.retrieve_alias(main_cmd).strip() == cmd.strip()
2391 2422 )
2392 2423
2393 2424 if main_cmd in has_magic_alternatives and not is_alias_expanded:
2394 2425 warnings.warn(
2395 2426 (
2396 2427 "You executed the system command !{0} which may not work "
2397 2428 "as expected. Try the IPython magic %{0} instead."
2398 2429 ).format(main_cmd)
2399 2430 )
2400 2431
2401 2432 # protect os.system from UNC paths on Windows, which it can't handle:
2402 2433 if sys.platform == 'win32':
2403 2434 from IPython.utils._process_win32 import AvoidUNCPath
2404 2435 with AvoidUNCPath() as path:
2405 2436 if path is not None:
2406 2437 cmd = '"pushd %s &&"%s' % (path, cmd)
2407 2438 try:
2408 2439 ec = os.system(cmd)
2409 2440 except KeyboardInterrupt:
2410 2441 print('\n' + self.get_exception_only(), file=sys.stderr)
2411 2442 ec = -2
2412 2443 else:
2413 2444 # For posix the result of the subprocess.call() below is an exit
2414 2445 # code, which by convention is zero for success, positive for
2415 2446 # program failure. Exit codes above 128 are reserved for signals,
2416 2447 # and the formula for converting a signal to an exit code is usually
2417 2448 # signal_number+128. To more easily differentiate between exit
2418 2449 # codes and signals, ipython uses negative numbers. For instance
2419 2450 # since control-c is signal 2 but exit code 130, ipython's
2420 2451 # _exit_code variable will read -2. Note that some shells like
2421 2452 # csh and fish don't follow sh/bash conventions for exit codes.
2422 2453 executable = os.environ.get('SHELL', None)
2423 2454 try:
2424 2455 # Use env shell instead of default /bin/sh
2425 2456 ec = subprocess.call(cmd, shell=True, executable=executable)
2426 2457 except KeyboardInterrupt:
2427 2458 # intercept control-C; a long traceback is not useful here
2428 2459 print('\n' + self.get_exception_only(), file=sys.stderr)
2429 2460 ec = 130
2430 2461 if ec > 128:
2431 2462 ec = -(ec - 128)
2432 2463
2433 2464 # We explicitly do NOT return the subprocess status code, because
2434 2465 # a non-None value would trigger :func:`sys.displayhook` calls.
2435 2466 # Instead, we store the exit_code in user_ns. Note the semantics
2436 2467 # of _exit_code: for control-c, _exit_code == -signal.SIGNIT,
2437 2468 # but raising SystemExit(_exit_code) will give status 254!
2438 2469 self.user_ns['_exit_code'] = ec
2439 2470
2440 2471 # use piped system by default, because it is better behaved
2441 2472 system = system_piped
2442 2473
2443 2474 def getoutput(self, cmd, split=True, depth=0):
2444 2475 """Get output (possibly including stderr) from a subprocess.
2445 2476
2446 2477 Parameters
2447 2478 ----------
2448 2479 cmd : str
2449 2480 Command to execute (can not end in '&', as background processes are
2450 2481 not supported.
2451 2482 split : bool, optional
2452 2483 If True, split the output into an IPython SList. Otherwise, an
2453 2484 IPython LSString is returned. These are objects similar to normal
2454 2485 lists and strings, with a few convenience attributes for easier
2455 2486 manipulation of line-based output. You can use '?' on them for
2456 2487 details.
2457 2488 depth : int, optional
2458 2489 How many frames above the caller are the local variables which should
2459 2490 be expanded in the command string? The default (0) assumes that the
2460 2491 expansion variables are in the stack frame calling this function.
2461 2492 """
2462 2493 if cmd.rstrip().endswith('&'):
2463 2494 # this is *far* from a rigorous test
2464 2495 raise OSError("Background processes not supported.")
2465 2496 out = getoutput(self.var_expand(cmd, depth=depth+1))
2466 2497 if split:
2467 2498 out = SList(out.splitlines())
2468 2499 else:
2469 2500 out = LSString(out)
2470 2501 return out
2471 2502
2472 2503 #-------------------------------------------------------------------------
2473 2504 # Things related to aliases
2474 2505 #-------------------------------------------------------------------------
2475 2506
2476 2507 def init_alias(self):
2477 2508 self.alias_manager = AliasManager(shell=self, parent=self)
2478 2509 self.configurables.append(self.alias_manager)
2479 2510
2480 2511 #-------------------------------------------------------------------------
2481 2512 # Things related to extensions
2482 2513 #-------------------------------------------------------------------------
2483 2514
2484 2515 def init_extension_manager(self):
2485 2516 self.extension_manager = ExtensionManager(shell=self, parent=self)
2486 2517 self.configurables.append(self.extension_manager)
2487 2518
2488 2519 #-------------------------------------------------------------------------
2489 2520 # Things related to payloads
2490 2521 #-------------------------------------------------------------------------
2491 2522
2492 2523 def init_payload(self):
2493 2524 self.payload_manager = PayloadManager(parent=self)
2494 2525 self.configurables.append(self.payload_manager)
2495 2526
2496 2527 #-------------------------------------------------------------------------
2497 2528 # Things related to the prefilter
2498 2529 #-------------------------------------------------------------------------
2499 2530
2500 2531 def init_prefilter(self):
2501 2532 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2502 2533 self.configurables.append(self.prefilter_manager)
2503 2534 # Ultimately this will be refactored in the new interpreter code, but
2504 2535 # for now, we should expose the main prefilter method (there's legacy
2505 2536 # code out there that may rely on this).
2506 2537 self.prefilter = self.prefilter_manager.prefilter_lines
2507 2538
2508 2539 def auto_rewrite_input(self, cmd):
2509 2540 """Print to the screen the rewritten form of the user's command.
2510 2541
2511 2542 This shows visual feedback by rewriting input lines that cause
2512 2543 automatic calling to kick in, like::
2513 2544
2514 2545 /f x
2515 2546
2516 2547 into::
2517 2548
2518 2549 ------> f(x)
2519 2550
2520 2551 after the user's input prompt. This helps the user understand that the
2521 2552 input line was transformed automatically by IPython.
2522 2553 """
2523 2554 if not self.show_rewritten_input:
2524 2555 return
2525 2556
2526 2557 # This is overridden in TerminalInteractiveShell to use fancy prompts
2527 2558 print("------> " + cmd)
2528 2559
2529 2560 #-------------------------------------------------------------------------
2530 2561 # Things related to extracting values/expressions from kernel and user_ns
2531 2562 #-------------------------------------------------------------------------
2532 2563
2533 2564 def _user_obj_error(self):
2534 2565 """return simple exception dict
2535 2566
2536 2567 for use in user_expressions
2537 2568 """
2538 2569
2539 2570 etype, evalue, tb = self._get_exc_info()
2540 2571 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2541 2572
2542 2573 exc_info = {
2543 2574 "status": "error",
2544 2575 "traceback": stb,
2545 2576 "ename": etype.__name__,
2546 2577 "evalue": py3compat.safe_unicode(evalue),
2547 2578 }
2548 2579
2549 2580 return exc_info
2550 2581
2551 2582 def _format_user_obj(self, obj):
2552 2583 """format a user object to display dict
2553 2584
2554 2585 for use in user_expressions
2555 2586 """
2556 2587
2557 2588 data, md = self.display_formatter.format(obj)
2558 2589 value = {
2559 2590 'status' : 'ok',
2560 2591 'data' : data,
2561 2592 'metadata' : md,
2562 2593 }
2563 2594 return value
2564 2595
2565 2596 def user_expressions(self, expressions):
2566 2597 """Evaluate a dict of expressions in the user's namespace.
2567 2598
2568 2599 Parameters
2569 2600 ----------
2570 2601 expressions : dict
2571 2602 A dict with string keys and string values. The expression values
2572 2603 should be valid Python expressions, each of which will be evaluated
2573 2604 in the user namespace.
2574 2605
2575 2606 Returns
2576 2607 -------
2577 2608 A dict, keyed like the input expressions dict, with the rich mime-typed
2578 2609 display_data of each value.
2579 2610 """
2580 2611 out = {}
2581 2612 user_ns = self.user_ns
2582 2613 global_ns = self.user_global_ns
2583 2614
2584 2615 for key, expr in expressions.items():
2585 2616 try:
2586 2617 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2587 2618 except:
2588 2619 value = self._user_obj_error()
2589 2620 out[key] = value
2590 2621 return out
2591 2622
2592 2623 #-------------------------------------------------------------------------
2593 2624 # Things related to the running of code
2594 2625 #-------------------------------------------------------------------------
2595 2626
2596 2627 def ex(self, cmd):
2597 2628 """Execute a normal python statement in user namespace."""
2598 2629 with self.builtin_trap:
2599 2630 exec(cmd, self.user_global_ns, self.user_ns)
2600 2631
2601 2632 def ev(self, expr):
2602 2633 """Evaluate python expression expr in user namespace.
2603 2634
2604 2635 Returns the result of evaluation
2605 2636 """
2606 2637 with self.builtin_trap:
2607 2638 return eval(expr, self.user_global_ns, self.user_ns)
2608 2639
2609 2640 def safe_execfile(self, fname, *where, exit_ignore=False, raise_exceptions=False, shell_futures=False):
2610 2641 """A safe version of the builtin execfile().
2611 2642
2612 2643 This version will never throw an exception, but instead print
2613 2644 helpful error messages to the screen. This only works on pure
2614 2645 Python files with the .py extension.
2615 2646
2616 2647 Parameters
2617 2648 ----------
2618 2649 fname : string
2619 2650 The name of the file to be executed.
2620 2651 *where : tuple
2621 2652 One or two namespaces, passed to execfile() as (globals,locals).
2622 2653 If only one is given, it is passed as both.
2623 2654 exit_ignore : bool (False)
2624 2655 If True, then silence SystemExit for non-zero status (it is always
2625 2656 silenced for zero status, as it is so common).
2626 2657 raise_exceptions : bool (False)
2627 2658 If True raise exceptions everywhere. Meant for testing.
2628 2659 shell_futures : bool (False)
2629 2660 If True, the code will share future statements with the interactive
2630 2661 shell. It will both be affected by previous __future__ imports, and
2631 2662 any __future__ imports in the code will affect the shell. If False,
2632 2663 __future__ imports are not shared in either direction.
2633 2664
2634 2665 """
2635 2666 fname = Path(fname).expanduser().resolve()
2636 2667
2637 2668 # Make sure we can open the file
2638 2669 try:
2639 2670 with fname.open():
2640 2671 pass
2641 2672 except:
2642 2673 warn('Could not open file <%s> for safe execution.' % fname)
2643 2674 return
2644 2675
2645 2676 # Find things also in current directory. This is needed to mimic the
2646 2677 # behavior of running a script from the system command line, where
2647 2678 # Python inserts the script's directory into sys.path
2648 2679 dname = str(fname.parent)
2649 2680
2650 2681 with prepended_to_syspath(dname), self.builtin_trap:
2651 2682 try:
2652 2683 glob, loc = (where + (None, ))[:2]
2653 2684 py3compat.execfile(
2654 2685 fname, glob, loc,
2655 2686 self.compile if shell_futures else None)
2656 2687 except SystemExit as status:
2657 2688 # If the call was made with 0 or None exit status (sys.exit(0)
2658 2689 # or sys.exit() ), don't bother showing a traceback, as both of
2659 2690 # these are considered normal by the OS:
2660 2691 # > python -c'import sys;sys.exit(0)'; echo $?
2661 2692 # 0
2662 2693 # > python -c'import sys;sys.exit()'; echo $?
2663 2694 # 0
2664 2695 # For other exit status, we show the exception unless
2665 2696 # explicitly silenced, but only in short form.
2666 2697 if status.code:
2667 2698 if raise_exceptions:
2668 2699 raise
2669 2700 if not exit_ignore:
2670 2701 self.showtraceback(exception_only=True)
2671 2702 except:
2672 2703 if raise_exceptions:
2673 2704 raise
2674 2705 # tb offset is 2 because we wrap execfile
2675 2706 self.showtraceback(tb_offset=2)
2676 2707
2677 2708 def safe_execfile_ipy(self, fname, shell_futures=False, raise_exceptions=False):
2678 2709 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2679 2710
2680 2711 Parameters
2681 2712 ----------
2682 2713 fname : str
2683 2714 The name of the file to execute. The filename must have a
2684 2715 .ipy or .ipynb extension.
2685 2716 shell_futures : bool (False)
2686 2717 If True, the code will share future statements with the interactive
2687 2718 shell. It will both be affected by previous __future__ imports, and
2688 2719 any __future__ imports in the code will affect the shell. If False,
2689 2720 __future__ imports are not shared in either direction.
2690 2721 raise_exceptions : bool (False)
2691 2722 If True raise exceptions everywhere. Meant for testing.
2692 2723 """
2693 2724 fname = Path(fname).expanduser().resolve()
2694 2725
2695 2726 # Make sure we can open the file
2696 2727 try:
2697 2728 with fname.open():
2698 2729 pass
2699 2730 except:
2700 2731 warn('Could not open file <%s> for safe execution.' % fname)
2701 2732 return
2702 2733
2703 2734 # Find things also in current directory. This is needed to mimic the
2704 2735 # behavior of running a script from the system command line, where
2705 2736 # Python inserts the script's directory into sys.path
2706 2737 dname = str(fname.parent)
2707 2738
2708 2739 def get_cells():
2709 2740 """generator for sequence of code blocks to run"""
2710 2741 if fname.suffix == ".ipynb":
2711 2742 from nbformat import read
2712 2743 nb = read(fname, as_version=4)
2713 2744 if not nb.cells:
2714 2745 return
2715 2746 for cell in nb.cells:
2716 2747 if cell.cell_type == 'code':
2717 2748 yield cell.source
2718 2749 else:
2719 2750 yield fname.read_text()
2720 2751
2721 2752 with prepended_to_syspath(dname):
2722 2753 try:
2723 2754 for cell in get_cells():
2724 2755 result = self.run_cell(cell, silent=True, shell_futures=shell_futures)
2725 2756 if raise_exceptions:
2726 2757 result.raise_error()
2727 2758 elif not result.success:
2728 2759 break
2729 2760 except:
2730 2761 if raise_exceptions:
2731 2762 raise
2732 2763 self.showtraceback()
2733 2764 warn('Unknown failure executing file: <%s>' % fname)
2734 2765
2735 2766 def safe_run_module(self, mod_name, where):
2736 2767 """A safe version of runpy.run_module().
2737 2768
2738 2769 This version will never throw an exception, but instead print
2739 2770 helpful error messages to the screen.
2740 2771
2741 2772 `SystemExit` exceptions with status code 0 or None are ignored.
2742 2773
2743 2774 Parameters
2744 2775 ----------
2745 2776 mod_name : string
2746 2777 The name of the module to be executed.
2747 2778 where : dict
2748 2779 The globals namespace.
2749 2780 """
2750 2781 try:
2751 2782 try:
2752 2783 where.update(
2753 2784 runpy.run_module(str(mod_name), run_name="__main__",
2754 2785 alter_sys=True)
2755 2786 )
2756 2787 except SystemExit as status:
2757 2788 if status.code:
2758 2789 raise
2759 2790 except:
2760 2791 self.showtraceback()
2761 2792 warn('Unknown failure executing module: <%s>' % mod_name)
2762 2793
2763 2794 def run_cell(self, raw_cell, store_history=False, silent=False, shell_futures=True):
2764 2795 """Run a complete IPython cell.
2765 2796
2766 2797 Parameters
2767 2798 ----------
2768 2799 raw_cell : str
2769 2800 The code (including IPython code such as %magic functions) to run.
2770 2801 store_history : bool
2771 2802 If True, the raw and translated cell will be stored in IPython's
2772 2803 history. For user code calling back into IPython's machinery, this
2773 2804 should be set to False.
2774 2805 silent : bool
2775 2806 If True, avoid side-effects, such as implicit displayhooks and
2776 2807 and logging. silent=True forces store_history=False.
2777 2808 shell_futures : bool
2778 2809 If True, the code will share future statements with the interactive
2779 2810 shell. It will both be affected by previous __future__ imports, and
2780 2811 any __future__ imports in the code will affect the shell. If False,
2781 2812 __future__ imports are not shared in either direction.
2782 2813
2783 2814 Returns
2784 2815 -------
2785 2816 result : :class:`ExecutionResult`
2786 2817 """
2787 2818 result = None
2788 2819 try:
2789 2820 result = self._run_cell(
2790 2821 raw_cell, store_history, silent, shell_futures)
2791 2822 finally:
2792 2823 self.events.trigger('post_execute')
2793 2824 if not silent:
2794 2825 self.events.trigger('post_run_cell', result)
2795 2826 return result
2796 2827
2797 2828 def _run_cell(self, raw_cell:str, store_history:bool, silent:bool, shell_futures:bool) -> ExecutionResult:
2798 2829 """Internal method to run a complete IPython cell."""
2799 2830
2800 2831 # we need to avoid calling self.transform_cell multiple time on the same thing
2801 2832 # so we need to store some results:
2802 2833 preprocessing_exc_tuple = None
2803 2834 try:
2804 2835 transformed_cell = self.transform_cell(raw_cell)
2805 2836 except Exception:
2806 2837 transformed_cell = raw_cell
2807 2838 preprocessing_exc_tuple = sys.exc_info()
2808 2839
2809 2840 assert transformed_cell is not None
2810 2841 coro = self.run_cell_async(
2811 2842 raw_cell,
2812 2843 store_history=store_history,
2813 2844 silent=silent,
2814 2845 shell_futures=shell_futures,
2815 2846 transformed_cell=transformed_cell,
2816 2847 preprocessing_exc_tuple=preprocessing_exc_tuple,
2817 2848 )
2818 2849
2819 2850 # run_cell_async is async, but may not actually need an eventloop.
2820 2851 # when this is the case, we want to run it using the pseudo_sync_runner
2821 2852 # so that code can invoke eventloops (for example via the %run , and
2822 2853 # `%paste` magic.
2823 2854 if self.trio_runner:
2824 2855 runner = self.trio_runner
2825 2856 elif self.should_run_async(
2826 2857 raw_cell,
2827 2858 transformed_cell=transformed_cell,
2828 2859 preprocessing_exc_tuple=preprocessing_exc_tuple,
2829 2860 ):
2830 2861 runner = self.loop_runner
2831 2862 else:
2832 2863 runner = _pseudo_sync_runner
2833 2864
2834 2865 try:
2835 2866 return runner(coro)
2836 2867 except BaseException as e:
2837 2868 info = ExecutionInfo(raw_cell, store_history, silent, shell_futures)
2838 2869 result = ExecutionResult(info)
2839 2870 result.error_in_exec = e
2840 2871 self.showtraceback(running_compiled_code=True)
2841 2872 return result
2842 2873
2843 2874 def should_run_async(
2844 2875 self, raw_cell: str, *, transformed_cell=None, preprocessing_exc_tuple=None
2845 2876 ) -> bool:
2846 2877 """Return whether a cell should be run asynchronously via a coroutine runner
2847 2878
2848 2879 Parameters
2849 2880 ----------
2850 2881 raw_cell : str
2851 2882 The code to be executed
2852 2883
2853 2884 Returns
2854 2885 -------
2855 2886 result: bool
2856 2887 Whether the code needs to be run with a coroutine runner or not
2857 2888 .. versionadded:: 7.0
2858 2889 """
2859 2890 if not self.autoawait:
2860 2891 return False
2861 2892 if preprocessing_exc_tuple is not None:
2862 2893 return False
2863 2894 assert preprocessing_exc_tuple is None
2864 2895 if transformed_cell is None:
2865 2896 warnings.warn(
2866 2897 "`should_run_async` will not call `transform_cell`"
2867 2898 " automatically in the future. Please pass the result to"
2868 2899 " `transformed_cell` argument and any exception that happen"
2869 2900 " during the"
2870 2901 "transform in `preprocessing_exc_tuple` in"
2871 2902 " IPython 7.17 and above.",
2872 2903 DeprecationWarning,
2873 2904 stacklevel=2,
2874 2905 )
2875 2906 try:
2876 2907 cell = self.transform_cell(raw_cell)
2877 2908 except Exception:
2878 2909 # any exception during transform will be raised
2879 2910 # prior to execution
2880 2911 return False
2881 2912 else:
2882 2913 cell = transformed_cell
2883 2914 return _should_be_async(cell)
2884 2915
2885 2916 async def run_cell_async(
2886 2917 self,
2887 2918 raw_cell: str,
2888 2919 store_history=False,
2889 2920 silent=False,
2890 2921 shell_futures=True,
2891 2922 *,
2892 2923 transformed_cell: Optional[str] = None,
2893 2924 preprocessing_exc_tuple: Optional[Any] = None
2894 2925 ) -> ExecutionResult:
2895 2926 """Run a complete IPython cell asynchronously.
2896 2927
2897 2928 Parameters
2898 2929 ----------
2899 2930 raw_cell : str
2900 2931 The code (including IPython code such as %magic functions) to run.
2901 2932 store_history : bool
2902 2933 If True, the raw and translated cell will be stored in IPython's
2903 2934 history. For user code calling back into IPython's machinery, this
2904 2935 should be set to False.
2905 2936 silent : bool
2906 2937 If True, avoid side-effects, such as implicit displayhooks and
2907 2938 and logging. silent=True forces store_history=False.
2908 2939 shell_futures : bool
2909 2940 If True, the code will share future statements with the interactive
2910 2941 shell. It will both be affected by previous __future__ imports, and
2911 2942 any __future__ imports in the code will affect the shell. If False,
2912 2943 __future__ imports are not shared in either direction.
2913 2944 transformed_cell: str
2914 2945 cell that was passed through transformers
2915 2946 preprocessing_exc_tuple:
2916 2947 trace if the transformation failed.
2917 2948
2918 2949 Returns
2919 2950 -------
2920 2951 result : :class:`ExecutionResult`
2921 2952
2922 2953 .. versionadded:: 7.0
2923 2954 """
2924 2955 info = ExecutionInfo(
2925 2956 raw_cell, store_history, silent, shell_futures)
2926 2957 result = ExecutionResult(info)
2927 2958
2928 2959 if (not raw_cell) or raw_cell.isspace():
2929 2960 self.last_execution_succeeded = True
2930 2961 self.last_execution_result = result
2931 2962 return result
2932 2963
2933 2964 if silent:
2934 2965 store_history = False
2935 2966
2936 2967 if store_history:
2937 2968 result.execution_count = self.execution_count
2938 2969
2939 2970 def error_before_exec(value):
2940 2971 if store_history:
2941 2972 self.execution_count += 1
2942 2973 result.error_before_exec = value
2943 2974 self.last_execution_succeeded = False
2944 2975 self.last_execution_result = result
2945 2976 return result
2946 2977
2947 2978 self.events.trigger('pre_execute')
2948 2979 if not silent:
2949 2980 self.events.trigger('pre_run_cell', info)
2950 2981
2951 2982 if transformed_cell is None:
2952 2983 warnings.warn(
2953 2984 "`run_cell_async` will not call `transform_cell`"
2954 2985 " automatically in the future. Please pass the result to"
2955 2986 " `transformed_cell` argument and any exception that happen"
2956 2987 " during the"
2957 2988 "transform in `preprocessing_exc_tuple` in"
2958 2989 " IPython 7.17 and above.",
2959 2990 DeprecationWarning,
2960 2991 stacklevel=2,
2961 2992 )
2962 2993 # If any of our input transformation (input_transformer_manager or
2963 2994 # prefilter_manager) raises an exception, we store it in this variable
2964 2995 # so that we can display the error after logging the input and storing
2965 2996 # it in the history.
2966 2997 try:
2967 2998 cell = self.transform_cell(raw_cell)
2968 2999 except Exception:
2969 3000 preprocessing_exc_tuple = sys.exc_info()
2970 3001 cell = raw_cell # cell has to exist so it can be stored/logged
2971 3002 else:
2972 3003 preprocessing_exc_tuple = None
2973 3004 else:
2974 3005 if preprocessing_exc_tuple is None:
2975 3006 cell = transformed_cell
2976 3007 else:
2977 3008 cell = raw_cell
2978 3009
2979 3010 # Store raw and processed history
2980 3011 if store_history:
2981 3012 self.history_manager.store_inputs(self.execution_count,
2982 3013 cell, raw_cell)
2983 3014 if not silent:
2984 3015 self.logger.log(cell, raw_cell)
2985 3016
2986 3017 # Display the exception if input processing failed.
2987 3018 if preprocessing_exc_tuple is not None:
2988 3019 self.showtraceback(preprocessing_exc_tuple)
2989 3020 if store_history:
2990 3021 self.execution_count += 1
2991 3022 return error_before_exec(preprocessing_exc_tuple[1])
2992 3023
2993 3024 # Our own compiler remembers the __future__ environment. If we want to
2994 3025 # run code with a separate __future__ environment, use the default
2995 3026 # compiler
2996 3027 compiler = self.compile if shell_futures else self.compiler_class()
2997 3028
2998 3029 _run_async = False
2999 3030
3000 3031 with self.builtin_trap:
3001 3032 cell_name = compiler.cache(cell, self.execution_count, raw_code=raw_cell)
3002 3033
3003 3034 with self.display_trap:
3004 3035 # Compile to bytecode
3005 3036 try:
3006 3037 code_ast = compiler.ast_parse(cell, filename=cell_name)
3007 3038 except self.custom_exceptions as e:
3008 3039 etype, value, tb = sys.exc_info()
3009 3040 self.CustomTB(etype, value, tb)
3010 3041 return error_before_exec(e)
3011 3042 except IndentationError as e:
3012 3043 self.showindentationerror()
3013 3044 return error_before_exec(e)
3014 3045 except (OverflowError, SyntaxError, ValueError, TypeError,
3015 3046 MemoryError) as e:
3016 3047 self.showsyntaxerror()
3017 3048 return error_before_exec(e)
3018 3049
3019 3050 # Apply AST transformations
3020 3051 try:
3021 3052 code_ast = self.transform_ast(code_ast)
3022 3053 except InputRejected as e:
3023 3054 self.showtraceback()
3024 3055 return error_before_exec(e)
3025 3056
3026 3057 # Give the displayhook a reference to our ExecutionResult so it
3027 3058 # can fill in the output value.
3028 3059 self.displayhook.exec_result = result
3029 3060
3030 3061 # Execute the user code
3031 3062 interactivity = "none" if silent else self.ast_node_interactivity
3032 3063
3033 3064 has_raised = await self.run_ast_nodes(code_ast.body, cell_name,
3034 3065 interactivity=interactivity, compiler=compiler, result=result)
3035 3066
3036 3067 self.last_execution_succeeded = not has_raised
3037 3068 self.last_execution_result = result
3038 3069
3039 3070 # Reset this so later displayed values do not modify the
3040 3071 # ExecutionResult
3041 3072 self.displayhook.exec_result = None
3042 3073
3043 3074 if store_history:
3044 3075 # Write output to the database. Does nothing unless
3045 3076 # history output logging is enabled.
3046 3077 self.history_manager.store_output(self.execution_count)
3047 3078 # Each cell is a *single* input, regardless of how many lines it has
3048 3079 self.execution_count += 1
3049 3080
3050 3081 return result
3051 3082
3052 3083 def transform_cell(self, raw_cell):
3053 3084 """Transform an input cell before parsing it.
3054 3085
3055 3086 Static transformations, implemented in IPython.core.inputtransformer2,
3056 3087 deal with things like ``%magic`` and ``!system`` commands.
3057 3088 These run on all input.
3058 3089 Dynamic transformations, for things like unescaped magics and the exit
3059 3090 autocall, depend on the state of the interpreter.
3060 3091 These only apply to single line inputs.
3061 3092
3062 3093 These string-based transformations are followed by AST transformations;
3063 3094 see :meth:`transform_ast`.
3064 3095 """
3065 3096 # Static input transformations
3066 3097 cell = self.input_transformer_manager.transform_cell(raw_cell)
3067 3098
3068 3099 if len(cell.splitlines()) == 1:
3069 3100 # Dynamic transformations - only applied for single line commands
3070 3101 with self.builtin_trap:
3071 3102 # use prefilter_lines to handle trailing newlines
3072 3103 # restore trailing newline for ast.parse
3073 3104 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
3074 3105
3075 3106 lines = cell.splitlines(keepends=True)
3076 3107 for transform in self.input_transformers_post:
3077 3108 lines = transform(lines)
3078 3109 cell = ''.join(lines)
3079 3110
3080 3111 return cell
3081 3112
3082 3113 def transform_ast(self, node):
3083 3114 """Apply the AST transformations from self.ast_transformers
3084 3115
3085 3116 Parameters
3086 3117 ----------
3087 3118 node : ast.Node
3088 3119 The root node to be transformed. Typically called with the ast.Module
3089 3120 produced by parsing user input.
3090 3121
3091 3122 Returns
3092 3123 -------
3093 3124 An ast.Node corresponding to the node it was called with. Note that it
3094 3125 may also modify the passed object, so don't rely on references to the
3095 3126 original AST.
3096 3127 """
3097 3128 for transformer in self.ast_transformers:
3098 3129 try:
3099 3130 node = transformer.visit(node)
3100 3131 except InputRejected:
3101 3132 # User-supplied AST transformers can reject an input by raising
3102 3133 # an InputRejected. Short-circuit in this case so that we
3103 3134 # don't unregister the transform.
3104 3135 raise
3105 3136 except Exception:
3106 3137 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
3107 3138 self.ast_transformers.remove(transformer)
3108 3139
3109 3140 if self.ast_transformers:
3110 3141 ast.fix_missing_locations(node)
3111 3142 return node
3112 3143
3113 3144 async def run_ast_nodes(
3114 3145 self,
3115 3146 nodelist: ListType[stmt],
3116 3147 cell_name: str,
3117 3148 interactivity="last_expr",
3118 3149 compiler=compile,
3119 3150 result=None,
3120 3151 ):
3121 3152 """Run a sequence of AST nodes. The execution mode depends on the
3122 3153 interactivity parameter.
3123 3154
3124 3155 Parameters
3125 3156 ----------
3126 3157 nodelist : list
3127 3158 A sequence of AST nodes to run.
3128 3159 cell_name : str
3129 3160 Will be passed to the compiler as the filename of the cell. Typically
3130 3161 the value returned by ip.compile.cache(cell).
3131 3162 interactivity : str
3132 3163 'all', 'last', 'last_expr' , 'last_expr_or_assign' or 'none',
3133 3164 specifying which nodes should be run interactively (displaying output
3134 3165 from expressions). 'last_expr' will run the last node interactively
3135 3166 only if it is an expression (i.e. expressions in loops or other blocks
3136 3167 are not displayed) 'last_expr_or_assign' will run the last expression
3137 3168 or the last assignment. Other values for this parameter will raise a
3138 3169 ValueError.
3139 3170
3140 3171 compiler : callable
3141 3172 A function with the same interface as the built-in compile(), to turn
3142 3173 the AST nodes into code objects. Default is the built-in compile().
3143 3174 result : ExecutionResult, optional
3144 3175 An object to store exceptions that occur during execution.
3145 3176
3146 3177 Returns
3147 3178 -------
3148 3179 True if an exception occurred while running code, False if it finished
3149 3180 running.
3150 3181 """
3151 3182 if not nodelist:
3152 3183 return
3153 3184
3154 3185
3155 3186 if interactivity == 'last_expr_or_assign':
3156 3187 if isinstance(nodelist[-1], _assign_nodes):
3157 3188 asg = nodelist[-1]
3158 3189 if isinstance(asg, ast.Assign) and len(asg.targets) == 1:
3159 3190 target = asg.targets[0]
3160 3191 elif isinstance(asg, _single_targets_nodes):
3161 3192 target = asg.target
3162 3193 else:
3163 3194 target = None
3164 3195 if isinstance(target, ast.Name):
3165 3196 nnode = ast.Expr(ast.Name(target.id, ast.Load()))
3166 3197 ast.fix_missing_locations(nnode)
3167 3198 nodelist.append(nnode)
3168 3199 interactivity = 'last_expr'
3169 3200
3170 3201 _async = False
3171 3202 if interactivity == 'last_expr':
3172 3203 if isinstance(nodelist[-1], ast.Expr):
3173 3204 interactivity = "last"
3174 3205 else:
3175 3206 interactivity = "none"
3176 3207
3177 3208 if interactivity == 'none':
3178 3209 to_run_exec, to_run_interactive = nodelist, []
3179 3210 elif interactivity == 'last':
3180 3211 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
3181 3212 elif interactivity == 'all':
3182 3213 to_run_exec, to_run_interactive = [], nodelist
3183 3214 else:
3184 3215 raise ValueError("Interactivity was %r" % interactivity)
3185 3216
3186 3217 try:
3187 3218
3188 3219 def compare(code):
3189 3220 is_async = inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE
3190 3221 return is_async
3191 3222
3192 3223 # refactor that to just change the mod constructor.
3193 3224 to_run = []
3194 3225 for node in to_run_exec:
3195 3226 to_run.append((node, "exec"))
3196 3227
3197 3228 for node in to_run_interactive:
3198 3229 to_run.append((node, "single"))
3199 3230
3200 3231 for node, mode in to_run:
3201 3232 if mode == "exec":
3202 3233 mod = Module([node], [])
3203 3234 elif mode == "single":
3204 3235 mod = ast.Interactive([node])
3205 3236 with compiler.extra_flags(
3206 3237 getattr(ast, "PyCF_ALLOW_TOP_LEVEL_AWAIT", 0x0)
3207 3238 if self.autoawait
3208 3239 else 0x0
3209 3240 ):
3210 3241 code = compiler(mod, cell_name, mode)
3211 3242 asy = compare(code)
3212 3243 if await self.run_code(code, result, async_=asy):
3213 3244 return True
3214 3245
3215 3246 # Flush softspace
3216 3247 if softspace(sys.stdout, 0):
3217 3248 print()
3218 3249
3219 3250 except:
3220 3251 # It's possible to have exceptions raised here, typically by
3221 3252 # compilation of odd code (such as a naked 'return' outside a
3222 3253 # function) that did parse but isn't valid. Typically the exception
3223 3254 # is a SyntaxError, but it's safest just to catch anything and show
3224 3255 # the user a traceback.
3225 3256
3226 3257 # We do only one try/except outside the loop to minimize the impact
3227 3258 # on runtime, and also because if any node in the node list is
3228 3259 # broken, we should stop execution completely.
3229 3260 if result:
3230 3261 result.error_before_exec = sys.exc_info()[1]
3231 3262 self.showtraceback()
3232 3263 return True
3233 3264
3234 3265 return False
3235 3266
3236 3267 async def run_code(self, code_obj, result=None, *, async_=False):
3237 3268 """Execute a code object.
3238 3269
3239 3270 When an exception occurs, self.showtraceback() is called to display a
3240 3271 traceback.
3241 3272
3242 3273 Parameters
3243 3274 ----------
3244 3275 code_obj : code object
3245 3276 A compiled code object, to be executed
3246 3277 result : ExecutionResult, optional
3247 3278 An object to store exceptions that occur during execution.
3248 3279 async_ : Bool (Experimental)
3249 3280 Attempt to run top-level asynchronous code in a default loop.
3250 3281
3251 3282 Returns
3252 3283 -------
3253 3284 False : successful execution.
3254 3285 True : an error occurred.
3255 3286 """
3256 3287 # special value to say that anything above is IPython and should be
3257 3288 # hidden.
3258 3289 __tracebackhide__ = "__ipython_bottom__"
3259 3290 # Set our own excepthook in case the user code tries to call it
3260 3291 # directly, so that the IPython crash handler doesn't get triggered
3261 3292 old_excepthook, sys.excepthook = sys.excepthook, self.excepthook
3262 3293
3263 3294 # we save the original sys.excepthook in the instance, in case config
3264 3295 # code (such as magics) needs access to it.
3265 3296 self.sys_excepthook = old_excepthook
3266 3297 outflag = True # happens in more places, so it's easier as default
3267 3298 try:
3268 3299 try:
3269 3300 if async_:
3270 3301 await eval(code_obj, self.user_global_ns, self.user_ns)
3271 3302 else:
3272 3303 exec(code_obj, self.user_global_ns, self.user_ns)
3273 3304 finally:
3274 3305 # Reset our crash handler in place
3275 3306 sys.excepthook = old_excepthook
3276 3307 except SystemExit as e:
3277 3308 if result is not None:
3278 3309 result.error_in_exec = e
3279 3310 self.showtraceback(exception_only=True)
3280 3311 warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
3281 3312 except self.custom_exceptions:
3282 3313 etype, value, tb = sys.exc_info()
3283 3314 if result is not None:
3284 3315 result.error_in_exec = value
3285 3316 self.CustomTB(etype, value, tb)
3286 3317 except:
3287 3318 if result is not None:
3288 3319 result.error_in_exec = sys.exc_info()[1]
3289 3320 self.showtraceback(running_compiled_code=True)
3290 3321 else:
3291 3322 outflag = False
3292 3323 return outflag
3293 3324
3294 3325 # For backwards compatibility
3295 3326 runcode = run_code
3296 3327
3297 3328 def check_complete(self, code: str) -> Tuple[str, str]:
3298 3329 """Return whether a block of code is ready to execute, or should be continued
3299 3330
3300 3331 Parameters
3301 3332 ----------
3302 3333 code : string
3303 3334 Python input code, which can be multiline.
3304 3335
3305 3336 Returns
3306 3337 -------
3307 3338 status : str
3308 3339 One of 'complete', 'incomplete', or 'invalid' if source is not a
3309 3340 prefix of valid code.
3310 3341 indent : str
3311 3342 When status is 'incomplete', this is some whitespace to insert on
3312 3343 the next line of the prompt.
3313 3344 """
3314 3345 status, nspaces = self.input_transformer_manager.check_complete(code)
3315 3346 return status, ' ' * (nspaces or 0)
3316 3347
3317 3348 #-------------------------------------------------------------------------
3318 3349 # Things related to GUI support and pylab
3319 3350 #-------------------------------------------------------------------------
3320 3351
3321 3352 active_eventloop = None
3322 3353
3323 3354 def enable_gui(self, gui=None):
3324 3355 raise NotImplementedError('Implement enable_gui in a subclass')
3325 3356
3326 3357 def enable_matplotlib(self, gui=None):
3327 3358 """Enable interactive matplotlib and inline figure support.
3328 3359
3329 3360 This takes the following steps:
3330 3361
3331 3362 1. select the appropriate eventloop and matplotlib backend
3332 3363 2. set up matplotlib for interactive use with that backend
3333 3364 3. configure formatters for inline figure display
3334 3365 4. enable the selected gui eventloop
3335 3366
3336 3367 Parameters
3337 3368 ----------
3338 3369 gui : optional, string
3339 3370 If given, dictates the choice of matplotlib GUI backend to use
3340 3371 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3341 3372 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3342 3373 matplotlib (as dictated by the matplotlib build-time options plus the
3343 3374 user's matplotlibrc configuration file). Note that not all backends
3344 3375 make sense in all contexts, for example a terminal ipython can't
3345 3376 display figures inline.
3346 3377 """
3347 3378 from IPython.core import pylabtools as pt
3348 3379 from matplotlib_inline.backend_inline import configure_inline_support
3349 3380 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
3350 3381
3351 3382 if gui != 'inline':
3352 3383 # If we have our first gui selection, store it
3353 3384 if self.pylab_gui_select is None:
3354 3385 self.pylab_gui_select = gui
3355 3386 # Otherwise if they are different
3356 3387 elif gui != self.pylab_gui_select:
3357 3388 print('Warning: Cannot change to a different GUI toolkit: %s.'
3358 3389 ' Using %s instead.' % (gui, self.pylab_gui_select))
3359 3390 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
3360 3391
3361 3392 pt.activate_matplotlib(backend)
3362 3393 configure_inline_support(self, backend)
3363 3394
3364 3395 # Now we must activate the gui pylab wants to use, and fix %run to take
3365 3396 # plot updates into account
3366 3397 self.enable_gui(gui)
3367 3398 self.magics_manager.registry['ExecutionMagics'].default_runner = \
3368 3399 pt.mpl_runner(self.safe_execfile)
3369 3400
3370 3401 return gui, backend
3371 3402
3372 3403 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
3373 3404 """Activate pylab support at runtime.
3374 3405
3375 3406 This turns on support for matplotlib, preloads into the interactive
3376 3407 namespace all of numpy and pylab, and configures IPython to correctly
3377 3408 interact with the GUI event loop. The GUI backend to be used can be
3378 3409 optionally selected with the optional ``gui`` argument.
3379 3410
3380 3411 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
3381 3412
3382 3413 Parameters
3383 3414 ----------
3384 3415 gui : optional, string
3385 3416 If given, dictates the choice of matplotlib GUI backend to use
3386 3417 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3387 3418 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3388 3419 matplotlib (as dictated by the matplotlib build-time options plus the
3389 3420 user's matplotlibrc configuration file). Note that not all backends
3390 3421 make sense in all contexts, for example a terminal ipython can't
3391 3422 display figures inline.
3392 3423 import_all : optional, bool, default: True
3393 3424 Whether to do `from numpy import *` and `from pylab import *`
3394 3425 in addition to module imports.
3395 3426 welcome_message : deprecated
3396 3427 This argument is ignored, no welcome message will be displayed.
3397 3428 """
3398 3429 from IPython.core.pylabtools import import_pylab
3399 3430
3400 3431 gui, backend = self.enable_matplotlib(gui)
3401 3432
3402 3433 # We want to prevent the loading of pylab to pollute the user's
3403 3434 # namespace as shown by the %who* magics, so we execute the activation
3404 3435 # code in an empty namespace, and we update *both* user_ns and
3405 3436 # user_ns_hidden with this information.
3406 3437 ns = {}
3407 3438 import_pylab(ns, import_all)
3408 3439 # warn about clobbered names
3409 3440 ignored = {"__builtins__"}
3410 3441 both = set(ns).intersection(self.user_ns).difference(ignored)
3411 3442 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
3412 3443 self.user_ns.update(ns)
3413 3444 self.user_ns_hidden.update(ns)
3414 3445 return gui, backend, clobbered
3415 3446
3416 3447 #-------------------------------------------------------------------------
3417 3448 # Utilities
3418 3449 #-------------------------------------------------------------------------
3419 3450
3420 3451 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
3421 3452 """Expand python variables in a string.
3422 3453
3423 3454 The depth argument indicates how many frames above the caller should
3424 3455 be walked to look for the local namespace where to expand variables.
3425 3456
3426 3457 The global namespace for expansion is always the user's interactive
3427 3458 namespace.
3428 3459 """
3429 3460 ns = self.user_ns.copy()
3430 3461 try:
3431 3462 frame = sys._getframe(depth+1)
3432 3463 except ValueError:
3433 3464 # This is thrown if there aren't that many frames on the stack,
3434 3465 # e.g. if a script called run_line_magic() directly.
3435 3466 pass
3436 3467 else:
3437 3468 ns.update(frame.f_locals)
3438 3469
3439 3470 try:
3440 3471 # We have to use .vformat() here, because 'self' is a valid and common
3441 3472 # name, and expanding **ns for .format() would make it collide with
3442 3473 # the 'self' argument of the method.
3443 3474 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3444 3475 except Exception:
3445 3476 # if formatter couldn't format, just let it go untransformed
3446 3477 pass
3447 3478 return cmd
3448 3479
3449 3480 def mktempfile(self, data=None, prefix='ipython_edit_'):
3450 3481 """Make a new tempfile and return its filename.
3451 3482
3452 3483 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3453 3484 but it registers the created filename internally so ipython cleans it up
3454 3485 at exit time.
3455 3486
3456 3487 Optional inputs:
3457 3488
3458 3489 - data(None): if data is given, it gets written out to the temp file
3459 3490 immediately, and the file is closed again."""
3460 3491
3461 3492 dir_path = Path(tempfile.mkdtemp(prefix=prefix))
3462 3493 self.tempdirs.append(dir_path)
3463 3494
3464 3495 handle, filename = tempfile.mkstemp(".py", prefix, dir=str(dir_path))
3465 3496 os.close(handle) # On Windows, there can only be one open handle on a file
3466 3497
3467 3498 file_path = Path(filename)
3468 3499 self.tempfiles.append(file_path)
3469 3500
3470 3501 if data:
3471 3502 file_path.write_text(data)
3472 3503 return filename
3473 3504
3474 3505 def ask_yes_no(self, prompt, default=None, interrupt=None):
3475 3506 if self.quiet:
3476 3507 return True
3477 3508 return ask_yes_no(prompt,default,interrupt)
3478 3509
3479 3510 def show_usage(self):
3480 3511 """Show a usage message"""
3481 3512 page.page(IPython.core.usage.interactive_usage)
3482 3513
3483 3514 def extract_input_lines(self, range_str, raw=False):
3484 3515 """Return as a string a set of input history slices.
3485 3516
3486 3517 Parameters
3487 3518 ----------
3488 3519 range_str : str
3489 3520 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3490 3521 since this function is for use by magic functions which get their
3491 3522 arguments as strings. The number before the / is the session
3492 3523 number: ~n goes n back from the current session.
3493 3524
3494 3525 If empty string is given, returns history of current session
3495 3526 without the last input.
3496 3527
3497 3528 raw : bool, optional
3498 3529 By default, the processed input is used. If this is true, the raw
3499 3530 input history is used instead.
3500 3531
3501 3532 Notes
3502 3533 -----
3503 3534 Slices can be described with two notations:
3504 3535
3505 3536 * ``N:M`` -> standard python form, means including items N...(M-1).
3506 3537 * ``N-M`` -> include items N..M (closed endpoint).
3507 3538 """
3508 3539 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3509 3540 text = "\n".join(x for _, _, x in lines)
3510 3541
3511 3542 # Skip the last line, as it's probably the magic that called this
3512 3543 if not range_str:
3513 3544 if "\n" not in text:
3514 3545 text = ""
3515 3546 else:
3516 3547 text = text[: text.rfind("\n")]
3517 3548
3518 3549 return text
3519 3550
3520 3551 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False):
3521 3552 """Get a code string from history, file, url, or a string or macro.
3522 3553
3523 3554 This is mainly used by magic functions.
3524 3555
3525 3556 Parameters
3526 3557 ----------
3527 3558 target : str
3528 3559 A string specifying code to retrieve. This will be tried respectively
3529 3560 as: ranges of input history (see %history for syntax), url,
3530 3561 corresponding .py file, filename, or an expression evaluating to a
3531 3562 string or Macro in the user namespace.
3532 3563
3533 3564 If empty string is given, returns complete history of current
3534 3565 session, without the last line.
3535 3566
3536 3567 raw : bool
3537 3568 If true (default), retrieve raw history. Has no effect on the other
3538 3569 retrieval mechanisms.
3539 3570
3540 3571 py_only : bool (default False)
3541 3572 Only try to fetch python code, do not try alternative methods to decode file
3542 3573 if unicode fails.
3543 3574
3544 3575 Returns
3545 3576 -------
3546 3577 A string of code.
3547 3578 ValueError is raised if nothing is found, and TypeError if it evaluates
3548 3579 to an object of another type. In each case, .args[0] is a printable
3549 3580 message.
3550 3581 """
3551 3582 code = self.extract_input_lines(target, raw=raw) # Grab history
3552 3583 if code:
3553 3584 return code
3554 3585 try:
3555 3586 if target.startswith(('http://', 'https://')):
3556 3587 return openpy.read_py_url(target, skip_encoding_cookie=skip_encoding_cookie)
3557 3588 except UnicodeDecodeError as e:
3558 3589 if not py_only :
3559 3590 # Deferred import
3560 3591 from urllib.request import urlopen
3561 3592 response = urlopen(target)
3562 3593 return response.read().decode('latin1')
3563 3594 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3564 3595
3565 3596 potential_target = [target]
3566 3597 try :
3567 3598 potential_target.insert(0,get_py_filename(target))
3568 3599 except IOError:
3569 3600 pass
3570 3601
3571 3602 for tgt in potential_target :
3572 3603 if os.path.isfile(tgt): # Read file
3573 3604 try :
3574 3605 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3575 3606 except UnicodeDecodeError as e:
3576 3607 if not py_only :
3577 3608 with io_open(tgt,'r', encoding='latin1') as f :
3578 3609 return f.read()
3579 3610 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3580 3611 elif os.path.isdir(os.path.expanduser(tgt)):
3581 3612 raise ValueError("'%s' is a directory, not a regular file." % target)
3582 3613
3583 3614 if search_ns:
3584 3615 # Inspect namespace to load object source
3585 3616 object_info = self.object_inspect(target, detail_level=1)
3586 3617 if object_info['found'] and object_info['source']:
3587 3618 return object_info['source']
3588 3619
3589 3620 try: # User namespace
3590 3621 codeobj = eval(target, self.user_ns)
3591 3622 except Exception as e:
3592 3623 raise ValueError(("'%s' was not found in history, as a file, url, "
3593 3624 "nor in the user namespace.") % target) from e
3594 3625
3595 3626 if isinstance(codeobj, str):
3596 3627 return codeobj
3597 3628 elif isinstance(codeobj, Macro):
3598 3629 return codeobj.value
3599 3630
3600 3631 raise TypeError("%s is neither a string nor a macro." % target,
3601 3632 codeobj)
3602 3633
3603 3634 def _atexit_once(self):
3604 3635 """
3605 3636 At exist operation that need to be called at most once.
3606 3637 Second call to this function per instance will do nothing.
3607 3638 """
3608 3639
3609 3640 if not getattr(self, "_atexit_once_called", False):
3610 3641 self._atexit_once_called = True
3611 3642 # Clear all user namespaces to release all references cleanly.
3612 3643 self.reset(new_session=False)
3613 3644 # Close the history session (this stores the end time and line count)
3614 3645 # this must be *before* the tempfile cleanup, in case of temporary
3615 3646 # history db
3616 3647 self.history_manager.end_session()
3617 3648 self.history_manager = None
3618 3649
3619 3650 #-------------------------------------------------------------------------
3620 3651 # Things related to IPython exiting
3621 3652 #-------------------------------------------------------------------------
3622 3653 def atexit_operations(self):
3623 3654 """This will be executed at the time of exit.
3624 3655
3625 3656 Cleanup operations and saving of persistent data that is done
3626 3657 unconditionally by IPython should be performed here.
3627 3658
3628 3659 For things that may depend on startup flags or platform specifics (such
3629 3660 as having readline or not), register a separate atexit function in the
3630 3661 code that has the appropriate information, rather than trying to
3631 3662 clutter
3632 3663 """
3633 3664 self._atexit_once()
3634 3665
3635 3666 # Cleanup all tempfiles and folders left around
3636 3667 for tfile in self.tempfiles:
3637 3668 try:
3638 3669 tfile.unlink()
3639 3670 self.tempfiles.remove(tfile)
3640 3671 except FileNotFoundError:
3641 3672 pass
3642 3673 del self.tempfiles
3643 3674 for tdir in self.tempdirs:
3644 3675 try:
3645 3676 tdir.rmdir()
3646 3677 self.tempdirs.remove(tdir)
3647 3678 except FileNotFoundError:
3648 3679 pass
3649 3680 del self.tempdirs
3650 3681
3651 3682
3652 3683 def cleanup(self):
3653 3684 self.restore_sys_module_state()
3654 3685
3655 3686
3656 3687 # Overridden in terminal subclass to change prompts
3657 3688 def switch_doctest_mode(self, mode):
3658 3689 pass
3659 3690
3660 3691
3661 3692 class InteractiveShellABC(metaclass=abc.ABCMeta):
3662 3693 """An abstract base class for InteractiveShell."""
3663 3694
3664 3695 InteractiveShellABC.register(InteractiveShell)
@@ -1,700 +1,746 b''
1 1 # encoding: utf-8
2 2 """Magic functions for InteractiveShell.
3 3 """
4 4
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
7 7 # Copyright (C) 2001 Fernando Perez <fperez@colorado.edu>
8 8 # Copyright (C) 2008 The IPython Development Team
9 9
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #-----------------------------------------------------------------------------
13 13
14 14 import os
15 15 import re
16 16 import sys
17 17 from getopt import getopt, GetoptError
18 18
19 19 from traitlets.config.configurable import Configurable
20 20 from . import oinspect
21 21 from .error import UsageError
22 22 from .inputtransformer2 import ESC_MAGIC, ESC_MAGIC2
23 23 from ..utils.ipstruct import Struct
24 24 from ..utils.process import arg_split
25 25 from ..utils.text import dedent
26 26 from traitlets import Bool, Dict, Instance, observe
27 27 from logging import error
28 28
29 29 #-----------------------------------------------------------------------------
30 30 # Globals
31 31 #-----------------------------------------------------------------------------
32 32
33 33 # A dict we'll use for each class that has magics, used as temporary storage to
34 34 # pass information between the @line/cell_magic method decorators and the
35 35 # @magics_class class decorator, because the method decorators have no
36 36 # access to the class when they run. See for more details:
37 37 # http://stackoverflow.com/questions/2366713/can-a-python-decorator-of-an-instance-method-access-the-class
38 38
39 39 magics = dict(line={}, cell={})
40 40
41 41 magic_kinds = ('line', 'cell')
42 42 magic_spec = ('line', 'cell', 'line_cell')
43 43 magic_escapes = dict(line=ESC_MAGIC, cell=ESC_MAGIC2)
44 44
45 45 #-----------------------------------------------------------------------------
46 46 # Utility classes and functions
47 47 #-----------------------------------------------------------------------------
48 48
49 49 class Bunch: pass
50 50
51 51
52 52 def on_off(tag):
53 53 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
54 54 return ['OFF','ON'][tag]
55 55
56 56
57 57 def compress_dhist(dh):
58 58 """Compress a directory history into a new one with at most 20 entries.
59 59
60 60 Return a new list made from the first and last 10 elements of dhist after
61 61 removal of duplicates.
62 62 """
63 63 head, tail = dh[:-10], dh[-10:]
64 64
65 65 newhead = []
66 66 done = set()
67 67 for h in head:
68 68 if h in done:
69 69 continue
70 70 newhead.append(h)
71 71 done.add(h)
72 72
73 73 return newhead + tail
74 74
75 75
76 76 def needs_local_scope(func):
77 77 """Decorator to mark magic functions which need to local scope to run."""
78 78 func.needs_local_scope = True
79 79 return func
80 80
81 81 #-----------------------------------------------------------------------------
82 82 # Class and method decorators for registering magics
83 83 #-----------------------------------------------------------------------------
84 84
85 85 def magics_class(cls):
86 86 """Class decorator for all subclasses of the main Magics class.
87 87
88 88 Any class that subclasses Magics *must* also apply this decorator, to
89 89 ensure that all the methods that have been decorated as line/cell magics
90 90 get correctly registered in the class instance. This is necessary because
91 91 when method decorators run, the class does not exist yet, so they
92 92 temporarily store their information into a module global. Application of
93 93 this class decorator copies that global data to the class instance and
94 94 clears the global.
95 95
96 96 Obviously, this mechanism is not thread-safe, which means that the
97 97 *creation* of subclasses of Magic should only be done in a single-thread
98 98 context. Instantiation of the classes has no restrictions. Given that
99 99 these classes are typically created at IPython startup time and before user
100 100 application code becomes active, in practice this should not pose any
101 101 problems.
102 102 """
103 103 cls.registered = True
104 104 cls.magics = dict(line = magics['line'],
105 105 cell = magics['cell'])
106 106 magics['line'] = {}
107 107 magics['cell'] = {}
108 108 return cls
109 109
110 110
111 111 def record_magic(dct, magic_kind, magic_name, func):
112 112 """Utility function to store a function as a magic of a specific kind.
113 113
114 114 Parameters
115 115 ----------
116 116 dct : dict
117 117 A dictionary with 'line' and 'cell' subdicts.
118 118 magic_kind : str
119 119 Kind of magic to be stored.
120 120 magic_name : str
121 121 Key to store the magic as.
122 122 func : function
123 123 Callable object to store.
124 124 """
125 125 if magic_kind == 'line_cell':
126 126 dct['line'][magic_name] = dct['cell'][magic_name] = func
127 127 else:
128 128 dct[magic_kind][magic_name] = func
129 129
130 130
131 131 def validate_type(magic_kind):
132 132 """Ensure that the given magic_kind is valid.
133 133
134 134 Check that the given magic_kind is one of the accepted spec types (stored
135 135 in the global `magic_spec`), raise ValueError otherwise.
136 136 """
137 137 if magic_kind not in magic_spec:
138 138 raise ValueError('magic_kind must be one of %s, %s given' %
139 139 magic_kinds, magic_kind)
140 140
141 141
142 142 # The docstrings for the decorator below will be fairly similar for the two
143 143 # types (method and function), so we generate them here once and reuse the
144 144 # templates below.
145 145 _docstring_template = \
146 146 """Decorate the given {0} as {1} magic.
147 147
148 148 The decorator can be used with or without arguments, as follows.
149 149
150 150 i) without arguments: it will create a {1} magic named as the {0} being
151 151 decorated::
152 152
153 153 @deco
154 154 def foo(...)
155 155
156 156 will create a {1} magic named `foo`.
157 157
158 158 ii) with one string argument: which will be used as the actual name of the
159 159 resulting magic::
160 160
161 161 @deco('bar')
162 162 def foo(...)
163 163
164 164 will create a {1} magic named `bar`.
165 165
166 166 To register a class magic use ``Interactiveshell.register_magic(class or instance)``.
167 167 """
168 168
169 169 # These two are decorator factories. While they are conceptually very similar,
170 170 # there are enough differences in the details that it's simpler to have them
171 171 # written as completely standalone functions rather than trying to share code
172 172 # and make a single one with convoluted logic.
173 173
174 174 def _method_magic_marker(magic_kind):
175 175 """Decorator factory for methods in Magics subclasses.
176 176 """
177 177
178 178 validate_type(magic_kind)
179 179
180 180 # This is a closure to capture the magic_kind. We could also use a class,
181 181 # but it's overkill for just that one bit of state.
182 182 def magic_deco(arg):
183 183 if callable(arg):
184 184 # "Naked" decorator call (just @foo, no args)
185 185 func = arg
186 186 name = func.__name__
187 187 retval = arg
188 188 record_magic(magics, magic_kind, name, name)
189 189 elif isinstance(arg, str):
190 190 # Decorator called with arguments (@foo('bar'))
191 191 name = arg
192 192 def mark(func, *a, **kw):
193 193 record_magic(magics, magic_kind, name, func.__name__)
194 194 return func
195 195 retval = mark
196 196 else:
197 197 raise TypeError("Decorator can only be called with "
198 198 "string or function")
199 199 return retval
200 200
201 201 # Ensure the resulting decorator has a usable docstring
202 202 magic_deco.__doc__ = _docstring_template.format('method', magic_kind)
203 203 return magic_deco
204 204
205 205
206 206 def _function_magic_marker(magic_kind):
207 207 """Decorator factory for standalone functions.
208 208 """
209 209 validate_type(magic_kind)
210 210
211 211 # This is a closure to capture the magic_kind. We could also use a class,
212 212 # but it's overkill for just that one bit of state.
213 213 def magic_deco(arg):
214 214 # Find get_ipython() in the caller's namespace
215 215 caller = sys._getframe(1)
216 216 for ns in ['f_locals', 'f_globals', 'f_builtins']:
217 217 get_ipython = getattr(caller, ns).get('get_ipython')
218 218 if get_ipython is not None:
219 219 break
220 220 else:
221 221 raise NameError('Decorator can only run in context where '
222 222 '`get_ipython` exists')
223 223
224 224 ip = get_ipython()
225 225
226 226 if callable(arg):
227 227 # "Naked" decorator call (just @foo, no args)
228 228 func = arg
229 229 name = func.__name__
230 230 ip.register_magic_function(func, magic_kind, name)
231 231 retval = arg
232 232 elif isinstance(arg, str):
233 233 # Decorator called with arguments (@foo('bar'))
234 234 name = arg
235 235 def mark(func, *a, **kw):
236 236 ip.register_magic_function(func, magic_kind, name)
237 237 return func
238 238 retval = mark
239 239 else:
240 240 raise TypeError("Decorator can only be called with "
241 241 "string or function")
242 242 return retval
243 243
244 244 # Ensure the resulting decorator has a usable docstring
245 245 ds = _docstring_template.format('function', magic_kind)
246 246
247 247 ds += dedent("""
248 248 Note: this decorator can only be used in a context where IPython is already
249 249 active, so that the `get_ipython()` call succeeds. You can therefore use
250 250 it in your startup files loaded after IPython initializes, but *not* in the
251 251 IPython configuration file itself, which is executed before IPython is
252 252 fully up and running. Any file located in the `startup` subdirectory of
253 253 your configuration profile will be OK in this sense.
254 254 """)
255 255
256 256 magic_deco.__doc__ = ds
257 257 return magic_deco
258 258
259 259
260 260 MAGIC_NO_VAR_EXPAND_ATTR = '_ipython_magic_no_var_expand'
261 261
262 262
263 263 def no_var_expand(magic_func):
264 264 """Mark a magic function as not needing variable expansion
265 265
266 266 By default, IPython interprets `{a}` or `$a` in the line passed to magics
267 267 as variables that should be interpolated from the interactive namespace
268 268 before passing the line to the magic function.
269 269 This is not always desirable, e.g. when the magic executes Python code
270 270 (%timeit, %time, etc.).
271 271 Decorate magics with `@no_var_expand` to opt-out of variable expansion.
272 272
273 273 .. versionadded:: 7.3
274 274 """
275 275 setattr(magic_func, MAGIC_NO_VAR_EXPAND_ATTR, True)
276 276 return magic_func
277 277
278 278
279 279 # Create the actual decorators for public use
280 280
281 281 # These three are used to decorate methods in class definitions
282 282 line_magic = _method_magic_marker('line')
283 283 cell_magic = _method_magic_marker('cell')
284 284 line_cell_magic = _method_magic_marker('line_cell')
285 285
286 286 # These three decorate standalone functions and perform the decoration
287 287 # immediately. They can only run where get_ipython() works
288 288 register_line_magic = _function_magic_marker('line')
289 289 register_cell_magic = _function_magic_marker('cell')
290 290 register_line_cell_magic = _function_magic_marker('line_cell')
291 291
292 292 #-----------------------------------------------------------------------------
293 293 # Core Magic classes
294 294 #-----------------------------------------------------------------------------
295 295
296 296 class MagicsManager(Configurable):
297 297 """Object that handles all magic-related functionality for IPython.
298 298 """
299 299 # Non-configurable class attributes
300 300
301 301 # A two-level dict, first keyed by magic type, then by magic function, and
302 302 # holding the actual callable object as value. This is the dict used for
303 303 # magic function dispatch
304 304 magics = Dict()
305 lazy_magics = Dict(
306 help="""
307 Mapping from magic names to modules to load.
308
309 This can be used in IPython/IPykernel configuration to declare lazy magics
310 that will only be imported/registered on first use.
311
312 For example::
313
314 c.MagicsManger.lazy_magics = {
315 "my_magic": "slow.to.import",
316 "my_other_magic": "also.slow",
317 }
318
319 On first invocation of `%my_magic`, `%%my_magic`, `%%my_other_magic` or
320 `%%my_other_magic`, the corresponding module will be loaded as an ipython
321 extensions as if you had previously done `%load_ext ipython`.
322
323 Magics names should be without percent(s) as magics can be both cell
324 and line magics.
325
326 Lazy loading happen relatively late in execution process, and
327 complex extensions that manipulate Python/IPython internal state or global state
328 might not support lazy loading.
329 """
330 ).tag(
331 config=True,
332 )
305 333
306 334 # A registry of the original objects that we've been given holding magics.
307 335 registry = Dict()
308 336
309 337 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
310 338
311 339 auto_magic = Bool(True, help=
312 340 "Automatically call line magics without requiring explicit % prefix"
313 341 ).tag(config=True)
314 342 @observe('auto_magic')
315 343 def _auto_magic_changed(self, change):
316 344 self.shell.automagic = change['new']
317 345
318 346 _auto_status = [
319 347 'Automagic is OFF, % prefix IS needed for line magics.',
320 348 'Automagic is ON, % prefix IS NOT needed for line magics.']
321 349
322 350 user_magics = Instance('IPython.core.magics.UserMagics', allow_none=True)
323 351
324 352 def __init__(self, shell=None, config=None, user_magics=None, **traits):
325 353
326 354 super(MagicsManager, self).__init__(shell=shell, config=config,
327 355 user_magics=user_magics, **traits)
328 356 self.magics = dict(line={}, cell={})
329 357 # Let's add the user_magics to the registry for uniformity, so *all*
330 358 # registered magic containers can be found there.
331 359 self.registry[user_magics.__class__.__name__] = user_magics
332 360
333 361 def auto_status(self):
334 362 """Return descriptive string with automagic status."""
335 363 return self._auto_status[self.auto_magic]
336 364
337 365 def lsmagic(self):
338 366 """Return a dict of currently available magic functions.
339 367
340 368 The return dict has the keys 'line' and 'cell', corresponding to the
341 369 two types of magics we support. Each value is a list of names.
342 370 """
343 371 return self.magics
344 372
345 373 def lsmagic_docs(self, brief=False, missing=''):
346 374 """Return dict of documentation of magic functions.
347 375
348 376 The return dict has the keys 'line' and 'cell', corresponding to the
349 377 two types of magics we support. Each value is a dict keyed by magic
350 378 name whose value is the function docstring. If a docstring is
351 379 unavailable, the value of `missing` is used instead.
352 380
353 381 If brief is True, only the first line of each docstring will be returned.
354 382 """
355 383 docs = {}
356 384 for m_type in self.magics:
357 385 m_docs = {}
358 386 for m_name, m_func in self.magics[m_type].items():
359 387 if m_func.__doc__:
360 388 if brief:
361 389 m_docs[m_name] = m_func.__doc__.split('\n', 1)[0]
362 390 else:
363 391 m_docs[m_name] = m_func.__doc__.rstrip()
364 392 else:
365 393 m_docs[m_name] = missing
366 394 docs[m_type] = m_docs
367 395 return docs
368 396
397 def register_lazy(self, name: str, fully_qualified_name: str):
398 """
399 Lazily register a magic via an extension.
400
401
402 Parameters
403 ----------
404 name : str
405 Name of the magic you wish to register.
406 fully_qualified_name :
407 Fully qualified name of the module/submodule that should be loaded
408 as an extensions when the magic is first called.
409 It is assumed that loading this extensions will register the given
410 magic.
411 """
412
413 self.lazy_magics[name] = fully_qualified_name
414
369 415 def register(self, *magic_objects):
370 416 """Register one or more instances of Magics.
371 417
372 418 Take one or more classes or instances of classes that subclass the main
373 419 `core.Magic` class, and register them with IPython to use the magic
374 420 functions they provide. The registration process will then ensure that
375 421 any methods that have decorated to provide line and/or cell magics will
376 422 be recognized with the `%x`/`%%x` syntax as a line/cell magic
377 423 respectively.
378 424
379 425 If classes are given, they will be instantiated with the default
380 426 constructor. If your classes need a custom constructor, you should
381 427 instanitate them first and pass the instance.
382 428
383 429 The provided arguments can be an arbitrary mix of classes and instances.
384 430
385 431 Parameters
386 432 ----------
387 433 *magic_objects : one or more classes or instances
388 434 """
389 435 # Start by validating them to ensure they have all had their magic
390 436 # methods registered at the instance level
391 437 for m in magic_objects:
392 438 if not m.registered:
393 439 raise ValueError("Class of magics %r was constructed without "
394 440 "the @register_magics class decorator")
395 441 if isinstance(m, type):
396 442 # If we're given an uninstantiated class
397 443 m = m(shell=self.shell)
398 444
399 445 # Now that we have an instance, we can register it and update the
400 446 # table of callables
401 447 self.registry[m.__class__.__name__] = m
402 448 for mtype in magic_kinds:
403 449 self.magics[mtype].update(m.magics[mtype])
404 450
405 451 def register_function(self, func, magic_kind='line', magic_name=None):
406 452 """Expose a standalone function as magic function for IPython.
407 453
408 454 This will create an IPython magic (line, cell or both) from a
409 455 standalone function. The functions should have the following
410 456 signatures:
411 457
412 458 * For line magics: `def f(line)`
413 459 * For cell magics: `def f(line, cell)`
414 460 * For a function that does both: `def f(line, cell=None)`
415 461
416 462 In the latter case, the function will be called with `cell==None` when
417 463 invoked as `%f`, and with cell as a string when invoked as `%%f`.
418 464
419 465 Parameters
420 466 ----------
421 467 func : callable
422 468 Function to be registered as a magic.
423 469 magic_kind : str
424 470 Kind of magic, one of 'line', 'cell' or 'line_cell'
425 471 magic_name : optional str
426 472 If given, the name the magic will have in the IPython namespace. By
427 473 default, the name of the function itself is used.
428 474 """
429 475
430 476 # Create the new method in the user_magics and register it in the
431 477 # global table
432 478 validate_type(magic_kind)
433 479 magic_name = func.__name__ if magic_name is None else magic_name
434 480 setattr(self.user_magics, magic_name, func)
435 481 record_magic(self.magics, magic_kind, magic_name, func)
436 482
437 483 def register_alias(self, alias_name, magic_name, magic_kind='line', magic_params=None):
438 484 """Register an alias to a magic function.
439 485
440 486 The alias is an instance of :class:`MagicAlias`, which holds the
441 487 name and kind of the magic it should call. Binding is done at
442 488 call time, so if the underlying magic function is changed the alias
443 489 will call the new function.
444 490
445 491 Parameters
446 492 ----------
447 493 alias_name : str
448 494 The name of the magic to be registered.
449 495 magic_name : str
450 496 The name of an existing magic.
451 497 magic_kind : str
452 498 Kind of magic, one of 'line' or 'cell'
453 499 """
454 500
455 501 # `validate_type` is too permissive, as it allows 'line_cell'
456 502 # which we do not handle.
457 503 if magic_kind not in magic_kinds:
458 504 raise ValueError('magic_kind must be one of %s, %s given' %
459 505 magic_kinds, magic_kind)
460 506
461 507 alias = MagicAlias(self.shell, magic_name, magic_kind, magic_params)
462 508 setattr(self.user_magics, alias_name, alias)
463 509 record_magic(self.magics, magic_kind, alias_name, alias)
464 510
465 511 # Key base class that provides the central functionality for magics.
466 512
467 513
468 514 class Magics(Configurable):
469 515 """Base class for implementing magic functions.
470 516
471 517 Shell functions which can be reached as %function_name. All magic
472 518 functions should accept a string, which they can parse for their own
473 519 needs. This can make some functions easier to type, eg `%cd ../`
474 520 vs. `%cd("../")`
475 521
476 522 Classes providing magic functions need to subclass this class, and they
477 523 MUST:
478 524
479 525 - Use the method decorators `@line_magic` and `@cell_magic` to decorate
480 526 individual methods as magic functions, AND
481 527
482 528 - Use the class decorator `@magics_class` to ensure that the magic
483 529 methods are properly registered at the instance level upon instance
484 530 initialization.
485 531
486 532 See :mod:`magic_functions` for examples of actual implementation classes.
487 533 """
488 534 # Dict holding all command-line options for each magic.
489 535 options_table = None
490 536 # Dict for the mapping of magic names to methods, set by class decorator
491 537 magics = None
492 538 # Flag to check that the class decorator was properly applied
493 539 registered = False
494 540 # Instance of IPython shell
495 541 shell = None
496 542
497 543 def __init__(self, shell=None, **kwargs):
498 544 if not(self.__class__.registered):
499 545 raise ValueError('Magics subclass without registration - '
500 546 'did you forget to apply @magics_class?')
501 547 if shell is not None:
502 548 if hasattr(shell, 'configurables'):
503 549 shell.configurables.append(self)
504 550 if hasattr(shell, 'config'):
505 551 kwargs.setdefault('parent', shell)
506 552
507 553 self.shell = shell
508 554 self.options_table = {}
509 555 # The method decorators are run when the instance doesn't exist yet, so
510 556 # they can only record the names of the methods they are supposed to
511 557 # grab. Only now, that the instance exists, can we create the proper
512 558 # mapping to bound methods. So we read the info off the original names
513 559 # table and replace each method name by the actual bound method.
514 560 # But we mustn't clobber the *class* mapping, in case of multiple instances.
515 561 class_magics = self.magics
516 562 self.magics = {}
517 563 for mtype in magic_kinds:
518 564 tab = self.magics[mtype] = {}
519 565 cls_tab = class_magics[mtype]
520 566 for magic_name, meth_name in cls_tab.items():
521 567 if isinstance(meth_name, str):
522 568 # it's a method name, grab it
523 569 tab[magic_name] = getattr(self, meth_name)
524 570 else:
525 571 # it's the real thing
526 572 tab[magic_name] = meth_name
527 573 # Configurable **needs** to be initiated at the end or the config
528 574 # magics get screwed up.
529 575 super(Magics, self).__init__(**kwargs)
530 576
531 577 def arg_err(self,func):
532 578 """Print docstring if incorrect arguments were passed"""
533 579 print('Error in arguments:')
534 580 print(oinspect.getdoc(func))
535 581
536 582 def format_latex(self, strng):
537 583 """Format a string for latex inclusion."""
538 584
539 585 # Characters that need to be escaped for latex:
540 586 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
541 587 # Magic command names as headers:
542 588 cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC,
543 589 re.MULTILINE)
544 590 # Magic commands
545 591 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC,
546 592 re.MULTILINE)
547 593 # Paragraph continue
548 594 par_re = re.compile(r'\\$',re.MULTILINE)
549 595
550 596 # The "\n" symbol
551 597 newline_re = re.compile(r'\\n')
552 598
553 599 # Now build the string for output:
554 600 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
555 601 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
556 602 strng)
557 603 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
558 604 strng = par_re.sub(r'\\\\',strng)
559 605 strng = escape_re.sub(r'\\\1',strng)
560 606 strng = newline_re.sub(r'\\textbackslash{}n',strng)
561 607 return strng
562 608
563 609 def parse_options(self, arg_str, opt_str, *long_opts, **kw):
564 610 """Parse options passed to an argument string.
565 611
566 612 The interface is similar to that of :func:`getopt.getopt`, but it
567 613 returns a :class:`~IPython.utils.struct.Struct` with the options as keys
568 614 and the stripped argument string still as a string.
569 615
570 616 arg_str is quoted as a true sys.argv vector by using shlex.split.
571 617 This allows us to easily expand variables, glob files, quote
572 618 arguments, etc.
573 619
574 620 Parameters
575 621 ----------
576 622 arg_str : str
577 623 The arguments to parse.
578 624 opt_str : str
579 625 The options specification.
580 626 mode : str, default 'string'
581 627 If given as 'list', the argument string is returned as a list (split
582 628 on whitespace) instead of a string.
583 629 list_all : bool, default False
584 630 Put all option values in lists. Normally only options
585 631 appearing more than once are put in a list.
586 632 posix : bool, default True
587 633 Whether to split the input line in POSIX mode or not, as per the
588 634 conventions outlined in the :mod:`shlex` module from the standard
589 635 library.
590 636 """
591 637
592 638 # inject default options at the beginning of the input line
593 639 caller = sys._getframe(1).f_code.co_name
594 640 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
595 641
596 642 mode = kw.get('mode','string')
597 643 if mode not in ['string','list']:
598 644 raise ValueError('incorrect mode given: %s' % mode)
599 645 # Get options
600 646 list_all = kw.get('list_all',0)
601 647 posix = kw.get('posix', os.name == 'posix')
602 648 strict = kw.get('strict', True)
603 649
604 650 preserve_non_opts = kw.get("preserve_non_opts", False)
605 651 remainder_arg_str = arg_str
606 652
607 653 # Check if we have more than one argument to warrant extra processing:
608 654 odict = {} # Dictionary with options
609 655 args = arg_str.split()
610 656 if len(args) >= 1:
611 657 # If the list of inputs only has 0 or 1 thing in it, there's no
612 658 # need to look for options
613 659 argv = arg_split(arg_str, posix, strict)
614 660 # Do regular option processing
615 661 try:
616 662 opts,args = getopt(argv, opt_str, long_opts)
617 663 except GetoptError as e:
618 664 raise UsageError(
619 665 '%s ( allowed: "%s" %s)' % (e.msg, opt_str, " ".join(long_opts))
620 666 ) from e
621 667 for o, a in opts:
622 668 if mode == "string" and preserve_non_opts:
623 669 # remove option-parts from the original args-string and preserve remaining-part.
624 670 # This relies on the arg_split(...) and getopt(...)'s impl spec, that the parsed options are
625 671 # returned in the original order.
626 672 remainder_arg_str = remainder_arg_str.replace(o, "", 1).replace(
627 673 a, "", 1
628 674 )
629 675 if o.startswith("--"):
630 676 o = o[2:]
631 677 else:
632 678 o = o[1:]
633 679 try:
634 680 odict[o].append(a)
635 681 except AttributeError:
636 682 odict[o] = [odict[o],a]
637 683 except KeyError:
638 684 if list_all:
639 685 odict[o] = [a]
640 686 else:
641 687 odict[o] = a
642 688
643 689 # Prepare opts,args for return
644 690 opts = Struct(odict)
645 691 if mode == 'string':
646 692 if preserve_non_opts:
647 693 args = remainder_arg_str.lstrip()
648 694 else:
649 695 args = " ".join(args)
650 696
651 697 return opts,args
652 698
653 699 def default_option(self, fn, optstr):
654 700 """Make an entry in the options_table for fn, with value optstr"""
655 701
656 702 if fn not in self.lsmagic():
657 703 error("%s is not a magic function" % fn)
658 704 self.options_table[fn] = optstr
659 705
660 706
661 707 class MagicAlias(object):
662 708 """An alias to another magic function.
663 709
664 710 An alias is determined by its magic name and magic kind. Lookup
665 711 is done at call time, so if the underlying magic changes the alias
666 712 will call the new function.
667 713
668 714 Use the :meth:`MagicsManager.register_alias` method or the
669 715 `%alias_magic` magic function to create and register a new alias.
670 716 """
671 717 def __init__(self, shell, magic_name, magic_kind, magic_params=None):
672 718 self.shell = shell
673 719 self.magic_name = magic_name
674 720 self.magic_params = magic_params
675 721 self.magic_kind = magic_kind
676 722
677 723 self.pretty_target = '%s%s' % (magic_escapes[self.magic_kind], self.magic_name)
678 724 self.__doc__ = "Alias for `%s`." % self.pretty_target
679 725
680 726 self._in_call = False
681 727
682 728 def __call__(self, *args, **kwargs):
683 729 """Call the magic alias."""
684 730 fn = self.shell.find_magic(self.magic_name, self.magic_kind)
685 731 if fn is None:
686 732 raise UsageError("Magic `%s` not found." % self.pretty_target)
687 733
688 734 # Protect against infinite recursion.
689 735 if self._in_call:
690 736 raise UsageError("Infinite recursion detected; "
691 737 "magic aliases cannot call themselves.")
692 738 self._in_call = True
693 739 try:
694 740 if self.magic_params:
695 741 args_list = list(args)
696 742 args_list[0] = self.magic_params + " " + args[0]
697 743 args = tuple(args_list)
698 744 return fn(*args, **kwargs)
699 745 finally:
700 746 self._in_call = False
@@ -1,1366 +1,1408 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for various magic functions."""
3 3
4 4 import asyncio
5 5 import gc
6 6 import io
7 7 import os
8 8 import re
9 9 import shlex
10 10 import sys
11 11 import warnings
12 12 from importlib import invalidate_caches
13 13 from io import StringIO
14 14 from pathlib import Path
15 15 from textwrap import dedent
16 16 from unittest import TestCase, mock
17 17
18 18 import pytest
19 19
20 20 from IPython import get_ipython
21 21 from IPython.core import magic
22 22 from IPython.core.error import UsageError
23 23 from IPython.core.magic import (
24 24 Magics,
25 25 cell_magic,
26 26 line_magic,
27 27 magics_class,
28 28 register_cell_magic,
29 29 register_line_magic,
30 30 )
31 31 from IPython.core.magics import code, execution, logging, osm, script
32 32 from IPython.testing import decorators as dec
33 33 from IPython.testing import tools as tt
34 34 from IPython.utils.io import capture_output
35 35 from IPython.utils.process import find_cmd
36 36 from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
37 from IPython.utils.syspathcontext import prepended_to_syspath
37 38
38 39 from .test_debugger import PdbTestInput
39 40
41 from tempfile import NamedTemporaryFile
40 42
41 43 @magic.magics_class
42 44 class DummyMagics(magic.Magics): pass
43 45
44 46 def test_extract_code_ranges():
45 47 instr = "1 3 5-6 7-9 10:15 17: :10 10- -13 :"
46 48 expected = [
47 49 (0, 1),
48 50 (2, 3),
49 51 (4, 6),
50 52 (6, 9),
51 53 (9, 14),
52 54 (16, None),
53 55 (None, 9),
54 56 (9, None),
55 57 (None, 13),
56 58 (None, None),
57 59 ]
58 60 actual = list(code.extract_code_ranges(instr))
59 61 assert actual == expected
60 62
61 63 def test_extract_symbols():
62 64 source = """import foo\na = 10\ndef b():\n return 42\n\n\nclass A: pass\n\n\n"""
63 65 symbols_args = ["a", "b", "A", "A,b", "A,a", "z"]
64 66 expected = [([], ['a']),
65 67 (["def b():\n return 42\n"], []),
66 68 (["class A: pass\n"], []),
67 69 (["class A: pass\n", "def b():\n return 42\n"], []),
68 70 (["class A: pass\n"], ['a']),
69 71 ([], ['z'])]
70 72 for symbols, exp in zip(symbols_args, expected):
71 73 assert code.extract_symbols(source, symbols) == exp
72 74
73 75
74 76 def test_extract_symbols_raises_exception_with_non_python_code():
75 77 source = ("=begin A Ruby program :)=end\n"
76 78 "def hello\n"
77 79 "puts 'Hello world'\n"
78 80 "end")
79 81 with pytest.raises(SyntaxError):
80 82 code.extract_symbols(source, "hello")
81 83
82 84
83 85 def test_magic_not_found():
84 86 # magic not found raises UsageError
85 87 with pytest.raises(UsageError):
86 88 _ip.magic('doesntexist')
87 89
88 90 # ensure result isn't success when a magic isn't found
89 91 result = _ip.run_cell('%doesntexist')
90 92 assert isinstance(result.error_in_exec, UsageError)
91 93
92 94
93 95 def test_cell_magic_not_found():
94 96 # magic not found raises UsageError
95 97 with pytest.raises(UsageError):
96 98 _ip.run_cell_magic('doesntexist', 'line', 'cell')
97 99
98 100 # ensure result isn't success when a magic isn't found
99 101 result = _ip.run_cell('%%doesntexist')
100 102 assert isinstance(result.error_in_exec, UsageError)
101 103
102 104
103 105 def test_magic_error_status():
104 106 def fail(shell):
105 107 1/0
106 108 _ip.register_magic_function(fail)
107 109 result = _ip.run_cell('%fail')
108 110 assert isinstance(result.error_in_exec, ZeroDivisionError)
109 111
110 112
111 113 def test_config():
112 114 """ test that config magic does not raise
113 115 can happen if Configurable init is moved too early into
114 116 Magics.__init__ as then a Config object will be registered as a
115 117 magic.
116 118 """
117 119 ## should not raise.
118 120 _ip.magic('config')
119 121
120 122 def test_config_available_configs():
121 123 """ test that config magic prints available configs in unique and
122 124 sorted order. """
123 125 with capture_output() as captured:
124 126 _ip.magic('config')
125 127
126 128 stdout = captured.stdout
127 129 config_classes = stdout.strip().split('\n')[1:]
128 130 assert config_classes == sorted(set(config_classes))
129 131
130 132 def test_config_print_class():
131 133 """ test that config with a classname prints the class's options. """
132 134 with capture_output() as captured:
133 135 _ip.magic('config TerminalInteractiveShell')
134 136
135 137 stdout = captured.stdout
136 138 assert re.match(
137 139 "TerminalInteractiveShell.* options", stdout.splitlines()[0]
138 140 ), f"{stdout}\n\n1st line of stdout not like 'TerminalInteractiveShell.* options'"
139 141
140 142
141 143 def test_rehashx():
142 144 # clear up everything
143 145 _ip.alias_manager.clear_aliases()
144 146 del _ip.db['syscmdlist']
145 147
146 148 _ip.magic('rehashx')
147 149 # Practically ALL ipython development systems will have more than 10 aliases
148 150
149 151 assert len(_ip.alias_manager.aliases) > 10
150 152 for name, cmd in _ip.alias_manager.aliases:
151 153 # we must strip dots from alias names
152 154 assert "." not in name
153 155
154 156 # rehashx must fill up syscmdlist
155 157 scoms = _ip.db['syscmdlist']
156 158 assert len(scoms) > 10
157 159
158 160
159 161 def test_magic_parse_options():
160 162 """Test that we don't mangle paths when parsing magic options."""
161 163 ip = get_ipython()
162 164 path = 'c:\\x'
163 165 m = DummyMagics(ip)
164 166 opts = m.parse_options('-f %s' % path,'f:')[0]
165 167 # argv splitting is os-dependent
166 168 if os.name == 'posix':
167 169 expected = 'c:x'
168 170 else:
169 171 expected = path
170 172 assert opts["f"] == expected
171 173
172 174
173 175 def test_magic_parse_long_options():
174 176 """Magic.parse_options can handle --foo=bar long options"""
175 177 ip = get_ipython()
176 178 m = DummyMagics(ip)
177 179 opts, _ = m.parse_options("--foo --bar=bubble", "a", "foo", "bar=")
178 180 assert "foo" in opts
179 181 assert "bar" in opts
180 182 assert opts["bar"] == "bubble"
181 183
182 184
183 185 def doctest_hist_f():
184 186 """Test %hist -f with temporary filename.
185 187
186 188 In [9]: import tempfile
187 189
188 190 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
189 191
190 192 In [11]: %hist -nl -f $tfile 3
191 193
192 194 In [13]: import os; os.unlink(tfile)
193 195 """
194 196
195 197
196 198 def doctest_hist_op():
197 199 """Test %hist -op
198 200
199 201 In [1]: class b(float):
200 202 ...: pass
201 203 ...:
202 204
203 205 In [2]: class s(object):
204 206 ...: def __str__(self):
205 207 ...: return 's'
206 208 ...:
207 209
208 210 In [3]:
209 211
210 212 In [4]: class r(b):
211 213 ...: def __repr__(self):
212 214 ...: return 'r'
213 215 ...:
214 216
215 217 In [5]: class sr(s,r): pass
216 218 ...:
217 219
218 220 In [6]:
219 221
220 222 In [7]: bb=b()
221 223
222 224 In [8]: ss=s()
223 225
224 226 In [9]: rr=r()
225 227
226 228 In [10]: ssrr=sr()
227 229
228 230 In [11]: 4.5
229 231 Out[11]: 4.5
230 232
231 233 In [12]: str(ss)
232 234 Out[12]: 's'
233 235
234 236 In [13]:
235 237
236 238 In [14]: %hist -op
237 239 >>> class b:
238 240 ... pass
239 241 ...
240 242 >>> class s(b):
241 243 ... def __str__(self):
242 244 ... return 's'
243 245 ...
244 246 >>>
245 247 >>> class r(b):
246 248 ... def __repr__(self):
247 249 ... return 'r'
248 250 ...
249 251 >>> class sr(s,r): pass
250 252 >>>
251 253 >>> bb=b()
252 254 >>> ss=s()
253 255 >>> rr=r()
254 256 >>> ssrr=sr()
255 257 >>> 4.5
256 258 4.5
257 259 >>> str(ss)
258 260 's'
259 261 >>>
260 262 """
261 263
262 264 def test_hist_pof():
263 265 ip = get_ipython()
264 266 ip.run_cell("1+2", store_history=True)
265 267 #raise Exception(ip.history_manager.session_number)
266 268 #raise Exception(list(ip.history_manager._get_range_session()))
267 269 with TemporaryDirectory() as td:
268 270 tf = os.path.join(td, 'hist.py')
269 271 ip.run_line_magic('history', '-pof %s' % tf)
270 272 assert os.path.isfile(tf)
271 273
272 274
273 275 def test_macro():
274 276 ip = get_ipython()
275 277 ip.history_manager.reset() # Clear any existing history.
276 278 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
277 279 for i, cmd in enumerate(cmds, start=1):
278 280 ip.history_manager.store_inputs(i, cmd)
279 281 ip.magic("macro test 1-3")
280 282 assert ip.user_ns["test"].value == "\n".join(cmds) + "\n"
281 283
282 284 # List macros
283 285 assert "test" in ip.magic("macro")
284 286
285 287
286 288 def test_macro_run():
287 289 """Test that we can run a multi-line macro successfully."""
288 290 ip = get_ipython()
289 291 ip.history_manager.reset()
290 292 cmds = ["a=10", "a+=1", "print(a)", "%macro test 2-3"]
291 293 for cmd in cmds:
292 294 ip.run_cell(cmd, store_history=True)
293 295 assert ip.user_ns["test"].value == "a+=1\nprint(a)\n"
294 296 with tt.AssertPrints("12"):
295 297 ip.run_cell("test")
296 298 with tt.AssertPrints("13"):
297 299 ip.run_cell("test")
298 300
299 301
300 302 def test_magic_magic():
301 303 """Test %magic"""
302 304 ip = get_ipython()
303 305 with capture_output() as captured:
304 306 ip.magic("magic")
305 307
306 308 stdout = captured.stdout
307 309 assert "%magic" in stdout
308 310 assert "IPython" in stdout
309 311 assert "Available" in stdout
310 312
311 313
312 314 @dec.skipif_not_numpy
313 315 def test_numpy_reset_array_undec():
314 316 "Test '%reset array' functionality"
315 317 _ip.ex("import numpy as np")
316 318 _ip.ex("a = np.empty(2)")
317 319 assert "a" in _ip.user_ns
318 320 _ip.magic("reset -f array")
319 321 assert "a" not in _ip.user_ns
320 322
321 323
322 324 def test_reset_out():
323 325 "Test '%reset out' magic"
324 326 _ip.run_cell("parrot = 'dead'", store_history=True)
325 327 # test '%reset -f out', make an Out prompt
326 328 _ip.run_cell("parrot", store_history=True)
327 329 assert "dead" in [_ip.user_ns[x] for x in ("_", "__", "___")]
328 330 _ip.magic("reset -f out")
329 331 assert "dead" not in [_ip.user_ns[x] for x in ("_", "__", "___")]
330 332 assert len(_ip.user_ns["Out"]) == 0
331 333
332 334
333 335 def test_reset_in():
334 336 "Test '%reset in' magic"
335 337 # test '%reset -f in'
336 338 _ip.run_cell("parrot", store_history=True)
337 339 assert "parrot" in [_ip.user_ns[x] for x in ("_i", "_ii", "_iii")]
338 340 _ip.magic("%reset -f in")
339 341 assert "parrot" not in [_ip.user_ns[x] for x in ("_i", "_ii", "_iii")]
340 342 assert len(set(_ip.user_ns["In"])) == 1
341 343
342 344
343 345 def test_reset_dhist():
344 346 "Test '%reset dhist' magic"
345 347 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
346 348 _ip.magic("cd " + os.path.dirname(pytest.__file__))
347 349 _ip.magic("cd -")
348 350 assert len(_ip.user_ns["_dh"]) > 0
349 351 _ip.magic("reset -f dhist")
350 352 assert len(_ip.user_ns["_dh"]) == 0
351 353 _ip.run_cell("_dh = [d for d in tmp]") # restore
352 354
353 355
354 356 def test_reset_in_length():
355 357 "Test that '%reset in' preserves In[] length"
356 358 _ip.run_cell("print 'foo'")
357 359 _ip.run_cell("reset -f in")
358 360 assert len(_ip.user_ns["In"]) == _ip.displayhook.prompt_count + 1
359 361
360 362
361 363 class TestResetErrors(TestCase):
362 364
363 365 def test_reset_redefine(self):
364 366
365 367 @magics_class
366 368 class KernelMagics(Magics):
367 369 @line_magic
368 370 def less(self, shell): pass
369 371
370 372 _ip.register_magics(KernelMagics)
371 373
372 374 with self.assertLogs() as cm:
373 375 # hack, we want to just capture logs, but assertLogs fails if not
374 376 # logs get produce.
375 377 # so log one things we ignore.
376 378 import logging as log_mod
377 379 log = log_mod.getLogger()
378 380 log.info('Nothing')
379 381 # end hack.
380 382 _ip.run_cell("reset -f")
381 383
382 384 assert len(cm.output) == 1
383 385 for out in cm.output:
384 386 assert "Invalid alias" not in out
385 387
386 388 def test_tb_syntaxerror():
387 389 """test %tb after a SyntaxError"""
388 390 ip = get_ipython()
389 391 ip.run_cell("for")
390 392
391 393 # trap and validate stdout
392 394 save_stdout = sys.stdout
393 395 try:
394 396 sys.stdout = StringIO()
395 397 ip.run_cell("%tb")
396 398 out = sys.stdout.getvalue()
397 399 finally:
398 400 sys.stdout = save_stdout
399 401 # trim output, and only check the last line
400 402 last_line = out.rstrip().splitlines()[-1].strip()
401 403 assert last_line == "SyntaxError: invalid syntax"
402 404
403 405
404 406 def test_time():
405 407 ip = get_ipython()
406 408
407 409 with tt.AssertPrints("Wall time: "):
408 410 ip.run_cell("%time None")
409 411
410 412 ip.run_cell("def f(kmjy):\n"
411 413 " %time print (2*kmjy)")
412 414
413 415 with tt.AssertPrints("Wall time: "):
414 416 with tt.AssertPrints("hihi", suppress=False):
415 417 ip.run_cell("f('hi')")
416 418
417 419 def test_time_last_not_expression():
418 420 ip.run_cell("%%time\n"
419 421 "var_1 = 1\n"
420 422 "var_2 = 2\n")
421 423 assert ip.user_ns['var_1'] == 1
422 424 del ip.user_ns['var_1']
423 425 assert ip.user_ns['var_2'] == 2
424 426 del ip.user_ns['var_2']
425 427
426 428
427 429 @dec.skip_win32
428 430 def test_time2():
429 431 ip = get_ipython()
430 432
431 433 with tt.AssertPrints("CPU times: user "):
432 434 ip.run_cell("%time None")
433 435
434 436 def test_time3():
435 437 """Erroneous magic function calls, issue gh-3334"""
436 438 ip = get_ipython()
437 439 ip.user_ns.pop('run', None)
438 440
439 441 with tt.AssertNotPrints("not found", channel='stderr'):
440 442 ip.run_cell("%%time\n"
441 443 "run = 0\n"
442 444 "run += 1")
443 445
444 446 def test_multiline_time():
445 447 """Make sure last statement from time return a value."""
446 448 ip = get_ipython()
447 449 ip.user_ns.pop('run', None)
448 450
449 451 ip.run_cell(dedent("""\
450 452 %%time
451 453 a = "ho"
452 454 b = "hey"
453 455 a+b
454 456 """
455 457 )
456 458 )
457 459 assert ip.user_ns_hidden["_"] == "hohey"
458 460
459 461
460 462 def test_time_local_ns():
461 463 """
462 464 Test that local_ns is actually global_ns when running a cell magic
463 465 """
464 466 ip = get_ipython()
465 467 ip.run_cell("%%time\n" "myvar = 1")
466 468 assert ip.user_ns["myvar"] == 1
467 469 del ip.user_ns["myvar"]
468 470
469 471
470 472 def test_doctest_mode():
471 473 "Toggle doctest_mode twice, it should be a no-op and run without error"
472 474 _ip.magic('doctest_mode')
473 475 _ip.magic('doctest_mode')
474 476
475 477
476 478 def test_parse_options():
477 479 """Tests for basic options parsing in magics."""
478 480 # These are only the most minimal of tests, more should be added later. At
479 481 # the very least we check that basic text/unicode calls work OK.
480 482 m = DummyMagics(_ip)
481 483 assert m.parse_options("foo", "")[1] == "foo"
482 484 assert m.parse_options("foo", "")[1] == "foo"
483 485
484 486
485 487 def test_parse_options_preserve_non_option_string():
486 488 """Test to assert preservation of non-option part of magic-block, while parsing magic options."""
487 489 m = DummyMagics(_ip)
488 490 opts, stmt = m.parse_options(
489 491 " -n1 -r 13 _ = 314 + foo", "n:r:", preserve_non_opts=True
490 492 )
491 493 assert opts == {"n": "1", "r": "13"}
492 494 assert stmt == "_ = 314 + foo"
493 495
494 496
495 497 def test_run_magic_preserve_code_block():
496 498 """Test to assert preservation of non-option part of magic-block, while running magic."""
497 499 _ip.user_ns["spaces"] = []
498 500 _ip.magic("timeit -n1 -r1 spaces.append([s.count(' ') for s in ['document']])")
499 501 assert _ip.user_ns["spaces"] == [[0]]
500 502
501 503
502 504 def test_dirops():
503 505 """Test various directory handling operations."""
504 506 # curpath = lambda :os.path.splitdrive(os.getcwd())[1].replace('\\','/')
505 507 curpath = os.getcwd
506 508 startdir = os.getcwd()
507 509 ipdir = os.path.realpath(_ip.ipython_dir)
508 510 try:
509 511 _ip.magic('cd "%s"' % ipdir)
510 512 assert curpath() == ipdir
511 513 _ip.magic('cd -')
512 514 assert curpath() == startdir
513 515 _ip.magic('pushd "%s"' % ipdir)
514 516 assert curpath() == ipdir
515 517 _ip.magic('popd')
516 518 assert curpath() == startdir
517 519 finally:
518 520 os.chdir(startdir)
519 521
520 522
521 523 def test_cd_force_quiet():
522 524 """Test OSMagics.cd_force_quiet option"""
523 525 _ip.config.OSMagics.cd_force_quiet = True
524 526 osmagics = osm.OSMagics(shell=_ip)
525 527
526 528 startdir = os.getcwd()
527 529 ipdir = os.path.realpath(_ip.ipython_dir)
528 530
529 531 try:
530 532 with tt.AssertNotPrints(ipdir):
531 533 osmagics.cd('"%s"' % ipdir)
532 534 with tt.AssertNotPrints(startdir):
533 535 osmagics.cd('-')
534 536 finally:
535 537 os.chdir(startdir)
536 538
537 539
538 540 def test_xmode():
539 541 # Calling xmode three times should be a no-op
540 542 xmode = _ip.InteractiveTB.mode
541 543 for i in range(4):
542 544 _ip.magic("xmode")
543 545 assert _ip.InteractiveTB.mode == xmode
544 546
545 547 def test_reset_hard():
546 548 monitor = []
547 549 class A(object):
548 550 def __del__(self):
549 551 monitor.append(1)
550 552 def __repr__(self):
551 553 return "<A instance>"
552 554
553 555 _ip.user_ns["a"] = A()
554 556 _ip.run_cell("a")
555 557
556 558 assert monitor == []
557 559 _ip.magic("reset -f")
558 560 assert monitor == [1]
559 561
560 562 class TestXdel(tt.TempFileMixin):
561 563 def test_xdel(self):
562 564 """Test that references from %run are cleared by xdel."""
563 565 src = ("class A(object):\n"
564 566 " monitor = []\n"
565 567 " def __del__(self):\n"
566 568 " self.monitor.append(1)\n"
567 569 "a = A()\n")
568 570 self.mktmp(src)
569 571 # %run creates some hidden references...
570 572 _ip.magic("run %s" % self.fname)
571 573 # ... as does the displayhook.
572 574 _ip.run_cell("a")
573 575
574 576 monitor = _ip.user_ns["A"].monitor
575 577 assert monitor == []
576 578
577 579 _ip.magic("xdel a")
578 580
579 581 # Check that a's __del__ method has been called.
580 582 gc.collect(0)
581 583 assert monitor == [1]
582 584
583 585 def doctest_who():
584 586 """doctest for %who
585 587
586 588 In [1]: %reset -sf
587 589
588 590 In [2]: alpha = 123
589 591
590 592 In [3]: beta = 'beta'
591 593
592 594 In [4]: %who int
593 595 alpha
594 596
595 597 In [5]: %who str
596 598 beta
597 599
598 600 In [6]: %whos
599 601 Variable Type Data/Info
600 602 ----------------------------
601 603 alpha int 123
602 604 beta str beta
603 605
604 606 In [7]: %who_ls
605 607 Out[7]: ['alpha', 'beta']
606 608 """
607 609
608 610 def test_whos():
609 611 """Check that whos is protected against objects where repr() fails."""
610 612 class A(object):
611 613 def __repr__(self):
612 614 raise Exception()
613 615 _ip.user_ns['a'] = A()
614 616 _ip.magic("whos")
615 617
616 618 def doctest_precision():
617 619 """doctest for %precision
618 620
619 621 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
620 622
621 623 In [2]: %precision 5
622 624 Out[2]: '%.5f'
623 625
624 626 In [3]: f.float_format
625 627 Out[3]: '%.5f'
626 628
627 629 In [4]: %precision %e
628 630 Out[4]: '%e'
629 631
630 632 In [5]: f(3.1415927)
631 633 Out[5]: '3.141593e+00'
632 634 """
633 635
634 636 def test_debug_magic():
635 637 """Test debugging a small code with %debug
636 638
637 639 In [1]: with PdbTestInput(['c']):
638 640 ...: %debug print("a b") #doctest: +ELLIPSIS
639 641 ...:
640 642 ...
641 643 ipdb> c
642 644 a b
643 645 In [2]:
644 646 """
645 647
646 648 def test_psearch():
647 649 with tt.AssertPrints("dict.fromkeys"):
648 650 _ip.run_cell("dict.fr*?")
649 651 with tt.AssertPrints("Ο€.is_integer"):
650 652 _ip.run_cell("Ο€ = 3.14;\nΟ€.is_integ*?")
651 653
652 654 def test_timeit_shlex():
653 655 """test shlex issues with timeit (#1109)"""
654 656 _ip.ex("def f(*a,**kw): pass")
655 657 _ip.magic('timeit -n1 "this is a bug".count(" ")')
656 658 _ip.magic('timeit -r1 -n1 f(" ", 1)')
657 659 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
658 660 _ip.magic('timeit -r1 -n1 ("a " + "b")')
659 661 _ip.magic('timeit -r1 -n1 f("a " + "b")')
660 662 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
661 663
662 664
663 665 def test_timeit_special_syntax():
664 666 "Test %%timeit with IPython special syntax"
665 667 @register_line_magic
666 668 def lmagic(line):
667 669 ip = get_ipython()
668 670 ip.user_ns['lmagic_out'] = line
669 671
670 672 # line mode test
671 673 _ip.run_line_magic("timeit", "-n1 -r1 %lmagic my line")
672 674 assert _ip.user_ns["lmagic_out"] == "my line"
673 675 # cell mode test
674 676 _ip.run_cell_magic("timeit", "-n1 -r1", "%lmagic my line2")
675 677 assert _ip.user_ns["lmagic_out"] == "my line2"
676 678
677 679
678 680 def test_timeit_return():
679 681 """
680 682 test whether timeit -o return object
681 683 """
682 684
683 685 res = _ip.run_line_magic('timeit','-n10 -r10 -o 1')
684 686 assert(res is not None)
685 687
686 688 def test_timeit_quiet():
687 689 """
688 690 test quiet option of timeit magic
689 691 """
690 692 with tt.AssertNotPrints("loops"):
691 693 _ip.run_cell("%timeit -n1 -r1 -q 1")
692 694
693 695 def test_timeit_return_quiet():
694 696 with tt.AssertNotPrints("loops"):
695 697 res = _ip.run_line_magic('timeit', '-n1 -r1 -q -o 1')
696 698 assert (res is not None)
697 699
698 700 def test_timeit_invalid_return():
699 701 with pytest.raises(SyntaxError):
700 702 _ip.run_line_magic('timeit', 'return')
701 703
702 704 @dec.skipif(execution.profile is None)
703 705 def test_prun_special_syntax():
704 706 "Test %%prun with IPython special syntax"
705 707 @register_line_magic
706 708 def lmagic(line):
707 709 ip = get_ipython()
708 710 ip.user_ns['lmagic_out'] = line
709 711
710 712 # line mode test
711 713 _ip.run_line_magic("prun", "-q %lmagic my line")
712 714 assert _ip.user_ns["lmagic_out"] == "my line"
713 715 # cell mode test
714 716 _ip.run_cell_magic("prun", "-q", "%lmagic my line2")
715 717 assert _ip.user_ns["lmagic_out"] == "my line2"
716 718
717 719
718 720 @dec.skipif(execution.profile is None)
719 721 def test_prun_quotes():
720 722 "Test that prun does not clobber string escapes (GH #1302)"
721 723 _ip.magic(r"prun -q x = '\t'")
722 724 assert _ip.user_ns["x"] == "\t"
723 725
724 726
725 727 def test_extension():
726 728 # Debugging information for failures of this test
727 729 print('sys.path:')
728 730 for p in sys.path:
729 731 print(' ', p)
730 732 print('CWD', os.getcwd())
731 733
732 734 pytest.raises(ImportError, _ip.magic, "load_ext daft_extension")
733 735 daft_path = os.path.join(os.path.dirname(__file__), "daft_extension")
734 736 sys.path.insert(0, daft_path)
735 737 try:
736 738 _ip.user_ns.pop('arq', None)
737 739 invalidate_caches() # Clear import caches
738 740 _ip.magic("load_ext daft_extension")
739 741 assert _ip.user_ns["arq"] == 185
740 742 _ip.magic("unload_ext daft_extension")
741 743 assert 'arq' not in _ip.user_ns
742 744 finally:
743 745 sys.path.remove(daft_path)
744 746
745 747
746 748 def test_notebook_export_json():
747 749 pytest.importorskip("nbformat")
748 750 _ip = get_ipython()
749 751 _ip.history_manager.reset() # Clear any existing history.
750 752 cmds = ["a=1", "def b():\n return a**2", "print('noΓ«l, Γ©tΓ©', b())"]
751 753 for i, cmd in enumerate(cmds, start=1):
752 754 _ip.history_manager.store_inputs(i, cmd)
753 755 with TemporaryDirectory() as td:
754 756 outfile = os.path.join(td, "nb.ipynb")
755 757 _ip.magic("notebook %s" % outfile)
756 758
757 759
758 760 class TestEnv(TestCase):
759 761
760 762 def test_env(self):
761 763 env = _ip.magic("env")
762 764 self.assertTrue(isinstance(env, dict))
763 765
764 766 def test_env_secret(self):
765 767 env = _ip.magic("env")
766 768 hidden = "<hidden>"
767 769 with mock.patch.dict(
768 770 os.environ,
769 771 {
770 772 "API_KEY": "abc123",
771 773 "SECRET_THING": "ssshhh",
772 774 "JUPYTER_TOKEN": "",
773 775 "VAR": "abc"
774 776 }
775 777 ):
776 778 env = _ip.magic("env")
777 779 assert env["API_KEY"] == hidden
778 780 assert env["SECRET_THING"] == hidden
779 781 assert env["JUPYTER_TOKEN"] == hidden
780 782 assert env["VAR"] == "abc"
781 783
782 784 def test_env_get_set_simple(self):
783 785 env = _ip.magic("env var val1")
784 786 self.assertEqual(env, None)
785 787 self.assertEqual(os.environ['var'], 'val1')
786 788 self.assertEqual(_ip.magic("env var"), 'val1')
787 789 env = _ip.magic("env var=val2")
788 790 self.assertEqual(env, None)
789 791 self.assertEqual(os.environ['var'], 'val2')
790 792
791 793 def test_env_get_set_complex(self):
792 794 env = _ip.magic("env var 'val1 '' 'val2")
793 795 self.assertEqual(env, None)
794 796 self.assertEqual(os.environ['var'], "'val1 '' 'val2")
795 797 self.assertEqual(_ip.magic("env var"), "'val1 '' 'val2")
796 798 env = _ip.magic('env var=val2 val3="val4')
797 799 self.assertEqual(env, None)
798 800 self.assertEqual(os.environ['var'], 'val2 val3="val4')
799 801
800 802 def test_env_set_bad_input(self):
801 803 self.assertRaises(UsageError, lambda: _ip.magic("set_env var"))
802 804
803 805 def test_env_set_whitespace(self):
804 806 self.assertRaises(UsageError, lambda: _ip.magic("env var A=B"))
805 807
806 808
807 809 class CellMagicTestCase(TestCase):
808 810
809 811 def check_ident(self, magic):
810 812 # Manually called, we get the result
811 813 out = _ip.run_cell_magic(magic, "a", "b")
812 814 assert out == ("a", "b")
813 815 # Via run_cell, it goes into the user's namespace via displayhook
814 816 _ip.run_cell("%%" + magic + " c\nd\n")
815 817 assert _ip.user_ns["_"] == ("c", "d\n")
816 818
817 819 def test_cell_magic_func_deco(self):
818 820 "Cell magic using simple decorator"
819 821 @register_cell_magic
820 822 def cellm(line, cell):
821 823 return line, cell
822 824
823 825 self.check_ident('cellm')
824 826
825 827 def test_cell_magic_reg(self):
826 828 "Cell magic manually registered"
827 829 def cellm(line, cell):
828 830 return line, cell
829 831
830 832 _ip.register_magic_function(cellm, 'cell', 'cellm2')
831 833 self.check_ident('cellm2')
832 834
833 835 def test_cell_magic_class(self):
834 836 "Cell magics declared via a class"
835 837 @magics_class
836 838 class MyMagics(Magics):
837 839
838 840 @cell_magic
839 841 def cellm3(self, line, cell):
840 842 return line, cell
841 843
842 844 _ip.register_magics(MyMagics)
843 845 self.check_ident('cellm3')
844 846
845 847 def test_cell_magic_class2(self):
846 848 "Cell magics declared via a class, #2"
847 849 @magics_class
848 850 class MyMagics2(Magics):
849 851
850 852 @cell_magic('cellm4')
851 853 def cellm33(self, line, cell):
852 854 return line, cell
853 855
854 856 _ip.register_magics(MyMagics2)
855 857 self.check_ident('cellm4')
856 858 # Check that nothing is registered as 'cellm33'
857 859 c33 = _ip.find_cell_magic('cellm33')
858 860 assert c33 == None
859 861
860 862 def test_file():
861 863 """Basic %%writefile"""
862 864 ip = get_ipython()
863 865 with TemporaryDirectory() as td:
864 866 fname = os.path.join(td, 'file1')
865 867 ip.run_cell_magic("writefile", fname, u'\n'.join([
866 868 'line1',
867 869 'line2',
868 870 ]))
869 871 s = Path(fname).read_text()
870 872 assert "line1\n" in s
871 873 assert "line2" in s
872 874
873 875
874 876 @dec.skip_win32
875 877 def test_file_single_quote():
876 878 """Basic %%writefile with embedded single quotes"""
877 879 ip = get_ipython()
878 880 with TemporaryDirectory() as td:
879 881 fname = os.path.join(td, '\'file1\'')
880 882 ip.run_cell_magic("writefile", fname, u'\n'.join([
881 883 'line1',
882 884 'line2',
883 885 ]))
884 886 s = Path(fname).read_text()
885 887 assert "line1\n" in s
886 888 assert "line2" in s
887 889
888 890
889 891 @dec.skip_win32
890 892 def test_file_double_quote():
891 893 """Basic %%writefile with embedded double quotes"""
892 894 ip = get_ipython()
893 895 with TemporaryDirectory() as td:
894 896 fname = os.path.join(td, '"file1"')
895 897 ip.run_cell_magic("writefile", fname, u'\n'.join([
896 898 'line1',
897 899 'line2',
898 900 ]))
899 901 s = Path(fname).read_text()
900 902 assert "line1\n" in s
901 903 assert "line2" in s
902 904
903 905
904 906 def test_file_var_expand():
905 907 """%%writefile $filename"""
906 908 ip = get_ipython()
907 909 with TemporaryDirectory() as td:
908 910 fname = os.path.join(td, 'file1')
909 911 ip.user_ns['filename'] = fname
910 912 ip.run_cell_magic("writefile", '$filename', u'\n'.join([
911 913 'line1',
912 914 'line2',
913 915 ]))
914 916 s = Path(fname).read_text()
915 917 assert "line1\n" in s
916 918 assert "line2" in s
917 919
918 920
919 921 def test_file_unicode():
920 922 """%%writefile with unicode cell"""
921 923 ip = get_ipython()
922 924 with TemporaryDirectory() as td:
923 925 fname = os.path.join(td, 'file1')
924 926 ip.run_cell_magic("writefile", fname, u'\n'.join([
925 927 u'linΓ©1',
926 928 u'linΓ©2',
927 929 ]))
928 930 with io.open(fname, encoding='utf-8') as f:
929 931 s = f.read()
930 932 assert "linΓ©1\n" in s
931 933 assert "linΓ©2" in s
932 934
933 935
934 936 def test_file_amend():
935 937 """%%writefile -a amends files"""
936 938 ip = get_ipython()
937 939 with TemporaryDirectory() as td:
938 940 fname = os.path.join(td, 'file2')
939 941 ip.run_cell_magic("writefile", fname, u'\n'.join([
940 942 'line1',
941 943 'line2',
942 944 ]))
943 945 ip.run_cell_magic("writefile", "-a %s" % fname, u'\n'.join([
944 946 'line3',
945 947 'line4',
946 948 ]))
947 949 s = Path(fname).read_text()
948 950 assert "line1\n" in s
949 951 assert "line3\n" in s
950 952
951 953
952 954 def test_file_spaces():
953 955 """%%file with spaces in filename"""
954 956 ip = get_ipython()
955 957 with TemporaryWorkingDirectory() as td:
956 958 fname = "file name"
957 959 ip.run_cell_magic("file", '"%s"'%fname, u'\n'.join([
958 960 'line1',
959 961 'line2',
960 962 ]))
961 963 s = Path(fname).read_text()
962 964 assert "line1\n" in s
963 965 assert "line2" in s
964 966
965 967
966 968 def test_script_config():
967 969 ip = get_ipython()
968 970 ip.config.ScriptMagics.script_magics = ['whoda']
969 971 sm = script.ScriptMagics(shell=ip)
970 972 assert "whoda" in sm.magics["cell"]
971 973
972 974
973 975 def test_script_out():
974 976 ip = get_ipython()
975 977 ip.run_cell_magic("script", f"--out output {sys.executable}", "print('hi')")
976 978 assert ip.user_ns["output"].strip() == "hi"
977 979
978 980
979 981 def test_script_err():
980 982 ip = get_ipython()
981 983 ip.run_cell_magic(
982 984 "script",
983 985 f"--err error {sys.executable}",
984 986 "import sys; print('hello', file=sys.stderr)",
985 987 )
986 988 assert ip.user_ns["error"].strip() == "hello"
987 989
988 990
989 991 def test_script_out_err():
990 992
991 993 ip = get_ipython()
992 994 ip.run_cell_magic(
993 995 "script",
994 996 f"--out output --err error {sys.executable}",
995 997 "\n".join(
996 998 [
997 999 "import sys",
998 1000 "print('hi')",
999 1001 "print('hello', file=sys.stderr)",
1000 1002 ]
1001 1003 ),
1002 1004 )
1003 1005 assert ip.user_ns["output"].strip() == "hi"
1004 1006 assert ip.user_ns["error"].strip() == "hello"
1005 1007
1006 1008
1007 1009 async def test_script_bg_out():
1008 1010 ip = get_ipython()
1009 1011 ip.run_cell_magic("script", f"--bg --out output {sys.executable}", "print('hi')")
1010 1012 assert (await ip.user_ns["output"].read()).strip() == b"hi"
1011 1013 assert ip.user_ns["output"].at_eof()
1012 1014
1013 1015
1014 1016 async def test_script_bg_err():
1015 1017 ip = get_ipython()
1016 1018 ip.run_cell_magic(
1017 1019 "script",
1018 1020 f"--bg --err error {sys.executable}",
1019 1021 "import sys; print('hello', file=sys.stderr)",
1020 1022 )
1021 1023 assert (await ip.user_ns["error"].read()).strip() == b"hello"
1022 1024 assert ip.user_ns["error"].at_eof()
1023 1025
1024 1026
1025 1027 async def test_script_bg_out_err():
1026 1028 ip = get_ipython()
1027 1029 ip.run_cell_magic(
1028 1030 "script",
1029 1031 f"--bg --out output --err error {sys.executable}",
1030 1032 "\n".join(
1031 1033 [
1032 1034 "import sys",
1033 1035 "print('hi')",
1034 1036 "print('hello', file=sys.stderr)",
1035 1037 ]
1036 1038 ),
1037 1039 )
1038 1040 assert (await ip.user_ns["output"].read()).strip() == b"hi"
1039 1041 assert (await ip.user_ns["error"].read()).strip() == b"hello"
1040 1042 assert ip.user_ns["output"].at_eof()
1041 1043 assert ip.user_ns["error"].at_eof()
1042 1044
1043 1045
1044 1046 async def test_script_bg_proc():
1045 1047 ip = get_ipython()
1046 1048 ip.run_cell_magic(
1047 1049 "script",
1048 1050 f"--bg --out output --proc p {sys.executable}",
1049 1051 "\n".join(
1050 1052 [
1051 1053 "import sys",
1052 1054 "print('hi')",
1053 1055 "print('hello', file=sys.stderr)",
1054 1056 ]
1055 1057 ),
1056 1058 )
1057 1059 p = ip.user_ns["p"]
1058 1060 await p.wait()
1059 1061 assert p.returncode == 0
1060 1062 assert (await p.stdout.read()).strip() == b"hi"
1061 1063 # not captured, so empty
1062 1064 assert (await p.stderr.read()) == b""
1063 1065 assert p.stdout.at_eof()
1064 1066 assert p.stderr.at_eof()
1065 1067
1066 1068
1067 1069 def test_script_defaults():
1068 1070 ip = get_ipython()
1069 1071 for cmd in ['sh', 'bash', 'perl', 'ruby']:
1070 1072 try:
1071 1073 find_cmd(cmd)
1072 1074 except Exception:
1073 1075 pass
1074 1076 else:
1075 1077 assert cmd in ip.magics_manager.magics["cell"]
1076 1078
1077 1079
1078 1080 @magics_class
1079 1081 class FooFoo(Magics):
1080 1082 """class with both %foo and %%foo magics"""
1081 1083 @line_magic('foo')
1082 1084 def line_foo(self, line):
1083 1085 "I am line foo"
1084 1086 pass
1085 1087
1086 1088 @cell_magic("foo")
1087 1089 def cell_foo(self, line, cell):
1088 1090 "I am cell foo, not line foo"
1089 1091 pass
1090 1092
1091 1093 def test_line_cell_info():
1092 1094 """%%foo and %foo magics are distinguishable to inspect"""
1093 1095 ip = get_ipython()
1094 1096 ip.magics_manager.register(FooFoo)
1095 1097 oinfo = ip.object_inspect("foo")
1096 1098 assert oinfo["found"] is True
1097 1099 assert oinfo["ismagic"] is True
1098 1100
1099 1101 oinfo = ip.object_inspect("%%foo")
1100 1102 assert oinfo["found"] is True
1101 1103 assert oinfo["ismagic"] is True
1102 1104 assert oinfo["docstring"] == FooFoo.cell_foo.__doc__
1103 1105
1104 1106 oinfo = ip.object_inspect("%foo")
1105 1107 assert oinfo["found"] is True
1106 1108 assert oinfo["ismagic"] is True
1107 1109 assert oinfo["docstring"] == FooFoo.line_foo.__doc__
1108 1110
1109 1111
1110 1112 def test_multiple_magics():
1111 1113 ip = get_ipython()
1112 1114 foo1 = FooFoo(ip)
1113 1115 foo2 = FooFoo(ip)
1114 1116 mm = ip.magics_manager
1115 1117 mm.register(foo1)
1116 1118 assert mm.magics["line"]["foo"].__self__ is foo1
1117 1119 mm.register(foo2)
1118 1120 assert mm.magics["line"]["foo"].__self__ is foo2
1119 1121
1120 1122
1121 1123 def test_alias_magic():
1122 1124 """Test %alias_magic."""
1123 1125 ip = get_ipython()
1124 1126 mm = ip.magics_manager
1125 1127
1126 1128 # Basic operation: both cell and line magics are created, if possible.
1127 1129 ip.run_line_magic("alias_magic", "timeit_alias timeit")
1128 1130 assert "timeit_alias" in mm.magics["line"]
1129 1131 assert "timeit_alias" in mm.magics["cell"]
1130 1132
1131 1133 # --cell is specified, line magic not created.
1132 1134 ip.run_line_magic("alias_magic", "--cell timeit_cell_alias timeit")
1133 1135 assert "timeit_cell_alias" not in mm.magics["line"]
1134 1136 assert "timeit_cell_alias" in mm.magics["cell"]
1135 1137
1136 1138 # Test that line alias is created successfully.
1137 1139 ip.run_line_magic("alias_magic", "--line env_alias env")
1138 1140 assert ip.run_line_magic("env", "") == ip.run_line_magic("env_alias", "")
1139 1141
1140 1142 # Test that line alias with parameters passed in is created successfully.
1141 1143 ip.run_line_magic(
1142 1144 "alias_magic", "--line history_alias history --params " + shlex.quote("3")
1143 1145 )
1144 1146 assert "history_alias" in mm.magics["line"]
1145 1147
1146 1148
1147 1149 def test_save():
1148 1150 """Test %save."""
1149 1151 ip = get_ipython()
1150 1152 ip.history_manager.reset() # Clear any existing history.
1151 1153 cmds = ["a=1", "def b():\n return a**2", "print(a, b())"]
1152 1154 for i, cmd in enumerate(cmds, start=1):
1153 1155 ip.history_manager.store_inputs(i, cmd)
1154 1156 with TemporaryDirectory() as tmpdir:
1155 1157 file = os.path.join(tmpdir, "testsave.py")
1156 1158 ip.run_line_magic("save", "%s 1-10" % file)
1157 1159 content = Path(file).read_text()
1158 1160 assert content.count(cmds[0]) == 1
1159 1161 assert "coding: utf-8" in content
1160 1162 ip.run_line_magic("save", "-a %s 1-10" % file)
1161 1163 content = Path(file).read_text()
1162 1164 assert content.count(cmds[0]) == 2
1163 1165 assert "coding: utf-8" in content
1164 1166
1165 1167
1166 1168 def test_save_with_no_args():
1167 1169 ip = get_ipython()
1168 1170 ip.history_manager.reset() # Clear any existing history.
1169 1171 cmds = ["a=1", "def b():\n return a**2", "print(a, b())", "%save"]
1170 1172 for i, cmd in enumerate(cmds, start=1):
1171 1173 ip.history_manager.store_inputs(i, cmd)
1172 1174
1173 1175 with TemporaryDirectory() as tmpdir:
1174 1176 path = os.path.join(tmpdir, "testsave.py")
1175 1177 ip.run_line_magic("save", path)
1176 1178 content = Path(path).read_text()
1177 1179 expected_content = dedent(
1178 1180 """\
1179 1181 # coding: utf-8
1180 1182 a=1
1181 1183 def b():
1182 1184 return a**2
1183 1185 print(a, b())
1184 1186 """
1185 1187 )
1186 1188 assert content == expected_content
1187 1189
1188 1190
1189 1191 def test_store():
1190 1192 """Test %store."""
1191 1193 ip = get_ipython()
1192 1194 ip.run_line_magic('load_ext', 'storemagic')
1193 1195
1194 1196 # make sure the storage is empty
1195 1197 ip.run_line_magic("store", "-z")
1196 1198 ip.user_ns["var"] = 42
1197 1199 ip.run_line_magic("store", "var")
1198 1200 ip.user_ns["var"] = 39
1199 1201 ip.run_line_magic("store", "-r")
1200 1202 assert ip.user_ns["var"] == 42
1201 1203
1202 1204 ip.run_line_magic("store", "-d var")
1203 1205 ip.user_ns["var"] = 39
1204 1206 ip.run_line_magic("store", "-r")
1205 1207 assert ip.user_ns["var"] == 39
1206 1208
1207 1209
1208 1210 def _run_edit_test(arg_s, exp_filename=None,
1209 1211 exp_lineno=-1,
1210 1212 exp_contents=None,
1211 1213 exp_is_temp=None):
1212 1214 ip = get_ipython()
1213 1215 M = code.CodeMagics(ip)
1214 1216 last_call = ['','']
1215 1217 opts,args = M.parse_options(arg_s,'prxn:')
1216 1218 filename, lineno, is_temp = M._find_edit_target(ip, args, opts, last_call)
1217 1219
1218 1220 if exp_filename is not None:
1219 1221 assert exp_filename == filename
1220 1222 if exp_contents is not None:
1221 1223 with io.open(filename, 'r', encoding='utf-8') as f:
1222 1224 contents = f.read()
1223 1225 assert exp_contents == contents
1224 1226 if exp_lineno != -1:
1225 1227 assert exp_lineno == lineno
1226 1228 if exp_is_temp is not None:
1227 1229 assert exp_is_temp == is_temp
1228 1230
1229 1231
1230 1232 def test_edit_interactive():
1231 1233 """%edit on interactively defined objects"""
1232 1234 ip = get_ipython()
1233 1235 n = ip.execution_count
1234 1236 ip.run_cell("def foo(): return 1", store_history=True)
1235 1237
1236 1238 with pytest.raises(code.InteractivelyDefined) as e:
1237 1239 _run_edit_test("foo")
1238 1240 assert e.value.index == n
1239 1241
1240 1242
1241 1243 def test_edit_cell():
1242 1244 """%edit [cell id]"""
1243 1245 ip = get_ipython()
1244 1246
1245 1247 ip.run_cell("def foo(): return 1", store_history=True)
1246 1248
1247 1249 # test
1248 1250 _run_edit_test("1", exp_contents=ip.user_ns['In'][1], exp_is_temp=True)
1249 1251
1250 1252 def test_edit_fname():
1251 1253 """%edit file"""
1252 1254 # test
1253 1255 _run_edit_test("test file.py", exp_filename="test file.py")
1254 1256
1255 1257 def test_bookmark():
1256 1258 ip = get_ipython()
1257 1259 ip.run_line_magic('bookmark', 'bmname')
1258 1260 with tt.AssertPrints('bmname'):
1259 1261 ip.run_line_magic('bookmark', '-l')
1260 1262 ip.run_line_magic('bookmark', '-d bmname')
1261 1263
1262 1264 def test_ls_magic():
1263 1265 ip = get_ipython()
1264 1266 json_formatter = ip.display_formatter.formatters['application/json']
1265 1267 json_formatter.enabled = True
1266 1268 lsmagic = ip.magic('lsmagic')
1267 1269 with warnings.catch_warnings(record=True) as w:
1268 1270 j = json_formatter(lsmagic)
1269 1271 assert sorted(j) == ["cell", "line"]
1270 1272 assert w == [] # no warnings
1271 1273
1272 1274
1273 1275 def test_strip_initial_indent():
1274 1276 def sii(s):
1275 1277 lines = s.splitlines()
1276 1278 return '\n'.join(code.strip_initial_indent(lines))
1277 1279
1278 1280 assert sii(" a = 1\nb = 2") == "a = 1\nb = 2"
1279 1281 assert sii(" a\n b\nc") == "a\n b\nc"
1280 1282 assert sii("a\n b") == "a\n b"
1281 1283
1282 1284 def test_logging_magic_quiet_from_arg():
1283 1285 _ip.config.LoggingMagics.quiet = False
1284 1286 lm = logging.LoggingMagics(shell=_ip)
1285 1287 with TemporaryDirectory() as td:
1286 1288 try:
1287 1289 with tt.AssertNotPrints(re.compile("Activating.*")):
1288 1290 lm.logstart('-q {}'.format(
1289 1291 os.path.join(td, "quiet_from_arg.log")))
1290 1292 finally:
1291 1293 _ip.logger.logstop()
1292 1294
1293 1295 def test_logging_magic_quiet_from_config():
1294 1296 _ip.config.LoggingMagics.quiet = True
1295 1297 lm = logging.LoggingMagics(shell=_ip)
1296 1298 with TemporaryDirectory() as td:
1297 1299 try:
1298 1300 with tt.AssertNotPrints(re.compile("Activating.*")):
1299 1301 lm.logstart(os.path.join(td, "quiet_from_config.log"))
1300 1302 finally:
1301 1303 _ip.logger.logstop()
1302 1304
1303 1305
1304 1306 def test_logging_magic_not_quiet():
1305 1307 _ip.config.LoggingMagics.quiet = False
1306 1308 lm = logging.LoggingMagics(shell=_ip)
1307 1309 with TemporaryDirectory() as td:
1308 1310 try:
1309 1311 with tt.AssertPrints(re.compile("Activating.*")):
1310 1312 lm.logstart(os.path.join(td, "not_quiet.log"))
1311 1313 finally:
1312 1314 _ip.logger.logstop()
1313 1315
1314 1316
1315 1317 def test_time_no_var_expand():
1316 1318 _ip.user_ns['a'] = 5
1317 1319 _ip.user_ns['b'] = []
1318 1320 _ip.magic('time b.append("{a}")')
1319 1321 assert _ip.user_ns['b'] == ['{a}']
1320 1322
1321 1323
1322 1324 # this is slow, put at the end for local testing.
1323 1325 def test_timeit_arguments():
1324 1326 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
1325 1327 _ip.magic("timeit -n1 -r1 a=('#')")
1326 1328
1327 1329
1330 MINIMAL_LAZY_MAGIC = """
1331 from IPython.core.magic import (
1332 Magics,
1333 magics_class,
1334 line_magic,
1335 cell_magic,
1336 )
1337
1338
1339 @magics_class
1340 class LazyMagics(Magics):
1341 @line_magic
1342 def lazy_line(self, line):
1343 print("Lazy Line")
1344
1345 @cell_magic
1346 def lazy_cell(self, line, cell):
1347 print("Lazy Cell")
1348
1349
1350 def load_ipython_extension(ipython):
1351 ipython.register_magics(LazyMagics)
1352 """
1353
1354
1355 def test_lazy_magics():
1356 with pytest.raises(UsageError):
1357 ip.run_line_magic("lazy_line", "")
1358
1359 startdir = os.getcwd()
1360
1361 with TemporaryDirectory() as tmpdir:
1362 with prepended_to_syspath(tmpdir):
1363 ptempdir = Path(tmpdir)
1364 tf = ptempdir / "lazy_magic_module.py"
1365 tf.write_text(MINIMAL_LAZY_MAGIC)
1366 ip.magics_manager.register_lazy("lazy_line", Path(tf.name).name[:-3])
1367 with tt.AssertPrints("Lazy Line"):
1368 ip.run_line_magic("lazy_line", "")
1369
1370
1328 1371 TEST_MODULE = """
1329 1372 print('Loaded my_tmp')
1330 1373 if __name__ == "__main__":
1331 1374 print('I just ran a script')
1332 1375 """
1333 1376
1334
1335 1377 def test_run_module_from_import_hook():
1336 1378 "Test that a module can be loaded via an import hook"
1337 1379 with TemporaryDirectory() as tmpdir:
1338 1380 fullpath = os.path.join(tmpdir, 'my_tmp.py')
1339 1381 Path(fullpath).write_text(TEST_MODULE)
1340 1382
1341 1383 import importlib.abc
1342 1384 import importlib.util
1343 1385
1344 1386 class MyTempImporter(importlib.abc.MetaPathFinder, importlib.abc.SourceLoader):
1345 1387 def find_spec(self, fullname, path, target=None):
1346 1388 if fullname == "my_tmp":
1347 1389 return importlib.util.spec_from_loader(fullname, self)
1348 1390
1349 1391 def get_filename(self, fullname):
1350 1392 assert fullname == "my_tmp"
1351 1393 return fullpath
1352 1394
1353 1395 def get_data(self, path):
1354 1396 assert Path(path).samefile(fullpath)
1355 1397 return Path(fullpath).read_text()
1356 1398
1357 1399 sys.meta_path.insert(0, MyTempImporter())
1358 1400
1359 1401 with capture_output() as captured:
1360 1402 _ip.magic("run -m my_tmp")
1361 1403 _ip.run_cell("import my_tmp")
1362 1404
1363 1405 output = "Loaded my_tmp\nI just ran a script\nLoaded my_tmp\n"
1364 1406 assert output == captured.stdout
1365 1407
1366 1408 sys.meta_path.pop(0)
@@ -1,187 +1,212 b''
1 1 """Tests for various magic functions specific to the terminal frontend."""
2 2
3 3 #-----------------------------------------------------------------------------
4 4 # Imports
5 5 #-----------------------------------------------------------------------------
6 6
7 7 import sys
8 8 from io import StringIO
9 9 from unittest import TestCase
10 10
11 11 from IPython.testing import tools as tt
12
13 12 #-----------------------------------------------------------------------------
14 13 # Test functions begin
15 14 #-----------------------------------------------------------------------------
16 15
16
17 MINIMAL_LAZY_MAGIC = """
18 from IPython.core.magic import (
19 Magics,
20 magics_class,
21 line_magic,
22 cell_magic,
23 )
24
25
26 @magics_class
27 class LazyMagics(Magics):
28 @line_magic
29 def lazy_line(self, line):
30 print("Lazy Line")
31
32 @cell_magic
33 def lazy_cell(self, line, cell):
34 print("Lazy Cell")
35
36
37 def load_ipython_extension(ipython):
38 ipython.register_magics(LazyMagics)
39 """
40
17 41 def check_cpaste(code, should_fail=False):
18 42 """Execute code via 'cpaste' and ensure it was executed, unless
19 43 should_fail is set.
20 44 """
21 45 ip.user_ns['code_ran'] = False
22 46
23 47 src = StringIO()
24 48 src.write(code)
25 49 src.write('\n--\n')
26 50 src.seek(0)
27 51
28 52 stdin_save = sys.stdin
29 53 sys.stdin = src
30 54
31 55 try:
32 56 context = tt.AssertPrints if should_fail else tt.AssertNotPrints
33 57 with context("Traceback (most recent call last)"):
34 ip.magic('cpaste')
58 ip.run_line_magic("cpaste", "")
35 59
36 60 if not should_fail:
37 61 assert ip.user_ns['code_ran'], "%r failed" % code
38 62 finally:
39 63 sys.stdin = stdin_save
40 64
41 65 def test_cpaste():
42 66 """Test cpaste magic"""
43 67
44 68 def runf():
45 69 """Marker function: sets a flag when executed.
46 70 """
47 71 ip.user_ns['code_ran'] = True
48 72 return 'runf' # return string so '+ runf()' doesn't result in success
49 73
50 74 tests = {'pass': ["runf()",
51 75 "In [1]: runf()",
52 76 "In [1]: if 1:\n ...: runf()",
53 77 "> > > runf()",
54 78 ">>> runf()",
55 79 " >>> runf()",
56 80 ],
57 81
58 82 'fail': ["1 + runf()",
59 83 "++ runf()",
60 84 ]}
61 85
62 86 ip.user_ns['runf'] = runf
63 87
64 88 for code in tests['pass']:
65 89 check_cpaste(code)
66 90
67 91 for code in tests['fail']:
68 92 check_cpaste(code, should_fail=True)
69 93
70 94
95
71 96 class PasteTestCase(TestCase):
72 97 """Multiple tests for clipboard pasting"""
73 98
74 99 def paste(self, txt, flags='-q'):
75 100 """Paste input text, by default in quiet mode"""
76 ip.hooks.clipboard_get = lambda : txt
77 ip.magic('paste '+flags)
101 ip.hooks.clipboard_get = lambda: txt
102 ip.run_line_magic("paste", flags)
78 103
79 104 def setUp(self):
80 105 # Inject fake clipboard hook but save original so we can restore it later
81 106 self.original_clip = ip.hooks.clipboard_get
82 107
83 108 def tearDown(self):
84 109 # Restore original hook
85 110 ip.hooks.clipboard_get = self.original_clip
86 111
87 112 def test_paste(self):
88 113 ip.user_ns.pop("x", None)
89 114 self.paste("x = 1")
90 115 self.assertEqual(ip.user_ns["x"], 1)
91 116 ip.user_ns.pop("x")
92 117
93 118 def test_paste_pyprompt(self):
94 119 ip.user_ns.pop("x", None)
95 120 self.paste(">>> x=2")
96 121 self.assertEqual(ip.user_ns["x"], 2)
97 122 ip.user_ns.pop("x")
98 123
99 124 def test_paste_py_multi(self):
100 125 self.paste("""
101 126 >>> x = [1,2,3]
102 127 >>> y = []
103 128 >>> for i in x:
104 129 ... y.append(i**2)
105 130 ...
106 131 """
107 132 )
108 133 self.assertEqual(ip.user_ns["x"], [1, 2, 3])
109 134 self.assertEqual(ip.user_ns["y"], [1, 4, 9])
110 135
111 136 def test_paste_py_multi_r(self):
112 137 "Now, test that self.paste -r works"
113 138 self.test_paste_py_multi()
114 139 self.assertEqual(ip.user_ns.pop("x"), [1, 2, 3])
115 140 self.assertEqual(ip.user_ns.pop("y"), [1, 4, 9])
116 141 self.assertFalse("x" in ip.user_ns)
117 ip.magic("paste -r")
142 ip.run_line_magic("paste", "-r")
118 143 self.assertEqual(ip.user_ns["x"], [1, 2, 3])
119 144 self.assertEqual(ip.user_ns["y"], [1, 4, 9])
120 145
121 146 def test_paste_email(self):
122 147 "Test pasting of email-quoted contents"
123 148 self.paste("""\
124 149 >> def foo(x):
125 150 >> return x + 1
126 151 >> xx = foo(1.1)"""
127 152 )
128 153 self.assertEqual(ip.user_ns["xx"], 2.1)
129 154
130 155 def test_paste_email2(self):
131 156 "Email again; some programs add a space also at each quoting level"
132 157 self.paste("""\
133 158 > > def foo(x):
134 159 > > return x + 1
135 160 > > yy = foo(2.1) """
136 161 )
137 162 self.assertEqual(ip.user_ns["yy"], 3.1)
138 163
139 164 def test_paste_email_py(self):
140 165 "Email quoting of interactive input"
141 166 self.paste("""\
142 167 >> >>> def f(x):
143 168 >> ... return x+1
144 169 >> ...
145 170 >> >>> zz = f(2.5) """
146 171 )
147 172 self.assertEqual(ip.user_ns["zz"], 3.5)
148 173
149 174 def test_paste_echo(self):
150 175 "Also test self.paste echoing, by temporarily faking the writer"
151 176 w = StringIO()
152 177 old_write = sys.stdout.write
153 178 sys.stdout.write = w.write
154 179 code = """
155 180 a = 100
156 181 b = 200"""
157 182 try:
158 183 self.paste(code,'')
159 184 out = w.getvalue()
160 185 finally:
161 186 sys.stdout.write = old_write
162 187 self.assertEqual(ip.user_ns["a"], 100)
163 188 self.assertEqual(ip.user_ns["b"], 200)
164 189 assert out == code + "\n## -- End pasted text --\n"
165 190
166 191 def test_paste_leading_commas(self):
167 192 "Test multiline strings with leading commas"
168 193 tm = ip.magics_manager.registry['TerminalMagics']
169 194 s = '''\
170 195 a = """
171 196 ,1,2,3
172 197 """'''
173 198 ip.user_ns.pop("foo", None)
174 199 tm.store_or_execute(s, "foo")
175 200 self.assertIn("foo", ip.user_ns)
176 201
177 202 def test_paste_trailing_question(self):
178 203 "Test pasting sources with trailing question marks"
179 204 tm = ip.magics_manager.registry['TerminalMagics']
180 205 s = '''\
181 206 def funcfoo():
182 207 if True: #am i true?
183 208 return 'fooresult'
184 209 '''
185 210 ip.user_ns.pop('funcfoo', None)
186 211 self.paste(s)
187 212 self.assertEqual(ip.user_ns["funcfoo"](), "fooresult")
@@ -1,340 +1,342 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 The :class:`~IPython.core.application.Application` object for the command
5 5 line :command:`ipython` program.
6 6 """
7 7
8 8 # Copyright (c) IPython Development Team.
9 9 # Distributed under the terms of the Modified BSD License.
10 10
11 11
12 12 import logging
13 13 import os
14 14 import sys
15 15 import warnings
16 16
17 17 from traitlets.config.loader import Config
18 18 from traitlets.config.application import boolean_flag, catch_config_error
19 19 from IPython.core import release
20 20 from IPython.core import usage
21 21 from IPython.core.completer import IPCompleter
22 22 from IPython.core.crashhandler import CrashHandler
23 23 from IPython.core.formatters import PlainTextFormatter
24 24 from IPython.core.history import HistoryManager
25 25 from IPython.core.application import (
26 26 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
27 27 )
28 from IPython.core.magic import MagicsManager
28 29 from IPython.core.magics import (
29 30 ScriptMagics, LoggingMagics
30 31 )
31 32 from IPython.core.shellapp import (
32 33 InteractiveShellApp, shell_flags, shell_aliases
33 34 )
34 35 from IPython.extensions.storemagic import StoreMagics
35 36 from .interactiveshell import TerminalInteractiveShell
36 37 from IPython.paths import get_ipython_dir
37 38 from traitlets import (
38 39 Bool, List, default, observe, Type
39 40 )
40 41
41 42 #-----------------------------------------------------------------------------
42 43 # Globals, utilities and helpers
43 44 #-----------------------------------------------------------------------------
44 45
45 46 _examples = """
46 47 ipython --matplotlib # enable matplotlib integration
47 48 ipython --matplotlib=qt # enable matplotlib integration with qt4 backend
48 49
49 50 ipython --log-level=DEBUG # set logging to DEBUG
50 51 ipython --profile=foo # start with profile foo
51 52
52 53 ipython profile create foo # create profile foo w/ default config files
53 54 ipython help profile # show the help for the profile subcmd
54 55
55 56 ipython locate # print the path to the IPython directory
56 57 ipython locate profile foo # print the path to the directory for profile `foo`
57 58 """
58 59
59 60 #-----------------------------------------------------------------------------
60 61 # Crash handler for this application
61 62 #-----------------------------------------------------------------------------
62 63
63 64 class IPAppCrashHandler(CrashHandler):
64 65 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
65 66
66 67 def __init__(self, app):
67 68 contact_name = release.author
68 69 contact_email = release.author_email
69 70 bug_tracker = 'https://github.com/ipython/ipython/issues'
70 71 super(IPAppCrashHandler,self).__init__(
71 72 app, contact_name, contact_email, bug_tracker
72 73 )
73 74
74 75 def make_report(self,traceback):
75 76 """Return a string containing a crash report."""
76 77
77 78 sec_sep = self.section_sep
78 79 # Start with parent report
79 80 report = [super(IPAppCrashHandler, self).make_report(traceback)]
80 81 # Add interactive-specific info we may have
81 82 rpt_add = report.append
82 83 try:
83 84 rpt_add(sec_sep+"History of session input:")
84 85 for line in self.app.shell.user_ns['_ih']:
85 86 rpt_add(line)
86 87 rpt_add('\n*** Last line of input (may not be in above history):\n')
87 88 rpt_add(self.app.shell._last_input_line+'\n')
88 89 except:
89 90 pass
90 91
91 92 return ''.join(report)
92 93
93 94 #-----------------------------------------------------------------------------
94 95 # Aliases and Flags
95 96 #-----------------------------------------------------------------------------
96 97 flags = dict(base_flags)
97 98 flags.update(shell_flags)
98 99 frontend_flags = {}
99 100 addflag = lambda *args: frontend_flags.update(boolean_flag(*args))
100 101 addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
101 102 'Turn on auto editing of files with syntax errors.',
102 103 'Turn off auto editing of files with syntax errors.'
103 104 )
104 105 addflag('simple-prompt', 'TerminalInteractiveShell.simple_prompt',
105 106 "Force simple minimal prompt using `raw_input`",
106 107 "Use a rich interactive prompt with prompt_toolkit",
107 108 )
108 109
109 110 addflag('banner', 'TerminalIPythonApp.display_banner',
110 111 "Display a banner upon starting IPython.",
111 112 "Don't display a banner upon starting IPython."
112 113 )
113 114 addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
114 115 """Set to confirm when you try to exit IPython with an EOF (Control-D
115 116 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
116 117 you can force a direct exit without any confirmation.""",
117 118 "Don't prompt the user when exiting."
118 119 )
119 120 addflag('term-title', 'TerminalInteractiveShell.term_title',
120 121 "Enable auto setting the terminal title.",
121 122 "Disable auto setting the terminal title."
122 123 )
123 124 classic_config = Config()
124 125 classic_config.InteractiveShell.cache_size = 0
125 126 classic_config.PlainTextFormatter.pprint = False
126 127 classic_config.TerminalInteractiveShell.prompts_class='IPython.terminal.prompts.ClassicPrompts'
127 128 classic_config.InteractiveShell.separate_in = ''
128 129 classic_config.InteractiveShell.separate_out = ''
129 130 classic_config.InteractiveShell.separate_out2 = ''
130 131 classic_config.InteractiveShell.colors = 'NoColor'
131 132 classic_config.InteractiveShell.xmode = 'Plain'
132 133
133 134 frontend_flags['classic']=(
134 135 classic_config,
135 136 "Gives IPython a similar feel to the classic Python prompt."
136 137 )
137 138 # # log doesn't make so much sense this way anymore
138 139 # paa('--log','-l',
139 140 # action='store_true', dest='InteractiveShell.logstart',
140 141 # help="Start logging to the default log file (./ipython_log.py).")
141 142 #
142 143 # # quick is harder to implement
143 144 frontend_flags['quick']=(
144 145 {'TerminalIPythonApp' : {'quick' : True}},
145 146 "Enable quick startup with no config files."
146 147 )
147 148
148 149 frontend_flags['i'] = (
149 150 {'TerminalIPythonApp' : {'force_interact' : True}},
150 151 """If running code from the command line, become interactive afterwards.
151 152 It is often useful to follow this with `--` to treat remaining flags as
152 153 script arguments.
153 154 """
154 155 )
155 156 flags.update(frontend_flags)
156 157
157 158 aliases = dict(base_aliases)
158 159 aliases.update(shell_aliases)
159 160
160 161 #-----------------------------------------------------------------------------
161 162 # Main classes and functions
162 163 #-----------------------------------------------------------------------------
163 164
164 165
165 166 class LocateIPythonApp(BaseIPythonApplication):
166 167 description = """print the path to the IPython dir"""
167 168 subcommands = dict(
168 169 profile=('IPython.core.profileapp.ProfileLocate',
169 170 "print the path to an IPython profile directory",
170 171 ),
171 172 )
172 173 def start(self):
173 174 if self.subapp is not None:
174 175 return self.subapp.start()
175 176 else:
176 177 print(self.ipython_dir)
177 178
178 179
179 180 class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):
180 181 name = u'ipython'
181 182 description = usage.cl_usage
182 183 crash_handler_class = IPAppCrashHandler
183 184 examples = _examples
184 185
185 186 flags = flags
186 187 aliases = aliases
187 188 classes = List()
188 189
189 190 interactive_shell_class = Type(
190 191 klass=object, # use default_value otherwise which only allow subclasses.
191 192 default_value=TerminalInteractiveShell,
192 193 help="Class to use to instantiate the TerminalInteractiveShell object. Useful for custom Frontends"
193 194 ).tag(config=True)
194 195
195 196 @default('classes')
196 197 def _classes_default(self):
197 198 """This has to be in a method, for TerminalIPythonApp to be available."""
198 199 return [
199 200 InteractiveShellApp, # ShellApp comes before TerminalApp, because
200 201 self.__class__, # it will also affect subclasses (e.g. QtConsole)
201 202 TerminalInteractiveShell,
202 203 HistoryManager,
204 MagicsManager,
203 205 ProfileDir,
204 206 PlainTextFormatter,
205 207 IPCompleter,
206 208 ScriptMagics,
207 209 LoggingMagics,
208 210 StoreMagics,
209 211 ]
210 212
211 213 subcommands = dict(
212 214 profile = ("IPython.core.profileapp.ProfileApp",
213 215 "Create and manage IPython profiles."
214 216 ),
215 217 kernel = ("ipykernel.kernelapp.IPKernelApp",
216 218 "Start a kernel without an attached frontend."
217 219 ),
218 220 locate=('IPython.terminal.ipapp.LocateIPythonApp',
219 221 LocateIPythonApp.description
220 222 ),
221 223 history=('IPython.core.historyapp.HistoryApp',
222 224 "Manage the IPython history database."
223 225 ),
224 226 )
225 227
226 228
227 229 # *do* autocreate requested profile, but don't create the config file.
228 230 auto_create=Bool(True)
229 231 # configurables
230 232 quick = Bool(False,
231 233 help="""Start IPython quickly by skipping the loading of config files."""
232 234 ).tag(config=True)
233 235 @observe('quick')
234 236 def _quick_changed(self, change):
235 237 if change['new']:
236 238 self.load_config_file = lambda *a, **kw: None
237 239
238 240 display_banner = Bool(True,
239 241 help="Whether to display a banner upon starting IPython."
240 242 ).tag(config=True)
241 243
242 244 # if there is code of files to run from the cmd line, don't interact
243 245 # unless the --i flag (App.force_interact) is true.
244 246 force_interact = Bool(False,
245 247 help="""If a command or file is given via the command-line,
246 248 e.g. 'ipython foo.py', start an interactive shell after executing the
247 249 file or command."""
248 250 ).tag(config=True)
249 251 @observe('force_interact')
250 252 def _force_interact_changed(self, change):
251 253 if change['new']:
252 254 self.interact = True
253 255
254 256 @observe('file_to_run', 'code_to_run', 'module_to_run')
255 257 def _file_to_run_changed(self, change):
256 258 new = change['new']
257 259 if new:
258 260 self.something_to_run = True
259 261 if new and not self.force_interact:
260 262 self.interact = False
261 263
262 264 # internal, not-configurable
263 265 something_to_run=Bool(False)
264 266
265 267 @catch_config_error
266 268 def initialize(self, argv=None):
267 269 """Do actions after construct, but before starting the app."""
268 270 super(TerminalIPythonApp, self).initialize(argv)
269 271 if self.subapp is not None:
270 272 # don't bother initializing further, starting subapp
271 273 return
272 274 # print self.extra_args
273 275 if self.extra_args and not self.something_to_run:
274 276 self.file_to_run = self.extra_args[0]
275 277 self.init_path()
276 278 # create the shell
277 279 self.init_shell()
278 280 # and draw the banner
279 281 self.init_banner()
280 282 # Now a variety of things that happen after the banner is printed.
281 283 self.init_gui_pylab()
282 284 self.init_extensions()
283 285 self.init_code()
284 286
285 287 def init_shell(self):
286 288 """initialize the InteractiveShell instance"""
287 289 # Create an InteractiveShell instance.
288 290 # shell.display_banner should always be False for the terminal
289 291 # based app, because we call shell.show_banner() by hand below
290 292 # so the banner shows *before* all extension loading stuff.
291 293 self.shell = self.interactive_shell_class.instance(parent=self,
292 294 profile_dir=self.profile_dir,
293 295 ipython_dir=self.ipython_dir, user_ns=self.user_ns)
294 296 self.shell.configurables.append(self)
295 297
296 298 def init_banner(self):
297 299 """optionally display the banner"""
298 300 if self.display_banner and self.interact:
299 301 self.shell.show_banner()
300 302 # Make sure there is a space below the banner.
301 303 if self.log_level <= logging.INFO: print()
302 304
303 305 def _pylab_changed(self, name, old, new):
304 306 """Replace --pylab='inline' with --pylab='auto'"""
305 307 if new == 'inline':
306 308 warnings.warn("'inline' not available as pylab backend, "
307 309 "using 'auto' instead.")
308 310 self.pylab = 'auto'
309 311
310 312 def start(self):
311 313 if self.subapp is not None:
312 314 return self.subapp.start()
313 315 # perform any prexec steps:
314 316 if self.interact:
315 317 self.log.debug("Starting IPython's mainloop...")
316 318 self.shell.mainloop()
317 319 else:
318 320 self.log.debug("IPython not interactive...")
319 321 if not self.shell.last_execution_succeeded:
320 322 sys.exit(1)
321 323
322 324 def load_default_config(ipython_dir=None):
323 325 """Load the default config file from the default ipython_dir.
324 326
325 327 This is useful for embedded shells.
326 328 """
327 329 if ipython_dir is None:
328 330 ipython_dir = get_ipython_dir()
329 331
330 332 profile_dir = os.path.join(ipython_dir, 'profile_default')
331 333 app = TerminalIPythonApp()
332 334 app.config_file_paths.append(profile_dir)
333 335 app.load_config_file()
334 336 return app.config
335 337
336 338 launch_new_instance = TerminalIPythonApp.launch_instance
337 339
338 340
339 341 if __name__ == '__main__':
340 342 launch_new_instance()
@@ -1,1740 +1,1758 b''
1 1 ============
2 2 7.x Series
3 3 ============
4 4
5 5
6 .. _version 7.32:
7
8 IPython 7.32
9 ============
10
11
12 The ability to configure magics to be lazily loaded has been added to IPython.
13 See the ``ipython --help-all`` section on ``MagicsManager.lazy_magic``.
14 One can now use::
15
16 c.MagicsManger.lazy_magics = {
17 "my_magic": "slow.to.import",
18 "my_other_magic": "also.slow",
19 }
20
21 And on first use of ``%my_magic``, or corresponding cell magic, or other line magic,
22 the corresponding ``load_ext`` will be called just before trying to invoke the magic.
23
6 24 .. _version 7.31:
7 25
8 26 IPython 7.31
9 27 ============
10 28
11 29 IPython 7.31 brings a couple of backports and fixes from the 8.0 branches,
12 30 it is likely one of the last releases of the 7.x series, as 8.0 will probably be released
13 31 between this release and what would have been 7.32.
14 32
15 33 Please test 8.0 beta/rc releases in addition to this release.
16 34
17 35 This Releases:
18 36 - Backport some fixes for Python 3.10 (:ghpull:`13412`)
19 37 - use full-alpha transparency on dvipng rendered LaTeX (:ghpull:`13372`)
20 38
21 39 Many thanks to all the contributors to this release. You can find all individual
22 40 contributions to this milestone `on github
23 41 <https://github.com/ipython/ipython/milestone/95>`__.
24 42
25 43 Thanks as well to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
26 44 work on IPython and related libraries.
27 45
28 46
29 47 .. _version 7.30:
30 48
31 49 IPython 7.30
32 50 ============
33 51
34 52 IPython 7.30 fixes a couple of bugs introduce in previous releases (in
35 53 particular with respect to path handling), and introduce a few features and
36 54 improvements:
37 55
38 56 Notably we will highlight :ghpull:`13267` "Document that ``%run`` can execute
39 57 notebooks and ipy scripts.", which is the first commit of Fernando PΓ©rez since
40 58 mid 2016 (IPython 5.1). If you are new to IPython, Fernando created IPython in
41 59 2001. The other most recent contribution of Fernando to IPython itself was
42 60 May 2018, by reviewing and merging PRs. I want to note that Fernando is still
43 61 active but mostly as a mentor and leader of the whole Jupyter organisation, but
44 62 we're still happy to see him contribute code !
45 63
46 64 :ghpull:`13290` "Use sphinxify (if available) in object_inspect_mime path"
47 65 should allow richer Repr of docstrings when using jupyterlab inspector.
48 66
49 67 :ghpull:`13311` make the debugger use ``ThreadPoolExecutor`` for debugger cmdloop.
50 68 This should fix some issues/infinite loop, but let us know if you come across
51 69 any regressions. In particular this fixes issues with `kmaork/madbg <https://github.com/kmaork/madbg>`_,
52 70 a remote debugger for IPython.
53 71
54 72 Note that this is likely the ante-penultimate release of IPython 7.x as a stable
55 73 branch, as I hope to release IPython 8.0 as well as IPython 7.31 next
56 74 month/early 2022.
57 75
58 76 IPython 8.0 will drop support for Python 3.7, removed nose as a dependency, and
59 77 7.x will only get critical bug fixes with 8.x becoming the new stable. This will
60 78 not be possible without `NumFOCUS Small Development Grants
61 79 <https://numfocus.org/programs/small-development-grants>`_ Which allowed us to
62 80 hire `Nikita Kniazev <https://github.com/Kojoley>`_ who provide Python and C++
63 81 help and contracting work.
64 82
65 83
66 84 Many thanks to all the contributors to this release. You can find all individual
67 85 contributions to this milestone `on github
68 86 <https://github.com/ipython/ipython/milestone/94?closed=1>`__.
69 87
70 88 Thanks as well to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
71 89 work on IPython and related libraries.
72 90
73 91
74 92 .. _version 7.29:
75 93
76 94 IPython 7.29
77 95 ============
78 96
79 97
80 98 IPython 7.29 brings a couple of new functionalities to IPython and a number of bugfixes.
81 99 It is one of the largest recent release, relatively speaking, with close to 15 Pull Requests.
82 100
83 101
84 102 - fix an issue where base64 was returned instead of bytes when showing figures :ghpull:`13162`
85 103 - fix compatibility with PyQt6, PySide 6 :ghpull:`13172`. This may be of
86 104 interest if you are running on Apple Silicon as only qt6.2+ is natively
87 105 compatible.
88 106 - fix matplotlib qtagg eventloop :ghpull:`13179`
89 107 - Multiple docs fixes, typos, ... etc.
90 108 - Debugger will now exit by default on SigInt :ghpull:`13218`, this will be
91 109 useful in notebook/lab if you forgot to exit the debugger. "Interrupt Kernel"
92 110 will now exist the debugger.
93 111
94 112 It give Pdb the ability to skip code in decorators. If functions contain a
95 113 special value names ``__debuggerskip__ = True|False``, the function will not be
96 114 stepped into, and Pdb will step into lower frames only if the value is set to
97 115 ``False``. The exact behavior is still likely to have corner cases and will be
98 116 refined in subsequent releases. Feedback welcome. See the debugger module
99 117 documentation for more info. Thanks to the `D. E. Shaw
100 118 group <https://deshaw.com/>`__ for funding this feature.
101 119
102 120 The main branch of IPython is receiving a number of changes as we received a
103 121 `NumFOCUS SDG <https://numfocus.org/programs/small-development-grants>`__
104 122 ($4800), to help us finish replacing ``nose`` by ``pytest``, and make IPython
105 123 future proof with an 8.0 release.
106 124
107 125
108 126 Many thanks to all the contributors to this release. You can find all individual
109 127 contributions to this milestone `on github
110 128 <https://github.com/ipython/ipython/milestone/93>`__.
111 129
112 130 Thanks as well to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
113 131 work on IPython and related libraries.
114 132
115 133
116 134 .. _version 7.28:
117 135
118 136 IPython 7.28
119 137 ============
120 138
121 139
122 140 IPython 7.28 is again a minor release that mostly bring bugfixes, and couple of
123 141 improvement. Many thanks to MrMino, who again did all the work this month, and
124 142 made a number of documentation improvements.
125 143
126 144 Here is a non-exhaustive list of changes,
127 145
128 146 Fixes:
129 147
130 148 - async with doesn't allow newlines :ghpull:`13090`
131 149 - Dynamically changing to vi mode via %config magic) :ghpull:`13091`
132 150
133 151 Virtualenv handling fixes:
134 152
135 153 - init_virtualenv now uses Pathlib :ghpull:`12548`
136 154 - Fix Improper path comparison of virtualenv directories :ghpull:`13140`
137 155 - Fix virtual environment user warning for lower case pathes :ghpull:`13094`
138 156 - Adapt to all sorts of drive names for cygwin :ghpull:`13153`
139 157
140 158 New Features:
141 159
142 160 - enable autoplay in embed YouTube player :ghpull:`13133`
143 161
144 162 Documentation:
145 163
146 164 - Fix formatting for the core.interactiveshell documentation :ghpull:`13118`
147 165 - Fix broken ipyparallel's refs :ghpull:`13138`
148 166 - Improve formatting of %time documentation :ghpull:`13125`
149 167 - Reword the YouTubeVideo autoplay WN :ghpull:`13147`
150 168
151 169
152 170 Highlighted features
153 171 --------------------
154 172
155 173
156 174 ``YouTubeVideo`` autoplay and the ability to add extra attributes to ``IFrame``
157 175 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
158 176
159 177 You can add any extra attributes to the ``<iframe>`` tag using the new
160 178 ``extras`` argument in the ``IFrame`` class. For example::
161 179
162 180 In [1]: from IPython.display import IFrame
163 181
164 182 In [2]: IFrame(src="src", width=300, height=300, extras=['loading="eager"'])
165 183
166 184 The above cells will result in the following HTML code being displayed in a
167 185 notebook::
168 186
169 187 <iframe
170 188 width="300"
171 189 height="300"
172 190 src="src"
173 191 frameborder="0"
174 192 allowfullscreen
175 193 loading="eager"
176 194 ></iframe>
177 195
178 196 Related to the above, the ``YouTubeVideo`` class now takes an
179 197 ``allow_autoplay`` flag, which sets up the iframe of the embedded YouTube video
180 198 such that it allows autoplay.
181 199
182 200 .. note::
183 201 Whether this works depends on the autoplay policy of the browser rendering
184 202 the HTML allowing it. It also could get blocked by some browser extensions.
185 203
186 204 Try it out!
187 205 ::
188 206
189 207 In [1]: from IPython.display import YouTubeVideo
190 208
191 209 In [2]: YouTubeVideo("dQw4w9WgXcQ", allow_autoplay=True)
192 210
193 211
194 212
195 213 Thanks
196 214 ------
197 215
198 216 Many thanks to all the contributors to this release. You can find all individual
199 217 contributions to this milestone `on github
200 218 <https://github.com/ipython/ipython/milestone/92>`__.
201 219
202 220 Thanks as well to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
203 221 work on IPython and related libraries.
204 222
205 223
206 224 .. _version 7.27:
207 225
208 226 IPython 7.27
209 227 ============
210 228
211 229 IPython 7.27 is a minor release that fixes a couple of issues and compatibility.
212 230
213 231 - Add support for GTK4 :ghpull:`131011`
214 232 - Add support for Qt6 :ghpull:`13085`
215 233 - Fix an issue with pip magic on windows :ghpull:`13093`
216 234
217 235 Thanks
218 236 ------
219 237
220 238 Many thanks to all the contributors to this release. You can find all individual
221 239 contributions to this milestone `on github
222 240 <https://github.com/ipython/ipython/milestone/91>`__.
223 241
224 242 Thanks as well to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
225 243 work on IPython and related libraries.
226 244
227 245 .. _version 7.26:
228 246
229 247 IPython 7.26
230 248 ============
231 249
232 250 IPython 7.26 is a minor release that fixes a couple of issues, updates in API
233 251 and Copyright/Licenses issues around various part of the codebase.
234 252
235 253 We'll highlight `this issue <https://github.com/ipython/ipython/issues/13039>`
236 254 pointing out we were including and refereeing to code from Stack Overflow which
237 255 was CC-BY-SA, hence incompatible with the BSD license of IPython. This lead us
238 256 to a rewriting of the corresponding logic which in our case was done in a more
239 257 efficient way (in our case we were searching string prefixes instead of full
240 258 strings).
241 259
242 260 You will notice also a number of documentation improvements and cleanup.
243 261
244 262 Of particular interest are the following Pull-requests:
245 263
246 264
247 265 - The IPython directive now uses Sphinx logging for warnings. :ghpull:`13030`.
248 266 - Add expiry days option to pastebin magic and change http protocol to https.
249 267 :ghpull:`13056`
250 268 - Make Ipython.utils.timing work with jupyterlite :ghpull:`13050`.
251 269
252 270 Pastebin magic expiry days option
253 271 ---------------------------------
254 272
255 273 The Pastebin magic now has ``-e`` option to determine
256 274 the number of days for paste expiration. For example
257 275 the paste that created with ``%pastebin -e 20 1`` magic will
258 276 be available for next 20 days.
259 277
260 278
261 279
262 280
263 281
264 282 Thanks
265 283 ------
266 284
267 285 Many thanks to all the contributors to this release and in particular MrMino who
268 286 is doing most of the work those days. You can find all individual contributions
269 287 to this milestone `on github <https://github.com/ipython/ipython/milestone/90>`__.
270 288
271 289 Thanks as well to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
272 290 work on IPython and related libraries.
273 291
274 292
275 293 .. _version 7.25:
276 294
277 295 IPython 7.25
278 296 ============
279 297
280 298 IPython 7.25 is a minor release that contains a single bugfix, which is highly
281 299 recommended for all users of ipdb, ipython debugger %debug magic and similar.
282 300
283 301 Issuing commands like ``where`` from within the debugger would reset the
284 302 local variables changes made by the user. It is interesting to look at the root
285 303 cause of the issue as accessing an attribute (``frame.f_locals``) would trigger
286 304 this side effects.
287 305
288 306 Thanks in particular to the patience from the reporters at D.E. Shaw for their
289 307 initial bug report that was due to a similar coding oversight in an extension,
290 308 and who took time to debug and narrow down the problem.
291 309
292 310 Thanks
293 311 ------
294 312
295 313 Many thanks to all the contributors to this release you can find all individual
296 314 contributions to this milestone `on github <https://github.com/ipython/ipython/milestone/89>`__.
297 315
298 316 Thanks as well to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
299 317 work on IPython and related libraries.
300 318
301 319
302 320 .. _version 7.24:
303 321
304 322 IPython 7.24
305 323 ============
306 324
307 325 Third release of IPython for 2021, mostly containing bug fixes. A couple of not
308 326 typical updates:
309 327
310 328 Misc
311 329 ----
312 330
313 331
314 332 - Fix an issue where ``%recall`` would both succeeded and print an error message
315 333 it failed. :ghpull:`12952`
316 334 - Drop support for NumPy 1.16 – practically has no effect beyond indicating in
317 335 package metadata that we do not support it. :ghpull:`12937`
318 336
319 337 Debugger improvements
320 338 ---------------------
321 339
322 340 The debugger (and ``%debug`` magic) have been improved and can skip or hide frames
323 341 originating from files that are not writable to the user, as these are less
324 342 likely to be the source of errors, or be part of system files this can be a useful
325 343 addition when debugging long errors.
326 344
327 345 In addition to the global ``skip_hidden True|False`` command, the debugger has
328 346 gained finer grained control of predicates as to whether to a frame should be
329 347 considered hidden. So far 3 predicates are available :
330 348
331 349 - ``tbhide``: frames containing the local variable ``__tracebackhide__`` set to
332 350 True.
333 351 - ``readonly``: frames originating from readonly files, set to False.
334 352 - ``ipython_internal``: frames that are likely to be from IPython internal
335 353 code, set to True.
336 354
337 355 You can toggle individual predicates during a session with
338 356
339 357 .. code-block::
340 358
341 359 ipdb> skip_predicates readonly True
342 360
343 361 Read-only files will now be considered hidden frames.
344 362
345 363
346 364 You can call ``skip_predicates`` without arguments to see the states of current
347 365 predicates:
348 366
349 367 .. code-block::
350 368
351 369 ipdb> skip_predicates
352 370 current predicates:
353 371 tbhide : True
354 372 readonly : False
355 373 ipython_internal : True
356 374
357 375 If all predicates are set to ``False``, ``skip_hidden`` will practically have
358 376 no effect. We attempt to warn you when all predicates are False.
359 377
360 378 Note that the ``readonly`` predicate may increase disk access as we check for
361 379 file access permission for all frames on many command invocation, but is usually
362 380 cached by operating systems. Let us know if you encounter any issues.
363 381
364 382 As the IPython debugger does not use the traitlets infrastructure for
365 383 configuration, by editing your ``.pdbrc`` files and appending commands you would
366 384 like to be executed just before entering the interactive prompt. For example:
367 385
368 386
369 387 .. code::
370 388
371 389 # file : ~/.pdbrc
372 390 skip_predicates readonly True
373 391 skip_predicates tbhide False
374 392
375 393 Will hide read only frames by default and show frames marked with
376 394 ``__tracebackhide__``.
377 395
378 396
379 397
380 398
381 399 Thanks
382 400 ------
383 401
384 402 Many thanks to all the contributors to this release you can find all individual
385 403 contributions to this milestone `on github <https://github.com/ipython/ipython/milestone/87>`__.
386 404
387 405 Thanks as well to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
388 406 work on IPython and related libraries, in particular above mentioned
389 407 improvements to the debugger.
390 408
391 409
392 410
393 411
394 412 .. _version 7.23:
395 413
396 414 IPython 7.23 and 7.23.1
397 415 =======================
398 416
399 417
400 418 Third release of IPython for 2021, mostly containing bug fixes. A couple of not
401 419 typical updates:
402 420
403 421 - We moved to GitHub actions away from Travis-CI, the transition may not be
404 422 100% complete (not testing on nightly anymore), but as we ran out of
405 423 Travis-Ci hours on the IPython organisation that was a necessary step.
406 424 :ghpull:`12900`.
407 425
408 426 - We have a new dependency: ``matplotlib-inline``, which try to extract
409 427 matplotlib inline backend specific behavior. It is available on PyPI and
410 428 conda-forge thus should not be a problem to upgrade to this version. If you
411 429 are a package maintainer that might be an extra dependency to package first.
412 430 :ghpull:`12817` (IPython 7.23.1 fix a typo that made this change fail)
413 431
414 432 In the addition/new feature category, ``display()`` now have a ``clear=True``
415 433 option to clear the display if any further outputs arrives, allowing users to
416 434 avoid having to use ``clear_output()`` directly. :ghpull:`12823`.
417 435
418 436 In bug fixes category, this release fix an issue when printing tracebacks
419 437 containing Unicode characters :ghpull:`12758`.
420 438
421 439 In code cleanup category :ghpull:`12932` remove usage of some deprecated
422 440 functionality for compatibility with Python 3.10.
423 441
424 442
425 443
426 444 Thanks
427 445 ------
428 446
429 447 Many thanks to all the contributors to this release you can find all individual
430 448 contributions to this milestone `on github <https://github.com/ipython/ipython/milestone/86>`__.
431 449 In particular MrMino for responding to almost all new issues, and triaging many
432 450 of the old ones, as well as takluyver, minrk, willingc for reacting quikly when
433 451 we ran out of CI Hours.
434 452
435 453 Thanks as well to organisations, QuantStack (martinRenou and SylvainCorlay) for
436 454 extracting matplotlib inline backend into its own package, and the `D. E. Shaw group
437 455 <https://deshaw.com/>`__ for sponsoring work on IPython and related libraries.
438 456
439 457
440 458 .. _version 7.22:
441 459
442 460 IPython 7.22
443 461 ============
444 462
445 463 Second release of IPython for 2021, mostly containing bug fixes. Here is a quick
446 464 rundown of the few changes.
447 465
448 466 - Fix some ``sys.excepthook`` shenanigan when embedding with qt, recommended if
449 467 you – for example – use `napari <https://napari.org>`__. :ghpull:`12842`.
450 468 - Fix bug when using the new ipdb ``%context`` magic :ghpull:`12844`
451 469 - Couples of deprecation cleanup :ghpull:`12868`
452 470 - Update for new dpast.com api if you use the ``%pastbin`` magic. :ghpull:`12712`
453 471 - Remove support for numpy before 1.16. :ghpull:`12836`
454 472
455 473
456 474 Thanks
457 475 ------
458 476
459 477 We have a new team member that you should see more often on the IPython
460 478 repository, BΕ‚aΕΌej Michalik (@MrMino) have been doing regular contributions to
461 479 IPython, and spent time replying to many issues and guiding new users to the
462 480 codebase; they now have triage permissions to the IPython repository and we'll
463 481 work toward giving them more permission in the future.
464 482
465 483 Many thanks to all the contributors to this release you can find all individual
466 484 contributions to this milestone `on github <https://github.com/ipython/ipython/milestone/84>`__.
467 485
468 486 Thanks as well to organisations, QuantStack for working on debugger
469 487 compatibility for Xeus_python, and the `D. E. Shaw group
470 488 <https://deshaw.com/>`__ for sponsoring work on IPython and related libraries.
471 489
472 490 .. _version 721:
473 491
474 492 IPython 7.21
475 493 ============
476 494
477 495 IPython 7.21 is the first release we have back on schedule of one release every
478 496 month; it contains a number of minor fixes and improvements, notably, the new
479 497 context command for ipdb
480 498
481 499
482 500 New "context" command in ipdb
483 501 -----------------------------
484 502
485 503 It is now possible to change the number of lines shown in the backtrace
486 504 information in ipdb using "context" command. :ghpull:`12826`
487 505
488 506 (thanks @MrMino, there are other improvement from them on master).
489 507
490 508 Other notable changes in IPython 7.21
491 509 -------------------------------------
492 510
493 511 - Fix some issues on new osx-arm64 :ghpull:`12804`, :ghpull:`12807`.
494 512 - Compatibility with Xeus-Python for debugger protocol, :ghpull:`12809`
495 513 - Misc docs fixes for compatibility and uniformity with Numpydoc.
496 514 :ghpull:`12824`
497 515
498 516
499 517 Thanks
500 518 ------
501 519
502 520 Many thanks to all the contributors to this release you can find all individual
503 521 contribution to this milestone `on github <https://github.com/ipython/ipython/milestone/83>`__.
504 522
505 523
506 524 .. _version 720:
507 525
508 526 IPython 7.20
509 527 ============
510 528
511 529 IPython 7.20 is the accumulation of 3 month of work on IPython, spacing between
512 530 IPython release have been increased from the usual once a month for various
513 531 reason.
514 532
515 533 - Mainly as I'm too busy and the effectively sole maintainer, and
516 534 - Second because not much changes happened before mid December.
517 535
518 536 The main driver for this release was the new version of Jedi 0.18 breaking API;
519 537 which was taken care of in the master branch early in 2020 but not in 7.x as I
520 538 though that by now 8.0 would be out.
521 539
522 540 The inclusion of a resolver in pip did not help and actually made things worse.
523 541 If usually I would have simply pinned Jedi to ``<0.18``; this is not a solution
524 542 anymore as now pip is free to install Jedi 0.18, and downgrade IPython.
525 543
526 544 I'll do my best to keep the regular release, but as the 8.0-dev branch and 7.x
527 545 are starting to diverge this is becoming difficult in particular with my limited
528 546 time, so if you have any cycles to spare I'll appreciate your help to respond to
529 547 issues and pushing 8.0 forward.
530 548
531 549 Here are thus some of the changes for IPython 7.20.
532 550
533 551 - Support for PyQt5 >= 5.11 :ghpull:`12715`
534 552 - ``%reset`` remove imports more agressively :ghpull:`12718`
535 553 - fix the ``%conda`` magic :ghpull:`12739`
536 554 - compatibility with Jedi 0.18, and bump minimum Jedi version. :ghpull:`12793`
537 555
538 556
539 557 .. _version 719:
540 558
541 559 IPython 7.19
542 560 ============
543 561
544 562 IPython 7.19 accumulative two month of works, bug fixes and improvements, there
545 563 was exceptionally no release last month.
546 564
547 565 - Fix to restore the ability to specify more than one extension using command
548 566 line flags when using traitlets 5.0 :ghpull:`12543`
549 567 - Docs docs formatting that make the install commands work on zsh
550 568 :ghpull:`12587`
551 569 - Always display the last frame in tracebacks even if hidden with
552 570 ``__tracebackhide__`` :ghpull:`12601`
553 571 - Avoid an issue where a callback can be registered multiple times.
554 572 :ghpull:`12625`
555 573 - Avoid an issue in debugger mode where frames changes could be lost.
556 574 :ghpull:`12627`
557 575
558 576 - Never hide the frames that invoke a debugger, even if marked as hidden by
559 577 ``__tracebackhide__`` :ghpull:`12631`
560 578 - Fix calling the debugger in a recursive manner :ghpull:`12659`
561 579
562 580
563 581 A number of code changes have landed on master and we are getting close to
564 582 enough new features and codebase improvement that a 8.0 start to make sens.
565 583 For downstream packages, please start working on migrating downstream testing
566 584 away from iptest and using pytest, as nose will not work on Python 3.10 and we
567 585 will likely start removing it as a dependency for testing.
568 586
569 587 .. _version 718:
570 588
571 589 IPython 7.18
572 590 ============
573 591
574 592 IPython 7.18 is a minor release that mostly contains bugfixes.
575 593
576 594 - ``CRLF`` is now handled by magics my default; solving some issues due to copy
577 595 pasting on windows. :ghpull:`12475`
578 596
579 597 - Requiring pexpect ``>=4.3`` as we are Python 3.7+ only and earlier version of
580 598 pexpect will be incompatible. :ghpull:`12510`
581 599
582 600 - Minimum jedi version is now 0.16. :ghpull:`12488`
583 601
584 602
585 603
586 604 .. _version 717:
587 605
588 606 IPython 7.17
589 607 ============
590 608
591 609 IPython 7.17 brings a couple of new improvements to API and a couple of user
592 610 facing changes to make the terminal experience more user friendly.
593 611
594 612 :ghpull:`12407` introduces the ability to pass extra argument to the IPython
595 613 debugger class; this is to help a new project from ``kmaork``
596 614 (https://github.com/kmaork/madbg) to feature a fully remote debugger.
597 615
598 616 :ghpull:`12410` finally remove support for 3.6, while the codebase is still
599 617 technically compatible; IPython will not install on Python 3.6.
600 618
601 619 lots of work on the debugger and hidden frames from ``@impact27`` in
602 620 :ghpull:`12437`, :ghpull:`12445`, :ghpull:`12460` and in particular
603 621 :ghpull:`12453` which make the debug magic more robust at handling spaces.
604 622
605 623 Biggest API addition is code transformation which is done before code execution;
606 624 IPython allows a number of hooks to catch non-valid Python syntax (magic, prompt
607 625 stripping...etc). Transformers are usually called many time; typically:
608 626
609 627 - When trying to figure out whether the code is complete and valid (should we
610 628 insert a new line or execute ?)
611 629 - During actual code execution pass before giving the code to Python's
612 630 ``exec``.
613 631
614 632 This lead to issues when transformer might have had side effects; or do external
615 633 queries. Starting with IPython 7.17 you can expect your transformer to be called
616 634 less time.
617 635
618 636 Input transformers are now called only once in the execution path of
619 637 `InteractiveShell`, allowing to register transformer that potentially have side
620 638 effects (note that this is not recommended). Internal methods `should_run_async`, and
621 639 `run_cell_async` now take a recommended optional `transformed_cell`, and
622 640 `preprocessing_exc_tuple` parameters that will become mandatory at some point in
623 641 the future; that is to say cells need to be explicitly transformed to be valid
624 642 Python syntax ahead of trying to run them. :ghpull:`12440`;
625 643
626 644 ``input_transformers`` can now also have an attribute ``has_side_effects`` set
627 645 to `True`, when this attribute is present; this will prevent the transformers
628 646 from being ran when IPython is trying to guess whether the user input is
629 647 complete. Note that this may means you will need to explicitly execute in some
630 648 case where your transformations are now not ran; but will not affect users with
631 649 no custom extensions.
632 650
633 651
634 652 API Changes
635 653 -----------
636 654
637 655 Change of API and exposed objects automatically detected using `frappuccino
638 656 <https://pypi.org/project/frappuccino/>`_
639 657
640 658
641 659 The following items are new since 7.16.0::
642 660
643 661 + IPython.core.interactiveshell.InteractiveShell.get_local_scope(self, stack_depth)
644 662
645 663 The following signatures differ since 7.16.0::
646 664
647 665 - IPython.core.interactiveshell.InteractiveShell.run_cell_async(self, raw_cell, store_history=False, silent=False, shell_futures=True)
648 666 + IPython.core.interactiveshell.InteractiveShell.run_cell_async(self, raw_cell, store_history=False, silent=False, shell_futures=True, *, transformed_cell=None, preprocessing_exc_tuple=None)
649 667
650 668 - IPython.core.interactiveshell.InteractiveShell.should_run_async(self, raw_cell)
651 669 + IPython.core.interactiveshell.InteractiveShell.should_run_async(self, raw_cell, *, transformed_cell=None, preprocessing_exc_tuple=None)
652 670
653 671 - IPython.terminal.debugger.TerminalPdb.pt_init(self)
654 672 + IPython.terminal.debugger.TerminalPdb.pt_init(self, pt_session_options=None)
655 673
656 674 This method was added::
657 675
658 676 + IPython.core.interactiveshell.InteractiveShell.get_local_scope
659 677
660 678 Which is now also present on subclasses::
661 679
662 680 + IPython.terminal.embed.InteractiveShellEmbed.get_local_scope
663 681 + IPython.terminal.interactiveshell.TerminalInteractiveShell.get_local_scope
664 682
665 683
666 684 .. _version 716:
667 685
668 686 IPython 7.16.1, 7.16.2
669 687 ======================
670 688
671 689 IPython 7.16.1 was release immediately after 7.16.0 to fix a conda packaging issue.
672 690 The source is identical to 7.16.0 but the file permissions in the tar are different.
673 691
674 692 IPython 7.16.2 pins jedi dependency to "<=0.17.2" which should prevent some
675 693 issues for users still on python 3.6. This may not be sufficient as pip may
676 694 still allow to downgrade IPython.
677 695
678 696 Compatibility with Jedi > 0.17.2 was not added as this would have meant bumping
679 697 the minimal version to >0.16.
680 698
681 699 IPython 7.16
682 700 ============
683 701
684 702
685 703 The default traceback mode will now skip frames that are marked with
686 704 ``__tracebackhide__ = True`` and show how many traceback frames have been
687 705 skipped. This can be toggled by using :magic:`xmode` with the ``--show`` or
688 706 ``--hide`` attribute. It will have no effect on non verbose traceback modes.
689 707
690 708 The ipython debugger also now understands ``__tracebackhide__`` as well and will
691 709 skip hidden frames when displaying. Movement up and down the stack will skip the
692 710 hidden frames and will show how many frames were hidden. Internal IPython frames
693 711 are also now hidden by default. The behavior can be changed with the
694 712 ``skip_hidden`` while in the debugger, command and accepts "yes", "no", "true"
695 713 and "false" case insensitive parameters.
696 714
697 715
698 716 Misc Noticeable changes:
699 717 ------------------------
700 718
701 719 - Exceptions are now (re)raised when running notebooks via the :magic:`%run`, helping to catch issues in workflows and
702 720 pipelines. :ghpull:`12301`
703 721 - Fix inputhook for qt 5.15.0 :ghpull:`12355`
704 722 - Fix wx inputhook :ghpull:`12375`
705 723 - Add handling for malformed pathext env var (Windows) :ghpull:`12367`
706 724 - use $SHELL in system_piped :ghpull:`12360` for uniform behavior with
707 725 ipykernel.
708 726
709 727 Reproducible Build
710 728 ------------------
711 729
712 730 IPython 7.15 reproducible build did not work, so we try again this month
713 731 :ghpull:`12358`.
714 732
715 733
716 734 API Changes
717 735 -----------
718 736
719 737 Change of API and exposed objects automatically detected using `frappuccino
720 738 <https://pypi.org/project/frappuccino/>`_ (still in beta):
721 739
722 740
723 741 The following items are new and mostly related to understanding ``__tracebackhide__``::
724 742
725 743 + IPython.core.debugger.Pdb.do_down(self, arg)
726 744 + IPython.core.debugger.Pdb.do_skip_hidden(self, arg)
727 745 + IPython.core.debugger.Pdb.do_up(self, arg)
728 746 + IPython.core.debugger.Pdb.hidden_frames(self, stack)
729 747 + IPython.core.debugger.Pdb.stop_here(self, frame)
730 748
731 749
732 750 The following items have been removed::
733 751
734 752 - IPython.core.debugger.Pdb.new_do_down
735 753 - IPython.core.debugger.Pdb.new_do_up
736 754
737 755 Those were implementation details.
738 756
739 757
740 758 .. _version 715:
741 759
742 760 IPython 7.15
743 761 ============
744 762
745 763 IPython 7.15 brings a number of bug fixes and user facing improvements.
746 764
747 765 Misc Noticeable changes:
748 766 ------------------------
749 767
750 768 - Long completion name have better elision in terminal :ghpull:`12284`
751 769 - I've started to test on Python 3.9 :ghpull:`12307` and fix some errors.
752 770 - Hi DPI scaling of figures when using qt eventloop :ghpull:`12314`
753 771 - Document the ability to have systemwide configuration for IPython.
754 772 :ghpull:`12328`
755 773 - Fix issues with input autoformatting :ghpull:`12336`
756 774 - ``IPython.core.debugger.Pdb`` is now interruptible (:ghpull:`12168`, in 7.14
757 775 but forgotten in release notes)
758 776 - Video HTML attributes (:ghpull:`12212`, in 7.14 but forgotten in release
759 777 notes)
760 778
761 779 Reproducible Build
762 780 ------------------
763 781
764 782 Starting with IPython 7.15, I am attempting to provide reproducible builds,
765 783 that is to say you should be able from the source tree to generate an sdist
766 784 and wheel that are identical byte for byte with the publish version on PyPI.
767 785
768 786 I've only tested on a couple of machines so far and the process is relatively
769 787 straightforward, so this mean that IPython not only have a deterministic build
770 788 process, but also I have either removed, or put under control all effects of
771 789 the build environments on the final artifact. I encourage you to attempt the
772 790 build process on your machine as documented in :ref:`core_developer_guide`
773 791 and let me know if you do not obtain an identical artifact.
774 792
775 793 While reproducible builds is critical to check that the supply chain of (open
776 794 source) software has not been compromised, it can also help to speedup many
777 795 of the build processes in large environment (conda, apt...) by allowing
778 796 better caching of intermediate build steps.
779 797
780 798 Learn more on `<https://reproducible-builds.org/>`_. `Reflections on trusting
781 799 trust <https://dl.acm.org/doi/10.1145/358198.358210>`_ is also one of the
782 800 cornerstone and recommended reads on this subject.
783 801
784 802 .. note::
785 803
786 804 The build commit from which the sdist is generated is also `signed
787 805 <https://en.wikipedia.org/wiki/Digital_signature>`_, so you should be able to
788 806 check it has not been compromised, and the git repository is a `merkle-tree
789 807 <https://en.wikipedia.org/wiki/Merkle_tree>`_, you can check the consistency
790 808 with `git-fsck <https://git-scm.com/docs/git-fsck>`_ which you likely `want
791 809 to enable by default
792 810 <https://gist.github.com/mbbx6spp/14b86437e794bffb4120>`_.
793 811
794 812 NEP29: Last version to support Python 3.6
795 813 -----------------------------------------
796 814
797 815 IPython 7.15 will be the Last IPython version to officially support Python
798 816 3.6, as stated by `NumPy Enhancement Proposal 29
799 817 <https://numpy.org/neps/nep-0029-deprecation_policy.html>`_. Starting with
800 818 next minor version of IPython I may stop testing on Python 3.6 and may stop
801 819 publishing release artifacts that install on Python 3.6
802 820
803 821 Highlighted features
804 822 --------------------
805 823
806 824 Highlighted features are not new, but seem to not be widely known, this
807 825 section will help you discover in more narrative form what you can do with
808 826 IPython.
809 827
810 828 Increase Tab Completion Menu Height
811 829 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
812 830
813 831 In terminal IPython it is possible to increase the hight of the tab-completion
814 832 menu. To do so set the value of
815 833 :configtrait:`TerminalInteractiveShell.space_for_menu`, this will reserve more
816 834 space at the bottom of the screen for various kind of menus in IPython including
817 835 tab completion and searching in history.
818 836
819 837 Autoformat Code in the terminal
820 838 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
821 839
822 840 If you have a preferred code formatter, you can configure IPython to
823 841 reformat your code. Set the value of
824 842 :configtrait:`TerminalInteractiveShell.autoformatter` to for example ``'black'``
825 843 and IPython will auto format your code when possible.
826 844
827 845
828 846 .. _version 714:
829 847
830 848 IPython 7.14
831 849 ============
832 850
833 851 IPython 7.14 is a minor release that fix a couple of bugs and prepare
834 852 compatibility with new or future versions of some libraries.
835 853
836 854 Important changes:
837 855 ------------------
838 856
839 857 - Fix compatibility with Sphinx 3+ :ghpull:`12235`
840 858 - Remove deprecated matplotlib parameter usage, compatibility with matplotlib
841 859 3.3+ :`122250`
842 860
843 861 Misc Changes
844 862 ------------
845 863
846 864 - set ``.py`` extension when editing current buffer in vi/emacs. :ghpull:`12167`
847 865 - support for unicode identifiers in ``?``/``??`` :ghpull:`12208`
848 866 - add extra options to the ``Video`` Rich objects :ghpull:`12212`
849 867 - add pretty-printing to ``SimpleNamespace`` :ghpull:`12230`
850 868
851 869 IPython.core.debugger.Pdb is now interruptible
852 870 ----------------------------------------------
853 871
854 872 A ``KeyboardInterrupt`` will now interrupt IPython's extended debugger, in order to make Jupyter able to interrupt it. (:ghpull:`12168`)
855 873
856 874 Video HTML attributes
857 875 ---------------------
858 876
859 877 Add an option to `IPython.display.Video` to change the attributes of the HTML display of the video (:ghpull:`12212`)
860 878
861 879
862 880 Pending deprecated imports
863 881 --------------------------
864 882
865 883 Many object present in ``IPython.core.display`` are there for internal use only,
866 884 and should already been imported from ``IPython.display`` by users and external
867 885 libraries. Trying to import those from ``IPython.core.display`` is still possible
868 886 but will trigger a
869 887 deprecation warning in later versions of IPython and will become errors in the
870 888 future.
871 889
872 890 This will simplify compatibility with other Python kernels (like Xeus-Python),
873 891 and simplify code base.
874 892
875 893
876 894
877 895
878 896 .. _version 713:
879 897
880 898 IPython 7.13
881 899 ============
882 900
883 901 IPython 7.13 is the final release of the 7.x branch since master is diverging
884 902 toward an 8.0. Exiting new features have already been merged in 8.0 and will
885 903 not be available on the 7.x branch. All the changes below have been backported
886 904 from the master branch.
887 905
888 906
889 907 - Fix inability to run PDB when inside an event loop :ghpull:`12141`
890 908 - Fix ability to interrupt some processes on windows :ghpull:`12137`
891 909 - Fix debugger shortcuts :ghpull:`12132`
892 910 - improve tab completion when inside a string by removing irrelevant elements :ghpull:`12128`
893 911 - Fix display of filename tab completion when the path is long :ghpull:`12122`
894 912 - Many removal of Python 2 specific code path :ghpull:`12110`
895 913 - displaying wav files do not require NumPy anymore, and is 5x to 30x faster :ghpull:`12113`
896 914
897 915 See the list of all closed issues and pull request on `github
898 916 <https://github.com/ipython/ipython/pulls?q=is%3Aclosed+milestone%3A7.13>`_.
899 917
900 918 .. _version 712:
901 919
902 920 IPython 7.12
903 921 ============
904 922
905 923 IPython 7.12 is a minor update that mostly brings code cleanup, removal of
906 924 longtime deprecated function and a couple update to documentation cleanup as well.
907 925
908 926 Notable changes are the following:
909 927
910 928 - Exit non-zero when ipython is given a file path to run that doesn't exist :ghpull:`12074`
911 929 - Test PR on ARM64 with Travis-CI :ghpull:`12073`
912 930 - Update CI to work with latest Pytest :ghpull:`12086`
913 931 - Add infrastructure to run ipykernel eventloop via trio :ghpull:`12097`
914 932 - Support git blame ignore revs :ghpull:`12091`
915 933 - Start multi-line ``__repr__`` s on their own line :ghpull:`12099`
916 934
917 935 .. _version 7111:
918 936
919 937 IPython 7.11.1
920 938 ==============
921 939
922 940 A couple of deprecated functions (no-op) have been reintroduces in py3compat as
923 941 Cython was still relying on them, and will be removed in a couple of versions.
924 942
925 943 .. _version 711:
926 944
927 945 IPython 7.11
928 946 ============
929 947
930 948 IPython 7.11 received a couple of compatibility fixes and code cleanup.
931 949
932 950 A number of function in the ``py3compat`` have been removed; a number of types
933 951 in the IPython code base are now non-ambiguous and now always ``unicode``
934 952 instead of ``Union[Unicode,bytes]``; many of the relevant code path have thus
935 953 been simplified/cleaned and types annotation added.
936 954
937 955 IPython support several verbosity level from exceptions. ``xmode plain`` now
938 956 support chained exceptions. :ghpull:`11999`
939 957
940 958 We are starting to remove ``shell=True`` in some usages of subprocess. While not directly
941 959 a security issue (as IPython is made to run arbitrary code anyway) it is not good
942 960 practice and we'd like to show the example. :ghissue:`12023`. This discussion
943 961 was started by ``@mschwager`` thanks to a new auditing tool they are working on
944 962 with duo-labs (`dlint <https://github.com/duo-labs/dlint>`_).
945 963
946 964 Work around some bugs in Python 3.9 tokenizer :ghpull:`12057`
947 965
948 966 IPython will now print its version after a crash. :ghpull:`11986`
949 967
950 968 This is likely the last release from the 7.x series that will see new feature.
951 969 The master branch will soon accept large code changes and thrilling new
952 970 features; the 7.x branch will only start to accept critical bug fixes, and
953 971 update dependencies.
954 972
955 973 .. _version 7102:
956 974
957 975 IPython 7.10.2
958 976 ==============
959 977
960 978 IPython 7.10.2 fix a couple of extra incompatibility between IPython, ipdb,
961 979 asyncio and Prompt Toolkit 3.
962 980
963 981 .. _version 7101:
964 982
965 983 IPython 7.10.1
966 984 ==============
967 985
968 986 IPython 7.10.1 fix a couple of incompatibilities with Prompt toolkit 3 (please
969 987 update Prompt toolkit to 3.0.2 at least), and fixes some interaction with
970 988 headless IPython.
971 989
972 990 .. _version 7100:
973 991
974 992 IPython 7.10.0
975 993 ==============
976 994
977 995 IPython 7.10 is the first double digit minor release in the last decade, and
978 996 first since the release of IPython 1.0, previous double digit minor release was
979 997 in August 2009.
980 998
981 999 We've been trying to give you regular release on the last Friday of every month
982 1000 for a guaranty of rapid access to bug fixes and new features.
983 1001
984 1002 Unlike the previous first few releases that have seen only a couple of code
985 1003 changes, 7.10 bring a number of changes, new features and bugfixes.
986 1004
987 1005 Stop Support for Python 3.5 – Adopt NEP 29
988 1006 ------------------------------------------
989 1007
990 1008 IPython has decided to follow the informational `NEP 29
991 1009 <https://numpy.org/neps/nep-0029-deprecation_policy.html>`_ which layout a clear
992 1010 policy as to which version of (C)Python and NumPy are supported.
993 1011
994 1012 We thus dropped support for Python 3.5, and cleaned up a number of code path
995 1013 that were Python-version dependant. If you are on 3.5 or earlier pip should
996 1014 automatically give you the latest compatible version of IPython so you do not
997 1015 need to pin to a given version.
998 1016
999 1017 Support for Prompt Toolkit 3.0
1000 1018 ------------------------------
1001 1019
1002 1020 Prompt Toolkit 3.0 was release a week before IPython 7.10 and introduces a few
1003 1021 breaking changes. We believe IPython 7.10 should be compatible with both Prompt
1004 1022 Toolkit 2.x and 3.x, though it has not been extensively tested with 3.x so
1005 1023 please report any issues.
1006 1024
1007 1025
1008 1026 Prompt Rendering Performance improvements
1009 1027 -----------------------------------------
1010 1028
1011 1029 Pull Request :ghpull:`11933` introduced an optimisation in the prompt rendering
1012 1030 logic that should decrease the resource usage of IPython when using the
1013 1031 _default_ configuration but could potentially introduce a regression of
1014 1032 functionalities if you are using a custom prompt.
1015 1033
1016 1034 We know assume if you haven't changed the default keybindings that the prompt
1017 1035 **will not change** during the duration of your input – which is for example
1018 1036 not true when using vi insert mode that switches between `[ins]` and `[nor]`
1019 1037 for the current mode.
1020 1038
1021 1039 If you are experiencing any issue let us know.
1022 1040
1023 1041 Code autoformatting
1024 1042 -------------------
1025 1043
1026 1044 The IPython terminal can now auto format your code just before entering a new
1027 1045 line or executing a command. To do so use the
1028 1046 ``--TerminalInteractiveShell.autoformatter`` option and set it to ``'black'``;
1029 1047 if black is installed IPython will use black to format your code when possible.
1030 1048
1031 1049 IPython cannot always properly format your code; in particular it will
1032 1050 auto formatting with *black* will only work if:
1033 1051
1034 1052 - Your code does not contains magics or special python syntax.
1035 1053
1036 1054 - There is no code after your cursor.
1037 1055
1038 1056 The Black API is also still in motion; so this may not work with all versions of
1039 1057 black.
1040 1058
1041 1059 It should be possible to register custom formatter, though the API is till in
1042 1060 flux.
1043 1061
1044 1062 Arbitrary Mimetypes Handing in Terminal (Aka inline images in terminal)
1045 1063 -----------------------------------------------------------------------
1046 1064
1047 1065 When using IPython terminal it is now possible to register function to handle
1048 1066 arbitrary mimetypes. While rendering non-text based representation was possible in
1049 1067 many jupyter frontend; it was not possible in terminal IPython, as usually
1050 1068 terminal are limited to displaying text. As many terminal these days provide
1051 1069 escape sequences to display non-text; bringing this loved feature to IPython CLI
1052 1070 made a lot of sens. This functionality will not only allow inline images; but
1053 1071 allow opening of external program; for example ``mplayer`` to "display" sound
1054 1072 files.
1055 1073
1056 1074 So far only the hooks necessary for this are in place, but no default mime
1057 1075 renderers added; so inline images will only be available via extensions. We will
1058 1076 progressively enable these features by default in the next few releases, and
1059 1077 contribution is welcomed.
1060 1078
1061 1079 We welcome any feedback on the API. See :ref:`shell_mimerenderer` for more
1062 1080 informations.
1063 1081
1064 1082 This is originally based on work form in :ghpull:`10610` from @stephanh42
1065 1083 started over two years ago, and still a lot need to be done.
1066 1084
1067 1085 MISC
1068 1086 ----
1069 1087
1070 1088 - Completions can define their own ordering :ghpull:`11855`
1071 1089 - Enable Plotting in the same cell than the one that import matplotlib
1072 1090 :ghpull:`11916`
1073 1091 - Allow to store and restore multiple variables at once :ghpull:`11930`
1074 1092
1075 1093 You can see `all pull-requests <https://github.com/ipython/ipython/pulls?q=is%3Apr+milestone%3A7.10+is%3Aclosed>`_ for this release.
1076 1094
1077 1095 API Changes
1078 1096 -----------
1079 1097
1080 1098 Change of API and exposed objects automatically detected using `frappuccino <https://pypi.org/project/frappuccino/>`_ (still in beta):
1081 1099
1082 1100 The following items are new in IPython 7.10::
1083 1101
1084 1102 + IPython.terminal.shortcuts.reformat_text_before_cursor(buffer, document, shell)
1085 1103 + IPython.terminal.interactiveshell.PTK3
1086 1104 + IPython.terminal.interactiveshell.black_reformat_handler(text_before_cursor)
1087 1105 + IPython.terminal.prompts.RichPromptDisplayHook.write_format_data(self, format_dict, md_dict='None')
1088 1106
1089 1107 The following items have been removed in 7.10::
1090 1108
1091 1109 - IPython.lib.pretty.DICT_IS_ORDERED
1092 1110
1093 1111 The following signatures differ between versions::
1094 1112
1095 1113 - IPython.extensions.storemagic.restore_aliases(ip)
1096 1114 + IPython.extensions.storemagic.restore_aliases(ip, alias='None')
1097 1115
1098 1116 Special Thanks
1099 1117 --------------
1100 1118
1101 1119 - @stephanh42 who started the work on inline images in terminal 2 years ago
1102 1120 - @augustogoulart who spent a lot of time triaging issues and responding to
1103 1121 users.
1104 1122 - @con-f-use who is my (@Carreau) first sponsor on GitHub, as a reminder if you
1105 1123 like IPython, Jupyter and many other library of the SciPy stack you can
1106 1124 donate to numfocus.org non profit
1107 1125
1108 1126 .. _version 790:
1109 1127
1110 1128 IPython 7.9.0
1111 1129 =============
1112 1130
1113 1131 IPython 7.9 is a small release with a couple of improvement and bug fixes.
1114 1132
1115 1133 - Xterm terminal title should be restored on exit :ghpull:`11910`
1116 1134 - special variables ``_``,``__``, ``___`` are not set anymore when cache size
1117 1135 is 0 or less. :ghpull:`11877`
1118 1136 - Autoreload should have regained some speed by using a new heuristic logic to
1119 1137 find all objects needing reload. This should avoid large objects traversal
1120 1138 like pandas dataframes. :ghpull:`11876`
1121 1139 - Get ready for Python 4. :ghpull:`11874`
1122 1140 - `%env` Magic now has heuristic to hide potentially sensitive values :ghpull:`11896`
1123 1141
1124 1142 This is a small release despite a number of Pull Request Pending that need to
1125 1143 be reviewed/worked on. Many of the core developers have been busy outside of
1126 1144 IPython/Jupyter and we thanks all contributor for their patience; we'll work on
1127 1145 these as soon as we have time.
1128 1146
1129 1147
1130 1148 .. _version780:
1131 1149
1132 1150 IPython 7.8.0
1133 1151 =============
1134 1152
1135 1153 IPython 7.8.0 contain a few bugfix and 2 new APIs:
1136 1154
1137 1155 - Enable changing the font color for LaTeX rendering :ghpull:`11840`
1138 1156 - and Re-Expose some PDB API (see below)
1139 1157
1140 1158 Expose Pdb API
1141 1159 --------------
1142 1160
1143 1161 Expose the built-in ``pdb.Pdb`` API. ``Pdb`` constructor arguments are generically
1144 1162 exposed, regardless of python version.
1145 1163 Newly exposed arguments:
1146 1164
1147 1165 - ``skip`` - Python 3.1+
1148 1166 - ``nosiginnt`` - Python 3.2+
1149 1167 - ``readrc`` - Python 3.6+
1150 1168
1151 1169 Try it out::
1152 1170
1153 1171 from IPython.terminal.debugger import TerminalPdb
1154 1172 pdb = TerminalPdb(skip=["skipthismodule"])
1155 1173
1156 1174
1157 1175 See :ghpull:`11840`
1158 1176
1159 1177 .. _version770:
1160 1178
1161 1179 IPython 7.7.0
1162 1180 =============
1163 1181
1164 1182 IPython 7.7.0 contain multiple bug fixes and documentation updates; Here are a
1165 1183 few of the outstanding issue fixed:
1166 1184
1167 1185 - Fix a bug introduced in 7.6 where the ``%matplotlib`` magic would fail on
1168 1186 previously acceptable arguments :ghpull:`11814`.
1169 1187 - Fix the manage location on freebsd :ghpull:`11808`.
1170 1188 - Fix error message about aliases after ``%reset`` call in ipykernel
1171 1189 :ghpull:`11806`
1172 1190 - Fix Duplication completions in emacs :ghpull:`11803`
1173 1191
1174 1192 We are planning to adopt `NEP29 <https://github.com/numpy/numpy/pull/14086>`_
1175 1193 (still currently in draft) which may make this minor version of IPython the
1176 1194 last one to support Python 3.5 and will make the code base more aggressive
1177 1195 toward removing compatibility with older versions of Python.
1178 1196
1179 1197 GitHub now support to give only "Triage" permissions to users; if you'd like to
1180 1198 help close stale issues and labels issues please reach to us with your GitHub
1181 1199 Username and we'll add you to the triage team. It is a great way to start
1182 1200 contributing and a path toward getting commit rights.
1183 1201
1184 1202 .. _version761:
1185 1203
1186 1204 IPython 7.6.1
1187 1205 =============
1188 1206
1189 1207 IPython 7.6.1 contain a critical bugfix in the ``%timeit`` magic, which would
1190 1208 crash on some inputs as a side effect of :ghpull:`11716`. See :ghpull:`11812`
1191 1209
1192 1210
1193 1211 .. _whatsnew760:
1194 1212
1195 1213 IPython 7.6.0
1196 1214 =============
1197 1215
1198 1216 IPython 7.6.0 contains a couple of bug fixes and number of small features
1199 1217 additions as well as some compatibility with the current development version of
1200 1218 Python 3.8.
1201 1219
1202 1220 - Add a ``-l`` option to :magic:`psearch` to list the available search
1203 1221 types. :ghpull:`11672`
1204 1222 - Support ``PathLike`` for ``DisplayObject`` and ``Image``. :ghpull:`11764`
1205 1223 - Configurability of timeout in the test suite for slow platforms.
1206 1224 :ghpull:`11756`
1207 1225 - Accept any casing for matplotlib backend. :ghpull:`121748`
1208 1226 - Properly skip test that requires numpy to be installed :ghpull:`11723`
1209 1227 - More support for Python 3.8 and positional only arguments (pep570)
1210 1228 :ghpull:`11720`
1211 1229 - Unicode names for the completion are loaded lazily on first use which
1212 1230 should decrease startup time. :ghpull:`11693`
1213 1231 - Autoreload now update the types of reloaded objects; this for example allow
1214 1232 pickling of reloaded objects. :ghpull:`11644`
1215 1233 - Fix a bug where ``%%time`` magic would suppress cell output. :ghpull:`11716`
1216 1234
1217 1235
1218 1236 Prepare migration to pytest (instead of nose) for testing
1219 1237 ---------------------------------------------------------
1220 1238
1221 1239 Most of the work between 7.5 and 7.6 was to prepare the migration from our
1222 1240 testing framework to pytest. Most of the test suite should now work by simply
1223 1241 issuing ``pytest`` from the root of the repository.
1224 1242
1225 1243 The migration to pytest is just at its beginning. Many of our test still rely
1226 1244 on IPython-specific plugins for nose using pytest (doctest using IPython syntax
1227 1245 is one example of this where test appear as "passing", while no code has been
1228 1246 ran). Many test also need to be updated like ``yield-test`` to be properly
1229 1247 parametrized tests.
1230 1248
1231 1249 Migration to pytest allowed me to discover a number of issues in our test
1232 1250 suite; which was hiding a number of subtle issues – or not actually running
1233 1251 some of the tests in our test suite – I have thus corrected many of those; like
1234 1252 improperly closed resources; or used of deprecated features. I also made use of
1235 1253 the ``pytest --durations=...`` to find some of our slowest test and speed them
1236 1254 up (our test suite can now be up to 10% faster). Pytest as also a variety of
1237 1255 plugins and flags which will make the code quality of IPython and the testing
1238 1256 experience better.
1239 1257
1240 1258 Misc
1241 1259 ----
1242 1260
1243 1261 We skipped the release of 7.6 at the end of May, but will attempt to get back
1244 1262 on schedule. We are starting to think about making introducing backward
1245 1263 incompatible change and start the 8.0 series.
1246 1264
1247 1265 Special Thanks to Gabriel (@gpotter2 on GitHub), who among other took care many
1248 1266 of the remaining task for 7.4 and 7.5, like updating the website.
1249 1267
1250 1268 .. _whatsnew750:
1251 1269
1252 1270 IPython 7.5.0
1253 1271 =============
1254 1272
1255 1273 IPython 7.5.0 consist mostly of bug-fixes, and documentation updates, with one
1256 1274 minor new feature. The `Audio` display element can now be assigned an element
1257 1275 id when displayed in browser. See :ghpull:`11670`
1258 1276
1259 1277 The major outstanding bug fix correct a change of behavior that was introduce
1260 1278 in 7.4.0 where some cell magics would not be able to access or modify global
1261 1279 scope when using the ``@needs_local_scope`` decorator. This was typically
1262 1280 encountered with the ``%%time`` and ``%%timeit`` magics. See :ghissue:`11659`
1263 1281 and :ghpull:`11698`.
1264 1282
1265 1283 .. _whatsnew740:
1266 1284
1267 1285 IPython 7.4.0
1268 1286 =============
1269 1287
1270 1288 Unicode name completions
1271 1289 ------------------------
1272 1290
1273 1291 Previously, we provided completion for a unicode name with its relative symbol.
1274 1292 With this, now IPython provides complete suggestions to unicode name symbols.
1275 1293
1276 1294 As on the PR, if user types ``\LAT<tab>``, IPython provides a list of
1277 1295 possible completions. In this case, it would be something like::
1278 1296
1279 1297 'LATIN CAPITAL LETTER A',
1280 1298 'LATIN CAPITAL LETTER B',
1281 1299 'LATIN CAPITAL LETTER C',
1282 1300 'LATIN CAPITAL LETTER D',
1283 1301 ....
1284 1302
1285 1303 This help to type unicode character that do not have short latex aliases, and
1286 1304 have long unicode names. for example ``Ν°``, ``\GREEK CAPITAL LETTER HETA``.
1287 1305
1288 1306 This feature was contributed by Luciana Marques :ghpull:`11583`.
1289 1307
1290 1308 Make audio normalization optional
1291 1309 ---------------------------------
1292 1310
1293 1311 Added 'normalize' argument to `IPython.display.Audio`. This argument applies
1294 1312 when audio data is given as an array of samples. The default of `normalize=True`
1295 1313 preserves prior behavior of normalizing the audio to the maximum possible range.
1296 1314 Setting to `False` disables normalization.
1297 1315
1298 1316
1299 1317 Miscellaneous
1300 1318 -------------
1301 1319
1302 1320 - Fix improper acceptation of ``return`` outside of functions. :ghpull:`11641`.
1303 1321 - Fixed PyQt 5.11 backwards incompatibility causing sip import failure.
1304 1322 :ghpull:`11613`.
1305 1323 - Fix Bug where ``type?`` would crash IPython. :ghpull:`1608`.
1306 1324 - Allow to apply ``@needs_local_scope`` to cell magics for convenience.
1307 1325 :ghpull:`11542`.
1308 1326
1309 1327 .. _whatsnew730:
1310 1328
1311 1329 IPython 7.3.0
1312 1330 =============
1313 1331
1314 1332 .. _whatsnew720:
1315 1333
1316 1334 IPython 7.3.0 bring several bug fixes and small improvements that you will
1317 1335 described bellow.
1318 1336
1319 1337 The biggest change to this release is the implementation of the ``%conda`` and
1320 1338 ``%pip`` magics, that will attempt to install packages in the **current
1321 1339 environment**. You may still need to restart your interpreter or kernel for the
1322 1340 change to be taken into account, but it should simplify installation of packages
1323 1341 into remote environment. Installing using pip/conda from the command line is
1324 1342 still the prefer method.
1325 1343
1326 1344 The ``%pip`` magic was already present, but was only printing a warning; now it
1327 1345 will actually forward commands to pip.
1328 1346
1329 1347 Misc bug fixes and improvements:
1330 1348
1331 1349 - Compatibility with Python 3.8.
1332 1350 - Do not expand shell variable in execution magics, and added the
1333 1351 ``no_var_expand`` decorator for magic requiring a similar functionality
1334 1352 :ghpull:`11516`
1335 1353 - Add ``%pip`` and ``%conda`` magic :ghpull:`11524`
1336 1354 - Re-initialize posix aliases after a ``%reset`` :ghpull:`11528`
1337 1355 - Allow the IPython command line to run ``*.ipynb`` files :ghpull:`11529`
1338 1356
1339 1357 IPython 7.2.0
1340 1358 =============
1341 1359
1342 1360 IPython 7.2.0 brings minor bugfixes, improvements, and new configuration options:
1343 1361
1344 1362 - Fix a bug preventing PySide2 GUI integration from working :ghpull:`11464`
1345 1363 - Run CI on Mac OS ! :ghpull:`11471`
1346 1364 - Fix IPython "Demo" mode. :ghpull:`11498`
1347 1365 - Fix ``%run`` magic with path in name :ghpull:`11499`
1348 1366 - Fix: add CWD to sys.path *after* stdlib :ghpull:`11502`
1349 1367 - Better rendering of signatures, especially long ones. :ghpull:`11505`
1350 1368 - Re-enable jedi by default if it's installed :ghpull:`11506`
1351 1369 - Add New ``minimal`` exception reporting mode (useful for educational purpose). See :ghpull:`11509`
1352 1370
1353 1371
1354 1372 Added ability to show subclasses when using pinfo and other utilities
1355 1373 ---------------------------------------------------------------------
1356 1374
1357 1375 When using ``?``/``??`` on a class, IPython will now list the first 10 subclasses.
1358 1376
1359 1377 Special Thanks to Chris Mentzel of the Moore Foundation for this feature. Chris
1360 1378 is one of the people who played a critical role in IPython/Jupyter getting
1361 1379 funding.
1362 1380
1363 1381 We are grateful for all the help Chris has given us over the years,
1364 1382 and we're now proud to have code contributed by Chris in IPython.
1365 1383
1366 1384 OSMagics.cd_force_quiet configuration option
1367 1385 --------------------------------------------
1368 1386
1369 1387 You can set this option to force the %cd magic to behave as if ``-q`` was passed:
1370 1388 ::
1371 1389
1372 1390 In [1]: cd /
1373 1391 /
1374 1392
1375 1393 In [2]: %config OSMagics.cd_force_quiet = True
1376 1394
1377 1395 In [3]: cd /tmp
1378 1396
1379 1397 In [4]:
1380 1398
1381 1399 See :ghpull:`11491`
1382 1400
1383 1401 In vi editing mode, whether the prompt includes the current vi mode can now be configured
1384 1402 -----------------------------------------------------------------------------------------
1385 1403
1386 1404 Set the ``TerminalInteractiveShell.prompt_includes_vi_mode`` to a boolean value
1387 1405 (default: True) to control this feature. See :ghpull:`11492`
1388 1406
1389 1407 .. _whatsnew710:
1390 1408
1391 1409 IPython 7.1.0
1392 1410 =============
1393 1411
1394 1412 IPython 7.1.0 is the first minor release after 7.0.0 and mostly brings fixes to
1395 1413 new features, internal refactoring, and fixes for regressions that happened during the 6.x->7.x
1396 1414 transition. It also brings **Compatibility with Python 3.7.1**, as we're
1397 1415 unwillingly relying on a bug in CPython.
1398 1416
1399 1417 New Core Dev:
1400 1418
1401 1419 - We welcome Jonathan Slenders to the commiters. Jonathan has done a fantastic
1402 1420 work on prompt_toolkit, and we'd like to recognise his impact by giving him
1403 1421 commit rights. :ghissue:`11397`
1404 1422
1405 1423 Notable Changes
1406 1424
1407 1425 - Major update of "latex to unicode" tab completion map (see below)
1408 1426
1409 1427 Notable New Features:
1410 1428
1411 1429 - Restore functionality and documentation of the **sphinx directive**, which
1412 1430 is now stricter (fail on error by daefault), has new configuration options,
1413 1431 has a brand new documentation page :ref:`ipython_directive` (which needs
1414 1432 some cleanup). It is also now *tested* so we hope to have less regressions.
1415 1433 :ghpull:`11402`
1416 1434
1417 1435 - ``IPython.display.Video`` now supports ``width`` and ``height`` arguments,
1418 1436 allowing a custom width and height to be set instead of using the video's
1419 1437 width and height. :ghpull:`11353`
1420 1438
1421 1439 - Warn when using ``HTML('<iframe>')`` instead of ``IFrame`` :ghpull:`11350`
1422 1440
1423 1441 - Allow Dynamic switching of editing mode between vi/emacs and show
1424 1442 normal/input mode in prompt when using vi. :ghpull:`11390`. Use ``%config
1425 1443 TerminalInteractiveShell.editing_mode = 'vi'`` or ``%config
1426 1444 TerminalInteractiveShell.editing_mode = 'emacs'`` to dynamically switch
1427 1445 between modes.
1428 1446
1429 1447
1430 1448 Notable Fixes:
1431 1449
1432 1450 - Fix entering of **multi-line blocks in terminal** IPython, and various
1433 1451 crashes in the new input transformation machinery :ghpull:`11354`,
1434 1452 :ghpull:`11356`, :ghpull:`11358`. These also fix a **Compatibility bug
1435 1453 with Python 3.7.1**.
1436 1454
1437 1455 - Fix moving through generator stack in ipdb :ghpull:`11266`
1438 1456
1439 1457 - %Magic command arguments now support quoting. :ghpull:`11330`
1440 1458
1441 1459 - Re-add ``rprint`` and ``rprinte`` aliases. :ghpull:`11331`
1442 1460
1443 1461 - Remove implicit dependency on ``ipython_genutils`` :ghpull:`11317`
1444 1462
1445 1463 - Make ``nonlocal`` raise ``SyntaxError`` instead of silently failing in async
1446 1464 mode. :ghpull:`11382`
1447 1465
1448 1466 - Fix mishandling of magics and ``= !`` assignment just after a dedent in
1449 1467 nested code blocks :ghpull:`11418`
1450 1468
1451 1469 - Fix instructions for custom shortcuts :ghpull:`11426`
1452 1470
1453 1471
1454 1472 Notable Internals improvements:
1455 1473
1456 1474 - Use of ``os.scandir`` (Python 3 only) to speed up some file system operations.
1457 1475 :ghpull:`11365`
1458 1476
1459 1477 - use ``perf_counter`` instead of ``clock`` for more precise
1460 1478 timing results with ``%time`` :ghpull:`11376`
1461 1479
1462 1480 Many thanks to all the contributors and in particular to ``bartskowron`` and
1463 1481 ``tonyfast`` who handled some pretty complicated bugs in the input machinery. We
1464 1482 had a number of first time contributors and maybe hacktoberfest participants that
1465 1483 made significant contributions and helped us free some time to focus on more
1466 1484 complicated bugs.
1467 1485
1468 1486 You
1469 1487 can see all the closed issues and Merged PR, new features and fixes `here
1470 1488 <https://github.com/ipython/ipython/issues?utf8=%E2%9C%93&q=+is%3Aclosed+milestone%3A7.1+>`_.
1471 1489
1472 1490 Unicode Completion update
1473 1491 -------------------------
1474 1492
1475 1493 In IPython 7.1 the Unicode completion map has been updated and synchronized with
1476 1494 the Julia language.
1477 1495
1478 1496 Added and removed character characters:
1479 1497
1480 1498 ``\jmath`` (``Θ·``), ``\\underleftrightarrow`` (U+034D, combining) have been
1481 1499 added, while ``\\textasciicaron`` have been removed
1482 1500
1483 1501 Some sequences have seen their prefix removed:
1484 1502
1485 1503 - 6 characters ``\text...<tab>`` should now be inputed with ``\...<tab>`` directly,
1486 1504 - 45 characters ``\Elz...<tab>`` should now be inputed with ``\...<tab>`` directly,
1487 1505 - 65 characters ``\B...<tab>`` should now be inputed with ``\...<tab>`` directly,
1488 1506 - 450 characters ``\m...<tab>`` should now be inputed with ``\...<tab>`` directly,
1489 1507
1490 1508 Some sequences have seen their prefix shortened:
1491 1509
1492 1510 - 5 characters ``\mitBbb...<tab>`` should now be inputed with ``\bbi...<tab>`` directly,
1493 1511 - 52 characters ``\mit...<tab>`` should now be inputed with ``\i...<tab>`` directly,
1494 1512 - 216 characters ``\mbfit...<tab>`` should now be inputed with ``\bi...<tab>`` directly,
1495 1513 - 222 characters ``\mbf...<tab>`` should now be inputed with ``\b...<tab>`` directly,
1496 1514
1497 1515 A couple of characters had their sequence simplified:
1498 1516
1499 1517 - ``Γ°``, type ``\dh<tab>``, instead of ``\eth<tab>``
1500 1518 - ``Δ§``, type ``\hbar<tab>``, instead of ``\Elzxh<tab>``
1501 1519 - ``ΙΈ``, type ``\ltphi<tab>``, instead of ``\textphi<tab>``
1502 1520 - ``Ο΄``, type ``\varTheta<tab>``, instead of ``\textTheta<tab>``
1503 1521 - ``ℇ``, type ``\eulermascheroni<tab>``, instead of ``\Eulerconst<tab>``
1504 1522 - ``β„Ž``, type ``\planck<tab>``, instead of ``\Planckconst<tab>``
1505 1523
1506 1524 - U+0336 (COMBINING LONG STROKE OVERLAY), type ``\strike<tab>``, instead of ``\Elzbar<tab>``.
1507 1525
1508 1526 A couple of sequences have been updated:
1509 1527
1510 1528 - ``\varepsilon`` now gives ``Ι›`` (GREEK SMALL LETTER EPSILON) instead of ``Ξ΅`` (GREEK LUNATE EPSILON SYMBOL),
1511 1529 - ``\underbar`` now gives U+0331 (COMBINING MACRON BELOW) instead of U+0332 (COMBINING LOW LINE).
1512 1530
1513 1531
1514 1532 .. _whatsnew700:
1515 1533
1516 1534 IPython 7.0.0
1517 1535 =============
1518 1536
1519 1537 Released Thursday September 27th, 2018
1520 1538
1521 1539 IPython 7 includes major feature improvements.
1522 1540 This is also the second major version of IPython to support only
1523 1541 Python 3 – starting at Python 3.4. Python 2 is still community-supported
1524 1542 on the bugfix only 5.x branch, but we remind you that Python 2 "end of life"
1525 1543 is on Jan 1st 2020.
1526 1544
1527 1545 We were able to backport bug fixes to the 5.x branch thanks to our backport bot which
1528 1546 backported more than `70 Pull-Requests
1529 1547 <https://github.com/ipython/ipython/pulls?page=3&q=is%3Apr+sort%3Aupdated-desc+author%3Aapp%2Fmeeseeksdev++5.x&utf8=%E2%9C%93>`_, but there are still many PRs that required manual work. This is an area of the project where you can easily contribute by looking for `PRs that still need manual backport <https://github.com/ipython/ipython/issues?q=label%3A%22Still+Needs+Manual+Backport%22+is%3Aclosed+sort%3Aupdated-desc>`_
1530 1548
1531 1549 The IPython 6.x branch will likely not see any further release unless critical
1532 1550 bugs are found.
1533 1551
1534 1552 Make sure you have pip > 9.0 before upgrading. You should be able to update by running:
1535 1553
1536 1554 .. code::
1537 1555
1538 1556 pip install ipython --upgrade
1539 1557
1540 1558 .. only:: ipydev
1541 1559
1542 1560 If you are trying to install or update an ``alpha``, ``beta``, or ``rc``
1543 1561 version, use pip ``--pre`` flag.
1544 1562
1545 1563 .. code::
1546 1564
1547 1565 pip install ipython --upgrade --pre
1548 1566
1549 1567
1550 1568 Or, if you have conda installed:
1551 1569
1552 1570 .. code::
1553 1571
1554 1572 conda install ipython
1555 1573
1556 1574
1557 1575
1558 1576 Prompt Toolkit 2.0
1559 1577 ------------------
1560 1578
1561 1579 IPython 7.0+ now uses ``prompt_toolkit 2.0``. If you still need to use an earlier
1562 1580 ``prompt_toolkit`` version, you may need to pin IPython to ``<7.0``.
1563 1581
1564 1582 Autowait: Asynchronous REPL
1565 1583 ---------------------------
1566 1584
1567 1585 Staring with IPython 7.0 on Python 3.6+, IPython can automatically ``await``
1568 1586 top level code. You should not need to access an event loop or runner
1569 1587 yourself. To learn more, read the :ref:`autoawait` section of our docs, see
1570 1588 :ghpull:`11265`, or try the following code::
1571 1589
1572 1590 Python 3.6.0
1573 1591 Type 'copyright', 'credits' or 'license' for more information
1574 1592 IPython 7.0.0 -- An enhanced Interactive Python. Type '?' for help.
1575 1593
1576 1594 In [1]: import aiohttp
1577 1595 ...: result = aiohttp.get('https://api.github.com')
1578 1596
1579 1597 In [2]: response = await result
1580 1598 <pause for a few 100s ms>
1581 1599
1582 1600 In [3]: await response.json()
1583 1601 Out[3]:
1584 1602 {'authorizations_url': 'https://api.github.com/authorizations',
1585 1603 'code_search_url': 'https://api.github.com/search/code?q={query}{&page,per_page,sort,order}',
1586 1604 ...
1587 1605 }
1588 1606
1589 1607 .. note::
1590 1608
1591 1609 Async integration is experimental code, behavior may change or be removed
1592 1610 between Python and IPython versions without warnings.
1593 1611
1594 1612 Integration is by default with `asyncio`, but other libraries can be configured --
1595 1613 like ``curio`` or ``trio`` -- to improve concurrency in the REPL::
1596 1614
1597 1615 In [1]: %autoawait trio
1598 1616
1599 1617 In [2]: import trio
1600 1618
1601 1619 In [3]: async def child(i):
1602 1620 ...: print(" child %s goes to sleep"%i)
1603 1621 ...: await trio.sleep(2)
1604 1622 ...: print(" child %s wakes up"%i)
1605 1623
1606 1624 In [4]: print('parent start')
1607 1625 ...: async with trio.open_nursery() as n:
1608 1626 ...: for i in range(3):
1609 1627 ...: n.spawn(child, i)
1610 1628 ...: print('parent end')
1611 1629 parent start
1612 1630 child 2 goes to sleep
1613 1631 child 0 goes to sleep
1614 1632 child 1 goes to sleep
1615 1633 <about 2 seconds pause>
1616 1634 child 2 wakes up
1617 1635 child 1 wakes up
1618 1636 child 0 wakes up
1619 1637 parent end
1620 1638
1621 1639 See :ref:`autoawait` for more information.
1622 1640
1623 1641
1624 1642 Asynchronous code in a Notebook interface or any other frontend using the
1625 1643 Jupyter Protocol will require further updates to the IPykernel package.
1626 1644
1627 1645 Non-Asynchronous code
1628 1646 ~~~~~~~~~~~~~~~~~~~~~
1629 1647
1630 1648 As the internal API of IPython is now asynchronous, IPython needs to run under
1631 1649 an event loop. In order to allow many workflows, (like using the :magic:`%run`
1632 1650 magic, or copy-pasting code that explicitly starts/stop event loop), when
1633 1651 top-level code is detected as not being asynchronous, IPython code is advanced
1634 1652 via a pseudo-synchronous runner, and may not advance pending tasks.
1635 1653
1636 1654 Change to Nested Embed
1637 1655 ~~~~~~~~~~~~~~~~~~~~~~
1638 1656
1639 1657 The introduction of the ability to run async code had some effect on the
1640 1658 ``IPython.embed()`` API. By default, embed will not allow you to run asynchronous
1641 1659 code unless an event loop is specified.
1642 1660
1643 1661 Effects on Magics
1644 1662 ~~~~~~~~~~~~~~~~~
1645 1663
1646 1664 Some magics will not work with async until they're updated.
1647 1665 Contributions welcome.
1648 1666
1649 1667 Expected Future changes
1650 1668 ~~~~~~~~~~~~~~~~~~~~~~~
1651 1669
1652 1670 We expect more internal but public IPython functions to become ``async``, and
1653 1671 will likely end up having a persistent event loop while IPython is running.
1654 1672
1655 1673 Thanks
1656 1674 ~~~~~~
1657 1675
1658 1676 This release took more than a year in the making.
1659 1677 The code was rebased a number of
1660 1678 times; leading to commit authorship that may have been lost in the final
1661 1679 Pull-Request. Huge thanks to many people for contribution, discussion, code,
1662 1680 documentation, use-cases: dalejung, danielballan, ellisonbg, fperez, gnestor,
1663 1681 minrk, njsmith, pganssle, tacaswell, takluyver , vidartf ... And many others.
1664 1682
1665 1683
1666 1684 Autoreload Improvement
1667 1685 ----------------------
1668 1686
1669 1687 The magic :magic:`%autoreload 2 <autoreload>` now captures new methods added to
1670 1688 classes. Earlier, only methods existing as of the initial import were being
1671 1689 tracked and updated.
1672 1690
1673 1691 This new feature helps dual environment development - Jupyter+IDE - where the
1674 1692 code gradually moves from notebook cells to package files as it gets
1675 1693 structured.
1676 1694
1677 1695 **Example**: An instance of the class ``MyClass`` will be able to access the
1678 1696 method ``cube()`` after it is uncommented and the file ``file1.py`` is saved on
1679 1697 disk.
1680 1698
1681 1699
1682 1700 .. code::
1683 1701
1684 1702 # notebook
1685 1703
1686 1704 from mymodule import MyClass
1687 1705 first = MyClass(5)
1688 1706
1689 1707 .. code::
1690 1708
1691 1709 # mymodule/file1.py
1692 1710
1693 1711 class MyClass:
1694 1712
1695 1713 def __init__(self, a=10):
1696 1714 self.a = a
1697 1715
1698 1716 def square(self):
1699 1717 print('compute square')
1700 1718 return self.a*self.a
1701 1719
1702 1720 # def cube(self):
1703 1721 # print('compute cube')
1704 1722 # return self.a*self.a*self.a
1705 1723
1706 1724
1707 1725
1708 1726
1709 1727 Misc
1710 1728 ----
1711 1729
1712 1730 The autoindent feature that was deprecated in 5.x was re-enabled and
1713 1731 un-deprecated in :ghpull:`11257`
1714 1732
1715 1733 Make :magic:`%run -n -i ... <run>` work correctly. Earlier, if :magic:`%run` was
1716 1734 passed both arguments, ``-n`` would be silently ignored. See :ghpull:`10308`
1717 1735
1718 1736
1719 1737 The :cellmagic:`%%script` (as well as :cellmagic:`%%bash`,
1720 1738 :cellmagic:`%%ruby`... ) cell magics now raise by default if the return code of
1721 1739 the given code is non-zero (thus halting execution of further cells in a
1722 1740 notebook). The behavior can be disable by passing the ``--no-raise-error`` flag.
1723 1741
1724 1742
1725 1743 Deprecations
1726 1744 ------------
1727 1745
1728 1746 A couple of unused functions and methods have been deprecated and will be removed
1729 1747 in future versions:
1730 1748
1731 1749 - ``IPython.utils.io.raw_print_err``
1732 1750 - ``IPython.utils.io.raw_print``
1733 1751
1734 1752
1735 1753 Backwards incompatible changes
1736 1754 ------------------------------
1737 1755
1738 1756 * The API for transforming input before it is parsed as Python code has been
1739 1757 completely redesigned: any custom input transformations will need to be
1740 1758 rewritten. See :doc:`/config/inputtransforms` for details of the new API.
General Comments 0
You need to be logged in to leave comments. Login now