##// END OF EJS Templates
Notebook magic used old terminology "input"...
Matthias Bussonnier -
Show More
@@ -1,613 +1,613 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
4
5 import io
5 import io
6 import json
6 import json
7 import sys
7 import sys
8 from pprint import pformat
8 from pprint import pformat
9
9
10 from IPython.core import magic_arguments, page
10 from IPython.core import magic_arguments, page
11 from IPython.core.error import UsageError
11 from IPython.core.error import UsageError
12 from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
12 from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
13 from IPython.utils.text import format_screen, dedent, indent
13 from IPython.utils.text import format_screen, dedent, indent
14 from IPython.testing.skipdoctest import skip_doctest
14 from IPython.testing.skipdoctest import skip_doctest
15 from IPython.utils.ipstruct import Struct
15 from IPython.utils.ipstruct import Struct
16 from IPython.utils.path import unquote_filename
16 from IPython.utils.path import unquote_filename
17 from IPython.utils.py3compat import unicode_type
17 from IPython.utils.py3compat import unicode_type
18 from IPython.utils.warn import warn, error
18 from IPython.utils.warn import warn, error
19
19
20
20
21 class MagicsDisplay(object):
21 class MagicsDisplay(object):
22 def __init__(self, magics_manager):
22 def __init__(self, magics_manager):
23 self.magics_manager = magics_manager
23 self.magics_manager = magics_manager
24
24
25 def _lsmagic(self):
25 def _lsmagic(self):
26 """The main implementation of the %lsmagic"""
26 """The main implementation of the %lsmagic"""
27 mesc = magic_escapes['line']
27 mesc = magic_escapes['line']
28 cesc = magic_escapes['cell']
28 cesc = magic_escapes['cell']
29 mman = self.magics_manager
29 mman = self.magics_manager
30 magics = mman.lsmagic()
30 magics = mman.lsmagic()
31 out = ['Available line magics:',
31 out = ['Available line magics:',
32 mesc + (' '+mesc).join(sorted(magics['line'])),
32 mesc + (' '+mesc).join(sorted(magics['line'])),
33 '',
33 '',
34 'Available cell magics:',
34 'Available cell magics:',
35 cesc + (' '+cesc).join(sorted(magics['cell'])),
35 cesc + (' '+cesc).join(sorted(magics['cell'])),
36 '',
36 '',
37 mman.auto_status()]
37 mman.auto_status()]
38 return '\n'.join(out)
38 return '\n'.join(out)
39
39
40 def _repr_pretty_(self, p, cycle):
40 def _repr_pretty_(self, p, cycle):
41 p.text(self._lsmagic())
41 p.text(self._lsmagic())
42
42
43 def __str__(self):
43 def __str__(self):
44 return self._lsmagic()
44 return self._lsmagic()
45
45
46 def _jsonable(self):
46 def _jsonable(self):
47 """turn magics dict into jsonable dict of the same structure
47 """turn magics dict into jsonable dict of the same structure
48
48
49 replaces object instances with their class names as strings
49 replaces object instances with their class names as strings
50 """
50 """
51 magic_dict = {}
51 magic_dict = {}
52 mman = self.magics_manager
52 mman = self.magics_manager
53 magics = mman.lsmagic()
53 magics = mman.lsmagic()
54 for key, subdict in magics.items():
54 for key, subdict in magics.items():
55 d = {}
55 d = {}
56 magic_dict[key] = d
56 magic_dict[key] = d
57 for name, obj in subdict.items():
57 for name, obj in subdict.items():
58 try:
58 try:
59 classname = obj.__self__.__class__.__name__
59 classname = obj.__self__.__class__.__name__
60 except AttributeError:
60 except AttributeError:
61 classname = 'Other'
61 classname = 'Other'
62
62
63 d[name] = classname
63 d[name] = classname
64 return magic_dict
64 return magic_dict
65
65
66 def _repr_json_(self):
66 def _repr_json_(self):
67 return self._jsonable()
67 return self._jsonable()
68
68
69
69
70 @magics_class
70 @magics_class
71 class BasicMagics(Magics):
71 class BasicMagics(Magics):
72 """Magics that provide central IPython functionality.
72 """Magics that provide central IPython functionality.
73
73
74 These are various magics that don't fit into specific categories but that
74 These are various magics that don't fit into specific categories but that
75 are all part of the base 'IPython experience'."""
75 are all part of the base 'IPython experience'."""
76
76
77 @magic_arguments.magic_arguments()
77 @magic_arguments.magic_arguments()
78 @magic_arguments.argument(
78 @magic_arguments.argument(
79 '-l', '--line', action='store_true',
79 '-l', '--line', action='store_true',
80 help="""Create a line magic alias."""
80 help="""Create a line magic alias."""
81 )
81 )
82 @magic_arguments.argument(
82 @magic_arguments.argument(
83 '-c', '--cell', action='store_true',
83 '-c', '--cell', action='store_true',
84 help="""Create a cell magic alias."""
84 help="""Create a cell magic alias."""
85 )
85 )
86 @magic_arguments.argument(
86 @magic_arguments.argument(
87 'name',
87 'name',
88 help="""Name of the magic to be created."""
88 help="""Name of the magic to be created."""
89 )
89 )
90 @magic_arguments.argument(
90 @magic_arguments.argument(
91 'target',
91 'target',
92 help="""Name of the existing line or cell magic."""
92 help="""Name of the existing line or cell magic."""
93 )
93 )
94 @line_magic
94 @line_magic
95 def alias_magic(self, line=''):
95 def alias_magic(self, line=''):
96 """Create an alias for an existing line or cell magic.
96 """Create an alias for an existing line or cell magic.
97
97
98 Examples
98 Examples
99 --------
99 --------
100 ::
100 ::
101
101
102 In [1]: %alias_magic t timeit
102 In [1]: %alias_magic t timeit
103 Created `%t` as an alias for `%timeit`.
103 Created `%t` as an alias for `%timeit`.
104 Created `%%t` as an alias for `%%timeit`.
104 Created `%%t` as an alias for `%%timeit`.
105
105
106 In [2]: %t -n1 pass
106 In [2]: %t -n1 pass
107 1 loops, best of 3: 954 ns per loop
107 1 loops, best of 3: 954 ns per loop
108
108
109 In [3]: %%t -n1
109 In [3]: %%t -n1
110 ...: pass
110 ...: pass
111 ...:
111 ...:
112 1 loops, best of 3: 954 ns per loop
112 1 loops, best of 3: 954 ns per loop
113
113
114 In [4]: %alias_magic --cell whereami pwd
114 In [4]: %alias_magic --cell whereami pwd
115 UsageError: Cell magic function `%%pwd` not found.
115 UsageError: Cell magic function `%%pwd` not found.
116 In [5]: %alias_magic --line whereami pwd
116 In [5]: %alias_magic --line whereami pwd
117 Created `%whereami` as an alias for `%pwd`.
117 Created `%whereami` as an alias for `%pwd`.
118
118
119 In [6]: %whereami
119 In [6]: %whereami
120 Out[6]: u'/home/testuser'
120 Out[6]: u'/home/testuser'
121 """
121 """
122 args = magic_arguments.parse_argstring(self.alias_magic, line)
122 args = magic_arguments.parse_argstring(self.alias_magic, line)
123 shell = self.shell
123 shell = self.shell
124 mman = self.shell.magics_manager
124 mman = self.shell.magics_manager
125 escs = ''.join(magic_escapes.values())
125 escs = ''.join(magic_escapes.values())
126
126
127 target = args.target.lstrip(escs)
127 target = args.target.lstrip(escs)
128 name = args.name.lstrip(escs)
128 name = args.name.lstrip(escs)
129
129
130 # Find the requested magics.
130 # Find the requested magics.
131 m_line = shell.find_magic(target, 'line')
131 m_line = shell.find_magic(target, 'line')
132 m_cell = shell.find_magic(target, 'cell')
132 m_cell = shell.find_magic(target, 'cell')
133 if args.line and m_line is None:
133 if args.line and m_line is None:
134 raise UsageError('Line magic function `%s%s` not found.' %
134 raise UsageError('Line magic function `%s%s` not found.' %
135 (magic_escapes['line'], target))
135 (magic_escapes['line'], target))
136 if args.cell and m_cell is None:
136 if args.cell and m_cell is None:
137 raise UsageError('Cell magic function `%s%s` not found.' %
137 raise UsageError('Cell magic function `%s%s` not found.' %
138 (magic_escapes['cell'], target))
138 (magic_escapes['cell'], target))
139
139
140 # If --line and --cell are not specified, default to the ones
140 # If --line and --cell are not specified, default to the ones
141 # that are available.
141 # that are available.
142 if not args.line and not args.cell:
142 if not args.line and not args.cell:
143 if not m_line and not m_cell:
143 if not m_line and not m_cell:
144 raise UsageError(
144 raise UsageError(
145 'No line or cell magic with name `%s` found.' % target
145 'No line or cell magic with name `%s` found.' % target
146 )
146 )
147 args.line = bool(m_line)
147 args.line = bool(m_line)
148 args.cell = bool(m_cell)
148 args.cell = bool(m_cell)
149
149
150 if args.line:
150 if args.line:
151 mman.register_alias(name, target, 'line')
151 mman.register_alias(name, target, 'line')
152 print('Created `%s%s` as an alias for `%s%s`.' % (
152 print('Created `%s%s` as an alias for `%s%s`.' % (
153 magic_escapes['line'], name,
153 magic_escapes['line'], name,
154 magic_escapes['line'], target))
154 magic_escapes['line'], target))
155
155
156 if args.cell:
156 if args.cell:
157 mman.register_alias(name, target, 'cell')
157 mman.register_alias(name, target, 'cell')
158 print('Created `%s%s` as an alias for `%s%s`.' % (
158 print('Created `%s%s` as an alias for `%s%s`.' % (
159 magic_escapes['cell'], name,
159 magic_escapes['cell'], name,
160 magic_escapes['cell'], target))
160 magic_escapes['cell'], target))
161
161
162 @line_magic
162 @line_magic
163 def lsmagic(self, parameter_s=''):
163 def lsmagic(self, parameter_s=''):
164 """List currently available magic functions."""
164 """List currently available magic functions."""
165 return MagicsDisplay(self.shell.magics_manager)
165 return MagicsDisplay(self.shell.magics_manager)
166
166
167 def _magic_docs(self, brief=False, rest=False):
167 def _magic_docs(self, brief=False, rest=False):
168 """Return docstrings from magic functions."""
168 """Return docstrings from magic functions."""
169 mman = self.shell.magics_manager
169 mman = self.shell.magics_manager
170 docs = mman.lsmagic_docs(brief, missing='No documentation')
170 docs = mman.lsmagic_docs(brief, missing='No documentation')
171
171
172 if rest:
172 if rest:
173 format_string = '**%s%s**::\n\n%s\n\n'
173 format_string = '**%s%s**::\n\n%s\n\n'
174 else:
174 else:
175 format_string = '%s%s:\n%s\n'
175 format_string = '%s%s:\n%s\n'
176
176
177 return ''.join(
177 return ''.join(
178 [format_string % (magic_escapes['line'], fname,
178 [format_string % (magic_escapes['line'], fname,
179 indent(dedent(fndoc)))
179 indent(dedent(fndoc)))
180 for fname, fndoc in sorted(docs['line'].items())]
180 for fname, fndoc in sorted(docs['line'].items())]
181 +
181 +
182 [format_string % (magic_escapes['cell'], fname,
182 [format_string % (magic_escapes['cell'], fname,
183 indent(dedent(fndoc)))
183 indent(dedent(fndoc)))
184 for fname, fndoc in sorted(docs['cell'].items())]
184 for fname, fndoc in sorted(docs['cell'].items())]
185 )
185 )
186
186
187 @line_magic
187 @line_magic
188 def magic(self, parameter_s=''):
188 def magic(self, parameter_s=''):
189 """Print information about the magic function system.
189 """Print information about the magic function system.
190
190
191 Supported formats: -latex, -brief, -rest
191 Supported formats: -latex, -brief, -rest
192 """
192 """
193
193
194 mode = ''
194 mode = ''
195 try:
195 try:
196 mode = parameter_s.split()[0][1:]
196 mode = parameter_s.split()[0][1:]
197 if mode == 'rest':
197 if mode == 'rest':
198 rest_docs = []
198 rest_docs = []
199 except IndexError:
199 except IndexError:
200 pass
200 pass
201
201
202 brief = (mode == 'brief')
202 brief = (mode == 'brief')
203 rest = (mode == 'rest')
203 rest = (mode == 'rest')
204 magic_docs = self._magic_docs(brief, rest)
204 magic_docs = self._magic_docs(brief, rest)
205
205
206 if mode == 'latex':
206 if mode == 'latex':
207 print(self.format_latex(magic_docs))
207 print(self.format_latex(magic_docs))
208 return
208 return
209 else:
209 else:
210 magic_docs = format_screen(magic_docs)
210 magic_docs = format_screen(magic_docs)
211
211
212 out = ["""
212 out = ["""
213 IPython's 'magic' functions
213 IPython's 'magic' functions
214 ===========================
214 ===========================
215
215
216 The magic function system provides a series of functions which allow you to
216 The magic function system provides a series of functions which allow you to
217 control the behavior of IPython itself, plus a lot of system-type
217 control the behavior of IPython itself, plus a lot of system-type
218 features. There are two kinds of magics, line-oriented and cell-oriented.
218 features. There are two kinds of magics, line-oriented and cell-oriented.
219
219
220 Line magics are prefixed with the % character and work much like OS
220 Line magics are prefixed with the % character and work much like OS
221 command-line calls: they get as an argument the rest of the line, where
221 command-line calls: they get as an argument the rest of the line, where
222 arguments are passed without parentheses or quotes. For example, this will
222 arguments are passed without parentheses or quotes. For example, this will
223 time the given statement::
223 time the given statement::
224
224
225 %timeit range(1000)
225 %timeit range(1000)
226
226
227 Cell magics are prefixed with a double %%, and they are functions that get as
227 Cell magics are prefixed with a double %%, and they are functions that get as
228 an argument not only the rest of the line, but also the lines below it in a
228 an argument not only the rest of the line, but also the lines below it in a
229 separate argument. These magics are called with two arguments: the rest of the
229 separate argument. These magics are called with two arguments: the rest of the
230 call line and the body of the cell, consisting of the lines below the first.
230 call line and the body of the cell, consisting of the lines below the first.
231 For example::
231 For example::
232
232
233 %%timeit x = numpy.random.randn((100, 100))
233 %%timeit x = numpy.random.randn((100, 100))
234 numpy.linalg.svd(x)
234 numpy.linalg.svd(x)
235
235
236 will time the execution of the numpy svd routine, running the assignment of x
236 will time the execution of the numpy svd routine, running the assignment of x
237 as part of the setup phase, which is not timed.
237 as part of the setup phase, which is not timed.
238
238
239 In a line-oriented client (the terminal or Qt console IPython), starting a new
239 In a line-oriented client (the terminal or Qt console IPython), starting a new
240 input with %% will automatically enter cell mode, and IPython will continue
240 input with %% will automatically enter cell mode, and IPython will continue
241 reading input until a blank line is given. In the notebook, simply type the
241 reading input until a blank line is given. In the notebook, simply type the
242 whole cell as one entity, but keep in mind that the %% escape can only be at
242 whole cell as one entity, but keep in mind that the %% escape can only be at
243 the very start of the cell.
243 the very start of the cell.
244
244
245 NOTE: If you have 'automagic' enabled (via the command line option or with the
245 NOTE: If you have 'automagic' enabled (via the command line option or with the
246 %automagic function), you don't need to type in the % explicitly for line
246 %automagic function), you don't need to type in the % explicitly for line
247 magics; cell magics always require an explicit '%%' escape. By default,
247 magics; cell magics always require an explicit '%%' escape. By default,
248 IPython ships with automagic on, so you should only rarely need the % escape.
248 IPython ships with automagic on, so you should only rarely need the % escape.
249
249
250 Example: typing '%cd mydir' (without the quotes) changes you working directory
250 Example: typing '%cd mydir' (without the quotes) changes you working directory
251 to 'mydir', if it exists.
251 to 'mydir', if it exists.
252
252
253 For a list of the available magic functions, use %lsmagic. For a description
253 For a list of the available magic functions, use %lsmagic. For a description
254 of any of them, type %magic_name?, e.g. '%cd?'.
254 of any of them, type %magic_name?, e.g. '%cd?'.
255
255
256 Currently the magic system has the following functions:""",
256 Currently the magic system has the following functions:""",
257 magic_docs,
257 magic_docs,
258 "Summary of magic functions (from %slsmagic):" % magic_escapes['line'],
258 "Summary of magic functions (from %slsmagic):" % magic_escapes['line'],
259 str(self.lsmagic()),
259 str(self.lsmagic()),
260 ]
260 ]
261 page.page('\n'.join(out))
261 page.page('\n'.join(out))
262
262
263
263
264 @line_magic
264 @line_magic
265 def page(self, parameter_s=''):
265 def page(self, parameter_s=''):
266 """Pretty print the object and display it through a pager.
266 """Pretty print the object and display it through a pager.
267
267
268 %page [options] OBJECT
268 %page [options] OBJECT
269
269
270 If no object is given, use _ (last output).
270 If no object is given, use _ (last output).
271
271
272 Options:
272 Options:
273
273
274 -r: page str(object), don't pretty-print it."""
274 -r: page str(object), don't pretty-print it."""
275
275
276 # After a function contributed by Olivier Aubert, slightly modified.
276 # After a function contributed by Olivier Aubert, slightly modified.
277
277
278 # Process options/args
278 # Process options/args
279 opts, args = self.parse_options(parameter_s, 'r')
279 opts, args = self.parse_options(parameter_s, 'r')
280 raw = 'r' in opts
280 raw = 'r' in opts
281
281
282 oname = args and args or '_'
282 oname = args and args or '_'
283 info = self.shell._ofind(oname)
283 info = self.shell._ofind(oname)
284 if info['found']:
284 if info['found']:
285 txt = (raw and str or pformat)( info['obj'] )
285 txt = (raw and str or pformat)( info['obj'] )
286 page.page(txt)
286 page.page(txt)
287 else:
287 else:
288 print('Object `%s` not found' % oname)
288 print('Object `%s` not found' % oname)
289
289
290 @line_magic
290 @line_magic
291 def profile(self, parameter_s=''):
291 def profile(self, parameter_s=''):
292 """Print your currently active IPython profile.
292 """Print your currently active IPython profile.
293
293
294 See Also
294 See Also
295 --------
295 --------
296 prun : run code using the Python profiler
296 prun : run code using the Python profiler
297 (:meth:`~IPython.core.magics.execution.ExecutionMagics.prun`)
297 (:meth:`~IPython.core.magics.execution.ExecutionMagics.prun`)
298 """
298 """
299 warn("%profile is now deprecated. Please use get_ipython().profile instead.")
299 warn("%profile is now deprecated. Please use get_ipython().profile instead.")
300 from IPython.core.application import BaseIPythonApplication
300 from IPython.core.application import BaseIPythonApplication
301 if BaseIPythonApplication.initialized():
301 if BaseIPythonApplication.initialized():
302 print(BaseIPythonApplication.instance().profile)
302 print(BaseIPythonApplication.instance().profile)
303 else:
303 else:
304 error("profile is an application-level value, but you don't appear to be in an IPython application")
304 error("profile is an application-level value, but you don't appear to be in an IPython application")
305
305
306 @line_magic
306 @line_magic
307 def pprint(self, parameter_s=''):
307 def pprint(self, parameter_s=''):
308 """Toggle pretty printing on/off."""
308 """Toggle pretty printing on/off."""
309 ptformatter = self.shell.display_formatter.formatters['text/plain']
309 ptformatter = self.shell.display_formatter.formatters['text/plain']
310 ptformatter.pprint = bool(1 - ptformatter.pprint)
310 ptformatter.pprint = bool(1 - ptformatter.pprint)
311 print('Pretty printing has been turned',
311 print('Pretty printing has been turned',
312 ['OFF','ON'][ptformatter.pprint])
312 ['OFF','ON'][ptformatter.pprint])
313
313
314 @line_magic
314 @line_magic
315 def colors(self, parameter_s=''):
315 def colors(self, parameter_s=''):
316 """Switch color scheme for prompts, info system and exception handlers.
316 """Switch color scheme for prompts, info system and exception handlers.
317
317
318 Currently implemented schemes: NoColor, Linux, LightBG.
318 Currently implemented schemes: NoColor, Linux, LightBG.
319
319
320 Color scheme names are not case-sensitive.
320 Color scheme names are not case-sensitive.
321
321
322 Examples
322 Examples
323 --------
323 --------
324 To get a plain black and white terminal::
324 To get a plain black and white terminal::
325
325
326 %colors nocolor
326 %colors nocolor
327 """
327 """
328 def color_switch_err(name):
328 def color_switch_err(name):
329 warn('Error changing %s color schemes.\n%s' %
329 warn('Error changing %s color schemes.\n%s' %
330 (name, sys.exc_info()[1]))
330 (name, sys.exc_info()[1]))
331
331
332
332
333 new_scheme = parameter_s.strip()
333 new_scheme = parameter_s.strip()
334 if not new_scheme:
334 if not new_scheme:
335 raise UsageError(
335 raise UsageError(
336 "%colors: you must specify a color scheme. See '%colors?'")
336 "%colors: you must specify a color scheme. See '%colors?'")
337 # local shortcut
337 # local shortcut
338 shell = self.shell
338 shell = self.shell
339
339
340 import IPython.utils.rlineimpl as readline
340 import IPython.utils.rlineimpl as readline
341
341
342 if not shell.colors_force and \
342 if not shell.colors_force and \
343 not readline.have_readline and \
343 not readline.have_readline and \
344 (sys.platform == "win32" or sys.platform == "cli"):
344 (sys.platform == "win32" or sys.platform == "cli"):
345 msg = """\
345 msg = """\
346 Proper color support under MS Windows requires the pyreadline library.
346 Proper color support under MS Windows requires the pyreadline library.
347 You can find it at:
347 You can find it at:
348 http://ipython.org/pyreadline.html
348 http://ipython.org/pyreadline.html
349
349
350 Defaulting color scheme to 'NoColor'"""
350 Defaulting color scheme to 'NoColor'"""
351 new_scheme = 'NoColor'
351 new_scheme = 'NoColor'
352 warn(msg)
352 warn(msg)
353
353
354 # readline option is 0
354 # readline option is 0
355 if not shell.colors_force and not shell.has_readline:
355 if not shell.colors_force and not shell.has_readline:
356 new_scheme = 'NoColor'
356 new_scheme = 'NoColor'
357
357
358 # Set prompt colors
358 # Set prompt colors
359 try:
359 try:
360 shell.prompt_manager.color_scheme = new_scheme
360 shell.prompt_manager.color_scheme = new_scheme
361 except:
361 except:
362 color_switch_err('prompt')
362 color_switch_err('prompt')
363 else:
363 else:
364 shell.colors = \
364 shell.colors = \
365 shell.prompt_manager.color_scheme_table.active_scheme_name
365 shell.prompt_manager.color_scheme_table.active_scheme_name
366 # Set exception colors
366 # Set exception colors
367 try:
367 try:
368 shell.InteractiveTB.set_colors(scheme = new_scheme)
368 shell.InteractiveTB.set_colors(scheme = new_scheme)
369 shell.SyntaxTB.set_colors(scheme = new_scheme)
369 shell.SyntaxTB.set_colors(scheme = new_scheme)
370 except:
370 except:
371 color_switch_err('exception')
371 color_switch_err('exception')
372
372
373 # Set info (for 'object?') colors
373 # Set info (for 'object?') colors
374 if shell.color_info:
374 if shell.color_info:
375 try:
375 try:
376 shell.inspector.set_active_scheme(new_scheme)
376 shell.inspector.set_active_scheme(new_scheme)
377 except:
377 except:
378 color_switch_err('object inspector')
378 color_switch_err('object inspector')
379 else:
379 else:
380 shell.inspector.set_active_scheme('NoColor')
380 shell.inspector.set_active_scheme('NoColor')
381
381
382 @line_magic
382 @line_magic
383 def xmode(self, parameter_s=''):
383 def xmode(self, parameter_s=''):
384 """Switch modes for the exception handlers.
384 """Switch modes for the exception handlers.
385
385
386 Valid modes: Plain, Context and Verbose.
386 Valid modes: Plain, Context and Verbose.
387
387
388 If called without arguments, acts as a toggle."""
388 If called without arguments, acts as a toggle."""
389
389
390 def xmode_switch_err(name):
390 def xmode_switch_err(name):
391 warn('Error changing %s exception modes.\n%s' %
391 warn('Error changing %s exception modes.\n%s' %
392 (name,sys.exc_info()[1]))
392 (name,sys.exc_info()[1]))
393
393
394 shell = self.shell
394 shell = self.shell
395 new_mode = parameter_s.strip().capitalize()
395 new_mode = parameter_s.strip().capitalize()
396 try:
396 try:
397 shell.InteractiveTB.set_mode(mode=new_mode)
397 shell.InteractiveTB.set_mode(mode=new_mode)
398 print('Exception reporting mode:',shell.InteractiveTB.mode)
398 print('Exception reporting mode:',shell.InteractiveTB.mode)
399 except:
399 except:
400 xmode_switch_err('user')
400 xmode_switch_err('user')
401
401
402 @line_magic
402 @line_magic
403 def quickref(self,arg):
403 def quickref(self,arg):
404 """ Show a quick reference sheet """
404 """ Show a quick reference sheet """
405 from IPython.core.usage import quick_reference
405 from IPython.core.usage import quick_reference
406 qr = quick_reference + self._magic_docs(brief=True)
406 qr = quick_reference + self._magic_docs(brief=True)
407 page.page(qr)
407 page.page(qr)
408
408
409 @line_magic
409 @line_magic
410 def doctest_mode(self, parameter_s=''):
410 def doctest_mode(self, parameter_s=''):
411 """Toggle doctest mode on and off.
411 """Toggle doctest mode on and off.
412
412
413 This mode is intended to make IPython behave as much as possible like a
413 This mode is intended to make IPython behave as much as possible like a
414 plain Python shell, from the perspective of how its prompts, exceptions
414 plain Python shell, from the perspective of how its prompts, exceptions
415 and output look. This makes it easy to copy and paste parts of a
415 and output look. This makes it easy to copy and paste parts of a
416 session into doctests. It does so by:
416 session into doctests. It does so by:
417
417
418 - Changing the prompts to the classic ``>>>`` ones.
418 - Changing the prompts to the classic ``>>>`` ones.
419 - Changing the exception reporting mode to 'Plain'.
419 - Changing the exception reporting mode to 'Plain'.
420 - Disabling pretty-printing of output.
420 - Disabling pretty-printing of output.
421
421
422 Note that IPython also supports the pasting of code snippets that have
422 Note that IPython also supports the pasting of code snippets that have
423 leading '>>>' and '...' prompts in them. This means that you can paste
423 leading '>>>' and '...' prompts in them. This means that you can paste
424 doctests from files or docstrings (even if they have leading
424 doctests from files or docstrings (even if they have leading
425 whitespace), and the code will execute correctly. You can then use
425 whitespace), and the code will execute correctly. You can then use
426 '%history -t' to see the translated history; this will give you the
426 '%history -t' to see the translated history; this will give you the
427 input after removal of all the leading prompts and whitespace, which
427 input after removal of all the leading prompts and whitespace, which
428 can be pasted back into an editor.
428 can be pasted back into an editor.
429
429
430 With these features, you can switch into this mode easily whenever you
430 With these features, you can switch into this mode easily whenever you
431 need to do testing and changes to doctests, without having to leave
431 need to do testing and changes to doctests, without having to leave
432 your existing IPython session.
432 your existing IPython session.
433 """
433 """
434
434
435 # Shorthands
435 # Shorthands
436 shell = self.shell
436 shell = self.shell
437 pm = shell.prompt_manager
437 pm = shell.prompt_manager
438 meta = shell.meta
438 meta = shell.meta
439 disp_formatter = self.shell.display_formatter
439 disp_formatter = self.shell.display_formatter
440 ptformatter = disp_formatter.formatters['text/plain']
440 ptformatter = disp_formatter.formatters['text/plain']
441 # dstore is a data store kept in the instance metadata bag to track any
441 # dstore is a data store kept in the instance metadata bag to track any
442 # changes we make, so we can undo them later.
442 # changes we make, so we can undo them later.
443 dstore = meta.setdefault('doctest_mode',Struct())
443 dstore = meta.setdefault('doctest_mode',Struct())
444 save_dstore = dstore.setdefault
444 save_dstore = dstore.setdefault
445
445
446 # save a few values we'll need to recover later
446 # save a few values we'll need to recover later
447 mode = save_dstore('mode',False)
447 mode = save_dstore('mode',False)
448 save_dstore('rc_pprint',ptformatter.pprint)
448 save_dstore('rc_pprint',ptformatter.pprint)
449 save_dstore('xmode',shell.InteractiveTB.mode)
449 save_dstore('xmode',shell.InteractiveTB.mode)
450 save_dstore('rc_separate_out',shell.separate_out)
450 save_dstore('rc_separate_out',shell.separate_out)
451 save_dstore('rc_separate_out2',shell.separate_out2)
451 save_dstore('rc_separate_out2',shell.separate_out2)
452 save_dstore('rc_prompts_pad_left',pm.justify)
452 save_dstore('rc_prompts_pad_left',pm.justify)
453 save_dstore('rc_separate_in',shell.separate_in)
453 save_dstore('rc_separate_in',shell.separate_in)
454 save_dstore('rc_active_types',disp_formatter.active_types)
454 save_dstore('rc_active_types',disp_formatter.active_types)
455 save_dstore('prompt_templates',(pm.in_template, pm.in2_template, pm.out_template))
455 save_dstore('prompt_templates',(pm.in_template, pm.in2_template, pm.out_template))
456
456
457 if mode == False:
457 if mode == False:
458 # turn on
458 # turn on
459 pm.in_template = '>>> '
459 pm.in_template = '>>> '
460 pm.in2_template = '... '
460 pm.in2_template = '... '
461 pm.out_template = ''
461 pm.out_template = ''
462
462
463 # Prompt separators like plain python
463 # Prompt separators like plain python
464 shell.separate_in = ''
464 shell.separate_in = ''
465 shell.separate_out = ''
465 shell.separate_out = ''
466 shell.separate_out2 = ''
466 shell.separate_out2 = ''
467
467
468 pm.justify = False
468 pm.justify = False
469
469
470 ptformatter.pprint = False
470 ptformatter.pprint = False
471 disp_formatter.active_types = ['text/plain']
471 disp_formatter.active_types = ['text/plain']
472
472
473 shell.magic('xmode Plain')
473 shell.magic('xmode Plain')
474 else:
474 else:
475 # turn off
475 # turn off
476 pm.in_template, pm.in2_template, pm.out_template = dstore.prompt_templates
476 pm.in_template, pm.in2_template, pm.out_template = dstore.prompt_templates
477
477
478 shell.separate_in = dstore.rc_separate_in
478 shell.separate_in = dstore.rc_separate_in
479
479
480 shell.separate_out = dstore.rc_separate_out
480 shell.separate_out = dstore.rc_separate_out
481 shell.separate_out2 = dstore.rc_separate_out2
481 shell.separate_out2 = dstore.rc_separate_out2
482
482
483 pm.justify = dstore.rc_prompts_pad_left
483 pm.justify = dstore.rc_prompts_pad_left
484
484
485 ptformatter.pprint = dstore.rc_pprint
485 ptformatter.pprint = dstore.rc_pprint
486 disp_formatter.active_types = dstore.rc_active_types
486 disp_formatter.active_types = dstore.rc_active_types
487
487
488 shell.magic('xmode ' + dstore.xmode)
488 shell.magic('xmode ' + dstore.xmode)
489
489
490 # Store new mode and inform
490 # Store new mode and inform
491 dstore.mode = bool(1-int(mode))
491 dstore.mode = bool(1-int(mode))
492 mode_label = ['OFF','ON'][dstore.mode]
492 mode_label = ['OFF','ON'][dstore.mode]
493 print('Doctest mode is:', mode_label)
493 print('Doctest mode is:', mode_label)
494
494
495 @line_magic
495 @line_magic
496 def gui(self, parameter_s=''):
496 def gui(self, parameter_s=''):
497 """Enable or disable IPython GUI event loop integration.
497 """Enable or disable IPython GUI event loop integration.
498
498
499 %gui [GUINAME]
499 %gui [GUINAME]
500
500
501 This magic replaces IPython's threaded shells that were activated
501 This magic replaces IPython's threaded shells that were activated
502 using the (pylab/wthread/etc.) command line flags. GUI toolkits
502 using the (pylab/wthread/etc.) command line flags. GUI toolkits
503 can now be enabled at runtime and keyboard
503 can now be enabled at runtime and keyboard
504 interrupts should work without any problems. The following toolkits
504 interrupts should work without any problems. The following toolkits
505 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
505 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
506
506
507 %gui wx # enable wxPython event loop integration
507 %gui wx # enable wxPython event loop integration
508 %gui qt4|qt # enable PyQt4 event loop integration
508 %gui qt4|qt # enable PyQt4 event loop integration
509 %gui qt5 # enable PyQt5 event loop integration
509 %gui qt5 # enable PyQt5 event loop integration
510 %gui gtk # enable PyGTK event loop integration
510 %gui gtk # enable PyGTK event loop integration
511 %gui gtk3 # enable Gtk3 event loop integration
511 %gui gtk3 # enable Gtk3 event loop integration
512 %gui tk # enable Tk event loop integration
512 %gui tk # enable Tk event loop integration
513 %gui osx # enable Cocoa event loop integration
513 %gui osx # enable Cocoa event loop integration
514 # (requires %matplotlib 1.1)
514 # (requires %matplotlib 1.1)
515 %gui # disable all event loop integration
515 %gui # disable all event loop integration
516
516
517 WARNING: after any of these has been called you can simply create
517 WARNING: after any of these has been called you can simply create
518 an application object, but DO NOT start the event loop yourself, as
518 an application object, but DO NOT start the event loop yourself, as
519 we have already handled that.
519 we have already handled that.
520 """
520 """
521 opts, arg = self.parse_options(parameter_s, '')
521 opts, arg = self.parse_options(parameter_s, '')
522 if arg=='': arg = None
522 if arg=='': arg = None
523 try:
523 try:
524 return self.shell.enable_gui(arg)
524 return self.shell.enable_gui(arg)
525 except Exception as e:
525 except Exception as e:
526 # print simple error message, rather than traceback if we can't
526 # print simple error message, rather than traceback if we can't
527 # hook up the GUI
527 # hook up the GUI
528 error(str(e))
528 error(str(e))
529
529
530 @skip_doctest
530 @skip_doctest
531 @line_magic
531 @line_magic
532 def precision(self, s=''):
532 def precision(self, s=''):
533 """Set floating point precision for pretty printing.
533 """Set floating point precision for pretty printing.
534
534
535 Can set either integer precision or a format string.
535 Can set either integer precision or a format string.
536
536
537 If numpy has been imported and precision is an int,
537 If numpy has been imported and precision is an int,
538 numpy display precision will also be set, via ``numpy.set_printoptions``.
538 numpy display precision will also be set, via ``numpy.set_printoptions``.
539
539
540 If no argument is given, defaults will be restored.
540 If no argument is given, defaults will be restored.
541
541
542 Examples
542 Examples
543 --------
543 --------
544 ::
544 ::
545
545
546 In [1]: from math import pi
546 In [1]: from math import pi
547
547
548 In [2]: %precision 3
548 In [2]: %precision 3
549 Out[2]: u'%.3f'
549 Out[2]: u'%.3f'
550
550
551 In [3]: pi
551 In [3]: pi
552 Out[3]: 3.142
552 Out[3]: 3.142
553
553
554 In [4]: %precision %i
554 In [4]: %precision %i
555 Out[4]: u'%i'
555 Out[4]: u'%i'
556
556
557 In [5]: pi
557 In [5]: pi
558 Out[5]: 3
558 Out[5]: 3
559
559
560 In [6]: %precision %e
560 In [6]: %precision %e
561 Out[6]: u'%e'
561 Out[6]: u'%e'
562
562
563 In [7]: pi**10
563 In [7]: pi**10
564 Out[7]: 9.364805e+04
564 Out[7]: 9.364805e+04
565
565
566 In [8]: %precision
566 In [8]: %precision
567 Out[8]: u'%r'
567 Out[8]: u'%r'
568
568
569 In [9]: pi**10
569 In [9]: pi**10
570 Out[9]: 93648.047476082982
570 Out[9]: 93648.047476082982
571 """
571 """
572 ptformatter = self.shell.display_formatter.formatters['text/plain']
572 ptformatter = self.shell.display_formatter.formatters['text/plain']
573 ptformatter.float_precision = s
573 ptformatter.float_precision = s
574 return ptformatter.float_format
574 return ptformatter.float_format
575
575
576 @magic_arguments.magic_arguments()
576 @magic_arguments.magic_arguments()
577 @magic_arguments.argument(
577 @magic_arguments.argument(
578 '-e', '--export', action='store_true', default=False,
578 '-e', '--export', action='store_true', default=False,
579 help='Export IPython history as a notebook. The filename argument '
579 help='Export IPython history as a notebook. The filename argument '
580 'is used to specify the notebook name and format. For example '
580 'is used to specify the notebook name and format. For example '
581 'a filename of notebook.ipynb will result in a notebook name '
581 'a filename of notebook.ipynb will result in a notebook name '
582 'of "notebook" and a format of "json". Likewise using a ".py" '
582 'of "notebook" and a format of "json". Likewise using a ".py" '
583 'file extension will write the notebook as a Python script'
583 'file extension will write the notebook as a Python script'
584 )
584 )
585 @magic_arguments.argument(
585 @magic_arguments.argument(
586 'filename', type=unicode_type,
586 'filename', type=unicode_type,
587 help='Notebook name or filename'
587 help='Notebook name or filename'
588 )
588 )
589 @line_magic
589 @line_magic
590 def notebook(self, s):
590 def notebook(self, s):
591 """Export and convert IPython notebooks.
591 """Export and convert IPython notebooks.
592
592
593 This function can export the current IPython history to a notebook file.
593 This function can export the current IPython history to a notebook file.
594 For example, to export the history to "foo.ipynb" do "%notebook -e foo.ipynb".
594 For example, to export the history to "foo.ipynb" do "%notebook -e foo.ipynb".
595 To export the history to "foo.py" do "%notebook -e foo.py".
595 To export the history to "foo.py" do "%notebook -e foo.py".
596 """
596 """
597 args = magic_arguments.parse_argstring(self.notebook, s)
597 args = magic_arguments.parse_argstring(self.notebook, s)
598
598
599 from IPython.nbformat import write, v4
599 from IPython.nbformat import write, v4
600 args.filename = unquote_filename(args.filename)
600 args.filename = unquote_filename(args.filename)
601 if args.export:
601 if args.export:
602 cells = []
602 cells = []
603 hist = list(self.shell.history_manager.get_range())
603 hist = list(self.shell.history_manager.get_range())
604 if(len(hist)<=1):
604 if(len(hist)<=1):
605 raise ValueError('History is empty, cannot export')
605 raise ValueError('History is empty, cannot export')
606 for session, execution_count, input in hist[:-1]:
606 for session, execution_count, source in hist[:-1]:
607 cells.append(v4.new_code_cell(
607 cells.append(v4.new_code_cell(
608 execution_count=execution_count,
608 execution_count=execution_count,
609 source=source
609 source=source
610 ))
610 ))
611 nb = v4.new_notebook(cells=cells)
611 nb = v4.new_notebook(cells=cells)
612 with io.open(args.filename, 'w', encoding='utf-8') as f:
612 with io.open(args.filename, 'w', encoding='utf-8') as f:
613 write(nb, f, version=4)
613 write(nb, f, version=4)
@@ -1,998 +1,998 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for various magic functions.
2 """Tests for various magic functions.
3
3
4 Needs to be run by nose (to make ipython session available).
4 Needs to be run by nose (to make ipython session available).
5 """
5 """
6 from __future__ import absolute_import
6 from __future__ import absolute_import
7
7
8 import io
8 import io
9 import os
9 import os
10 import sys
10 import sys
11 import warnings
11 import warnings
12 from unittest import TestCase, skipIf
12 from unittest import TestCase, skipIf
13
13
14 try:
14 try:
15 from importlib import invalidate_caches # Required from Python 3.3
15 from importlib import invalidate_caches # Required from Python 3.3
16 except ImportError:
16 except ImportError:
17 def invalidate_caches():
17 def invalidate_caches():
18 pass
18 pass
19
19
20 import nose.tools as nt
20 import nose.tools as nt
21
21
22 from IPython import get_ipython
22 from IPython import get_ipython
23 from IPython.core import magic
23 from IPython.core import magic
24 from IPython.core.error import UsageError
24 from IPython.core.error import UsageError
25 from IPython.core.magic import (Magics, magics_class, line_magic,
25 from IPython.core.magic import (Magics, magics_class, line_magic,
26 cell_magic, line_cell_magic,
26 cell_magic, line_cell_magic,
27 register_line_magic, register_cell_magic,
27 register_line_magic, register_cell_magic,
28 register_line_cell_magic)
28 register_line_cell_magic)
29 from IPython.core.magics import execution, script, code
29 from IPython.core.magics import execution, script, code
30 from IPython.testing import decorators as dec
30 from IPython.testing import decorators as dec
31 from IPython.testing import tools as tt
31 from IPython.testing import tools as tt
32 from IPython.utils import py3compat
32 from IPython.utils import py3compat
33 from IPython.utils.io import capture_output
33 from IPython.utils.io import capture_output
34 from IPython.utils.tempdir import TemporaryDirectory
34 from IPython.utils.tempdir import TemporaryDirectory
35 from IPython.utils.process import find_cmd
35 from IPython.utils.process import find_cmd
36
36
37 if py3compat.PY3:
37 if py3compat.PY3:
38 from io import StringIO
38 from io import StringIO
39 else:
39 else:
40 from StringIO import StringIO
40 from StringIO import StringIO
41
41
42
42
43 @magic.magics_class
43 @magic.magics_class
44 class DummyMagics(magic.Magics): pass
44 class DummyMagics(magic.Magics): pass
45
45
46 def test_extract_code_ranges():
46 def test_extract_code_ranges():
47 instr = "1 3 5-6 7-9 10:15 17: :10 10- -13 :"
47 instr = "1 3 5-6 7-9 10:15 17: :10 10- -13 :"
48 expected = [(0, 1),
48 expected = [(0, 1),
49 (2, 3),
49 (2, 3),
50 (4, 6),
50 (4, 6),
51 (6, 9),
51 (6, 9),
52 (9, 14),
52 (9, 14),
53 (16, None),
53 (16, None),
54 (None, 9),
54 (None, 9),
55 (9, None),
55 (9, None),
56 (None, 13),
56 (None, 13),
57 (None, None)]
57 (None, None)]
58 actual = list(code.extract_code_ranges(instr))
58 actual = list(code.extract_code_ranges(instr))
59 nt.assert_equal(actual, expected)
59 nt.assert_equal(actual, expected)
60
60
61 def test_extract_symbols():
61 def test_extract_symbols():
62 source = """import foo\na = 10\ndef b():\n return 42\n\n\nclass A: pass\n\n\n"""
62 source = """import foo\na = 10\ndef b():\n return 42\n\n\nclass A: pass\n\n\n"""
63 symbols_args = ["a", "b", "A", "A,b", "A,a", "z"]
63 symbols_args = ["a", "b", "A", "A,b", "A,a", "z"]
64 expected = [([], ['a']),
64 expected = [([], ['a']),
65 (["def b():\n return 42\n"], []),
65 (["def b():\n return 42\n"], []),
66 (["class A: pass\n"], []),
66 (["class A: pass\n"], []),
67 (["class A: pass\n", "def b():\n return 42\n"], []),
67 (["class A: pass\n", "def b():\n return 42\n"], []),
68 (["class A: pass\n"], ['a']),
68 (["class A: pass\n"], ['a']),
69 ([], ['z'])]
69 ([], ['z'])]
70 for symbols, exp in zip(symbols_args, expected):
70 for symbols, exp in zip(symbols_args, expected):
71 nt.assert_equal(code.extract_symbols(source, symbols), exp)
71 nt.assert_equal(code.extract_symbols(source, symbols), exp)
72
72
73
73
74 def test_extract_symbols_raises_exception_with_non_python_code():
74 def test_extract_symbols_raises_exception_with_non_python_code():
75 source = ("=begin A Ruby program :)=end\n"
75 source = ("=begin A Ruby program :)=end\n"
76 "def hello\n"
76 "def hello\n"
77 "puts 'Hello world'\n"
77 "puts 'Hello world'\n"
78 "end")
78 "end")
79 with nt.assert_raises(SyntaxError):
79 with nt.assert_raises(SyntaxError):
80 code.extract_symbols(source, "hello")
80 code.extract_symbols(source, "hello")
81
81
82 def test_config():
82 def test_config():
83 """ test that config magic does not raise
83 """ test that config magic does not raise
84 can happen if Configurable init is moved too early into
84 can happen if Configurable init is moved too early into
85 Magics.__init__ as then a Config object will be registerd as a
85 Magics.__init__ as then a Config object will be registerd as a
86 magic.
86 magic.
87 """
87 """
88 ## should not raise.
88 ## should not raise.
89 _ip.magic('config')
89 _ip.magic('config')
90
90
91 def test_rehashx():
91 def test_rehashx():
92 # clear up everything
92 # clear up everything
93 _ip = get_ipython()
93 _ip = get_ipython()
94 _ip.alias_manager.clear_aliases()
94 _ip.alias_manager.clear_aliases()
95 del _ip.db['syscmdlist']
95 del _ip.db['syscmdlist']
96
96
97 _ip.magic('rehashx')
97 _ip.magic('rehashx')
98 # Practically ALL ipython development systems will have more than 10 aliases
98 # Practically ALL ipython development systems will have more than 10 aliases
99
99
100 nt.assert_true(len(_ip.alias_manager.aliases) > 10)
100 nt.assert_true(len(_ip.alias_manager.aliases) > 10)
101 for name, cmd in _ip.alias_manager.aliases:
101 for name, cmd in _ip.alias_manager.aliases:
102 # we must strip dots from alias names
102 # we must strip dots from alias names
103 nt.assert_not_in('.', name)
103 nt.assert_not_in('.', name)
104
104
105 # rehashx must fill up syscmdlist
105 # rehashx must fill up syscmdlist
106 scoms = _ip.db['syscmdlist']
106 scoms = _ip.db['syscmdlist']
107 nt.assert_true(len(scoms) > 10)
107 nt.assert_true(len(scoms) > 10)
108
108
109
109
110 def test_magic_parse_options():
110 def test_magic_parse_options():
111 """Test that we don't mangle paths when parsing magic options."""
111 """Test that we don't mangle paths when parsing magic options."""
112 ip = get_ipython()
112 ip = get_ipython()
113 path = 'c:\\x'
113 path = 'c:\\x'
114 m = DummyMagics(ip)
114 m = DummyMagics(ip)
115 opts = m.parse_options('-f %s' % path,'f:')[0]
115 opts = m.parse_options('-f %s' % path,'f:')[0]
116 # argv splitting is os-dependent
116 # argv splitting is os-dependent
117 if os.name == 'posix':
117 if os.name == 'posix':
118 expected = 'c:x'
118 expected = 'c:x'
119 else:
119 else:
120 expected = path
120 expected = path
121 nt.assert_equal(opts['f'], expected)
121 nt.assert_equal(opts['f'], expected)
122
122
123 def test_magic_parse_long_options():
123 def test_magic_parse_long_options():
124 """Magic.parse_options can handle --foo=bar long options"""
124 """Magic.parse_options can handle --foo=bar long options"""
125 ip = get_ipython()
125 ip = get_ipython()
126 m = DummyMagics(ip)
126 m = DummyMagics(ip)
127 opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=')
127 opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=')
128 nt.assert_in('foo', opts)
128 nt.assert_in('foo', opts)
129 nt.assert_in('bar', opts)
129 nt.assert_in('bar', opts)
130 nt.assert_equal(opts['bar'], "bubble")
130 nt.assert_equal(opts['bar'], "bubble")
131
131
132
132
133 @dec.skip_without('sqlite3')
133 @dec.skip_without('sqlite3')
134 def doctest_hist_f():
134 def doctest_hist_f():
135 """Test %hist -f with temporary filename.
135 """Test %hist -f with temporary filename.
136
136
137 In [9]: import tempfile
137 In [9]: import tempfile
138
138
139 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
139 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
140
140
141 In [11]: %hist -nl -f $tfile 3
141 In [11]: %hist -nl -f $tfile 3
142
142
143 In [13]: import os; os.unlink(tfile)
143 In [13]: import os; os.unlink(tfile)
144 """
144 """
145
145
146
146
147 @dec.skip_without('sqlite3')
147 @dec.skip_without('sqlite3')
148 def doctest_hist_r():
148 def doctest_hist_r():
149 """Test %hist -r
149 """Test %hist -r
150
150
151 XXX - This test is not recording the output correctly. For some reason, in
151 XXX - This test is not recording the output correctly. For some reason, in
152 testing mode the raw history isn't getting populated. No idea why.
152 testing mode the raw history isn't getting populated. No idea why.
153 Disabling the output checking for now, though at least we do run it.
153 Disabling the output checking for now, though at least we do run it.
154
154
155 In [1]: 'hist' in _ip.lsmagic()
155 In [1]: 'hist' in _ip.lsmagic()
156 Out[1]: True
156 Out[1]: True
157
157
158 In [2]: x=1
158 In [2]: x=1
159
159
160 In [3]: %hist -rl 2
160 In [3]: %hist -rl 2
161 x=1 # random
161 x=1 # random
162 %hist -r 2
162 %hist -r 2
163 """
163 """
164
164
165
165
166 @dec.skip_without('sqlite3')
166 @dec.skip_without('sqlite3')
167 def doctest_hist_op():
167 def doctest_hist_op():
168 """Test %hist -op
168 """Test %hist -op
169
169
170 In [1]: class b(float):
170 In [1]: class b(float):
171 ...: pass
171 ...: pass
172 ...:
172 ...:
173
173
174 In [2]: class s(object):
174 In [2]: class s(object):
175 ...: def __str__(self):
175 ...: def __str__(self):
176 ...: return 's'
176 ...: return 's'
177 ...:
177 ...:
178
178
179 In [3]:
179 In [3]:
180
180
181 In [4]: class r(b):
181 In [4]: class r(b):
182 ...: def __repr__(self):
182 ...: def __repr__(self):
183 ...: return 'r'
183 ...: return 'r'
184 ...:
184 ...:
185
185
186 In [5]: class sr(s,r): pass
186 In [5]: class sr(s,r): pass
187 ...:
187 ...:
188
188
189 In [6]:
189 In [6]:
190
190
191 In [7]: bb=b()
191 In [7]: bb=b()
192
192
193 In [8]: ss=s()
193 In [8]: ss=s()
194
194
195 In [9]: rr=r()
195 In [9]: rr=r()
196
196
197 In [10]: ssrr=sr()
197 In [10]: ssrr=sr()
198
198
199 In [11]: 4.5
199 In [11]: 4.5
200 Out[11]: 4.5
200 Out[11]: 4.5
201
201
202 In [12]: str(ss)
202 In [12]: str(ss)
203 Out[12]: 's'
203 Out[12]: 's'
204
204
205 In [13]:
205 In [13]:
206
206
207 In [14]: %hist -op
207 In [14]: %hist -op
208 >>> class b:
208 >>> class b:
209 ... pass
209 ... pass
210 ...
210 ...
211 >>> class s(b):
211 >>> class s(b):
212 ... def __str__(self):
212 ... def __str__(self):
213 ... return 's'
213 ... return 's'
214 ...
214 ...
215 >>>
215 >>>
216 >>> class r(b):
216 >>> class r(b):
217 ... def __repr__(self):
217 ... def __repr__(self):
218 ... return 'r'
218 ... return 'r'
219 ...
219 ...
220 >>> class sr(s,r): pass
220 >>> class sr(s,r): pass
221 >>>
221 >>>
222 >>> bb=b()
222 >>> bb=b()
223 >>> ss=s()
223 >>> ss=s()
224 >>> rr=r()
224 >>> rr=r()
225 >>> ssrr=sr()
225 >>> ssrr=sr()
226 >>> 4.5
226 >>> 4.5
227 4.5
227 4.5
228 >>> str(ss)
228 >>> str(ss)
229 's'
229 's'
230 >>>
230 >>>
231 """
231 """
232
232
233 def test_hist_pof():
233 def test_hist_pof():
234 ip = get_ipython()
234 ip = get_ipython()
235 ip.run_cell(u"1+2", store_history=True)
235 ip.run_cell(u"1+2", store_history=True)
236 #raise Exception(ip.history_manager.session_number)
236 #raise Exception(ip.history_manager.session_number)
237 #raise Exception(list(ip.history_manager._get_range_session()))
237 #raise Exception(list(ip.history_manager._get_range_session()))
238 with TemporaryDirectory() as td:
238 with TemporaryDirectory() as td:
239 tf = os.path.join(td, 'hist.py')
239 tf = os.path.join(td, 'hist.py')
240 ip.run_line_magic('history', '-pof %s' % tf)
240 ip.run_line_magic('history', '-pof %s' % tf)
241 assert os.path.isfile(tf)
241 assert os.path.isfile(tf)
242
242
243
243
244 @dec.skip_without('sqlite3')
244 @dec.skip_without('sqlite3')
245 def test_macro():
245 def test_macro():
246 ip = get_ipython()
246 ip = get_ipython()
247 ip.history_manager.reset() # Clear any existing history.
247 ip.history_manager.reset() # Clear any existing history.
248 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
248 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
249 for i, cmd in enumerate(cmds, start=1):
249 for i, cmd in enumerate(cmds, start=1):
250 ip.history_manager.store_inputs(i, cmd)
250 ip.history_manager.store_inputs(i, cmd)
251 ip.magic("macro test 1-3")
251 ip.magic("macro test 1-3")
252 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
252 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
253
253
254 # List macros
254 # List macros
255 nt.assert_in("test", ip.magic("macro"))
255 nt.assert_in("test", ip.magic("macro"))
256
256
257
257
258 @dec.skip_without('sqlite3')
258 @dec.skip_without('sqlite3')
259 def test_macro_run():
259 def test_macro_run():
260 """Test that we can run a multi-line macro successfully."""
260 """Test that we can run a multi-line macro successfully."""
261 ip = get_ipython()
261 ip = get_ipython()
262 ip.history_manager.reset()
262 ip.history_manager.reset()
263 cmds = ["a=10", "a+=1", py3compat.doctest_refactor_print("print a"),
263 cmds = ["a=10", "a+=1", py3compat.doctest_refactor_print("print a"),
264 "%macro test 2-3"]
264 "%macro test 2-3"]
265 for cmd in cmds:
265 for cmd in cmds:
266 ip.run_cell(cmd, store_history=True)
266 ip.run_cell(cmd, store_history=True)
267 nt.assert_equal(ip.user_ns["test"].value,
267 nt.assert_equal(ip.user_ns["test"].value,
268 py3compat.doctest_refactor_print("a+=1\nprint a\n"))
268 py3compat.doctest_refactor_print("a+=1\nprint a\n"))
269 with tt.AssertPrints("12"):
269 with tt.AssertPrints("12"):
270 ip.run_cell("test")
270 ip.run_cell("test")
271 with tt.AssertPrints("13"):
271 with tt.AssertPrints("13"):
272 ip.run_cell("test")
272 ip.run_cell("test")
273
273
274
274
275 def test_magic_magic():
275 def test_magic_magic():
276 """Test %magic"""
276 """Test %magic"""
277 ip = get_ipython()
277 ip = get_ipython()
278 with capture_output() as captured:
278 with capture_output() as captured:
279 ip.magic("magic")
279 ip.magic("magic")
280
280
281 stdout = captured.stdout
281 stdout = captured.stdout
282 nt.assert_in('%magic', stdout)
282 nt.assert_in('%magic', stdout)
283 nt.assert_in('IPython', stdout)
283 nt.assert_in('IPython', stdout)
284 nt.assert_in('Available', stdout)
284 nt.assert_in('Available', stdout)
285
285
286
286
287 @dec.skipif_not_numpy
287 @dec.skipif_not_numpy
288 def test_numpy_reset_array_undec():
288 def test_numpy_reset_array_undec():
289 "Test '%reset array' functionality"
289 "Test '%reset array' functionality"
290 _ip.ex('import numpy as np')
290 _ip.ex('import numpy as np')
291 _ip.ex('a = np.empty(2)')
291 _ip.ex('a = np.empty(2)')
292 nt.assert_in('a', _ip.user_ns)
292 nt.assert_in('a', _ip.user_ns)
293 _ip.magic('reset -f array')
293 _ip.magic('reset -f array')
294 nt.assert_not_in('a', _ip.user_ns)
294 nt.assert_not_in('a', _ip.user_ns)
295
295
296 def test_reset_out():
296 def test_reset_out():
297 "Test '%reset out' magic"
297 "Test '%reset out' magic"
298 _ip.run_cell("parrot = 'dead'", store_history=True)
298 _ip.run_cell("parrot = 'dead'", store_history=True)
299 # test '%reset -f out', make an Out prompt
299 # test '%reset -f out', make an Out prompt
300 _ip.run_cell("parrot", store_history=True)
300 _ip.run_cell("parrot", store_history=True)
301 nt.assert_true('dead' in [_ip.user_ns[x] for x in ('_','__','___')])
301 nt.assert_true('dead' in [_ip.user_ns[x] for x in ('_','__','___')])
302 _ip.magic('reset -f out')
302 _ip.magic('reset -f out')
303 nt.assert_false('dead' in [_ip.user_ns[x] for x in ('_','__','___')])
303 nt.assert_false('dead' in [_ip.user_ns[x] for x in ('_','__','___')])
304 nt.assert_equal(len(_ip.user_ns['Out']), 0)
304 nt.assert_equal(len(_ip.user_ns['Out']), 0)
305
305
306 def test_reset_in():
306 def test_reset_in():
307 "Test '%reset in' magic"
307 "Test '%reset in' magic"
308 # test '%reset -f in'
308 # test '%reset -f in'
309 _ip.run_cell("parrot", store_history=True)
309 _ip.run_cell("parrot", store_history=True)
310 nt.assert_true('parrot' in [_ip.user_ns[x] for x in ('_i','_ii','_iii')])
310 nt.assert_true('parrot' in [_ip.user_ns[x] for x in ('_i','_ii','_iii')])
311 _ip.magic('%reset -f in')
311 _ip.magic('%reset -f in')
312 nt.assert_false('parrot' in [_ip.user_ns[x] for x in ('_i','_ii','_iii')])
312 nt.assert_false('parrot' in [_ip.user_ns[x] for x in ('_i','_ii','_iii')])
313 nt.assert_equal(len(set(_ip.user_ns['In'])), 1)
313 nt.assert_equal(len(set(_ip.user_ns['In'])), 1)
314
314
315 def test_reset_dhist():
315 def test_reset_dhist():
316 "Test '%reset dhist' magic"
316 "Test '%reset dhist' magic"
317 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
317 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
318 _ip.magic('cd ' + os.path.dirname(nt.__file__))
318 _ip.magic('cd ' + os.path.dirname(nt.__file__))
319 _ip.magic('cd -')
319 _ip.magic('cd -')
320 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
320 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
321 _ip.magic('reset -f dhist')
321 _ip.magic('reset -f dhist')
322 nt.assert_equal(len(_ip.user_ns['_dh']), 0)
322 nt.assert_equal(len(_ip.user_ns['_dh']), 0)
323 _ip.run_cell("_dh = [d for d in tmp]") #restore
323 _ip.run_cell("_dh = [d for d in tmp]") #restore
324
324
325 def test_reset_in_length():
325 def test_reset_in_length():
326 "Test that '%reset in' preserves In[] length"
326 "Test that '%reset in' preserves In[] length"
327 _ip.run_cell("print 'foo'")
327 _ip.run_cell("print 'foo'")
328 _ip.run_cell("reset -f in")
328 _ip.run_cell("reset -f in")
329 nt.assert_equal(len(_ip.user_ns['In']), _ip.displayhook.prompt_count+1)
329 nt.assert_equal(len(_ip.user_ns['In']), _ip.displayhook.prompt_count+1)
330
330
331 def test_tb_syntaxerror():
331 def test_tb_syntaxerror():
332 """test %tb after a SyntaxError"""
332 """test %tb after a SyntaxError"""
333 ip = get_ipython()
333 ip = get_ipython()
334 ip.run_cell("for")
334 ip.run_cell("for")
335
335
336 # trap and validate stdout
336 # trap and validate stdout
337 save_stdout = sys.stdout
337 save_stdout = sys.stdout
338 try:
338 try:
339 sys.stdout = StringIO()
339 sys.stdout = StringIO()
340 ip.run_cell("%tb")
340 ip.run_cell("%tb")
341 out = sys.stdout.getvalue()
341 out = sys.stdout.getvalue()
342 finally:
342 finally:
343 sys.stdout = save_stdout
343 sys.stdout = save_stdout
344 # trim output, and only check the last line
344 # trim output, and only check the last line
345 last_line = out.rstrip().splitlines()[-1].strip()
345 last_line = out.rstrip().splitlines()[-1].strip()
346 nt.assert_equal(last_line, "SyntaxError: invalid syntax")
346 nt.assert_equal(last_line, "SyntaxError: invalid syntax")
347
347
348
348
349 def test_time():
349 def test_time():
350 ip = get_ipython()
350 ip = get_ipython()
351
351
352 with tt.AssertPrints("Wall time: "):
352 with tt.AssertPrints("Wall time: "):
353 ip.run_cell("%time None")
353 ip.run_cell("%time None")
354
354
355 ip.run_cell("def f(kmjy):\n"
355 ip.run_cell("def f(kmjy):\n"
356 " %time print (2*kmjy)")
356 " %time print (2*kmjy)")
357
357
358 with tt.AssertPrints("Wall time: "):
358 with tt.AssertPrints("Wall time: "):
359 with tt.AssertPrints("hihi", suppress=False):
359 with tt.AssertPrints("hihi", suppress=False):
360 ip.run_cell("f('hi')")
360 ip.run_cell("f('hi')")
361
361
362
362
363 @dec.skip_win32
363 @dec.skip_win32
364 def test_time2():
364 def test_time2():
365 ip = get_ipython()
365 ip = get_ipython()
366
366
367 with tt.AssertPrints("CPU times: user "):
367 with tt.AssertPrints("CPU times: user "):
368 ip.run_cell("%time None")
368 ip.run_cell("%time None")
369
369
370 def test_time3():
370 def test_time3():
371 """Erroneous magic function calls, issue gh-3334"""
371 """Erroneous magic function calls, issue gh-3334"""
372 ip = get_ipython()
372 ip = get_ipython()
373 ip.user_ns.pop('run', None)
373 ip.user_ns.pop('run', None)
374
374
375 with tt.AssertNotPrints("not found", channel='stderr'):
375 with tt.AssertNotPrints("not found", channel='stderr'):
376 ip.run_cell("%%time\n"
376 ip.run_cell("%%time\n"
377 "run = 0\n"
377 "run = 0\n"
378 "run += 1")
378 "run += 1")
379
379
380 @dec.skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
380 @dec.skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
381 def test_time_futures():
381 def test_time_futures():
382 "Test %time with __future__ environments"
382 "Test %time with __future__ environments"
383 ip = get_ipython()
383 ip = get_ipython()
384 ip.autocall = 0
384 ip.autocall = 0
385 ip.run_cell("from __future__ import division")
385 ip.run_cell("from __future__ import division")
386 with tt.AssertPrints('0.25'):
386 with tt.AssertPrints('0.25'):
387 ip.run_line_magic('time', 'print(1/4)')
387 ip.run_line_magic('time', 'print(1/4)')
388 ip.compile.reset_compiler_flags()
388 ip.compile.reset_compiler_flags()
389 with tt.AssertNotPrints('0.25'):
389 with tt.AssertNotPrints('0.25'):
390 ip.run_line_magic('time', 'print(1/4)')
390 ip.run_line_magic('time', 'print(1/4)')
391
391
392 def test_doctest_mode():
392 def test_doctest_mode():
393 "Toggle doctest_mode twice, it should be a no-op and run without error"
393 "Toggle doctest_mode twice, it should be a no-op and run without error"
394 _ip.magic('doctest_mode')
394 _ip.magic('doctest_mode')
395 _ip.magic('doctest_mode')
395 _ip.magic('doctest_mode')
396
396
397
397
398 def test_parse_options():
398 def test_parse_options():
399 """Tests for basic options parsing in magics."""
399 """Tests for basic options parsing in magics."""
400 # These are only the most minimal of tests, more should be added later. At
400 # These are only the most minimal of tests, more should be added later. At
401 # the very least we check that basic text/unicode calls work OK.
401 # the very least we check that basic text/unicode calls work OK.
402 m = DummyMagics(_ip)
402 m = DummyMagics(_ip)
403 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
403 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
404 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
404 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
405
405
406
406
407 def test_dirops():
407 def test_dirops():
408 """Test various directory handling operations."""
408 """Test various directory handling operations."""
409 # curpath = lambda :os.path.splitdrive(py3compat.getcwd())[1].replace('\\','/')
409 # curpath = lambda :os.path.splitdrive(py3compat.getcwd())[1].replace('\\','/')
410 curpath = py3compat.getcwd
410 curpath = py3compat.getcwd
411 startdir = py3compat.getcwd()
411 startdir = py3compat.getcwd()
412 ipdir = os.path.realpath(_ip.ipython_dir)
412 ipdir = os.path.realpath(_ip.ipython_dir)
413 try:
413 try:
414 _ip.magic('cd "%s"' % ipdir)
414 _ip.magic('cd "%s"' % ipdir)
415 nt.assert_equal(curpath(), ipdir)
415 nt.assert_equal(curpath(), ipdir)
416 _ip.magic('cd -')
416 _ip.magic('cd -')
417 nt.assert_equal(curpath(), startdir)
417 nt.assert_equal(curpath(), startdir)
418 _ip.magic('pushd "%s"' % ipdir)
418 _ip.magic('pushd "%s"' % ipdir)
419 nt.assert_equal(curpath(), ipdir)
419 nt.assert_equal(curpath(), ipdir)
420 _ip.magic('popd')
420 _ip.magic('popd')
421 nt.assert_equal(curpath(), startdir)
421 nt.assert_equal(curpath(), startdir)
422 finally:
422 finally:
423 os.chdir(startdir)
423 os.chdir(startdir)
424
424
425
425
426 def test_xmode():
426 def test_xmode():
427 # Calling xmode three times should be a no-op
427 # Calling xmode three times should be a no-op
428 xmode = _ip.InteractiveTB.mode
428 xmode = _ip.InteractiveTB.mode
429 for i in range(3):
429 for i in range(3):
430 _ip.magic("xmode")
430 _ip.magic("xmode")
431 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
431 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
432
432
433 def test_reset_hard():
433 def test_reset_hard():
434 monitor = []
434 monitor = []
435 class A(object):
435 class A(object):
436 def __del__(self):
436 def __del__(self):
437 monitor.append(1)
437 monitor.append(1)
438 def __repr__(self):
438 def __repr__(self):
439 return "<A instance>"
439 return "<A instance>"
440
440
441 _ip.user_ns["a"] = A()
441 _ip.user_ns["a"] = A()
442 _ip.run_cell("a")
442 _ip.run_cell("a")
443
443
444 nt.assert_equal(monitor, [])
444 nt.assert_equal(monitor, [])
445 _ip.magic("reset -f")
445 _ip.magic("reset -f")
446 nt.assert_equal(monitor, [1])
446 nt.assert_equal(monitor, [1])
447
447
448 class TestXdel(tt.TempFileMixin):
448 class TestXdel(tt.TempFileMixin):
449 def test_xdel(self):
449 def test_xdel(self):
450 """Test that references from %run are cleared by xdel."""
450 """Test that references from %run are cleared by xdel."""
451 src = ("class A(object):\n"
451 src = ("class A(object):\n"
452 " monitor = []\n"
452 " monitor = []\n"
453 " def __del__(self):\n"
453 " def __del__(self):\n"
454 " self.monitor.append(1)\n"
454 " self.monitor.append(1)\n"
455 "a = A()\n")
455 "a = A()\n")
456 self.mktmp(src)
456 self.mktmp(src)
457 # %run creates some hidden references...
457 # %run creates some hidden references...
458 _ip.magic("run %s" % self.fname)
458 _ip.magic("run %s" % self.fname)
459 # ... as does the displayhook.
459 # ... as does the displayhook.
460 _ip.run_cell("a")
460 _ip.run_cell("a")
461
461
462 monitor = _ip.user_ns["A"].monitor
462 monitor = _ip.user_ns["A"].monitor
463 nt.assert_equal(monitor, [])
463 nt.assert_equal(monitor, [])
464
464
465 _ip.magic("xdel a")
465 _ip.magic("xdel a")
466
466
467 # Check that a's __del__ method has been called.
467 # Check that a's __del__ method has been called.
468 nt.assert_equal(monitor, [1])
468 nt.assert_equal(monitor, [1])
469
469
470 def doctest_who():
470 def doctest_who():
471 """doctest for %who
471 """doctest for %who
472
472
473 In [1]: %reset -f
473 In [1]: %reset -f
474
474
475 In [2]: alpha = 123
475 In [2]: alpha = 123
476
476
477 In [3]: beta = 'beta'
477 In [3]: beta = 'beta'
478
478
479 In [4]: %who int
479 In [4]: %who int
480 alpha
480 alpha
481
481
482 In [5]: %who str
482 In [5]: %who str
483 beta
483 beta
484
484
485 In [6]: %whos
485 In [6]: %whos
486 Variable Type Data/Info
486 Variable Type Data/Info
487 ----------------------------
487 ----------------------------
488 alpha int 123
488 alpha int 123
489 beta str beta
489 beta str beta
490
490
491 In [7]: %who_ls
491 In [7]: %who_ls
492 Out[7]: ['alpha', 'beta']
492 Out[7]: ['alpha', 'beta']
493 """
493 """
494
494
495 def test_whos():
495 def test_whos():
496 """Check that whos is protected against objects where repr() fails."""
496 """Check that whos is protected against objects where repr() fails."""
497 class A(object):
497 class A(object):
498 def __repr__(self):
498 def __repr__(self):
499 raise Exception()
499 raise Exception()
500 _ip.user_ns['a'] = A()
500 _ip.user_ns['a'] = A()
501 _ip.magic("whos")
501 _ip.magic("whos")
502
502
503 @py3compat.u_format
503 @py3compat.u_format
504 def doctest_precision():
504 def doctest_precision():
505 """doctest for %precision
505 """doctest for %precision
506
506
507 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
507 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
508
508
509 In [2]: %precision 5
509 In [2]: %precision 5
510 Out[2]: {u}'%.5f'
510 Out[2]: {u}'%.5f'
511
511
512 In [3]: f.float_format
512 In [3]: f.float_format
513 Out[3]: {u}'%.5f'
513 Out[3]: {u}'%.5f'
514
514
515 In [4]: %precision %e
515 In [4]: %precision %e
516 Out[4]: {u}'%e'
516 Out[4]: {u}'%e'
517
517
518 In [5]: f(3.1415927)
518 In [5]: f(3.1415927)
519 Out[5]: {u}'3.141593e+00'
519 Out[5]: {u}'3.141593e+00'
520 """
520 """
521
521
522 def test_psearch():
522 def test_psearch():
523 with tt.AssertPrints("dict.fromkeys"):
523 with tt.AssertPrints("dict.fromkeys"):
524 _ip.run_cell("dict.fr*?")
524 _ip.run_cell("dict.fr*?")
525
525
526 def test_timeit_shlex():
526 def test_timeit_shlex():
527 """test shlex issues with timeit (#1109)"""
527 """test shlex issues with timeit (#1109)"""
528 _ip.ex("def f(*a,**kw): pass")
528 _ip.ex("def f(*a,**kw): pass")
529 _ip.magic('timeit -n1 "this is a bug".count(" ")')
529 _ip.magic('timeit -n1 "this is a bug".count(" ")')
530 _ip.magic('timeit -r1 -n1 f(" ", 1)')
530 _ip.magic('timeit -r1 -n1 f(" ", 1)')
531 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
531 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
532 _ip.magic('timeit -r1 -n1 ("a " + "b")')
532 _ip.magic('timeit -r1 -n1 ("a " + "b")')
533 _ip.magic('timeit -r1 -n1 f("a " + "b")')
533 _ip.magic('timeit -r1 -n1 f("a " + "b")')
534 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
534 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
535
535
536
536
537 def test_timeit_arguments():
537 def test_timeit_arguments():
538 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
538 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
539 _ip.magic("timeit ('#')")
539 _ip.magic("timeit ('#')")
540
540
541
541
542 def test_timeit_special_syntax():
542 def test_timeit_special_syntax():
543 "Test %%timeit with IPython special syntax"
543 "Test %%timeit with IPython special syntax"
544 @register_line_magic
544 @register_line_magic
545 def lmagic(line):
545 def lmagic(line):
546 ip = get_ipython()
546 ip = get_ipython()
547 ip.user_ns['lmagic_out'] = line
547 ip.user_ns['lmagic_out'] = line
548
548
549 # line mode test
549 # line mode test
550 _ip.run_line_magic('timeit', '-n1 -r1 %lmagic my line')
550 _ip.run_line_magic('timeit', '-n1 -r1 %lmagic my line')
551 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
551 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
552 # cell mode test
552 # cell mode test
553 _ip.run_cell_magic('timeit', '-n1 -r1', '%lmagic my line2')
553 _ip.run_cell_magic('timeit', '-n1 -r1', '%lmagic my line2')
554 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
554 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
555
555
556 def test_timeit_return():
556 def test_timeit_return():
557 """
557 """
558 test wether timeit -o return object
558 test wether timeit -o return object
559 """
559 """
560
560
561 res = _ip.run_line_magic('timeit','-n10 -r10 -o 1')
561 res = _ip.run_line_magic('timeit','-n10 -r10 -o 1')
562 assert(res is not None)
562 assert(res is not None)
563
563
564 def test_timeit_quiet():
564 def test_timeit_quiet():
565 """
565 """
566 test quiet option of timeit magic
566 test quiet option of timeit magic
567 """
567 """
568 with tt.AssertNotPrints("loops"):
568 with tt.AssertNotPrints("loops"):
569 _ip.run_cell("%timeit -n1 -r1 -q 1")
569 _ip.run_cell("%timeit -n1 -r1 -q 1")
570
570
571 @dec.skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
571 @dec.skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
572 def test_timeit_futures():
572 def test_timeit_futures():
573 "Test %timeit with __future__ environments"
573 "Test %timeit with __future__ environments"
574 ip = get_ipython()
574 ip = get_ipython()
575 ip.run_cell("from __future__ import division")
575 ip.run_cell("from __future__ import division")
576 with tt.AssertPrints('0.25'):
576 with tt.AssertPrints('0.25'):
577 ip.run_line_magic('timeit', '-n1 -r1 print(1/4)')
577 ip.run_line_magic('timeit', '-n1 -r1 print(1/4)')
578 ip.compile.reset_compiler_flags()
578 ip.compile.reset_compiler_flags()
579 with tt.AssertNotPrints('0.25'):
579 with tt.AssertNotPrints('0.25'):
580 ip.run_line_magic('timeit', '-n1 -r1 print(1/4)')
580 ip.run_line_magic('timeit', '-n1 -r1 print(1/4)')
581
581
582 @dec.skipif(execution.profile is None)
582 @dec.skipif(execution.profile is None)
583 def test_prun_special_syntax():
583 def test_prun_special_syntax():
584 "Test %%prun with IPython special syntax"
584 "Test %%prun with IPython special syntax"
585 @register_line_magic
585 @register_line_magic
586 def lmagic(line):
586 def lmagic(line):
587 ip = get_ipython()
587 ip = get_ipython()
588 ip.user_ns['lmagic_out'] = line
588 ip.user_ns['lmagic_out'] = line
589
589
590 # line mode test
590 # line mode test
591 _ip.run_line_magic('prun', '-q %lmagic my line')
591 _ip.run_line_magic('prun', '-q %lmagic my line')
592 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
592 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
593 # cell mode test
593 # cell mode test
594 _ip.run_cell_magic('prun', '-q', '%lmagic my line2')
594 _ip.run_cell_magic('prun', '-q', '%lmagic my line2')
595 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
595 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
596
596
597 @dec.skipif(execution.profile is None)
597 @dec.skipif(execution.profile is None)
598 def test_prun_quotes():
598 def test_prun_quotes():
599 "Test that prun does not clobber string escapes (GH #1302)"
599 "Test that prun does not clobber string escapes (GH #1302)"
600 _ip.magic(r"prun -q x = '\t'")
600 _ip.magic(r"prun -q x = '\t'")
601 nt.assert_equal(_ip.user_ns['x'], '\t')
601 nt.assert_equal(_ip.user_ns['x'], '\t')
602
602
603 def test_extension():
603 def test_extension():
604 tmpdir = TemporaryDirectory()
604 tmpdir = TemporaryDirectory()
605 orig_ipython_dir = _ip.ipython_dir
605 orig_ipython_dir = _ip.ipython_dir
606 try:
606 try:
607 _ip.ipython_dir = tmpdir.name
607 _ip.ipython_dir = tmpdir.name
608 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
608 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
609 url = os.path.join(os.path.dirname(__file__), "daft_extension.py")
609 url = os.path.join(os.path.dirname(__file__), "daft_extension.py")
610 _ip.magic("install_ext %s" % url)
610 _ip.magic("install_ext %s" % url)
611 _ip.user_ns.pop('arq', None)
611 _ip.user_ns.pop('arq', None)
612 invalidate_caches() # Clear import caches
612 invalidate_caches() # Clear import caches
613 _ip.magic("load_ext daft_extension")
613 _ip.magic("load_ext daft_extension")
614 nt.assert_equal(_ip.user_ns['arq'], 185)
614 nt.assert_equal(_ip.user_ns['arq'], 185)
615 _ip.magic("unload_ext daft_extension")
615 _ip.magic("unload_ext daft_extension")
616 assert 'arq' not in _ip.user_ns
616 assert 'arq' not in _ip.user_ns
617 finally:
617 finally:
618 _ip.ipython_dir = orig_ipython_dir
618 _ip.ipython_dir = orig_ipython_dir
619 tmpdir.cleanup()
619 tmpdir.cleanup()
620
620
621
621
622 # The nose skip decorator doesn't work on classes, so this uses unittest's skipIf
622 # The nose skip decorator doesn't work on classes, so this uses unittest's skipIf
623 @skipIf(dec.module_not_available('IPython.nbformat'), 'nbformat not importable')
623 @skipIf(dec.module_not_available('IPython.nbformat'), 'nbformat not importable')
624 class NotebookExportMagicTests(TestCase):
624 class NotebookExportMagicTests(TestCase):
625 def test_notebook_export_json(self):
625 def test_notebook_export_json(self):
626 _ip = get_ipython()
626 _ip = get_ipython()
627 _ip.history_manager.reset() # Clear any existing history.
627 _ip.history_manager.reset() # Clear any existing history.
628 cmds = [u"a=1", u"def b():\n return a**2", u"print(a, b())"]
628 cmds = [u"a=1", u"def b():\n return a**2", u"print('noΓ«l, Γ©tΓ©', b())"]
629 for i, cmd in enumerate(cmds, start=1):
629 for i, cmd in enumerate(cmds, start=1):
630 _ip.history_manager.store_inputs(i, cmd)
630 _ip.history_manager.store_inputs(i, cmd)
631 with TemporaryDirectory() as td:
631 with TemporaryDirectory() as td:
632 outfile = os.path.join(td, "nb.ipynb")
632 outfile = os.path.join(td, "nb.ipynb")
633 _ip.magic("notebook -e %s" % outfile)
633 _ip.magic("notebook -e %s" % outfile)
634
634
635
635
636 class TestEnv(TestCase):
636 class TestEnv(TestCase):
637
637
638 def test_env(self):
638 def test_env(self):
639 env = _ip.magic("env")
639 env = _ip.magic("env")
640 self.assertTrue(isinstance(env, dict))
640 self.assertTrue(isinstance(env, dict))
641
641
642 def test_env_get_set_simple(self):
642 def test_env_get_set_simple(self):
643 env = _ip.magic("env var val1")
643 env = _ip.magic("env var val1")
644 self.assertEqual(env, None)
644 self.assertEqual(env, None)
645 self.assertEqual(os.environ['var'], 'val1')
645 self.assertEqual(os.environ['var'], 'val1')
646 self.assertEqual(_ip.magic("env var"), 'val1')
646 self.assertEqual(_ip.magic("env var"), 'val1')
647 env = _ip.magic("env var=val2")
647 env = _ip.magic("env var=val2")
648 self.assertEqual(env, None)
648 self.assertEqual(env, None)
649 self.assertEqual(os.environ['var'], 'val2')
649 self.assertEqual(os.environ['var'], 'val2')
650
650
651 def test_env_get_set_complex(self):
651 def test_env_get_set_complex(self):
652 env = _ip.magic("env var 'val1 '' 'val2")
652 env = _ip.magic("env var 'val1 '' 'val2")
653 self.assertEqual(env, None)
653 self.assertEqual(env, None)
654 self.assertEqual(os.environ['var'], "'val1 '' 'val2")
654 self.assertEqual(os.environ['var'], "'val1 '' 'val2")
655 self.assertEqual(_ip.magic("env var"), "'val1 '' 'val2")
655 self.assertEqual(_ip.magic("env var"), "'val1 '' 'val2")
656 env = _ip.magic('env var=val2 val3="val4')
656 env = _ip.magic('env var=val2 val3="val4')
657 self.assertEqual(env, None)
657 self.assertEqual(env, None)
658 self.assertEqual(os.environ['var'], 'val2 val3="val4')
658 self.assertEqual(os.environ['var'], 'val2 val3="val4')
659
659
660 def test_env_set_bad_input(self):
660 def test_env_set_bad_input(self):
661 self.assertRaises(UsageError, lambda: _ip.magic("set_env var"))
661 self.assertRaises(UsageError, lambda: _ip.magic("set_env var"))
662
662
663 def test_env_set_whitespace(self):
663 def test_env_set_whitespace(self):
664 self.assertRaises(UsageError, lambda: _ip.magic("env var A=B"))
664 self.assertRaises(UsageError, lambda: _ip.magic("env var A=B"))
665
665
666
666
667 class CellMagicTestCase(TestCase):
667 class CellMagicTestCase(TestCase):
668
668
669 def check_ident(self, magic):
669 def check_ident(self, magic):
670 # Manually called, we get the result
670 # Manually called, we get the result
671 out = _ip.run_cell_magic(magic, 'a', 'b')
671 out = _ip.run_cell_magic(magic, 'a', 'b')
672 nt.assert_equal(out, ('a','b'))
672 nt.assert_equal(out, ('a','b'))
673 # Via run_cell, it goes into the user's namespace via displayhook
673 # Via run_cell, it goes into the user's namespace via displayhook
674 _ip.run_cell('%%' + magic +' c\nd')
674 _ip.run_cell('%%' + magic +' c\nd')
675 nt.assert_equal(_ip.user_ns['_'], ('c','d'))
675 nt.assert_equal(_ip.user_ns['_'], ('c','d'))
676
676
677 def test_cell_magic_func_deco(self):
677 def test_cell_magic_func_deco(self):
678 "Cell magic using simple decorator"
678 "Cell magic using simple decorator"
679 @register_cell_magic
679 @register_cell_magic
680 def cellm(line, cell):
680 def cellm(line, cell):
681 return line, cell
681 return line, cell
682
682
683 self.check_ident('cellm')
683 self.check_ident('cellm')
684
684
685 def test_cell_magic_reg(self):
685 def test_cell_magic_reg(self):
686 "Cell magic manually registered"
686 "Cell magic manually registered"
687 def cellm(line, cell):
687 def cellm(line, cell):
688 return line, cell
688 return line, cell
689
689
690 _ip.register_magic_function(cellm, 'cell', 'cellm2')
690 _ip.register_magic_function(cellm, 'cell', 'cellm2')
691 self.check_ident('cellm2')
691 self.check_ident('cellm2')
692
692
693 def test_cell_magic_class(self):
693 def test_cell_magic_class(self):
694 "Cell magics declared via a class"
694 "Cell magics declared via a class"
695 @magics_class
695 @magics_class
696 class MyMagics(Magics):
696 class MyMagics(Magics):
697
697
698 @cell_magic
698 @cell_magic
699 def cellm3(self, line, cell):
699 def cellm3(self, line, cell):
700 return line, cell
700 return line, cell
701
701
702 _ip.register_magics(MyMagics)
702 _ip.register_magics(MyMagics)
703 self.check_ident('cellm3')
703 self.check_ident('cellm3')
704
704
705 def test_cell_magic_class2(self):
705 def test_cell_magic_class2(self):
706 "Cell magics declared via a class, #2"
706 "Cell magics declared via a class, #2"
707 @magics_class
707 @magics_class
708 class MyMagics2(Magics):
708 class MyMagics2(Magics):
709
709
710 @cell_magic('cellm4')
710 @cell_magic('cellm4')
711 def cellm33(self, line, cell):
711 def cellm33(self, line, cell):
712 return line, cell
712 return line, cell
713
713
714 _ip.register_magics(MyMagics2)
714 _ip.register_magics(MyMagics2)
715 self.check_ident('cellm4')
715 self.check_ident('cellm4')
716 # Check that nothing is registered as 'cellm33'
716 # Check that nothing is registered as 'cellm33'
717 c33 = _ip.find_cell_magic('cellm33')
717 c33 = _ip.find_cell_magic('cellm33')
718 nt.assert_equal(c33, None)
718 nt.assert_equal(c33, None)
719
719
720 def test_file():
720 def test_file():
721 """Basic %%file"""
721 """Basic %%file"""
722 ip = get_ipython()
722 ip = get_ipython()
723 with TemporaryDirectory() as td:
723 with TemporaryDirectory() as td:
724 fname = os.path.join(td, 'file1')
724 fname = os.path.join(td, 'file1')
725 ip.run_cell_magic("file", fname, u'\n'.join([
725 ip.run_cell_magic("file", fname, u'\n'.join([
726 'line1',
726 'line1',
727 'line2',
727 'line2',
728 ]))
728 ]))
729 with open(fname) as f:
729 with open(fname) as f:
730 s = f.read()
730 s = f.read()
731 nt.assert_in('line1\n', s)
731 nt.assert_in('line1\n', s)
732 nt.assert_in('line2', s)
732 nt.assert_in('line2', s)
733
733
734 def test_file_var_expand():
734 def test_file_var_expand():
735 """%%file $filename"""
735 """%%file $filename"""
736 ip = get_ipython()
736 ip = get_ipython()
737 with TemporaryDirectory() as td:
737 with TemporaryDirectory() as td:
738 fname = os.path.join(td, 'file1')
738 fname = os.path.join(td, 'file1')
739 ip.user_ns['filename'] = fname
739 ip.user_ns['filename'] = fname
740 ip.run_cell_magic("file", '$filename', u'\n'.join([
740 ip.run_cell_magic("file", '$filename', u'\n'.join([
741 'line1',
741 'line1',
742 'line2',
742 'line2',
743 ]))
743 ]))
744 with open(fname) as f:
744 with open(fname) as f:
745 s = f.read()
745 s = f.read()
746 nt.assert_in('line1\n', s)
746 nt.assert_in('line1\n', s)
747 nt.assert_in('line2', s)
747 nt.assert_in('line2', s)
748
748
749 def test_file_unicode():
749 def test_file_unicode():
750 """%%file with unicode cell"""
750 """%%file with unicode cell"""
751 ip = get_ipython()
751 ip = get_ipython()
752 with TemporaryDirectory() as td:
752 with TemporaryDirectory() as td:
753 fname = os.path.join(td, 'file1')
753 fname = os.path.join(td, 'file1')
754 ip.run_cell_magic("file", fname, u'\n'.join([
754 ip.run_cell_magic("file", fname, u'\n'.join([
755 u'linΓ©1',
755 u'linΓ©1',
756 u'linΓ©2',
756 u'linΓ©2',
757 ]))
757 ]))
758 with io.open(fname, encoding='utf-8') as f:
758 with io.open(fname, encoding='utf-8') as f:
759 s = f.read()
759 s = f.read()
760 nt.assert_in(u'linΓ©1\n', s)
760 nt.assert_in(u'linΓ©1\n', s)
761 nt.assert_in(u'linΓ©2', s)
761 nt.assert_in(u'linΓ©2', s)
762
762
763 def test_file_amend():
763 def test_file_amend():
764 """%%file -a amends files"""
764 """%%file -a amends files"""
765 ip = get_ipython()
765 ip = get_ipython()
766 with TemporaryDirectory() as td:
766 with TemporaryDirectory() as td:
767 fname = os.path.join(td, 'file2')
767 fname = os.path.join(td, 'file2')
768 ip.run_cell_magic("file", fname, u'\n'.join([
768 ip.run_cell_magic("file", fname, u'\n'.join([
769 'line1',
769 'line1',
770 'line2',
770 'line2',
771 ]))
771 ]))
772 ip.run_cell_magic("file", "-a %s" % fname, u'\n'.join([
772 ip.run_cell_magic("file", "-a %s" % fname, u'\n'.join([
773 'line3',
773 'line3',
774 'line4',
774 'line4',
775 ]))
775 ]))
776 with open(fname) as f:
776 with open(fname) as f:
777 s = f.read()
777 s = f.read()
778 nt.assert_in('line1\n', s)
778 nt.assert_in('line1\n', s)
779 nt.assert_in('line3\n', s)
779 nt.assert_in('line3\n', s)
780
780
781
781
782 def test_script_config():
782 def test_script_config():
783 ip = get_ipython()
783 ip = get_ipython()
784 ip.config.ScriptMagics.script_magics = ['whoda']
784 ip.config.ScriptMagics.script_magics = ['whoda']
785 sm = script.ScriptMagics(shell=ip)
785 sm = script.ScriptMagics(shell=ip)
786 nt.assert_in('whoda', sm.magics['cell'])
786 nt.assert_in('whoda', sm.magics['cell'])
787
787
788 @dec.skip_win32
788 @dec.skip_win32
789 def test_script_out():
789 def test_script_out():
790 ip = get_ipython()
790 ip = get_ipython()
791 ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
791 ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
792 nt.assert_equal(ip.user_ns['output'], 'hi\n')
792 nt.assert_equal(ip.user_ns['output'], 'hi\n')
793
793
794 @dec.skip_win32
794 @dec.skip_win32
795 def test_script_err():
795 def test_script_err():
796 ip = get_ipython()
796 ip = get_ipython()
797 ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
797 ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
798 nt.assert_equal(ip.user_ns['error'], 'hello\n')
798 nt.assert_equal(ip.user_ns['error'], 'hello\n')
799
799
800 @dec.skip_win32
800 @dec.skip_win32
801 def test_script_out_err():
801 def test_script_out_err():
802 ip = get_ipython()
802 ip = get_ipython()
803 ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
803 ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
804 nt.assert_equal(ip.user_ns['output'], 'hi\n')
804 nt.assert_equal(ip.user_ns['output'], 'hi\n')
805 nt.assert_equal(ip.user_ns['error'], 'hello\n')
805 nt.assert_equal(ip.user_ns['error'], 'hello\n')
806
806
807 @dec.skip_win32
807 @dec.skip_win32
808 def test_script_bg_out():
808 def test_script_bg_out():
809 ip = get_ipython()
809 ip = get_ipython()
810 ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
810 ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
811 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
811 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
812
812
813 @dec.skip_win32
813 @dec.skip_win32
814 def test_script_bg_err():
814 def test_script_bg_err():
815 ip = get_ipython()
815 ip = get_ipython()
816 ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
816 ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
817 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
817 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
818
818
819 @dec.skip_win32
819 @dec.skip_win32
820 def test_script_bg_out_err():
820 def test_script_bg_out_err():
821 ip = get_ipython()
821 ip = get_ipython()
822 ip.run_cell_magic("script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2")
822 ip.run_cell_magic("script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2")
823 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
823 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
824 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
824 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
825
825
826 def test_script_defaults():
826 def test_script_defaults():
827 ip = get_ipython()
827 ip = get_ipython()
828 for cmd in ['sh', 'bash', 'perl', 'ruby']:
828 for cmd in ['sh', 'bash', 'perl', 'ruby']:
829 try:
829 try:
830 find_cmd(cmd)
830 find_cmd(cmd)
831 except Exception:
831 except Exception:
832 pass
832 pass
833 else:
833 else:
834 nt.assert_in(cmd, ip.magics_manager.magics['cell'])
834 nt.assert_in(cmd, ip.magics_manager.magics['cell'])
835
835
836
836
837 @magics_class
837 @magics_class
838 class FooFoo(Magics):
838 class FooFoo(Magics):
839 """class with both %foo and %%foo magics"""
839 """class with both %foo and %%foo magics"""
840 @line_magic('foo')
840 @line_magic('foo')
841 def line_foo(self, line):
841 def line_foo(self, line):
842 "I am line foo"
842 "I am line foo"
843 pass
843 pass
844
844
845 @cell_magic("foo")
845 @cell_magic("foo")
846 def cell_foo(self, line, cell):
846 def cell_foo(self, line, cell):
847 "I am cell foo, not line foo"
847 "I am cell foo, not line foo"
848 pass
848 pass
849
849
850 def test_line_cell_info():
850 def test_line_cell_info():
851 """%%foo and %foo magics are distinguishable to inspect"""
851 """%%foo and %foo magics are distinguishable to inspect"""
852 ip = get_ipython()
852 ip = get_ipython()
853 ip.magics_manager.register(FooFoo)
853 ip.magics_manager.register(FooFoo)
854 oinfo = ip.object_inspect('foo')
854 oinfo = ip.object_inspect('foo')
855 nt.assert_true(oinfo['found'])
855 nt.assert_true(oinfo['found'])
856 nt.assert_true(oinfo['ismagic'])
856 nt.assert_true(oinfo['ismagic'])
857
857
858 oinfo = ip.object_inspect('%%foo')
858 oinfo = ip.object_inspect('%%foo')
859 nt.assert_true(oinfo['found'])
859 nt.assert_true(oinfo['found'])
860 nt.assert_true(oinfo['ismagic'])
860 nt.assert_true(oinfo['ismagic'])
861 nt.assert_equal(oinfo['docstring'], FooFoo.cell_foo.__doc__)
861 nt.assert_equal(oinfo['docstring'], FooFoo.cell_foo.__doc__)
862
862
863 oinfo = ip.object_inspect('%foo')
863 oinfo = ip.object_inspect('%foo')
864 nt.assert_true(oinfo['found'])
864 nt.assert_true(oinfo['found'])
865 nt.assert_true(oinfo['ismagic'])
865 nt.assert_true(oinfo['ismagic'])
866 nt.assert_equal(oinfo['docstring'], FooFoo.line_foo.__doc__)
866 nt.assert_equal(oinfo['docstring'], FooFoo.line_foo.__doc__)
867
867
868 def test_multiple_magics():
868 def test_multiple_magics():
869 ip = get_ipython()
869 ip = get_ipython()
870 foo1 = FooFoo(ip)
870 foo1 = FooFoo(ip)
871 foo2 = FooFoo(ip)
871 foo2 = FooFoo(ip)
872 mm = ip.magics_manager
872 mm = ip.magics_manager
873 mm.register(foo1)
873 mm.register(foo1)
874 nt.assert_true(mm.magics['line']['foo'].__self__ is foo1)
874 nt.assert_true(mm.magics['line']['foo'].__self__ is foo1)
875 mm.register(foo2)
875 mm.register(foo2)
876 nt.assert_true(mm.magics['line']['foo'].__self__ is foo2)
876 nt.assert_true(mm.magics['line']['foo'].__self__ is foo2)
877
877
878 def test_alias_magic():
878 def test_alias_magic():
879 """Test %alias_magic."""
879 """Test %alias_magic."""
880 ip = get_ipython()
880 ip = get_ipython()
881 mm = ip.magics_manager
881 mm = ip.magics_manager
882
882
883 # Basic operation: both cell and line magics are created, if possible.
883 # Basic operation: both cell and line magics are created, if possible.
884 ip.run_line_magic('alias_magic', 'timeit_alias timeit')
884 ip.run_line_magic('alias_magic', 'timeit_alias timeit')
885 nt.assert_in('timeit_alias', mm.magics['line'])
885 nt.assert_in('timeit_alias', mm.magics['line'])
886 nt.assert_in('timeit_alias', mm.magics['cell'])
886 nt.assert_in('timeit_alias', mm.magics['cell'])
887
887
888 # --cell is specified, line magic not created.
888 # --cell is specified, line magic not created.
889 ip.run_line_magic('alias_magic', '--cell timeit_cell_alias timeit')
889 ip.run_line_magic('alias_magic', '--cell timeit_cell_alias timeit')
890 nt.assert_not_in('timeit_cell_alias', mm.magics['line'])
890 nt.assert_not_in('timeit_cell_alias', mm.magics['line'])
891 nt.assert_in('timeit_cell_alias', mm.magics['cell'])
891 nt.assert_in('timeit_cell_alias', mm.magics['cell'])
892
892
893 # Test that line alias is created successfully.
893 # Test that line alias is created successfully.
894 ip.run_line_magic('alias_magic', '--line env_alias env')
894 ip.run_line_magic('alias_magic', '--line env_alias env')
895 nt.assert_equal(ip.run_line_magic('env', ''),
895 nt.assert_equal(ip.run_line_magic('env', ''),
896 ip.run_line_magic('env_alias', ''))
896 ip.run_line_magic('env_alias', ''))
897
897
898 def test_save():
898 def test_save():
899 """Test %save."""
899 """Test %save."""
900 ip = get_ipython()
900 ip = get_ipython()
901 ip.history_manager.reset() # Clear any existing history.
901 ip.history_manager.reset() # Clear any existing history.
902 cmds = [u"a=1", u"def b():\n return a**2", u"print(a, b())"]
902 cmds = [u"a=1", u"def b():\n return a**2", u"print(a, b())"]
903 for i, cmd in enumerate(cmds, start=1):
903 for i, cmd in enumerate(cmds, start=1):
904 ip.history_manager.store_inputs(i, cmd)
904 ip.history_manager.store_inputs(i, cmd)
905 with TemporaryDirectory() as tmpdir:
905 with TemporaryDirectory() as tmpdir:
906 file = os.path.join(tmpdir, "testsave.py")
906 file = os.path.join(tmpdir, "testsave.py")
907 ip.run_line_magic("save", "%s 1-10" % file)
907 ip.run_line_magic("save", "%s 1-10" % file)
908 with open(file) as f:
908 with open(file) as f:
909 content = f.read()
909 content = f.read()
910 nt.assert_equal(content.count(cmds[0]), 1)
910 nt.assert_equal(content.count(cmds[0]), 1)
911 nt.assert_in('coding: utf-8', content)
911 nt.assert_in('coding: utf-8', content)
912 ip.run_line_magic("save", "-a %s 1-10" % file)
912 ip.run_line_magic("save", "-a %s 1-10" % file)
913 with open(file) as f:
913 with open(file) as f:
914 content = f.read()
914 content = f.read()
915 nt.assert_equal(content.count(cmds[0]), 2)
915 nt.assert_equal(content.count(cmds[0]), 2)
916 nt.assert_in('coding: utf-8', content)
916 nt.assert_in('coding: utf-8', content)
917
917
918
918
919 def test_store():
919 def test_store():
920 """Test %store."""
920 """Test %store."""
921 ip = get_ipython()
921 ip = get_ipython()
922 ip.run_line_magic('load_ext', 'storemagic')
922 ip.run_line_magic('load_ext', 'storemagic')
923
923
924 # make sure the storage is empty
924 # make sure the storage is empty
925 ip.run_line_magic('store', '-z')
925 ip.run_line_magic('store', '-z')
926 ip.user_ns['var'] = 42
926 ip.user_ns['var'] = 42
927 ip.run_line_magic('store', 'var')
927 ip.run_line_magic('store', 'var')
928 ip.user_ns['var'] = 39
928 ip.user_ns['var'] = 39
929 ip.run_line_magic('store', '-r')
929 ip.run_line_magic('store', '-r')
930 nt.assert_equal(ip.user_ns['var'], 42)
930 nt.assert_equal(ip.user_ns['var'], 42)
931
931
932 ip.run_line_magic('store', '-d var')
932 ip.run_line_magic('store', '-d var')
933 ip.user_ns['var'] = 39
933 ip.user_ns['var'] = 39
934 ip.run_line_magic('store' , '-r')
934 ip.run_line_magic('store' , '-r')
935 nt.assert_equal(ip.user_ns['var'], 39)
935 nt.assert_equal(ip.user_ns['var'], 39)
936
936
937
937
938 def _run_edit_test(arg_s, exp_filename=None,
938 def _run_edit_test(arg_s, exp_filename=None,
939 exp_lineno=-1,
939 exp_lineno=-1,
940 exp_contents=None,
940 exp_contents=None,
941 exp_is_temp=None):
941 exp_is_temp=None):
942 ip = get_ipython()
942 ip = get_ipython()
943 M = code.CodeMagics(ip)
943 M = code.CodeMagics(ip)
944 last_call = ['','']
944 last_call = ['','']
945 opts,args = M.parse_options(arg_s,'prxn:')
945 opts,args = M.parse_options(arg_s,'prxn:')
946 filename, lineno, is_temp = M._find_edit_target(ip, args, opts, last_call)
946 filename, lineno, is_temp = M._find_edit_target(ip, args, opts, last_call)
947
947
948 if exp_filename is not None:
948 if exp_filename is not None:
949 nt.assert_equal(exp_filename, filename)
949 nt.assert_equal(exp_filename, filename)
950 if exp_contents is not None:
950 if exp_contents is not None:
951 with io.open(filename, 'r', encoding='utf-8') as f:
951 with io.open(filename, 'r', encoding='utf-8') as f:
952 contents = f.read()
952 contents = f.read()
953 nt.assert_equal(exp_contents, contents)
953 nt.assert_equal(exp_contents, contents)
954 if exp_lineno != -1:
954 if exp_lineno != -1:
955 nt.assert_equal(exp_lineno, lineno)
955 nt.assert_equal(exp_lineno, lineno)
956 if exp_is_temp is not None:
956 if exp_is_temp is not None:
957 nt.assert_equal(exp_is_temp, is_temp)
957 nt.assert_equal(exp_is_temp, is_temp)
958
958
959
959
960 def test_edit_interactive():
960 def test_edit_interactive():
961 """%edit on interactively defined objects"""
961 """%edit on interactively defined objects"""
962 ip = get_ipython()
962 ip = get_ipython()
963 n = ip.execution_count
963 n = ip.execution_count
964 ip.run_cell(u"def foo(): return 1", store_history=True)
964 ip.run_cell(u"def foo(): return 1", store_history=True)
965
965
966 try:
966 try:
967 _run_edit_test("foo")
967 _run_edit_test("foo")
968 except code.InteractivelyDefined as e:
968 except code.InteractivelyDefined as e:
969 nt.assert_equal(e.index, n)
969 nt.assert_equal(e.index, n)
970 else:
970 else:
971 raise AssertionError("Should have raised InteractivelyDefined")
971 raise AssertionError("Should have raised InteractivelyDefined")
972
972
973
973
974 def test_edit_cell():
974 def test_edit_cell():
975 """%edit [cell id]"""
975 """%edit [cell id]"""
976 ip = get_ipython()
976 ip = get_ipython()
977
977
978 ip.run_cell(u"def foo(): return 1", store_history=True)
978 ip.run_cell(u"def foo(): return 1", store_history=True)
979
979
980 # test
980 # test
981 _run_edit_test("1", exp_contents=ip.user_ns['In'][1], exp_is_temp=True)
981 _run_edit_test("1", exp_contents=ip.user_ns['In'][1], exp_is_temp=True)
982
982
983 def test_bookmark():
983 def test_bookmark():
984 ip = get_ipython()
984 ip = get_ipython()
985 ip.run_line_magic('bookmark', 'bmname')
985 ip.run_line_magic('bookmark', 'bmname')
986 with tt.AssertPrints('bmname'):
986 with tt.AssertPrints('bmname'):
987 ip.run_line_magic('bookmark', '-l')
987 ip.run_line_magic('bookmark', '-l')
988 ip.run_line_magic('bookmark', '-d bmname')
988 ip.run_line_magic('bookmark', '-d bmname')
989
989
990 def test_ls_magic():
990 def test_ls_magic():
991 ip = get_ipython()
991 ip = get_ipython()
992 json_formatter = ip.display_formatter.formatters['application/json']
992 json_formatter = ip.display_formatter.formatters['application/json']
993 json_formatter.enabled = True
993 json_formatter.enabled = True
994 lsmagic = ip.magic('lsmagic')
994 lsmagic = ip.magic('lsmagic')
995 with warnings.catch_warnings(record=True) as w:
995 with warnings.catch_warnings(record=True) as w:
996 j = json_formatter(lsmagic)
996 j = json_formatter(lsmagic)
997 nt.assert_equal(sorted(j), ['cell', 'line'])
997 nt.assert_equal(sorted(j), ['cell', 'line'])
998 nt.assert_equal(w, []) # no warnings
998 nt.assert_equal(w, []) # no warnings
General Comments 0
You need to be logged in to leave comments. Login now