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