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