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