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