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