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