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