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