##// END OF EJS Templates
Backport PR #10707 on branch 5.x...
Thomas Kluyver -
Show More
@@ -1,583 +1,585 b''
1 1 """Implementation of basic magic functions."""
2 2
3 3 from __future__ import print_function
4 4 from __future__ import absolute_import
5 5
6 6 import argparse
7 7 import io
8 8 import sys
9 9 from pprint import pformat
10 10
11 11 from IPython.core import magic_arguments, page
12 12 from IPython.core.error import UsageError
13 13 from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
14 14 from IPython.utils.text import format_screen, dedent, indent
15 15 from IPython.testing.skipdoctest import skip_doctest
16 16 from IPython.utils.ipstruct import Struct
17 17 from IPython.utils.py3compat import unicode_type
18 18 from warnings import warn
19 19 from logging import error
20 20
21 21
22 22 class MagicsDisplay(object):
23 23 def __init__(self, magics_manager):
24 24 self.magics_manager = magics_manager
25 25
26 26 def _lsmagic(self):
27 27 """The main implementation of the %lsmagic"""
28 28 mesc = magic_escapes['line']
29 29 cesc = magic_escapes['cell']
30 30 mman = self.magics_manager
31 31 magics = mman.lsmagic()
32 32 out = ['Available line magics:',
33 33 mesc + (' '+mesc).join(sorted(magics['line'])),
34 34 '',
35 35 'Available cell magics:',
36 36 cesc + (' '+cesc).join(sorted(magics['cell'])),
37 37 '',
38 38 mman.auto_status()]
39 39 return '\n'.join(out)
40 40
41 41 def _repr_pretty_(self, p, cycle):
42 42 p.text(self._lsmagic())
43 43
44 44 def __str__(self):
45 45 return self._lsmagic()
46 46
47 47 def _jsonable(self):
48 48 """turn magics dict into jsonable dict of the same structure
49 49
50 50 replaces object instances with their class names as strings
51 51 """
52 52 magic_dict = {}
53 53 mman = self.magics_manager
54 54 magics = mman.lsmagic()
55 55 for key, subdict in magics.items():
56 56 d = {}
57 57 magic_dict[key] = d
58 58 for name, obj in subdict.items():
59 59 try:
60 60 classname = obj.__self__.__class__.__name__
61 61 except AttributeError:
62 62 classname = 'Other'
63 63
64 64 d[name] = classname
65 65 return magic_dict
66 66
67 67 def _repr_json_(self):
68 68 return self._jsonable()
69 69
70 70
71 71 @magics_class
72 72 class BasicMagics(Magics):
73 73 """Magics that provide central IPython functionality.
74 74
75 75 These are various magics that don't fit into specific categories but that
76 76 are all part of the base 'IPython experience'."""
77 77
78 78 @magic_arguments.magic_arguments()
79 79 @magic_arguments.argument(
80 80 '-l', '--line', action='store_true',
81 81 help="""Create a line magic alias."""
82 82 )
83 83 @magic_arguments.argument(
84 84 '-c', '--cell', action='store_true',
85 85 help="""Create a cell magic alias."""
86 86 )
87 87 @magic_arguments.argument(
88 88 'name',
89 89 help="""Name of the magic to be created."""
90 90 )
91 91 @magic_arguments.argument(
92 92 'target',
93 93 help="""Name of the existing line or cell magic."""
94 94 )
95 95 @line_magic
96 96 def alias_magic(self, line=''):
97 97 """Create an alias for an existing line or cell magic.
98 98
99 99 Examples
100 100 --------
101 101 ::
102 102
103 103 In [1]: %alias_magic t timeit
104 104 Created `%t` as an alias for `%timeit`.
105 105 Created `%%t` as an alias for `%%timeit`.
106 106
107 107 In [2]: %t -n1 pass
108 108 1 loops, best of 3: 954 ns per loop
109 109
110 110 In [3]: %%t -n1
111 111 ...: pass
112 112 ...:
113 113 1 loops, best of 3: 954 ns per loop
114 114
115 115 In [4]: %alias_magic --cell whereami pwd
116 116 UsageError: Cell magic function `%%pwd` not found.
117 117 In [5]: %alias_magic --line whereami pwd
118 118 Created `%whereami` as an alias for `%pwd`.
119 119
120 120 In [6]: %whereami
121 121 Out[6]: u'/home/testuser'
122 122 """
123 123 args = magic_arguments.parse_argstring(self.alias_magic, line)
124 124 shell = self.shell
125 125 mman = self.shell.magics_manager
126 126 escs = ''.join(magic_escapes.values())
127 127
128 128 target = args.target.lstrip(escs)
129 129 name = args.name.lstrip(escs)
130 130
131 131 # Find the requested magics.
132 132 m_line = shell.find_magic(target, 'line')
133 133 m_cell = shell.find_magic(target, 'cell')
134 134 if args.line and m_line is None:
135 135 raise UsageError('Line magic function `%s%s` not found.' %
136 136 (magic_escapes['line'], target))
137 137 if args.cell and m_cell is None:
138 138 raise UsageError('Cell magic function `%s%s` not found.' %
139 139 (magic_escapes['cell'], target))
140 140
141 141 # If --line and --cell are not specified, default to the ones
142 142 # that are available.
143 143 if not args.line and not args.cell:
144 144 if not m_line and not m_cell:
145 145 raise UsageError(
146 146 'No line or cell magic with name `%s` found.' % target
147 147 )
148 148 args.line = bool(m_line)
149 149 args.cell = bool(m_cell)
150 150
151 151 if args.line:
152 152 mman.register_alias(name, target, 'line')
153 153 print('Created `%s%s` as an alias for `%s%s`.' % (
154 154 magic_escapes['line'], name,
155 155 magic_escapes['line'], target))
156 156
157 157 if args.cell:
158 158 mman.register_alias(name, target, 'cell')
159 159 print('Created `%s%s` as an alias for `%s%s`.' % (
160 160 magic_escapes['cell'], name,
161 161 magic_escapes['cell'], target))
162 162
163 163 @line_magic
164 164 def lsmagic(self, parameter_s=''):
165 165 """List currently available magic functions."""
166 166 return MagicsDisplay(self.shell.magics_manager)
167 167
168 168 def _magic_docs(self, brief=False, rest=False):
169 169 """Return docstrings from magic functions."""
170 170 mman = self.shell.magics_manager
171 171 docs = mman.lsmagic_docs(brief, missing='No documentation')
172 172
173 173 if rest:
174 174 format_string = '**%s%s**::\n\n%s\n\n'
175 175 else:
176 176 format_string = '%s%s:\n%s\n'
177 177
178 178 return ''.join(
179 179 [format_string % (magic_escapes['line'], fname,
180 180 indent(dedent(fndoc)))
181 181 for fname, fndoc in sorted(docs['line'].items())]
182 182 +
183 183 [format_string % (magic_escapes['cell'], fname,
184 184 indent(dedent(fndoc)))
185 185 for fname, fndoc in sorted(docs['cell'].items())]
186 186 )
187 187
188 188 @line_magic
189 189 def magic(self, parameter_s=''):
190 190 """Print information about the magic function system.
191 191
192 192 Supported formats: -latex, -brief, -rest
193 193 """
194 194
195 195 mode = ''
196 196 try:
197 197 mode = parameter_s.split()[0][1:]
198 198 except IndexError:
199 199 pass
200 200
201 201 brief = (mode == 'brief')
202 202 rest = (mode == 'rest')
203 203 magic_docs = self._magic_docs(brief, rest)
204 204
205 205 if mode == 'latex':
206 206 print(self.format_latex(magic_docs))
207 207 return
208 208 else:
209 209 magic_docs = format_screen(magic_docs)
210 210
211 211 out = ["""
212 212 IPython's 'magic' functions
213 213 ===========================
214 214
215 215 The magic function system provides a series of functions which allow you to
216 216 control the behavior of IPython itself, plus a lot of system-type
217 217 features. There are two kinds of magics, line-oriented and cell-oriented.
218 218
219 219 Line magics are prefixed with the % character and work much like OS
220 220 command-line calls: they get as an argument the rest of the line, where
221 221 arguments are passed without parentheses or quotes. For example, this will
222 222 time the given statement::
223 223
224 224 %timeit range(1000)
225 225
226 226 Cell magics are prefixed with a double %%, and they are functions that get as
227 227 an argument not only the rest of the line, but also the lines below it in a
228 228 separate argument. These magics are called with two arguments: the rest of the
229 229 call line and the body of the cell, consisting of the lines below the first.
230 230 For example::
231 231
232 232 %%timeit x = numpy.random.randn((100, 100))
233 233 numpy.linalg.svd(x)
234 234
235 235 will time the execution of the numpy svd routine, running the assignment of x
236 236 as part of the setup phase, which is not timed.
237 237
238 238 In a line-oriented client (the terminal or Qt console IPython), starting a new
239 239 input with %% will automatically enter cell mode, and IPython will continue
240 240 reading input until a blank line is given. In the notebook, simply type the
241 241 whole cell as one entity, but keep in mind that the %% escape can only be at
242 242 the very start of the cell.
243 243
244 244 NOTE: If you have 'automagic' enabled (via the command line option or with the
245 245 %automagic function), you don't need to type in the % explicitly for line
246 246 magics; cell magics always require an explicit '%%' escape. By default,
247 247 IPython ships with automagic on, so you should only rarely need the % escape.
248 248
249 249 Example: typing '%cd mydir' (without the quotes) changes your working directory
250 250 to 'mydir', if it exists.
251 251
252 252 For a list of the available magic functions, use %lsmagic. For a description
253 253 of any of them, type %magic_name?, e.g. '%cd?'.
254 254
255 255 Currently the magic system has the following functions:""",
256 256 magic_docs,
257 257 "Summary of magic functions (from %slsmagic):" % magic_escapes['line'],
258 258 str(self.lsmagic()),
259 259 ]
260 260 page.page('\n'.join(out))
261 261
262 262
263 263 @line_magic
264 264 def page(self, parameter_s=''):
265 265 """Pretty print the object and display it through a pager.
266 266
267 267 %page [options] OBJECT
268 268
269 269 If no object is given, use _ (last output).
270 270
271 271 Options:
272 272
273 273 -r: page str(object), don't pretty-print it."""
274 274
275 275 # After a function contributed by Olivier Aubert, slightly modified.
276 276
277 277 # Process options/args
278 278 opts, args = self.parse_options(parameter_s, 'r')
279 279 raw = 'r' in opts
280 280
281 281 oname = args and args or '_'
282 282 info = self.shell._ofind(oname)
283 283 if info['found']:
284 284 txt = (raw and str or pformat)( info['obj'] )
285 285 page.page(txt)
286 286 else:
287 287 print('Object `%s` not found' % oname)
288 288
289 289 @line_magic
290 290 def profile(self, parameter_s=''):
291 """Print your currently active IPython profile.
291 """DEPRECATED since IPython 2.0.
292
293 Raise `UsageError`. To profile code use the :magic:`prun` magic.
294
292 295
293 296 See Also
294 297 --------
295 prun : run code using the Python profiler
296 (:meth:`~IPython.core.magics.execution.ExecutionMagics.prun`)
298 prun : run code using the Python profiler (:magic:`prun`)
297 299 """
298 300 warn("%profile is now deprecated. Please use get_ipython().profile instead.")
299 301 from IPython.core.application import BaseIPythonApplication
300 302 if BaseIPythonApplication.initialized():
301 303 print(BaseIPythonApplication.instance().profile)
302 304 else:
303 305 error("profile is an application-level value, but you don't appear to be in an IPython application")
304 306
305 307 @line_magic
306 308 def pprint(self, parameter_s=''):
307 309 """Toggle pretty printing on/off."""
308 310 ptformatter = self.shell.display_formatter.formatters['text/plain']
309 311 ptformatter.pprint = bool(1 - ptformatter.pprint)
310 312 print('Pretty printing has been turned',
311 313 ['OFF','ON'][ptformatter.pprint])
312 314
313 315 @line_magic
314 316 def colors(self, parameter_s=''):
315 317 """Switch color scheme for prompts, info system and exception handlers.
316 318
317 319 Currently implemented schemes: NoColor, Linux, LightBG.
318 320
319 321 Color scheme names are not case-sensitive.
320 322
321 323 Examples
322 324 --------
323 325 To get a plain black and white terminal::
324 326
325 327 %colors nocolor
326 328 """
327 329 def color_switch_err(name):
328 330 warn('Error changing %s color schemes.\n%s' %
329 331 (name, sys.exc_info()[1]), stacklevel=2)
330 332
331 333
332 334 new_scheme = parameter_s.strip()
333 335 if not new_scheme:
334 336 raise UsageError(
335 337 "%colors: you must specify a color scheme. See '%colors?'")
336 338 # local shortcut
337 339 shell = self.shell
338 340
339 341 # Set shell colour scheme
340 342 try:
341 343 shell.colors = new_scheme
342 344 shell.refresh_style()
343 345 except:
344 346 color_switch_err('shell')
345 347
346 348 # Set exception colors
347 349 try:
348 350 shell.InteractiveTB.set_colors(scheme = new_scheme)
349 351 shell.SyntaxTB.set_colors(scheme = new_scheme)
350 352 except:
351 353 color_switch_err('exception')
352 354
353 355 # Set info (for 'object?') colors
354 356 if shell.color_info:
355 357 try:
356 358 shell.inspector.set_active_scheme(new_scheme)
357 359 except:
358 360 color_switch_err('object inspector')
359 361 else:
360 362 shell.inspector.set_active_scheme('NoColor')
361 363
362 364 @line_magic
363 365 def xmode(self, parameter_s=''):
364 366 """Switch modes for the exception handlers.
365 367
366 368 Valid modes: Plain, Context and Verbose.
367 369
368 370 If called without arguments, acts as a toggle."""
369 371
370 372 def xmode_switch_err(name):
371 373 warn('Error changing %s exception modes.\n%s' %
372 374 (name,sys.exc_info()[1]))
373 375
374 376 shell = self.shell
375 377 new_mode = parameter_s.strip().capitalize()
376 378 try:
377 379 shell.InteractiveTB.set_mode(mode=new_mode)
378 380 print('Exception reporting mode:',shell.InteractiveTB.mode)
379 381 except:
380 382 xmode_switch_err('user')
381 383
382 384 @line_magic
383 385 def quickref(self,arg):
384 386 """ Show a quick reference sheet """
385 387 from IPython.core.usage import quick_reference
386 388 qr = quick_reference + self._magic_docs(brief=True)
387 389 page.page(qr)
388 390
389 391 @line_magic
390 392 def doctest_mode(self, parameter_s=''):
391 393 """Toggle doctest mode on and off.
392 394
393 395 This mode is intended to make IPython behave as much as possible like a
394 396 plain Python shell, from the perspective of how its prompts, exceptions
395 397 and output look. This makes it easy to copy and paste parts of a
396 398 session into doctests. It does so by:
397 399
398 400 - Changing the prompts to the classic ``>>>`` ones.
399 401 - Changing the exception reporting mode to 'Plain'.
400 402 - Disabling pretty-printing of output.
401 403
402 404 Note that IPython also supports the pasting of code snippets that have
403 405 leading '>>>' and '...' prompts in them. This means that you can paste
404 406 doctests from files or docstrings (even if they have leading
405 407 whitespace), and the code will execute correctly. You can then use
406 408 '%history -t' to see the translated history; this will give you the
407 409 input after removal of all the leading prompts and whitespace, which
408 410 can be pasted back into an editor.
409 411
410 412 With these features, you can switch into this mode easily whenever you
411 413 need to do testing and changes to doctests, without having to leave
412 414 your existing IPython session.
413 415 """
414 416
415 417 # Shorthands
416 418 shell = self.shell
417 419 meta = shell.meta
418 420 disp_formatter = self.shell.display_formatter
419 421 ptformatter = disp_formatter.formatters['text/plain']
420 422 # dstore is a data store kept in the instance metadata bag to track any
421 423 # changes we make, so we can undo them later.
422 424 dstore = meta.setdefault('doctest_mode',Struct())
423 425 save_dstore = dstore.setdefault
424 426
425 427 # save a few values we'll need to recover later
426 428 mode = save_dstore('mode',False)
427 429 save_dstore('rc_pprint',ptformatter.pprint)
428 430 save_dstore('xmode',shell.InteractiveTB.mode)
429 431 save_dstore('rc_separate_out',shell.separate_out)
430 432 save_dstore('rc_separate_out2',shell.separate_out2)
431 433 save_dstore('rc_separate_in',shell.separate_in)
432 434 save_dstore('rc_active_types',disp_formatter.active_types)
433 435
434 436 if not mode:
435 437 # turn on
436 438
437 439 # Prompt separators like plain python
438 440 shell.separate_in = ''
439 441 shell.separate_out = ''
440 442 shell.separate_out2 = ''
441 443
442 444
443 445 ptformatter.pprint = False
444 446 disp_formatter.active_types = ['text/plain']
445 447
446 448 shell.magic('xmode Plain')
447 449 else:
448 450 # turn off
449 451 shell.separate_in = dstore.rc_separate_in
450 452
451 453 shell.separate_out = dstore.rc_separate_out
452 454 shell.separate_out2 = dstore.rc_separate_out2
453 455
454 456 ptformatter.pprint = dstore.rc_pprint
455 457 disp_formatter.active_types = dstore.rc_active_types
456 458
457 459 shell.magic('xmode ' + dstore.xmode)
458 460
459 461 # mode here is the state before we switch; switch_doctest_mode takes
460 462 # the mode we're switching to.
461 463 shell.switch_doctest_mode(not mode)
462 464
463 465 # Store new mode and inform
464 466 dstore.mode = bool(not mode)
465 467 mode_label = ['OFF','ON'][dstore.mode]
466 468 print('Doctest mode is:', mode_label)
467 469
468 470 @line_magic
469 471 def gui(self, parameter_s=''):
470 472 """Enable or disable IPython GUI event loop integration.
471 473
472 474 %gui [GUINAME]
473 475
474 476 This magic replaces IPython's threaded shells that were activated
475 477 using the (pylab/wthread/etc.) command line flags. GUI toolkits
476 478 can now be enabled at runtime and keyboard
477 479 interrupts should work without any problems. The following toolkits
478 480 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
479 481
480 482 %gui wx # enable wxPython event loop integration
481 483 %gui qt4|qt # enable PyQt4 event loop integration
482 484 %gui qt5 # enable PyQt5 event loop integration
483 485 %gui gtk # enable PyGTK event loop integration
484 486 %gui gtk3 # enable Gtk3 event loop integration
485 487 %gui tk # enable Tk event loop integration
486 488 %gui osx # enable Cocoa event loop integration
487 489 # (requires %matplotlib 1.1)
488 490 %gui # disable all event loop integration
489 491
490 492 WARNING: after any of these has been called you can simply create
491 493 an application object, but DO NOT start the event loop yourself, as
492 494 we have already handled that.
493 495 """
494 496 opts, arg = self.parse_options(parameter_s, '')
495 497 if arg=='': arg = None
496 498 try:
497 499 return self.shell.enable_gui(arg)
498 500 except Exception as e:
499 501 # print simple error message, rather than traceback if we can't
500 502 # hook up the GUI
501 503 error(str(e))
502 504
503 505 @skip_doctest
504 506 @line_magic
505 507 def precision(self, s=''):
506 508 """Set floating point precision for pretty printing.
507 509
508 510 Can set either integer precision or a format string.
509 511
510 512 If numpy has been imported and precision is an int,
511 513 numpy display precision will also be set, via ``numpy.set_printoptions``.
512 514
513 515 If no argument is given, defaults will be restored.
514 516
515 517 Examples
516 518 --------
517 519 ::
518 520
519 521 In [1]: from math import pi
520 522
521 523 In [2]: %precision 3
522 524 Out[2]: u'%.3f'
523 525
524 526 In [3]: pi
525 527 Out[3]: 3.142
526 528
527 529 In [4]: %precision %i
528 530 Out[4]: u'%i'
529 531
530 532 In [5]: pi
531 533 Out[5]: 3
532 534
533 535 In [6]: %precision %e
534 536 Out[6]: u'%e'
535 537
536 538 In [7]: pi**10
537 539 Out[7]: 9.364805e+04
538 540
539 541 In [8]: %precision
540 542 Out[8]: u'%r'
541 543
542 544 In [9]: pi**10
543 545 Out[9]: 93648.047476082982
544 546 """
545 547 ptformatter = self.shell.display_formatter.formatters['text/plain']
546 548 ptformatter.float_precision = s
547 549 return ptformatter.float_format
548 550
549 551 @magic_arguments.magic_arguments()
550 552 @magic_arguments.argument(
551 553 '-e', '--export', action='store_true', default=False,
552 554 help=argparse.SUPPRESS
553 555 )
554 556 @magic_arguments.argument(
555 557 'filename', type=unicode_type,
556 558 help='Notebook name or filename'
557 559 )
558 560 @line_magic
559 561 def notebook(self, s):
560 562 """Export and convert IPython notebooks.
561 563
562 564 This function can export the current IPython history to a notebook file.
563 565 For example, to export the history to "foo.ipynb" do "%notebook foo.ipynb".
564 566
565 567 The -e or --export flag is deprecated in IPython 5.2, and will be
566 568 removed in the future.
567 569 """
568 570 args = magic_arguments.parse_argstring(self.notebook, s)
569 571
570 572 from nbformat import write, v4
571 573
572 574 cells = []
573 575 hist = list(self.shell.history_manager.get_range())
574 576 if(len(hist)<=1):
575 577 raise ValueError('History is empty, cannot export')
576 578 for session, execution_count, source in hist[:-1]:
577 579 cells.append(v4.new_code_cell(
578 580 execution_count=execution_count,
579 581 source=source
580 582 ))
581 583 nb = v4.new_notebook(cells=cells)
582 584 with io.open(args.filename, 'w', encoding='utf-8') as f:
583 585 write(nb, f, version=4)
General Comments 0
You need to be logged in to leave comments. Login now