##// END OF EJS Templates
Merge pull request #2855 from JanSchulz/2751_timit...
Thomas Kluyver -
r9483:50cb32f8 merge
parent child Browse files
Show More
@@ -1,1094 +1,1116 b''
1 # -*- coding: utf-8 -*-
1 """Implementation of execution-related magic functions.
2 """Implementation of execution-related magic functions.
2 """
3 """
3 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012 The IPython Development Team.
5 # Copyright (c) 2012 The IPython Development Team.
5 #
6 #
6 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
7 #
8 #
8 # The full license is in the file COPYING.txt, distributed with this software.
9 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
10
11
11 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
12 # Imports
13 # Imports
13 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
14
15
15 # Stdlib
16 # Stdlib
16 import __builtin__ as builtin_mod
17 import __builtin__ as builtin_mod
17 import ast
18 import ast
18 import bdb
19 import bdb
19 import os
20 import os
20 import sys
21 import sys
21 import time
22 import time
22 from StringIO import StringIO
23 from StringIO import StringIO
23
24
24 # cProfile was added in Python2.5
25 # cProfile was added in Python2.5
25 try:
26 try:
26 import cProfile as profile
27 import cProfile as profile
27 import pstats
28 import pstats
28 except ImportError:
29 except ImportError:
29 # profile isn't bundled by default in Debian for license reasons
30 # profile isn't bundled by default in Debian for license reasons
30 try:
31 try:
31 import profile, pstats
32 import profile, pstats
32 except ImportError:
33 except ImportError:
33 profile = pstats = None
34 profile = pstats = None
34
35
35 # Our own packages
36 # Our own packages
36 from IPython.core import debugger, oinspect
37 from IPython.core import debugger, oinspect
37 from IPython.core import magic_arguments
38 from IPython.core import magic_arguments
38 from IPython.core import page
39 from IPython.core import page
39 from IPython.core.error import UsageError
40 from IPython.core.error import UsageError
40 from IPython.core.macro import Macro
41 from IPython.core.macro import Macro
41 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
42 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
42 line_cell_magic, on_off, needs_local_scope)
43 line_cell_magic, on_off, needs_local_scope)
43 from IPython.testing.skipdoctest import skip_doctest
44 from IPython.testing.skipdoctest import skip_doctest
44 from IPython.utils import py3compat
45 from IPython.utils import py3compat
45 from IPython.utils.contexts import preserve_keys
46 from IPython.utils.contexts import preserve_keys
46 from IPython.utils.io import capture_output
47 from IPython.utils.io import capture_output
47 from IPython.utils.ipstruct import Struct
48 from IPython.utils.ipstruct import Struct
48 from IPython.utils.module_paths import find_mod
49 from IPython.utils.module_paths import find_mod
49 from IPython.utils.path import get_py_filename, unquote_filename, shellglob
50 from IPython.utils.path import get_py_filename, unquote_filename, shellglob
50 from IPython.utils.timing import clock, clock2
51 from IPython.utils.timing import clock, clock2
51 from IPython.utils.warn import warn, error
52 from IPython.utils.warn import warn, error
52
53
53
54
54 #-----------------------------------------------------------------------------
55 #-----------------------------------------------------------------------------
55 # Magic implementation classes
56 # Magic implementation classes
56 #-----------------------------------------------------------------------------
57 #-----------------------------------------------------------------------------
57
58
58 @magics_class
59 @magics_class
59 class ExecutionMagics(Magics):
60 class ExecutionMagics(Magics):
60 """Magics related to code execution, debugging, profiling, etc.
61 """Magics related to code execution, debugging, profiling, etc.
61
62
62 """
63 """
63
64
64 def __init__(self, shell):
65 def __init__(self, shell):
65 super(ExecutionMagics, self).__init__(shell)
66 super(ExecutionMagics, self).__init__(shell)
66 if profile is None:
67 if profile is None:
67 self.prun = self.profile_missing_notice
68 self.prun = self.profile_missing_notice
68 # Default execution function used to actually run user code.
69 # Default execution function used to actually run user code.
69 self.default_runner = None
70 self.default_runner = None
70
71
71 def profile_missing_notice(self, *args, **kwargs):
72 def profile_missing_notice(self, *args, **kwargs):
72 error("""\
73 error("""\
73 The profile module could not be found. It has been removed from the standard
74 The profile module could not be found. It has been removed from the standard
74 python packages because of its non-free license. To use profiling, install the
75 python packages because of its non-free license. To use profiling, install the
75 python-profiler package from non-free.""")
76 python-profiler package from non-free.""")
76
77
77 @skip_doctest
78 @skip_doctest
78 @line_cell_magic
79 @line_cell_magic
79 def prun(self, parameter_s='', cell=None, user_mode=True,
80 def prun(self, parameter_s='', cell=None, user_mode=True,
80 opts=None,arg_lst=None,prog_ns=None):
81 opts=None,arg_lst=None,prog_ns=None):
81
82
82 """Run a statement through the python code profiler.
83 """Run a statement through the python code profiler.
83
84
84 Usage, in line mode:
85 Usage, in line mode:
85 %prun [options] statement
86 %prun [options] statement
86
87
87 Usage, in cell mode:
88 Usage, in cell mode:
88 %%prun [options] [statement]
89 %%prun [options] [statement]
89 code...
90 code...
90 code...
91 code...
91
92
92 In cell mode, the additional code lines are appended to the (possibly
93 In cell mode, the additional code lines are appended to the (possibly
93 empty) statement in the first line. Cell mode allows you to easily
94 empty) statement in the first line. Cell mode allows you to easily
94 profile multiline blocks without having to put them in a separate
95 profile multiline blocks without having to put them in a separate
95 function.
96 function.
96
97
97 The given statement (which doesn't require quote marks) is run via the
98 The given statement (which doesn't require quote marks) is run via the
98 python profiler in a manner similar to the profile.run() function.
99 python profiler in a manner similar to the profile.run() function.
99 Namespaces are internally managed to work correctly; profile.run
100 Namespaces are internally managed to work correctly; profile.run
100 cannot be used in IPython because it makes certain assumptions about
101 cannot be used in IPython because it makes certain assumptions about
101 namespaces which do not hold under IPython.
102 namespaces which do not hold under IPython.
102
103
103 Options:
104 Options:
104
105
105 -l <limit>: you can place restrictions on what or how much of the
106 -l <limit>: you can place restrictions on what or how much of the
106 profile gets printed. The limit value can be:
107 profile gets printed. The limit value can be:
107
108
108 * A string: only information for function names containing this string
109 * A string: only information for function names containing this string
109 is printed.
110 is printed.
110
111
111 * An integer: only these many lines are printed.
112 * An integer: only these many lines are printed.
112
113
113 * A float (between 0 and 1): this fraction of the report is printed
114 * A float (between 0 and 1): this fraction of the report is printed
114 (for example, use a limit of 0.4 to see the topmost 40% only).
115 (for example, use a limit of 0.4 to see the topmost 40% only).
115
116
116 You can combine several limits with repeated use of the option. For
117 You can combine several limits with repeated use of the option. For
117 example, '-l __init__ -l 5' will print only the topmost 5 lines of
118 example, '-l __init__ -l 5' will print only the topmost 5 lines of
118 information about class constructors.
119 information about class constructors.
119
120
120 -r: return the pstats.Stats object generated by the profiling. This
121 -r: return the pstats.Stats object generated by the profiling. This
121 object has all the information about the profile in it, and you can
122 object has all the information about the profile in it, and you can
122 later use it for further analysis or in other functions.
123 later use it for further analysis or in other functions.
123
124
124 -s <key>: sort profile by given key. You can provide more than one key
125 -s <key>: sort profile by given key. You can provide more than one key
125 by using the option several times: '-s key1 -s key2 -s key3...'. The
126 by using the option several times: '-s key1 -s key2 -s key3...'. The
126 default sorting key is 'time'.
127 default sorting key is 'time'.
127
128
128 The following is copied verbatim from the profile documentation
129 The following is copied verbatim from the profile documentation
129 referenced below:
130 referenced below:
130
131
131 When more than one key is provided, additional keys are used as
132 When more than one key is provided, additional keys are used as
132 secondary criteria when the there is equality in all keys selected
133 secondary criteria when the there is equality in all keys selected
133 before them.
134 before them.
134
135
135 Abbreviations can be used for any key names, as long as the
136 Abbreviations can be used for any key names, as long as the
136 abbreviation is unambiguous. The following are the keys currently
137 abbreviation is unambiguous. The following are the keys currently
137 defined:
138 defined:
138
139
139 Valid Arg Meaning
140 Valid Arg Meaning
140 "calls" call count
141 "calls" call count
141 "cumulative" cumulative time
142 "cumulative" cumulative time
142 "file" file name
143 "file" file name
143 "module" file name
144 "module" file name
144 "pcalls" primitive call count
145 "pcalls" primitive call count
145 "line" line number
146 "line" line number
146 "name" function name
147 "name" function name
147 "nfl" name/file/line
148 "nfl" name/file/line
148 "stdname" standard name
149 "stdname" standard name
149 "time" internal time
150 "time" internal time
150
151
151 Note that all sorts on statistics are in descending order (placing
152 Note that all sorts on statistics are in descending order (placing
152 most time consuming items first), where as name, file, and line number
153 most time consuming items first), where as name, file, and line number
153 searches are in ascending order (i.e., alphabetical). The subtle
154 searches are in ascending order (i.e., alphabetical). The subtle
154 distinction between "nfl" and "stdname" is that the standard name is a
155 distinction between "nfl" and "stdname" is that the standard name is a
155 sort of the name as printed, which means that the embedded line
156 sort of the name as printed, which means that the embedded line
156 numbers get compared in an odd way. For example, lines 3, 20, and 40
157 numbers get compared in an odd way. For example, lines 3, 20, and 40
157 would (if the file names were the same) appear in the string order
158 would (if the file names were the same) appear in the string order
158 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
159 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
159 line numbers. In fact, sort_stats("nfl") is the same as
160 line numbers. In fact, sort_stats("nfl") is the same as
160 sort_stats("name", "file", "line").
161 sort_stats("name", "file", "line").
161
162
162 -T <filename>: save profile results as shown on screen to a text
163 -T <filename>: save profile results as shown on screen to a text
163 file. The profile is still shown on screen.
164 file. The profile is still shown on screen.
164
165
165 -D <filename>: save (via dump_stats) profile statistics to given
166 -D <filename>: save (via dump_stats) profile statistics to given
166 filename. This data is in a format understood by the pstats module, and
167 filename. This data is in a format understood by the pstats module, and
167 is generated by a call to the dump_stats() method of profile
168 is generated by a call to the dump_stats() method of profile
168 objects. The profile is still shown on screen.
169 objects. The profile is still shown on screen.
169
170
170 -q: suppress output to the pager. Best used with -T and/or -D above.
171 -q: suppress output to the pager. Best used with -T and/or -D above.
171
172
172 If you want to run complete programs under the profiler's control, use
173 If you want to run complete programs under the profiler's control, use
173 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
174 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
174 contains profiler specific options as described here.
175 contains profiler specific options as described here.
175
176
176 You can read the complete documentation for the profile module with::
177 You can read the complete documentation for the profile module with::
177
178
178 In [1]: import profile; profile.help()
179 In [1]: import profile; profile.help()
179 """
180 """
180
181
181 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
182 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
182
183
183 if user_mode: # regular user call
184 if user_mode: # regular user call
184 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:q',
185 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:q',
185 list_all=True, posix=False)
186 list_all=True, posix=False)
186 namespace = self.shell.user_ns
187 namespace = self.shell.user_ns
187 if cell is not None:
188 if cell is not None:
188 arg_str += '\n' + cell
189 arg_str += '\n' + cell
189 else: # called to run a program by %run -p
190 else: # called to run a program by %run -p
190 try:
191 try:
191 filename = get_py_filename(arg_lst[0])
192 filename = get_py_filename(arg_lst[0])
192 except IOError as e:
193 except IOError as e:
193 try:
194 try:
194 msg = str(e)
195 msg = str(e)
195 except UnicodeError:
196 except UnicodeError:
196 msg = e.message
197 msg = e.message
197 error(msg)
198 error(msg)
198 return
199 return
199
200
200 arg_str = 'execfile(filename,prog_ns)'
201 arg_str = 'execfile(filename,prog_ns)'
201 namespace = {
202 namespace = {
202 'execfile': self.shell.safe_execfile,
203 'execfile': self.shell.safe_execfile,
203 'prog_ns': prog_ns,
204 'prog_ns': prog_ns,
204 'filename': filename
205 'filename': filename
205 }
206 }
206
207
207 opts.merge(opts_def)
208 opts.merge(opts_def)
208
209
209 prof = profile.Profile()
210 prof = profile.Profile()
210 try:
211 try:
211 prof = prof.runctx(arg_str,namespace,namespace)
212 prof = prof.runctx(arg_str,namespace,namespace)
212 sys_exit = ''
213 sys_exit = ''
213 except SystemExit:
214 except SystemExit:
214 sys_exit = """*** SystemExit exception caught in code being profiled."""
215 sys_exit = """*** SystemExit exception caught in code being profiled."""
215
216
216 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
217 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
217
218
218 lims = opts.l
219 lims = opts.l
219 if lims:
220 if lims:
220 lims = [] # rebuild lims with ints/floats/strings
221 lims = [] # rebuild lims with ints/floats/strings
221 for lim in opts.l:
222 for lim in opts.l:
222 try:
223 try:
223 lims.append(int(lim))
224 lims.append(int(lim))
224 except ValueError:
225 except ValueError:
225 try:
226 try:
226 lims.append(float(lim))
227 lims.append(float(lim))
227 except ValueError:
228 except ValueError:
228 lims.append(lim)
229 lims.append(lim)
229
230
230 # Trap output.
231 # Trap output.
231 stdout_trap = StringIO()
232 stdout_trap = StringIO()
232 stats_stream = stats.stream
233 stats_stream = stats.stream
233 try:
234 try:
234 stats.stream = stdout_trap
235 stats.stream = stdout_trap
235 stats.print_stats(*lims)
236 stats.print_stats(*lims)
236 finally:
237 finally:
237 stats.stream = stats_stream
238 stats.stream = stats_stream
238
239
239 output = stdout_trap.getvalue()
240 output = stdout_trap.getvalue()
240 output = output.rstrip()
241 output = output.rstrip()
241
242
242 if 'q' not in opts:
243 if 'q' not in opts:
243 page.page(output)
244 page.page(output)
244 print sys_exit,
245 print sys_exit,
245
246
246 dump_file = opts.D[0]
247 dump_file = opts.D[0]
247 text_file = opts.T[0]
248 text_file = opts.T[0]
248 if dump_file:
249 if dump_file:
249 dump_file = unquote_filename(dump_file)
250 dump_file = unquote_filename(dump_file)
250 prof.dump_stats(dump_file)
251 prof.dump_stats(dump_file)
251 print '\n*** Profile stats marshalled to file',\
252 print '\n*** Profile stats marshalled to file',\
252 repr(dump_file)+'.',sys_exit
253 repr(dump_file)+'.',sys_exit
253 if text_file:
254 if text_file:
254 text_file = unquote_filename(text_file)
255 text_file = unquote_filename(text_file)
255 pfile = open(text_file,'w')
256 pfile = open(text_file,'w')
256 pfile.write(output)
257 pfile.write(output)
257 pfile.close()
258 pfile.close()
258 print '\n*** Profile printout saved to text file',\
259 print '\n*** Profile printout saved to text file',\
259 repr(text_file)+'.',sys_exit
260 repr(text_file)+'.',sys_exit
260
261
261 if 'r' in opts:
262 if 'r' in opts:
262 return stats
263 return stats
263 else:
264 else:
264 return None
265 return None
265
266
266 @line_magic
267 @line_magic
267 def pdb(self, parameter_s=''):
268 def pdb(self, parameter_s=''):
268 """Control the automatic calling of the pdb interactive debugger.
269 """Control the automatic calling of the pdb interactive debugger.
269
270
270 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
271 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
271 argument it works as a toggle.
272 argument it works as a toggle.
272
273
273 When an exception is triggered, IPython can optionally call the
274 When an exception is triggered, IPython can optionally call the
274 interactive pdb debugger after the traceback printout. %pdb toggles
275 interactive pdb debugger after the traceback printout. %pdb toggles
275 this feature on and off.
276 this feature on and off.
276
277
277 The initial state of this feature is set in your configuration
278 The initial state of this feature is set in your configuration
278 file (the option is ``InteractiveShell.pdb``).
279 file (the option is ``InteractiveShell.pdb``).
279
280
280 If you want to just activate the debugger AFTER an exception has fired,
281 If you want to just activate the debugger AFTER an exception has fired,
281 without having to type '%pdb on' and rerunning your code, you can use
282 without having to type '%pdb on' and rerunning your code, you can use
282 the %debug magic."""
283 the %debug magic."""
283
284
284 par = parameter_s.strip().lower()
285 par = parameter_s.strip().lower()
285
286
286 if par:
287 if par:
287 try:
288 try:
288 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
289 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
289 except KeyError:
290 except KeyError:
290 print ('Incorrect argument. Use on/1, off/0, '
291 print ('Incorrect argument. Use on/1, off/0, '
291 'or nothing for a toggle.')
292 'or nothing for a toggle.')
292 return
293 return
293 else:
294 else:
294 # toggle
295 # toggle
295 new_pdb = not self.shell.call_pdb
296 new_pdb = not self.shell.call_pdb
296
297
297 # set on the shell
298 # set on the shell
298 self.shell.call_pdb = new_pdb
299 self.shell.call_pdb = new_pdb
299 print 'Automatic pdb calling has been turned',on_off(new_pdb)
300 print 'Automatic pdb calling has been turned',on_off(new_pdb)
300
301
301 @line_magic
302 @line_magic
302 def debug(self, parameter_s=''):
303 def debug(self, parameter_s=''):
303 """Activate the interactive debugger in post-mortem mode.
304 """Activate the interactive debugger in post-mortem mode.
304
305
305 If an exception has just occurred, this lets you inspect its stack
306 If an exception has just occurred, this lets you inspect its stack
306 frames interactively. Note that this will always work only on the last
307 frames interactively. Note that this will always work only on the last
307 traceback that occurred, so you must call this quickly after an
308 traceback that occurred, so you must call this quickly after an
308 exception that you wish to inspect has fired, because if another one
309 exception that you wish to inspect has fired, because if another one
309 occurs, it clobbers the previous one.
310 occurs, it clobbers the previous one.
310
311
311 If you want IPython to automatically do this on every exception, see
312 If you want IPython to automatically do this on every exception, see
312 the %pdb magic for more details.
313 the %pdb magic for more details.
313 """
314 """
314 self.shell.debugger(force=True)
315 self.shell.debugger(force=True)
315
316
316 @line_magic
317 @line_magic
317 def tb(self, s):
318 def tb(self, s):
318 """Print the last traceback with the currently active exception mode.
319 """Print the last traceback with the currently active exception mode.
319
320
320 See %xmode for changing exception reporting modes."""
321 See %xmode for changing exception reporting modes."""
321 self.shell.showtraceback()
322 self.shell.showtraceback()
322
323
323 @skip_doctest
324 @skip_doctest
324 @line_magic
325 @line_magic
325 def run(self, parameter_s='', runner=None,
326 def run(self, parameter_s='', runner=None,
326 file_finder=get_py_filename):
327 file_finder=get_py_filename):
327 """Run the named file inside IPython as a program.
328 """Run the named file inside IPython as a program.
328
329
329 Usage:\\
330 Usage:\\
330 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options] -G] file [args]
331 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options] -G] file [args]
331
332
332 Parameters after the filename are passed as command-line arguments to
333 Parameters after the filename are passed as command-line arguments to
333 the program (put in sys.argv). Then, control returns to IPython's
334 the program (put in sys.argv). Then, control returns to IPython's
334 prompt.
335 prompt.
335
336
336 This is similar to running at a system prompt:\\
337 This is similar to running at a system prompt:\\
337 $ python file args\\
338 $ python file args\\
338 but with the advantage of giving you IPython's tracebacks, and of
339 but with the advantage of giving you IPython's tracebacks, and of
339 loading all variables into your interactive namespace for further use
340 loading all variables into your interactive namespace for further use
340 (unless -p is used, see below).
341 (unless -p is used, see below).
341
342
342 The file is executed in a namespace initially consisting only of
343 The file is executed in a namespace initially consisting only of
343 __name__=='__main__' and sys.argv constructed as indicated. It thus
344 __name__=='__main__' and sys.argv constructed as indicated. It thus
344 sees its environment as if it were being run as a stand-alone program
345 sees its environment as if it were being run as a stand-alone program
345 (except for sharing global objects such as previously imported
346 (except for sharing global objects such as previously imported
346 modules). But after execution, the IPython interactive namespace gets
347 modules). But after execution, the IPython interactive namespace gets
347 updated with all variables defined in the program (except for __name__
348 updated with all variables defined in the program (except for __name__
348 and sys.argv). This allows for very convenient loading of code for
349 and sys.argv). This allows for very convenient loading of code for
349 interactive work, while giving each program a 'clean sheet' to run in.
350 interactive work, while giving each program a 'clean sheet' to run in.
350
351
351 Arguments are expanded using shell-like glob match. Patterns
352 Arguments are expanded using shell-like glob match. Patterns
352 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
353 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
353 tilde '~' will be expanded into user's home directory. Unlike
354 tilde '~' will be expanded into user's home directory. Unlike
354 real shells, quotation does not suppress expansions. Use
355 real shells, quotation does not suppress expansions. Use
355 *two* back slashes (e.g., '\\\\*') to suppress expansions.
356 *two* back slashes (e.g., '\\\\*') to suppress expansions.
356 To completely disable these expansions, you can use -G flag.
357 To completely disable these expansions, you can use -G flag.
357
358
358 Options:
359 Options:
359
360
360 -n: __name__ is NOT set to '__main__', but to the running file's name
361 -n: __name__ is NOT set to '__main__', but to the running file's name
361 without extension (as python does under import). This allows running
362 without extension (as python does under import). This allows running
362 scripts and reloading the definitions in them without calling code
363 scripts and reloading the definitions in them without calling code
363 protected by an ' if __name__ == "__main__" ' clause.
364 protected by an ' if __name__ == "__main__" ' clause.
364
365
365 -i: run the file in IPython's namespace instead of an empty one. This
366 -i: run the file in IPython's namespace instead of an empty one. This
366 is useful if you are experimenting with code written in a text editor
367 is useful if you are experimenting with code written in a text editor
367 which depends on variables defined interactively.
368 which depends on variables defined interactively.
368
369
369 -e: ignore sys.exit() calls or SystemExit exceptions in the script
370 -e: ignore sys.exit() calls or SystemExit exceptions in the script
370 being run. This is particularly useful if IPython is being used to
371 being run. This is particularly useful if IPython is being used to
371 run unittests, which always exit with a sys.exit() call. In such
372 run unittests, which always exit with a sys.exit() call. In such
372 cases you are interested in the output of the test results, not in
373 cases you are interested in the output of the test results, not in
373 seeing a traceback of the unittest module.
374 seeing a traceback of the unittest module.
374
375
375 -t: print timing information at the end of the run. IPython will give
376 -t: print timing information at the end of the run. IPython will give
376 you an estimated CPU time consumption for your script, which under
377 you an estimated CPU time consumption for your script, which under
377 Unix uses the resource module to avoid the wraparound problems of
378 Unix uses the resource module to avoid the wraparound problems of
378 time.clock(). Under Unix, an estimate of time spent on system tasks
379 time.clock(). Under Unix, an estimate of time spent on system tasks
379 is also given (for Windows platforms this is reported as 0.0).
380 is also given (for Windows platforms this is reported as 0.0).
380
381
381 If -t is given, an additional -N<N> option can be given, where <N>
382 If -t is given, an additional -N<N> option can be given, where <N>
382 must be an integer indicating how many times you want the script to
383 must be an integer indicating how many times you want the script to
383 run. The final timing report will include total and per run results.
384 run. The final timing report will include total and per run results.
384
385
385 For example (testing the script uniq_stable.py)::
386 For example (testing the script uniq_stable.py)::
386
387
387 In [1]: run -t uniq_stable
388 In [1]: run -t uniq_stable
388
389
389 IPython CPU timings (estimated):\\
390 IPython CPU timings (estimated):\\
390 User : 0.19597 s.\\
391 User : 0.19597 s.\\
391 System: 0.0 s.\\
392 System: 0.0 s.\\
392
393
393 In [2]: run -t -N5 uniq_stable
394 In [2]: run -t -N5 uniq_stable
394
395
395 IPython CPU timings (estimated):\\
396 IPython CPU timings (estimated):\\
396 Total runs performed: 5\\
397 Total runs performed: 5\\
397 Times : Total Per run\\
398 Times : Total Per run\\
398 User : 0.910862 s, 0.1821724 s.\\
399 User : 0.910862 s, 0.1821724 s.\\
399 System: 0.0 s, 0.0 s.
400 System: 0.0 s, 0.0 s.
400
401
401 -d: run your program under the control of pdb, the Python debugger.
402 -d: run your program under the control of pdb, the Python debugger.
402 This allows you to execute your program step by step, watch variables,
403 This allows you to execute your program step by step, watch variables,
403 etc. Internally, what IPython does is similar to calling:
404 etc. Internally, what IPython does is similar to calling:
404
405
405 pdb.run('execfile("YOURFILENAME")')
406 pdb.run('execfile("YOURFILENAME")')
406
407
407 with a breakpoint set on line 1 of your file. You can change the line
408 with a breakpoint set on line 1 of your file. You can change the line
408 number for this automatic breakpoint to be <N> by using the -bN option
409 number for this automatic breakpoint to be <N> by using the -bN option
409 (where N must be an integer). For example::
410 (where N must be an integer). For example::
410
411
411 %run -d -b40 myscript
412 %run -d -b40 myscript
412
413
413 will set the first breakpoint at line 40 in myscript.py. Note that
414 will set the first breakpoint at line 40 in myscript.py. Note that
414 the first breakpoint must be set on a line which actually does
415 the first breakpoint must be set on a line which actually does
415 something (not a comment or docstring) for it to stop execution.
416 something (not a comment or docstring) for it to stop execution.
416
417
417 Or you can specify a breakpoint in a different file::
418 Or you can specify a breakpoint in a different file::
418
419
419 %run -d -b myotherfile.py:20 myscript
420 %run -d -b myotherfile.py:20 myscript
420
421
421 When the pdb debugger starts, you will see a (Pdb) prompt. You must
422 When the pdb debugger starts, you will see a (Pdb) prompt. You must
422 first enter 'c' (without quotes) to start execution up to the first
423 first enter 'c' (without quotes) to start execution up to the first
423 breakpoint.
424 breakpoint.
424
425
425 Entering 'help' gives information about the use of the debugger. You
426 Entering 'help' gives information about the use of the debugger. You
426 can easily see pdb's full documentation with "import pdb;pdb.help()"
427 can easily see pdb's full documentation with "import pdb;pdb.help()"
427 at a prompt.
428 at a prompt.
428
429
429 -p: run program under the control of the Python profiler module (which
430 -p: run program under the control of the Python profiler module (which
430 prints a detailed report of execution times, function calls, etc).
431 prints a detailed report of execution times, function calls, etc).
431
432
432 You can pass other options after -p which affect the behavior of the
433 You can pass other options after -p which affect the behavior of the
433 profiler itself. See the docs for %prun for details.
434 profiler itself. See the docs for %prun for details.
434
435
435 In this mode, the program's variables do NOT propagate back to the
436 In this mode, the program's variables do NOT propagate back to the
436 IPython interactive namespace (because they remain in the namespace
437 IPython interactive namespace (because they remain in the namespace
437 where the profiler executes them).
438 where the profiler executes them).
438
439
439 Internally this triggers a call to %prun, see its documentation for
440 Internally this triggers a call to %prun, see its documentation for
440 details on the options available specifically for profiling.
441 details on the options available specifically for profiling.
441
442
442 There is one special usage for which the text above doesn't apply:
443 There is one special usage for which the text above doesn't apply:
443 if the filename ends with .ipy, the file is run as ipython script,
444 if the filename ends with .ipy, the file is run as ipython script,
444 just as if the commands were written on IPython prompt.
445 just as if the commands were written on IPython prompt.
445
446
446 -m: specify module name to load instead of script path. Similar to
447 -m: specify module name to load instead of script path. Similar to
447 the -m option for the python interpreter. Use this option last if you
448 the -m option for the python interpreter. Use this option last if you
448 want to combine with other %run options. Unlike the python interpreter
449 want to combine with other %run options. Unlike the python interpreter
449 only source modules are allowed no .pyc or .pyo files.
450 only source modules are allowed no .pyc or .pyo files.
450 For example::
451 For example::
451
452
452 %run -m example
453 %run -m example
453
454
454 will run the example module.
455 will run the example module.
455
456
456 -G: disable shell-like glob expansion of arguments.
457 -G: disable shell-like glob expansion of arguments.
457
458
458 """
459 """
459
460
460 # get arguments and set sys.argv for program to be run.
461 # get arguments and set sys.argv for program to be run.
461 opts, arg_lst = self.parse_options(parameter_s,
462 opts, arg_lst = self.parse_options(parameter_s,
462 'nidtN:b:pD:l:rs:T:em:G',
463 'nidtN:b:pD:l:rs:T:em:G',
463 mode='list', list_all=1)
464 mode='list', list_all=1)
464 if "m" in opts:
465 if "m" in opts:
465 modulename = opts["m"][0]
466 modulename = opts["m"][0]
466 modpath = find_mod(modulename)
467 modpath = find_mod(modulename)
467 if modpath is None:
468 if modpath is None:
468 warn('%r is not a valid modulename on sys.path'%modulename)
469 warn('%r is not a valid modulename on sys.path'%modulename)
469 return
470 return
470 arg_lst = [modpath] + arg_lst
471 arg_lst = [modpath] + arg_lst
471 try:
472 try:
472 filename = file_finder(arg_lst[0])
473 filename = file_finder(arg_lst[0])
473 except IndexError:
474 except IndexError:
474 warn('you must provide at least a filename.')
475 warn('you must provide at least a filename.')
475 print '\n%run:\n', oinspect.getdoc(self.run)
476 print '\n%run:\n', oinspect.getdoc(self.run)
476 return
477 return
477 except IOError as e:
478 except IOError as e:
478 try:
479 try:
479 msg = str(e)
480 msg = str(e)
480 except UnicodeError:
481 except UnicodeError:
481 msg = e.message
482 msg = e.message
482 error(msg)
483 error(msg)
483 return
484 return
484
485
485 if filename.lower().endswith('.ipy'):
486 if filename.lower().endswith('.ipy'):
486 with preserve_keys(self.shell.user_ns, '__file__'):
487 with preserve_keys(self.shell.user_ns, '__file__'):
487 self.shell.user_ns['__file__'] = filename
488 self.shell.user_ns['__file__'] = filename
488 self.shell.safe_execfile_ipy(filename)
489 self.shell.safe_execfile_ipy(filename)
489 return
490 return
490
491
491 # Control the response to exit() calls made by the script being run
492 # Control the response to exit() calls made by the script being run
492 exit_ignore = 'e' in opts
493 exit_ignore = 'e' in opts
493
494
494 # Make sure that the running script gets a proper sys.argv as if it
495 # Make sure that the running script gets a proper sys.argv as if it
495 # were run from a system shell.
496 # were run from a system shell.
496 save_argv = sys.argv # save it for later restoring
497 save_argv = sys.argv # save it for later restoring
497
498
498 if 'G' in opts:
499 if 'G' in opts:
499 args = arg_lst[1:]
500 args = arg_lst[1:]
500 else:
501 else:
501 # tilde and glob expansion
502 # tilde and glob expansion
502 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
503 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
503
504
504 sys.argv = [filename] + args # put in the proper filename
505 sys.argv = [filename] + args # put in the proper filename
505 # protect sys.argv from potential unicode strings on Python 2:
506 # protect sys.argv from potential unicode strings on Python 2:
506 if not py3compat.PY3:
507 if not py3compat.PY3:
507 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
508 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
508
509
509 if 'i' in opts:
510 if 'i' in opts:
510 # Run in user's interactive namespace
511 # Run in user's interactive namespace
511 prog_ns = self.shell.user_ns
512 prog_ns = self.shell.user_ns
512 __name__save = self.shell.user_ns['__name__']
513 __name__save = self.shell.user_ns['__name__']
513 prog_ns['__name__'] = '__main__'
514 prog_ns['__name__'] = '__main__'
514 main_mod = self.shell.new_main_mod(prog_ns)
515 main_mod = self.shell.new_main_mod(prog_ns)
515 else:
516 else:
516 # Run in a fresh, empty namespace
517 # Run in a fresh, empty namespace
517 if 'n' in opts:
518 if 'n' in opts:
518 name = os.path.splitext(os.path.basename(filename))[0]
519 name = os.path.splitext(os.path.basename(filename))[0]
519 else:
520 else:
520 name = '__main__'
521 name = '__main__'
521
522
522 main_mod = self.shell.new_main_mod()
523 main_mod = self.shell.new_main_mod()
523 prog_ns = main_mod.__dict__
524 prog_ns = main_mod.__dict__
524 prog_ns['__name__'] = name
525 prog_ns['__name__'] = name
525
526
526 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
527 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
527 # set the __file__ global in the script's namespace
528 # set the __file__ global in the script's namespace
528 prog_ns['__file__'] = filename
529 prog_ns['__file__'] = filename
529
530
530 # pickle fix. See interactiveshell for an explanation. But we need to
531 # pickle fix. See interactiveshell for an explanation. But we need to
531 # make sure that, if we overwrite __main__, we replace it at the end
532 # make sure that, if we overwrite __main__, we replace it at the end
532 main_mod_name = prog_ns['__name__']
533 main_mod_name = prog_ns['__name__']
533
534
534 if main_mod_name == '__main__':
535 if main_mod_name == '__main__':
535 restore_main = sys.modules['__main__']
536 restore_main = sys.modules['__main__']
536 else:
537 else:
537 restore_main = False
538 restore_main = False
538
539
539 # This needs to be undone at the end to prevent holding references to
540 # This needs to be undone at the end to prevent holding references to
540 # every single object ever created.
541 # every single object ever created.
541 sys.modules[main_mod_name] = main_mod
542 sys.modules[main_mod_name] = main_mod
542
543
543 try:
544 try:
544 stats = None
545 stats = None
545 with self.shell.readline_no_record:
546 with self.shell.readline_no_record:
546 if 'p' in opts:
547 if 'p' in opts:
547 stats = self.prun('', None, False, opts, arg_lst, prog_ns)
548 stats = self.prun('', None, False, opts, arg_lst, prog_ns)
548 else:
549 else:
549 if 'd' in opts:
550 if 'd' in opts:
550 deb = debugger.Pdb(self.shell.colors)
551 deb = debugger.Pdb(self.shell.colors)
551 # reset Breakpoint state, which is moronically kept
552 # reset Breakpoint state, which is moronically kept
552 # in a class
553 # in a class
553 bdb.Breakpoint.next = 1
554 bdb.Breakpoint.next = 1
554 bdb.Breakpoint.bplist = {}
555 bdb.Breakpoint.bplist = {}
555 bdb.Breakpoint.bpbynumber = [None]
556 bdb.Breakpoint.bpbynumber = [None]
556 # Set an initial breakpoint to stop execution
557 # Set an initial breakpoint to stop execution
557 maxtries = 10
558 maxtries = 10
558 bp_file, bp_line = parse_breakpoint(opts.get('b', ['1'])[0], filename)
559 bp_file, bp_line = parse_breakpoint(opts.get('b', ['1'])[0], filename)
559 checkline = deb.checkline(bp_file, bp_line)
560 checkline = deb.checkline(bp_file, bp_line)
560 if not checkline:
561 if not checkline:
561 for bp in range(bp_line + 1, bp_line + maxtries + 1):
562 for bp in range(bp_line + 1, bp_line + maxtries + 1):
562 if deb.checkline(bp_file, bp):
563 if deb.checkline(bp_file, bp):
563 break
564 break
564 else:
565 else:
565 msg = ("\nI failed to find a valid line to set "
566 msg = ("\nI failed to find a valid line to set "
566 "a breakpoint\n"
567 "a breakpoint\n"
567 "after trying up to line: %s.\n"
568 "after trying up to line: %s.\n"
568 "Please set a valid breakpoint manually "
569 "Please set a valid breakpoint manually "
569 "with the -b option." % bp)
570 "with the -b option." % bp)
570 error(msg)
571 error(msg)
571 return
572 return
572 # if we find a good linenumber, set the breakpoint
573 # if we find a good linenumber, set the breakpoint
573 deb.do_break('%s:%s' % (bp_file, bp_line))
574 deb.do_break('%s:%s' % (bp_file, bp_line))
574
575
575 # Mimic Pdb._runscript(...)
576 # Mimic Pdb._runscript(...)
576 deb._wait_for_mainpyfile = True
577 deb._wait_for_mainpyfile = True
577 deb.mainpyfile = deb.canonic(filename)
578 deb.mainpyfile = deb.canonic(filename)
578
579
579 # Start file run
580 # Start file run
580 print "NOTE: Enter 'c' at the",
581 print "NOTE: Enter 'c' at the",
581 print "%s prompt to start your script." % deb.prompt
582 print "%s prompt to start your script." % deb.prompt
582 ns = {'execfile': py3compat.execfile, 'prog_ns': prog_ns}
583 ns = {'execfile': py3compat.execfile, 'prog_ns': prog_ns}
583 try:
584 try:
584 #save filename so it can be used by methods on the deb object
585 #save filename so it can be used by methods on the deb object
585 deb._exec_filename = filename
586 deb._exec_filename = filename
586 deb.run('execfile("%s", prog_ns)' % filename, ns)
587 deb.run('execfile("%s", prog_ns)' % filename, ns)
587
588
588 except:
589 except:
589 etype, value, tb = sys.exc_info()
590 etype, value, tb = sys.exc_info()
590 # Skip three frames in the traceback: the %run one,
591 # Skip three frames in the traceback: the %run one,
591 # one inside bdb.py, and the command-line typed by the
592 # one inside bdb.py, and the command-line typed by the
592 # user (run by exec in pdb itself).
593 # user (run by exec in pdb itself).
593 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
594 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
594 else:
595 else:
595 if runner is None:
596 if runner is None:
596 runner = self.default_runner
597 runner = self.default_runner
597 if runner is None:
598 if runner is None:
598 runner = self.shell.safe_execfile
599 runner = self.shell.safe_execfile
599 if 't' in opts:
600 if 't' in opts:
600 # timed execution
601 # timed execution
601 try:
602 try:
602 nruns = int(opts['N'][0])
603 nruns = int(opts['N'][0])
603 if nruns < 1:
604 if nruns < 1:
604 error('Number of runs must be >=1')
605 error('Number of runs must be >=1')
605 return
606 return
606 except (KeyError):
607 except (KeyError):
607 nruns = 1
608 nruns = 1
608 twall0 = time.time()
609 twall0 = time.time()
609 if nruns == 1:
610 if nruns == 1:
610 t0 = clock2()
611 t0 = clock2()
611 runner(filename, prog_ns, prog_ns,
612 runner(filename, prog_ns, prog_ns,
612 exit_ignore=exit_ignore)
613 exit_ignore=exit_ignore)
613 t1 = clock2()
614 t1 = clock2()
614 t_usr = t1[0] - t0[0]
615 t_usr = t1[0] - t0[0]
615 t_sys = t1[1] - t0[1]
616 t_sys = t1[1] - t0[1]
616 print "\nIPython CPU timings (estimated):"
617 print "\nIPython CPU timings (estimated):"
617 print " User : %10.2f s." % t_usr
618 print " User : %10.2f s." % t_usr
618 print " System : %10.2f s." % t_sys
619 print " System : %10.2f s." % t_sys
619 else:
620 else:
620 runs = range(nruns)
621 runs = range(nruns)
621 t0 = clock2()
622 t0 = clock2()
622 for nr in runs:
623 for nr in runs:
623 runner(filename, prog_ns, prog_ns,
624 runner(filename, prog_ns, prog_ns,
624 exit_ignore=exit_ignore)
625 exit_ignore=exit_ignore)
625 t1 = clock2()
626 t1 = clock2()
626 t_usr = t1[0] - t0[0]
627 t_usr = t1[0] - t0[0]
627 t_sys = t1[1] - t0[1]
628 t_sys = t1[1] - t0[1]
628 print "\nIPython CPU timings (estimated):"
629 print "\nIPython CPU timings (estimated):"
629 print "Total runs performed:", nruns
630 print "Total runs performed:", nruns
630 print " Times : %10s %10s" % ('Total', 'Per run')
631 print " Times : %10s %10s" % ('Total', 'Per run')
631 print " User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns)
632 print " User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns)
632 print " System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns)
633 print " System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns)
633 twall1 = time.time()
634 twall1 = time.time()
634 print "Wall time: %10.2f s." % (twall1 - twall0)
635 print "Wall time: %10.2f s." % (twall1 - twall0)
635
636
636 else:
637 else:
637 # regular execution
638 # regular execution
638 runner(filename, prog_ns, prog_ns, exit_ignore=exit_ignore)
639 runner(filename, prog_ns, prog_ns, exit_ignore=exit_ignore)
639
640
640 if 'i' in opts:
641 if 'i' in opts:
641 self.shell.user_ns['__name__'] = __name__save
642 self.shell.user_ns['__name__'] = __name__save
642 else:
643 else:
643 # The shell MUST hold a reference to prog_ns so after %run
644 # The shell MUST hold a reference to prog_ns so after %run
644 # exits, the python deletion mechanism doesn't zero it out
645 # exits, the python deletion mechanism doesn't zero it out
645 # (leaving dangling references).
646 # (leaving dangling references).
646 self.shell.cache_main_mod(prog_ns, filename)
647 self.shell.cache_main_mod(prog_ns, filename)
647 # update IPython interactive namespace
648 # update IPython interactive namespace
648
649
649 # Some forms of read errors on the file may mean the
650 # Some forms of read errors on the file may mean the
650 # __name__ key was never set; using pop we don't have to
651 # __name__ key was never set; using pop we don't have to
651 # worry about a possible KeyError.
652 # worry about a possible KeyError.
652 prog_ns.pop('__name__', None)
653 prog_ns.pop('__name__', None)
653
654
654 with preserve_keys(self.shell.user_ns, '__file__'):
655 with preserve_keys(self.shell.user_ns, '__file__'):
655 self.shell.user_ns.update(prog_ns)
656 self.shell.user_ns.update(prog_ns)
656 finally:
657 finally:
657 # It's a bit of a mystery why, but __builtins__ can change from
658 # It's a bit of a mystery why, but __builtins__ can change from
658 # being a module to becoming a dict missing some key data after
659 # being a module to becoming a dict missing some key data after
659 # %run. As best I can see, this is NOT something IPython is doing
660 # %run. As best I can see, this is NOT something IPython is doing
660 # at all, and similar problems have been reported before:
661 # at all, and similar problems have been reported before:
661 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
662 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
662 # Since this seems to be done by the interpreter itself, the best
663 # Since this seems to be done by the interpreter itself, the best
663 # we can do is to at least restore __builtins__ for the user on
664 # we can do is to at least restore __builtins__ for the user on
664 # exit.
665 # exit.
665 self.shell.user_ns['__builtins__'] = builtin_mod
666 self.shell.user_ns['__builtins__'] = builtin_mod
666
667
667 # Ensure key global structures are restored
668 # Ensure key global structures are restored
668 sys.argv = save_argv
669 sys.argv = save_argv
669 if restore_main:
670 if restore_main:
670 sys.modules['__main__'] = restore_main
671 sys.modules['__main__'] = restore_main
671 else:
672 else:
672 # Remove from sys.modules the reference to main_mod we'd
673 # Remove from sys.modules the reference to main_mod we'd
673 # added. Otherwise it will trap references to objects
674 # added. Otherwise it will trap references to objects
674 # contained therein.
675 # contained therein.
675 del sys.modules[main_mod_name]
676 del sys.modules[main_mod_name]
676
677
677 return stats
678 return stats
678
679
679 @skip_doctest
680 @skip_doctest
680 @line_cell_magic
681 @line_cell_magic
681 def timeit(self, line='', cell=None):
682 def timeit(self, line='', cell=None):
682 """Time execution of a Python statement or expression
683 """Time execution of a Python statement or expression
683
684
684 Usage, in line mode:
685 Usage, in line mode:
685 %timeit [-n<N> -r<R> [-t|-c]] statement
686 %timeit [-n<N> -r<R> [-t|-c]] statement
686 or in cell mode:
687 or in cell mode:
687 %%timeit [-n<N> -r<R> [-t|-c]] setup_code
688 %%timeit [-n<N> -r<R> [-t|-c]] setup_code
688 code
689 code
689 code...
690 code...
690
691
691 Time execution of a Python statement or expression using the timeit
692 Time execution of a Python statement or expression using the timeit
692 module. This function can be used both as a line and cell magic:
693 module. This function can be used both as a line and cell magic:
693
694
694 - In line mode you can time a single-line statement (though multiple
695 - In line mode you can time a single-line statement (though multiple
695 ones can be chained with using semicolons).
696 ones can be chained with using semicolons).
696
697
697 - In cell mode, the statement in the first line is used as setup code
698 - In cell mode, the statement in the first line is used as setup code
698 (executed but not timed) and the body of the cell is timed. The cell
699 (executed but not timed) and the body of the cell is timed. The cell
699 body has access to any variables created in the setup code.
700 body has access to any variables created in the setup code.
700
701
701 Options:
702 Options:
702 -n<N>: execute the given statement <N> times in a loop. If this value
703 -n<N>: execute the given statement <N> times in a loop. If this value
703 is not given, a fitting value is chosen.
704 is not given, a fitting value is chosen.
704
705
705 -r<R>: repeat the loop iteration <R> times and take the best result.
706 -r<R>: repeat the loop iteration <R> times and take the best result.
706 Default: 3
707 Default: 3
707
708
708 -t: use time.time to measure the time, which is the default on Unix.
709 -t: use time.time to measure the time, which is the default on Unix.
709 This function measures wall time.
710 This function measures wall time.
710
711
711 -c: use time.clock to measure the time, which is the default on
712 -c: use time.clock to measure the time, which is the default on
712 Windows and measures wall time. On Unix, resource.getrusage is used
713 Windows and measures wall time. On Unix, resource.getrusage is used
713 instead and returns the CPU user time.
714 instead and returns the CPU user time.
714
715
715 -p<P>: use a precision of <P> digits to display the timing result.
716 -p<P>: use a precision of <P> digits to display the timing result.
716 Default: 3
717 Default: 3
717
718
718
719
719 Examples
720 Examples
720 --------
721 --------
721 ::
722 ::
722
723
723 In [1]: %timeit pass
724 In [1]: %timeit pass
724 10000000 loops, best of 3: 53.3 ns per loop
725 10000000 loops, best of 3: 53.3 ns per loop
725
726
726 In [2]: u = None
727 In [2]: u = None
727
728
728 In [3]: %timeit u is None
729 In [3]: %timeit u is None
729 10000000 loops, best of 3: 184 ns per loop
730 10000000 loops, best of 3: 184 ns per loop
730
731
731 In [4]: %timeit -r 4 u == None
732 In [4]: %timeit -r 4 u == None
732 1000000 loops, best of 4: 242 ns per loop
733 1000000 loops, best of 4: 242 ns per loop
733
734
734 In [5]: import time
735 In [5]: import time
735
736
736 In [6]: %timeit -n1 time.sleep(2)
737 In [6]: %timeit -n1 time.sleep(2)
737 1 loops, best of 3: 2 s per loop
738 1 loops, best of 3: 2 s per loop
738
739
739
740
740 The times reported by %timeit will be slightly higher than those
741 The times reported by %timeit will be slightly higher than those
741 reported by the timeit.py script when variables are accessed. This is
742 reported by the timeit.py script when variables are accessed. This is
742 due to the fact that %timeit executes the statement in the namespace
743 due to the fact that %timeit executes the statement in the namespace
743 of the shell, compared with timeit.py, which uses a single setup
744 of the shell, compared with timeit.py, which uses a single setup
744 statement to import function or create variables. Generally, the bias
745 statement to import function or create variables. Generally, the bias
745 does not matter as long as results from timeit.py are not mixed with
746 does not matter as long as results from timeit.py are not mixed with
746 those from %timeit."""
747 those from %timeit."""
747
748
748 import timeit
749 import timeit
749 import math
750
751 # XXX: Unfortunately the unicode 'micro' symbol can cause problems in
752 # certain terminals. Until we figure out a robust way of
753 # auto-detecting if the terminal can deal with it, use plain 'us' for
754 # microseconds. I am really NOT happy about disabling the proper
755 # 'micro' prefix, but crashing is worse... If anyone knows what the
756 # right solution for this is, I'm all ears...
757 #
758 # Note: using
759 #
760 # s = u'\xb5'
761 # s.encode(sys.getdefaultencoding())
762 #
763 # is not sufficient, as I've seen terminals where that fails but
764 # print s
765 #
766 # succeeds
767 #
768 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
769
770 #units = [u"s", u"ms",u'\xb5',"ns"]
771 units = [u"s", u"ms",u'us',"ns"]
772
773 scaling = [1, 1e3, 1e6, 1e9]
774
750
775 opts, stmt = self.parse_options(line,'n:r:tcp:',
751 opts, stmt = self.parse_options(line,'n:r:tcp:',
776 posix=False, strict=False)
752 posix=False, strict=False)
777 if stmt == "" and cell is None:
753 if stmt == "" and cell is None:
778 return
754 return
779
755
780 timefunc = timeit.default_timer
756 timefunc = timeit.default_timer
781 number = int(getattr(opts, "n", 0))
757 number = int(getattr(opts, "n", 0))
782 repeat = int(getattr(opts, "r", timeit.default_repeat))
758 repeat = int(getattr(opts, "r", timeit.default_repeat))
783 precision = int(getattr(opts, "p", 3))
759 precision = int(getattr(opts, "p", 3))
784 if hasattr(opts, "t"):
760 if hasattr(opts, "t"):
785 timefunc = time.time
761 timefunc = time.time
786 if hasattr(opts, "c"):
762 if hasattr(opts, "c"):
787 timefunc = clock
763 timefunc = clock
788
764
789 timer = timeit.Timer(timer=timefunc)
765 timer = timeit.Timer(timer=timefunc)
790 # this code has tight coupling to the inner workings of timeit.Timer,
766 # this code has tight coupling to the inner workings of timeit.Timer,
791 # but is there a better way to achieve that the code stmt has access
767 # but is there a better way to achieve that the code stmt has access
792 # to the shell namespace?
768 # to the shell namespace?
793 transform = self.shell.input_splitter.transform_cell
769 transform = self.shell.input_splitter.transform_cell
794
770
795 if cell is None:
771 if cell is None:
796 # called as line magic
772 # called as line magic
797 ast_setup = ast.parse("pass")
773 ast_setup = ast.parse("pass")
798 ast_stmt = ast.parse(transform(stmt))
774 ast_stmt = ast.parse(transform(stmt))
799 else:
775 else:
800 ast_setup = ast.parse(transform(stmt))
776 ast_setup = ast.parse(transform(stmt))
801 ast_stmt = ast.parse(transform(cell))
777 ast_stmt = ast.parse(transform(cell))
802
778
803 ast_setup = self.shell.transform_ast(ast_setup)
779 ast_setup = self.shell.transform_ast(ast_setup)
804 ast_stmt = self.shell.transform_ast(ast_stmt)
780 ast_stmt = self.shell.transform_ast(ast_stmt)
805
781
806 # This codestring is taken from timeit.template - we fill it in as an
782 # This codestring is taken from timeit.template - we fill it in as an
807 # AST, so that we can apply our AST transformations to the user code
783 # AST, so that we can apply our AST transformations to the user code
808 # without affecting the timing code.
784 # without affecting the timing code.
809 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
785 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
810 ' setup\n'
786 ' setup\n'
811 ' _t0 = _timer()\n'
787 ' _t0 = _timer()\n'
812 ' for _i in _it:\n'
788 ' for _i in _it:\n'
813 ' stmt\n'
789 ' stmt\n'
814 ' _t1 = _timer()\n'
790 ' _t1 = _timer()\n'
815 ' return _t1 - _t0\n')
791 ' return _t1 - _t0\n')
816
792
817 class TimeitTemplateFiller(ast.NodeTransformer):
793 class TimeitTemplateFiller(ast.NodeTransformer):
818 "This is quite tightly tied to the template definition above."
794 "This is quite tightly tied to the template definition above."
819 def visit_FunctionDef(self, node):
795 def visit_FunctionDef(self, node):
820 "Fill in the setup statement"
796 "Fill in the setup statement"
821 self.generic_visit(node)
797 self.generic_visit(node)
822 if node.name == "inner":
798 if node.name == "inner":
823 node.body[:1] = ast_setup.body
799 node.body[:1] = ast_setup.body
824
800
825 return node
801 return node
826
802
827 def visit_For(self, node):
803 def visit_For(self, node):
828 "Fill in the statement to be timed"
804 "Fill in the statement to be timed"
829 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
805 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
830 node.body = ast_stmt.body
806 node.body = ast_stmt.body
831 return node
807 return node
832
808
833 timeit_ast = TimeitTemplateFiller().visit(timeit_ast_template)
809 timeit_ast = TimeitTemplateFiller().visit(timeit_ast_template)
834 timeit_ast = ast.fix_missing_locations(timeit_ast)
810 timeit_ast = ast.fix_missing_locations(timeit_ast)
835
811
836 # Track compilation time so it can be reported if too long
812 # Track compilation time so it can be reported if too long
837 # Minimum time above which compilation time will be reported
813 # Minimum time above which compilation time will be reported
838 tc_min = 0.1
814 tc_min = 0.1
839
815
840 t0 = clock()
816 t0 = clock()
841 code = compile(timeit_ast, "<magic-timeit>", "exec")
817 code = compile(timeit_ast, "<magic-timeit>", "exec")
842 tc = clock()-t0
818 tc = clock()-t0
843
819
844 ns = {}
820 ns = {}
845 exec code in self.shell.user_ns, ns
821 exec code in self.shell.user_ns, ns
846 timer.inner = ns["inner"]
822 timer.inner = ns["inner"]
847
823
848 if number == 0:
824 if number == 0:
849 # determine number so that 0.2 <= total time < 2.0
825 # determine number so that 0.2 <= total time < 2.0
850 number = 1
826 number = 1
851 for i in range(1, 10):
827 for i in range(1, 10):
852 if timer.timeit(number) >= 0.2:
828 if timer.timeit(number) >= 0.2:
853 break
829 break
854 number *= 10
830 number *= 10
855
831
856 best = min(timer.repeat(repeat, number)) / number
832 best = min(timer.repeat(repeat, number)) / number
857
833
858 if best > 0.0 and best < 1000.0:
834 print u"%d loops, best of %d: %s per loop" % (number, repeat,
859 order = min(-int(math.floor(math.log10(best)) // 3), 3)
835 _format_time(best, precision))
860 elif best >= 1000.0:
861 order = 0
862 else:
863 order = 3
864 print u"%d loops, best of %d: %.*g %s per loop" % (number, repeat,
865 precision,
866 best * scaling[order],
867 units[order])
868 if tc > tc_min:
836 if tc > tc_min:
869 print "Compiler time: %.2f s" % tc
837 print "Compiler time: %.2f s" % tc
870
838
871 @skip_doctest
839 @skip_doctest
872 @needs_local_scope
840 @needs_local_scope
873 @line_magic
841 @line_cell_magic
874 def time(self,parameter_s, local_ns=None):
842 def time(self,line='', cell=None, local_ns=None):
875 """Time execution of a Python statement or expression.
843 """Time execution of a Python statement or expression.
876
844
877 The CPU and wall clock times are printed, and the value of the
845 The CPU and wall clock times are printed, and the value of the
878 expression (if any) is returned. Note that under Win32, system time
846 expression (if any) is returned. Note that under Win32, system time
879 is always reported as 0, since it can not be measured.
847 is always reported as 0, since it can not be measured.
848
849 This function can be used both as a line and cell magic:
850
851 - In line mode you can time a single-line statement (though multiple
852 ones can be chained with using semicolons).
880
853
881 This function provides very basic timing functionality. In Python
854 - In cell mode, you can time the cell body (a directly
882 2.3, the timeit module offers more control and sophistication, so this
855 following statement raises an error).
883 could be rewritten to use it (patches welcome).
856
857 This function provides very basic timing functionality. Use the timeit
858 magic for more controll over the measurement.
884
859
885 Examples
860 Examples
886 --------
861 --------
887 ::
862 ::
888
863
889 In [1]: time 2**128
864 In [1]: %time 2**128
890 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
865 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
891 Wall time: 0.00
866 Wall time: 0.00
892 Out[1]: 340282366920938463463374607431768211456L
867 Out[1]: 340282366920938463463374607431768211456L
893
868
894 In [2]: n = 1000000
869 In [2]: n = 1000000
895
870
896 In [3]: time sum(range(n))
871 In [3]: %time sum(range(n))
897 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
872 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
898 Wall time: 1.37
873 Wall time: 1.37
899 Out[3]: 499999500000L
874 Out[3]: 499999500000L
900
875
901 In [4]: time print 'hello world'
876 In [4]: %time print 'hello world'
902 hello world
877 hello world
903 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
878 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
904 Wall time: 0.00
879 Wall time: 0.00
905
880
906 Note that the time needed by Python to compile the given expression
881 Note that the time needed by Python to compile the given expression
907 will be reported if it is more than 0.1s. In this example, the
882 will be reported if it is more than 0.1s. In this example, the
908 actual exponentiation is done by Python at compilation time, so while
883 actual exponentiation is done by Python at compilation time, so while
909 the expression can take a noticeable amount of time to compute, that
884 the expression can take a noticeable amount of time to compute, that
910 time is purely due to the compilation:
885 time is purely due to the compilation:
911
886
912 In [5]: time 3**9999;
887 In [5]: %time 3**9999;
913 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
888 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
914 Wall time: 0.00 s
889 Wall time: 0.00 s
915
890
916 In [6]: time 3**999999;
891 In [6]: %time 3**999999;
917 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
892 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
918 Wall time: 0.00 s
893 Wall time: 0.00 s
919 Compiler : 0.78 s
894 Compiler : 0.78 s
920 """
895 """
921
896
922 # fail immediately if the given expression can't be compiled
897 # fail immediately if the given expression can't be compiled
923
898
924 expr = self.shell.prefilter(parameter_s,False)
899 if line and cell:
900 raise UsageError("Can't use statement directly after '%%time'!")
901
902 if cell:
903 expr = self.shell.prefilter(cell,False)
904 else:
905 expr = self.shell.prefilter(line,False)
925
906
926 # Minimum time above which parse time will be reported
907 # Minimum time above which parse time will be reported
927 tp_min = 0.1
908 tp_min = 0.1
928
909
929 t0 = clock()
910 t0 = clock()
930 expr_ast = ast.parse(expr)
911 expr_ast = ast.parse(expr)
931 tp = clock()-t0
912 tp = clock()-t0
932
913
933 # Apply AST transformations
914 # Apply AST transformations
934 expr_ast = self.shell.transform_ast(expr_ast)
915 expr_ast = self.shell.transform_ast(expr_ast)
935
916
936 # Minimum time above which compilation time will be reported
917 # Minimum time above which compilation time will be reported
937 tc_min = 0.1
918 tc_min = 0.1
938
919
939 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
920 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
940 mode = 'eval'
921 mode = 'eval'
941 source = '<timed eval>'
922 source = '<timed eval>'
942 expr_ast = ast.Expression(expr_ast.body[0].value)
923 expr_ast = ast.Expression(expr_ast.body[0].value)
943 else:
924 else:
944 mode = 'exec'
925 mode = 'exec'
945 source = '<timed exec>'
926 source = '<timed exec>'
946 t0 = clock()
927 t0 = clock()
947 code = compile(expr_ast, source, mode)
928 code = compile(expr_ast, source, mode)
948 tc = clock()-t0
929 tc = clock()-t0
949
930
950 # skew measurement as little as possible
931 # skew measurement as little as possible
951 glob = self.shell.user_ns
932 glob = self.shell.user_ns
952 wtime = time.time
933 wtime = time.time
953 # time execution
934 # time execution
954 wall_st = wtime()
935 wall_st = wtime()
955 if mode=='eval':
936 if mode=='eval':
956 st = clock2()
937 st = clock2()
957 out = eval(code, glob, local_ns)
938 out = eval(code, glob, local_ns)
958 end = clock2()
939 end = clock2()
959 else:
940 else:
960 st = clock2()
941 st = clock2()
961 exec code in glob, local_ns
942 exec code in glob, local_ns
962 end = clock2()
943 end = clock2()
963 out = None
944 out = None
964 wall_end = wtime()
945 wall_end = wtime()
965 # Compute actual times and report
946 # Compute actual times and report
966 wall_time = wall_end-wall_st
947 wall_time = wall_end-wall_st
967 cpu_user = end[0]-st[0]
948 cpu_user = end[0]-st[0]
968 cpu_sys = end[1]-st[1]
949 cpu_sys = end[1]-st[1]
969 cpu_tot = cpu_user+cpu_sys
950 cpu_tot = cpu_user+cpu_sys
970 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
951 print "CPU times: user %s, sys: %s, total: %s" % \
971 (cpu_user,cpu_sys,cpu_tot)
952 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot))
972 print "Wall time: %.2f s" % wall_time
953 print "Wall time: %s" % _format_time(wall_time)
973 if tc > tc_min:
954 if tc > tc_min:
974 print "Compiler : %.2f s" % tc
955 print "Compiler : %s" % _format_time(tc)
975 if tp > tp_min:
956 if tp > tp_min:
976 print "Parser : %.2f s" % tp
957 print "Parser : %s" % _format_time(tp)
977 return out
958 return out
978
959
979 @skip_doctest
960 @skip_doctest
980 @line_magic
961 @line_magic
981 def macro(self, parameter_s=''):
962 def macro(self, parameter_s=''):
982 """Define a macro for future re-execution. It accepts ranges of history,
963 """Define a macro for future re-execution. It accepts ranges of history,
983 filenames or string objects.
964 filenames or string objects.
984
965
985 Usage:\\
966 Usage:\\
986 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
967 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
987
968
988 Options:
969 Options:
989
970
990 -r: use 'raw' input. By default, the 'processed' history is used,
971 -r: use 'raw' input. By default, the 'processed' history is used,
991 so that magics are loaded in their transformed version to valid
972 so that magics are loaded in their transformed version to valid
992 Python. If this option is given, the raw input as typed as the
973 Python. If this option is given, the raw input as typed as the
993 command line is used instead.
974 command line is used instead.
994
975
995 This will define a global variable called `name` which is a string
976 This will define a global variable called `name` which is a string
996 made of joining the slices and lines you specify (n1,n2,... numbers
977 made of joining the slices and lines you specify (n1,n2,... numbers
997 above) from your input history into a single string. This variable
978 above) from your input history into a single string. This variable
998 acts like an automatic function which re-executes those lines as if
979 acts like an automatic function which re-executes those lines as if
999 you had typed them. You just type 'name' at the prompt and the code
980 you had typed them. You just type 'name' at the prompt and the code
1000 executes.
981 executes.
1001
982
1002 The syntax for indicating input ranges is described in %history.
983 The syntax for indicating input ranges is described in %history.
1003
984
1004 Note: as a 'hidden' feature, you can also use traditional python slice
985 Note: as a 'hidden' feature, you can also use traditional python slice
1005 notation, where N:M means numbers N through M-1.
986 notation, where N:M means numbers N through M-1.
1006
987
1007 For example, if your history contains (%hist prints it)::
988 For example, if your history contains (%hist prints it)::
1008
989
1009 44: x=1
990 44: x=1
1010 45: y=3
991 45: y=3
1011 46: z=x+y
992 46: z=x+y
1012 47: print x
993 47: print x
1013 48: a=5
994 48: a=5
1014 49: print 'x',x,'y',y
995 49: print 'x',x,'y',y
1015
996
1016 you can create a macro with lines 44 through 47 (included) and line 49
997 you can create a macro with lines 44 through 47 (included) and line 49
1017 called my_macro with::
998 called my_macro with::
1018
999
1019 In [55]: %macro my_macro 44-47 49
1000 In [55]: %macro my_macro 44-47 49
1020
1001
1021 Now, typing `my_macro` (without quotes) will re-execute all this code
1002 Now, typing `my_macro` (without quotes) will re-execute all this code
1022 in one pass.
1003 in one pass.
1023
1004
1024 You don't need to give the line-numbers in order, and any given line
1005 You don't need to give the line-numbers in order, and any given line
1025 number can appear multiple times. You can assemble macros with any
1006 number can appear multiple times. You can assemble macros with any
1026 lines from your input history in any order.
1007 lines from your input history in any order.
1027
1008
1028 The macro is a simple object which holds its value in an attribute,
1009 The macro is a simple object which holds its value in an attribute,
1029 but IPython's display system checks for macros and executes them as
1010 but IPython's display system checks for macros and executes them as
1030 code instead of printing them when you type their name.
1011 code instead of printing them when you type their name.
1031
1012
1032 You can view a macro's contents by explicitly printing it with::
1013 You can view a macro's contents by explicitly printing it with::
1033
1014
1034 print macro_name
1015 print macro_name
1035
1016
1036 """
1017 """
1037 opts,args = self.parse_options(parameter_s,'r',mode='list')
1018 opts,args = self.parse_options(parameter_s,'r',mode='list')
1038 if not args: # List existing macros
1019 if not args: # List existing macros
1039 return sorted(k for k,v in self.shell.user_ns.iteritems() if\
1020 return sorted(k for k,v in self.shell.user_ns.iteritems() if\
1040 isinstance(v, Macro))
1021 isinstance(v, Macro))
1041 if len(args) == 1:
1022 if len(args) == 1:
1042 raise UsageError(
1023 raise UsageError(
1043 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1024 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1044 name, codefrom = args[0], " ".join(args[1:])
1025 name, codefrom = args[0], " ".join(args[1:])
1045
1026
1046 #print 'rng',ranges # dbg
1027 #print 'rng',ranges # dbg
1047 try:
1028 try:
1048 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1029 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1049 except (ValueError, TypeError) as e:
1030 except (ValueError, TypeError) as e:
1050 print e.args[0]
1031 print e.args[0]
1051 return
1032 return
1052 macro = Macro(lines)
1033 macro = Macro(lines)
1053 self.shell.define_macro(name, macro)
1034 self.shell.define_macro(name, macro)
1054 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
1035 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
1055 print '=== Macro contents: ==='
1036 print '=== Macro contents: ==='
1056 print macro,
1037 print macro,
1057
1038
1058 @magic_arguments.magic_arguments()
1039 @magic_arguments.magic_arguments()
1059 @magic_arguments.argument('output', type=str, default='', nargs='?',
1040 @magic_arguments.argument('output', type=str, default='', nargs='?',
1060 help="""The name of the variable in which to store output.
1041 help="""The name of the variable in which to store output.
1061 This is a utils.io.CapturedIO object with stdout/err attributes
1042 This is a utils.io.CapturedIO object with stdout/err attributes
1062 for the text of the captured output.
1043 for the text of the captured output.
1063
1044
1064 CapturedOutput also has a show() method for displaying the output,
1045 CapturedOutput also has a show() method for displaying the output,
1065 and __call__ as well, so you can use that to quickly display the
1046 and __call__ as well, so you can use that to quickly display the
1066 output.
1047 output.
1067
1048
1068 If unspecified, captured output is discarded.
1049 If unspecified, captured output is discarded.
1069 """
1050 """
1070 )
1051 )
1071 @magic_arguments.argument('--no-stderr', action="store_true",
1052 @magic_arguments.argument('--no-stderr', action="store_true",
1072 help="""Don't capture stderr."""
1053 help="""Don't capture stderr."""
1073 )
1054 )
1074 @magic_arguments.argument('--no-stdout', action="store_true",
1055 @magic_arguments.argument('--no-stdout', action="store_true",
1075 help="""Don't capture stdout."""
1056 help="""Don't capture stdout."""
1076 )
1057 )
1077 @cell_magic
1058 @cell_magic
1078 def capture(self, line, cell):
1059 def capture(self, line, cell):
1079 """run the cell, capturing stdout/err"""
1060 """run the cell, capturing stdout/err"""
1080 args = magic_arguments.parse_argstring(self.capture, line)
1061 args = magic_arguments.parse_argstring(self.capture, line)
1081 out = not args.no_stdout
1062 out = not args.no_stdout
1082 err = not args.no_stderr
1063 err = not args.no_stderr
1083 with capture_output(out, err) as io:
1064 with capture_output(out, err) as io:
1084 self.shell.run_cell(cell)
1065 self.shell.run_cell(cell)
1085 if args.output:
1066 if args.output:
1086 self.shell.user_ns[args.output] = io
1067 self.shell.user_ns[args.output] = io
1087
1068
1088 def parse_breakpoint(text, current_file):
1069 def parse_breakpoint(text, current_file):
1089 '''Returns (file, line) for file:line and (current_file, line) for line'''
1070 '''Returns (file, line) for file:line and (current_file, line) for line'''
1090 colon = text.find(':')
1071 colon = text.find(':')
1091 if colon == -1:
1072 if colon == -1:
1092 return current_file, int(text)
1073 return current_file, int(text)
1093 else:
1074 else:
1094 return text[:colon], int(text[colon+1:])
1075 return text[:colon], int(text[colon+1:])
1076
1077 def _format_time(timespan, precision=3):
1078 """Formats the timespan in a human readable form"""
1079 import math
1080
1081 if timespan >= 60.0:
1082 # we have more than a minute, format that in a human readable form
1083 # Idea from http://snipplr.com/view/5713/
1084 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1085 time = []
1086 leftover = timespan
1087 for suffix, length in parts:
1088 value = int(leftover / length)
1089 if value > 0:
1090 leftover = leftover % length
1091 time.append(u'%s%s' % (str(value), suffix))
1092 if leftover < 1:
1093 break
1094 return " ".join(time)
1095
1096
1097 # Unfortunately the unicode 'micro' symbol can cause problems in
1098 # certain terminals.
1099 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1100 # Try to prevent crashes by being more secure than it needs to
1101 # E.g. eclipse is able to print a Β΅, but has no sys.stdout.encoding set.
1102 units = [u"s", u"ms",u'us',"ns"] # the save value
1103 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1104 try:
1105 u'\xb5'.encode(sys.stdout.encoding)
1106 units = [u"s", u"ms",u'\xb5s',"ns"]
1107 except:
1108 pass
1109 scaling = [1, 1e3, 1e6, 1e9]
1110
1111 if timespan > 0.0:
1112 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1113 else:
1114 order = 3
1115 ret = u"%.*g %s" % (precision, timespan * scaling[order], units[order])
1116 return ret
@@ -1,840 +1,837 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 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Imports
9 # Imports
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 import io
12 import io
13 import os
13 import os
14 import sys
14 import sys
15 from StringIO import StringIO
15 from StringIO import StringIO
16 from unittest import TestCase
16 from unittest import TestCase
17
17
18 try:
18 try:
19 from importlib import invalidate_caches # Required from Python 3.3
19 from importlib import invalidate_caches # Required from Python 3.3
20 except ImportError:
20 except ImportError:
21 def invalidate_caches():
21 def invalidate_caches():
22 pass
22 pass
23
23
24 import nose.tools as nt
24 import nose.tools as nt
25
25
26 from IPython.core import magic
26 from IPython.core import magic
27 from IPython.core.magic import (Magics, magics_class, line_magic,
27 from IPython.core.magic import (Magics, magics_class, line_magic,
28 cell_magic, line_cell_magic,
28 cell_magic, line_cell_magic,
29 register_line_magic, register_cell_magic,
29 register_line_magic, register_cell_magic,
30 register_line_cell_magic)
30 register_line_cell_magic)
31 from IPython.core.magics import execution, script, code
31 from IPython.core.magics import execution, script, code
32 from IPython.nbformat.v3.tests.nbexamples import nb0
32 from IPython.nbformat.v3.tests.nbexamples import nb0
33 from IPython.nbformat import current
33 from IPython.nbformat import current
34 from IPython.testing import decorators as dec
34 from IPython.testing import decorators as dec
35 from IPython.testing import tools as tt
35 from IPython.testing import tools as tt
36 from IPython.utils import py3compat
36 from IPython.utils import py3compat
37 from IPython.utils.tempdir import TemporaryDirectory
37 from IPython.utils.tempdir import TemporaryDirectory
38 from IPython.utils.process import find_cmd
38 from IPython.utils.process import find_cmd
39
39
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41 # Test functions begin
41 # Test functions begin
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43
43
44 @magic.magics_class
44 @magic.magics_class
45 class DummyMagics(magic.Magics): pass
45 class DummyMagics(magic.Magics): pass
46
46
47 def test_rehashx():
47 def test_rehashx():
48 # clear up everything
48 # clear up everything
49 _ip = get_ipython()
49 _ip = get_ipython()
50 _ip.alias_manager.alias_table.clear()
50 _ip.alias_manager.alias_table.clear()
51 del _ip.db['syscmdlist']
51 del _ip.db['syscmdlist']
52
52
53 _ip.magic('rehashx')
53 _ip.magic('rehashx')
54 # Practically ALL ipython development systems will have more than 10 aliases
54 # Practically ALL ipython development systems will have more than 10 aliases
55
55
56 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
56 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
57 for key, val in _ip.alias_manager.alias_table.iteritems():
57 for key, val in _ip.alias_manager.alias_table.iteritems():
58 # we must strip dots from alias names
58 # we must strip dots from alias names
59 nt.assert_true('.' not in key)
59 nt.assert_true('.' not in key)
60
60
61 # rehashx must fill up syscmdlist
61 # rehashx must fill up syscmdlist
62 scoms = _ip.db['syscmdlist']
62 scoms = _ip.db['syscmdlist']
63 yield (nt.assert_true, len(scoms) > 10)
63 yield (nt.assert_true, len(scoms) > 10)
64
64
65
65
66 def test_magic_parse_options():
66 def test_magic_parse_options():
67 """Test that we don't mangle paths when parsing magic options."""
67 """Test that we don't mangle paths when parsing magic options."""
68 ip = get_ipython()
68 ip = get_ipython()
69 path = 'c:\\x'
69 path = 'c:\\x'
70 m = DummyMagics(ip)
70 m = DummyMagics(ip)
71 opts = m.parse_options('-f %s' % path,'f:')[0]
71 opts = m.parse_options('-f %s' % path,'f:')[0]
72 # argv splitting is os-dependent
72 # argv splitting is os-dependent
73 if os.name == 'posix':
73 if os.name == 'posix':
74 expected = 'c:x'
74 expected = 'c:x'
75 else:
75 else:
76 expected = path
76 expected = path
77 nt.assert_equal(opts['f'], expected)
77 nt.assert_equal(opts['f'], expected)
78
78
79 def test_magic_parse_long_options():
79 def test_magic_parse_long_options():
80 """Magic.parse_options can handle --foo=bar long options"""
80 """Magic.parse_options can handle --foo=bar long options"""
81 ip = get_ipython()
81 ip = get_ipython()
82 m = DummyMagics(ip)
82 m = DummyMagics(ip)
83 opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=')
83 opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=')
84 nt.assert_true('foo' in opts)
84 nt.assert_true('foo' in opts)
85 nt.assert_true('bar' in opts)
85 nt.assert_true('bar' in opts)
86 nt.assert_true(opts['bar'], "bubble")
86 nt.assert_true(opts['bar'], "bubble")
87
87
88
88
89 @dec.skip_without('sqlite3')
89 @dec.skip_without('sqlite3')
90 def doctest_hist_f():
90 def doctest_hist_f():
91 """Test %hist -f with temporary filename.
91 """Test %hist -f with temporary filename.
92
92
93 In [9]: import tempfile
93 In [9]: import tempfile
94
94
95 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
95 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
96
96
97 In [11]: %hist -nl -f $tfile 3
97 In [11]: %hist -nl -f $tfile 3
98
98
99 In [13]: import os; os.unlink(tfile)
99 In [13]: import os; os.unlink(tfile)
100 """
100 """
101
101
102
102
103 @dec.skip_without('sqlite3')
103 @dec.skip_without('sqlite3')
104 def doctest_hist_r():
104 def doctest_hist_r():
105 """Test %hist -r
105 """Test %hist -r
106
106
107 XXX - This test is not recording the output correctly. For some reason, in
107 XXX - This test is not recording the output correctly. For some reason, in
108 testing mode the raw history isn't getting populated. No idea why.
108 testing mode the raw history isn't getting populated. No idea why.
109 Disabling the output checking for now, though at least we do run it.
109 Disabling the output checking for now, though at least we do run it.
110
110
111 In [1]: 'hist' in _ip.lsmagic()
111 In [1]: 'hist' in _ip.lsmagic()
112 Out[1]: True
112 Out[1]: True
113
113
114 In [2]: x=1
114 In [2]: x=1
115
115
116 In [3]: %hist -rl 2
116 In [3]: %hist -rl 2
117 x=1 # random
117 x=1 # random
118 %hist -r 2
118 %hist -r 2
119 """
119 """
120
120
121
121
122 @dec.skip_without('sqlite3')
122 @dec.skip_without('sqlite3')
123 def doctest_hist_op():
123 def doctest_hist_op():
124 """Test %hist -op
124 """Test %hist -op
125
125
126 In [1]: class b(float):
126 In [1]: class b(float):
127 ...: pass
127 ...: pass
128 ...:
128 ...:
129
129
130 In [2]: class s(object):
130 In [2]: class s(object):
131 ...: def __str__(self):
131 ...: def __str__(self):
132 ...: return 's'
132 ...: return 's'
133 ...:
133 ...:
134
134
135 In [3]:
135 In [3]:
136
136
137 In [4]: class r(b):
137 In [4]: class r(b):
138 ...: def __repr__(self):
138 ...: def __repr__(self):
139 ...: return 'r'
139 ...: return 'r'
140 ...:
140 ...:
141
141
142 In [5]: class sr(s,r): pass
142 In [5]: class sr(s,r): pass
143 ...:
143 ...:
144
144
145 In [6]:
145 In [6]:
146
146
147 In [7]: bb=b()
147 In [7]: bb=b()
148
148
149 In [8]: ss=s()
149 In [8]: ss=s()
150
150
151 In [9]: rr=r()
151 In [9]: rr=r()
152
152
153 In [10]: ssrr=sr()
153 In [10]: ssrr=sr()
154
154
155 In [11]: 4.5
155 In [11]: 4.5
156 Out[11]: 4.5
156 Out[11]: 4.5
157
157
158 In [12]: str(ss)
158 In [12]: str(ss)
159 Out[12]: 's'
159 Out[12]: 's'
160
160
161 In [13]:
161 In [13]:
162
162
163 In [14]: %hist -op
163 In [14]: %hist -op
164 >>> class b:
164 >>> class b:
165 ... pass
165 ... pass
166 ...
166 ...
167 >>> class s(b):
167 >>> class s(b):
168 ... def __str__(self):
168 ... def __str__(self):
169 ... return 's'
169 ... return 's'
170 ...
170 ...
171 >>>
171 >>>
172 >>> class r(b):
172 >>> class r(b):
173 ... def __repr__(self):
173 ... def __repr__(self):
174 ... return 'r'
174 ... return 'r'
175 ...
175 ...
176 >>> class sr(s,r): pass
176 >>> class sr(s,r): pass
177 >>>
177 >>>
178 >>> bb=b()
178 >>> bb=b()
179 >>> ss=s()
179 >>> ss=s()
180 >>> rr=r()
180 >>> rr=r()
181 >>> ssrr=sr()
181 >>> ssrr=sr()
182 >>> 4.5
182 >>> 4.5
183 4.5
183 4.5
184 >>> str(ss)
184 >>> str(ss)
185 's'
185 's'
186 >>>
186 >>>
187 """
187 """
188
188
189
189
190 @dec.skip_without('sqlite3')
190 @dec.skip_without('sqlite3')
191 def test_macro():
191 def test_macro():
192 ip = get_ipython()
192 ip = get_ipython()
193 ip.history_manager.reset() # Clear any existing history.
193 ip.history_manager.reset() # Clear any existing history.
194 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
194 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
195 for i, cmd in enumerate(cmds, start=1):
195 for i, cmd in enumerate(cmds, start=1):
196 ip.history_manager.store_inputs(i, cmd)
196 ip.history_manager.store_inputs(i, cmd)
197 ip.magic("macro test 1-3")
197 ip.magic("macro test 1-3")
198 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
198 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
199
199
200 # List macros.
200 # List macros.
201 assert "test" in ip.magic("macro")
201 assert "test" in ip.magic("macro")
202
202
203
203
204 @dec.skip_without('sqlite3')
204 @dec.skip_without('sqlite3')
205 def test_macro_run():
205 def test_macro_run():
206 """Test that we can run a multi-line macro successfully."""
206 """Test that we can run a multi-line macro successfully."""
207 ip = get_ipython()
207 ip = get_ipython()
208 ip.history_manager.reset()
208 ip.history_manager.reset()
209 cmds = ["a=10", "a+=1", py3compat.doctest_refactor_print("print a"),
209 cmds = ["a=10", "a+=1", py3compat.doctest_refactor_print("print a"),
210 "%macro test 2-3"]
210 "%macro test 2-3"]
211 for cmd in cmds:
211 for cmd in cmds:
212 ip.run_cell(cmd, store_history=True)
212 ip.run_cell(cmd, store_history=True)
213 nt.assert_equal(ip.user_ns["test"].value,
213 nt.assert_equal(ip.user_ns["test"].value,
214 py3compat.doctest_refactor_print("a+=1\nprint a\n"))
214 py3compat.doctest_refactor_print("a+=1\nprint a\n"))
215 with tt.AssertPrints("12"):
215 with tt.AssertPrints("12"):
216 ip.run_cell("test")
216 ip.run_cell("test")
217 with tt.AssertPrints("13"):
217 with tt.AssertPrints("13"):
218 ip.run_cell("test")
218 ip.run_cell("test")
219
219
220
220
221 @dec.skipif_not_numpy
221 @dec.skipif_not_numpy
222 def test_numpy_reset_array_undec():
222 def test_numpy_reset_array_undec():
223 "Test '%reset array' functionality"
223 "Test '%reset array' functionality"
224 _ip.ex('import numpy as np')
224 _ip.ex('import numpy as np')
225 _ip.ex('a = np.empty(2)')
225 _ip.ex('a = np.empty(2)')
226 yield (nt.assert_true, 'a' in _ip.user_ns)
226 yield (nt.assert_true, 'a' in _ip.user_ns)
227 _ip.magic('reset -f array')
227 _ip.magic('reset -f array')
228 yield (nt.assert_false, 'a' in _ip.user_ns)
228 yield (nt.assert_false, 'a' in _ip.user_ns)
229
229
230 def test_reset_out():
230 def test_reset_out():
231 "Test '%reset out' magic"
231 "Test '%reset out' magic"
232 _ip.run_cell("parrot = 'dead'", store_history=True)
232 _ip.run_cell("parrot = 'dead'", store_history=True)
233 # test '%reset -f out', make an Out prompt
233 # test '%reset -f out', make an Out prompt
234 _ip.run_cell("parrot", store_history=True)
234 _ip.run_cell("parrot", store_history=True)
235 nt.assert_true('dead' in [_ip.user_ns[x] for x in '_','__','___'])
235 nt.assert_true('dead' in [_ip.user_ns[x] for x in '_','__','___'])
236 _ip.magic('reset -f out')
236 _ip.magic('reset -f out')
237 nt.assert_false('dead' in [_ip.user_ns[x] for x in '_','__','___'])
237 nt.assert_false('dead' in [_ip.user_ns[x] for x in '_','__','___'])
238 nt.assert_true(len(_ip.user_ns['Out']) == 0)
238 nt.assert_true(len(_ip.user_ns['Out']) == 0)
239
239
240 def test_reset_in():
240 def test_reset_in():
241 "Test '%reset in' magic"
241 "Test '%reset in' magic"
242 # test '%reset -f in'
242 # test '%reset -f in'
243 _ip.run_cell("parrot", store_history=True)
243 _ip.run_cell("parrot", store_history=True)
244 nt.assert_true('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
244 nt.assert_true('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
245 _ip.magic('%reset -f in')
245 _ip.magic('%reset -f in')
246 nt.assert_false('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
246 nt.assert_false('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
247 nt.assert_true(len(set(_ip.user_ns['In'])) == 1)
247 nt.assert_true(len(set(_ip.user_ns['In'])) == 1)
248
248
249 def test_reset_dhist():
249 def test_reset_dhist():
250 "Test '%reset dhist' magic"
250 "Test '%reset dhist' magic"
251 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
251 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
252 _ip.magic('cd ' + os.path.dirname(nt.__file__))
252 _ip.magic('cd ' + os.path.dirname(nt.__file__))
253 _ip.magic('cd -')
253 _ip.magic('cd -')
254 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
254 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
255 _ip.magic('reset -f dhist')
255 _ip.magic('reset -f dhist')
256 nt.assert_true(len(_ip.user_ns['_dh']) == 0)
256 nt.assert_true(len(_ip.user_ns['_dh']) == 0)
257 _ip.run_cell("_dh = [d for d in tmp]") #restore
257 _ip.run_cell("_dh = [d for d in tmp]") #restore
258
258
259 def test_reset_in_length():
259 def test_reset_in_length():
260 "Test that '%reset in' preserves In[] length"
260 "Test that '%reset in' preserves In[] length"
261 _ip.run_cell("print 'foo'")
261 _ip.run_cell("print 'foo'")
262 _ip.run_cell("reset -f in")
262 _ip.run_cell("reset -f in")
263 nt.assert_true(len(_ip.user_ns['In']) == _ip.displayhook.prompt_count+1)
263 nt.assert_true(len(_ip.user_ns['In']) == _ip.displayhook.prompt_count+1)
264
264
265 def test_time():
266 _ip.magic('time None')
267
268 def test_tb_syntaxerror():
265 def test_tb_syntaxerror():
269 """test %tb after a SyntaxError"""
266 """test %tb after a SyntaxError"""
270 ip = get_ipython()
267 ip = get_ipython()
271 ip.run_cell("for")
268 ip.run_cell("for")
272
269
273 # trap and validate stdout
270 # trap and validate stdout
274 save_stdout = sys.stdout
271 save_stdout = sys.stdout
275 try:
272 try:
276 sys.stdout = StringIO()
273 sys.stdout = StringIO()
277 ip.run_cell("%tb")
274 ip.run_cell("%tb")
278 out = sys.stdout.getvalue()
275 out = sys.stdout.getvalue()
279 finally:
276 finally:
280 sys.stdout = save_stdout
277 sys.stdout = save_stdout
281 # trim output, and only check the last line
278 # trim output, and only check the last line
282 last_line = out.rstrip().splitlines()[-1].strip()
279 last_line = out.rstrip().splitlines()[-1].strip()
283 nt.assert_equal(last_line, "SyntaxError: invalid syntax")
280 nt.assert_equal(last_line, "SyntaxError: invalid syntax")
284
281
285
282
286 def test_time():
283 def test_time():
287 ip = get_ipython()
284 ip = get_ipython()
288
285
289 with tt.AssertPrints("CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s"):
286 with tt.AssertPrints("CPU times: user 0 ns, sys: 0 ns, total: 0 ns"):
290 ip.run_cell("%time None")
287 ip.run_cell("%time None")
291
288
292 ip.run_cell("def f(kmjy):\n"
289 ip.run_cell("def f(kmjy):\n"
293 " %time print (2*kmjy)")
290 " %time print (2*kmjy)")
294
291
295 with tt.AssertPrints("CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s"):
292 with tt.AssertPrints("CPU times: user 0 ns, sys: 0 ns, total: 0 ns"):
296 with tt.AssertPrints("hihi", suppress=False):
293 with tt.AssertPrints("hihi", suppress=False):
297 ip.run_cell("f('hi')")
294 ip.run_cell("f('hi')")
298
295
299 def test_doctest_mode():
296 def test_doctest_mode():
300 "Toggle doctest_mode twice, it should be a no-op and run without error"
297 "Toggle doctest_mode twice, it should be a no-op and run without error"
301 _ip.magic('doctest_mode')
298 _ip.magic('doctest_mode')
302 _ip.magic('doctest_mode')
299 _ip.magic('doctest_mode')
303
300
304
301
305 def test_parse_options():
302 def test_parse_options():
306 """Tests for basic options parsing in magics."""
303 """Tests for basic options parsing in magics."""
307 # These are only the most minimal of tests, more should be added later. At
304 # These are only the most minimal of tests, more should be added later. At
308 # the very least we check that basic text/unicode calls work OK.
305 # the very least we check that basic text/unicode calls work OK.
309 m = DummyMagics(_ip)
306 m = DummyMagics(_ip)
310 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
307 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
311 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
308 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
312
309
313
310
314 def test_dirops():
311 def test_dirops():
315 """Test various directory handling operations."""
312 """Test various directory handling operations."""
316 # curpath = lambda :os.path.splitdrive(os.getcwdu())[1].replace('\\','/')
313 # curpath = lambda :os.path.splitdrive(os.getcwdu())[1].replace('\\','/')
317 curpath = os.getcwdu
314 curpath = os.getcwdu
318 startdir = os.getcwdu()
315 startdir = os.getcwdu()
319 ipdir = os.path.realpath(_ip.ipython_dir)
316 ipdir = os.path.realpath(_ip.ipython_dir)
320 try:
317 try:
321 _ip.magic('cd "%s"' % ipdir)
318 _ip.magic('cd "%s"' % ipdir)
322 nt.assert_equal(curpath(), ipdir)
319 nt.assert_equal(curpath(), ipdir)
323 _ip.magic('cd -')
320 _ip.magic('cd -')
324 nt.assert_equal(curpath(), startdir)
321 nt.assert_equal(curpath(), startdir)
325 _ip.magic('pushd "%s"' % ipdir)
322 _ip.magic('pushd "%s"' % ipdir)
326 nt.assert_equal(curpath(), ipdir)
323 nt.assert_equal(curpath(), ipdir)
327 _ip.magic('popd')
324 _ip.magic('popd')
328 nt.assert_equal(curpath(), startdir)
325 nt.assert_equal(curpath(), startdir)
329 finally:
326 finally:
330 os.chdir(startdir)
327 os.chdir(startdir)
331
328
332
329
333 def test_xmode():
330 def test_xmode():
334 # Calling xmode three times should be a no-op
331 # Calling xmode three times should be a no-op
335 xmode = _ip.InteractiveTB.mode
332 xmode = _ip.InteractiveTB.mode
336 for i in range(3):
333 for i in range(3):
337 _ip.magic("xmode")
334 _ip.magic("xmode")
338 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
335 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
339
336
340 def test_reset_hard():
337 def test_reset_hard():
341 monitor = []
338 monitor = []
342 class A(object):
339 class A(object):
343 def __del__(self):
340 def __del__(self):
344 monitor.append(1)
341 monitor.append(1)
345 def __repr__(self):
342 def __repr__(self):
346 return "<A instance>"
343 return "<A instance>"
347
344
348 _ip.user_ns["a"] = A()
345 _ip.user_ns["a"] = A()
349 _ip.run_cell("a")
346 _ip.run_cell("a")
350
347
351 nt.assert_equal(monitor, [])
348 nt.assert_equal(monitor, [])
352 _ip.magic("reset -f")
349 _ip.magic("reset -f")
353 nt.assert_equal(monitor, [1])
350 nt.assert_equal(monitor, [1])
354
351
355 class TestXdel(tt.TempFileMixin):
352 class TestXdel(tt.TempFileMixin):
356 def test_xdel(self):
353 def test_xdel(self):
357 """Test that references from %run are cleared by xdel."""
354 """Test that references from %run are cleared by xdel."""
358 src = ("class A(object):\n"
355 src = ("class A(object):\n"
359 " monitor = []\n"
356 " monitor = []\n"
360 " def __del__(self):\n"
357 " def __del__(self):\n"
361 " self.monitor.append(1)\n"
358 " self.monitor.append(1)\n"
362 "a = A()\n")
359 "a = A()\n")
363 self.mktmp(src)
360 self.mktmp(src)
364 # %run creates some hidden references...
361 # %run creates some hidden references...
365 _ip.magic("run %s" % self.fname)
362 _ip.magic("run %s" % self.fname)
366 # ... as does the displayhook.
363 # ... as does the displayhook.
367 _ip.run_cell("a")
364 _ip.run_cell("a")
368
365
369 monitor = _ip.user_ns["A"].monitor
366 monitor = _ip.user_ns["A"].monitor
370 nt.assert_equal(monitor, [])
367 nt.assert_equal(monitor, [])
371
368
372 _ip.magic("xdel a")
369 _ip.magic("xdel a")
373
370
374 # Check that a's __del__ method has been called.
371 # Check that a's __del__ method has been called.
375 nt.assert_equal(monitor, [1])
372 nt.assert_equal(monitor, [1])
376
373
377 def doctest_who():
374 def doctest_who():
378 """doctest for %who
375 """doctest for %who
379
376
380 In [1]: %reset -f
377 In [1]: %reset -f
381
378
382 In [2]: alpha = 123
379 In [2]: alpha = 123
383
380
384 In [3]: beta = 'beta'
381 In [3]: beta = 'beta'
385
382
386 In [4]: %who int
383 In [4]: %who int
387 alpha
384 alpha
388
385
389 In [5]: %who str
386 In [5]: %who str
390 beta
387 beta
391
388
392 In [6]: %whos
389 In [6]: %whos
393 Variable Type Data/Info
390 Variable Type Data/Info
394 ----------------------------
391 ----------------------------
395 alpha int 123
392 alpha int 123
396 beta str beta
393 beta str beta
397
394
398 In [7]: %who_ls
395 In [7]: %who_ls
399 Out[7]: ['alpha', 'beta']
396 Out[7]: ['alpha', 'beta']
400 """
397 """
401
398
402 def test_whos():
399 def test_whos():
403 """Check that whos is protected against objects where repr() fails."""
400 """Check that whos is protected against objects where repr() fails."""
404 class A(object):
401 class A(object):
405 def __repr__(self):
402 def __repr__(self):
406 raise Exception()
403 raise Exception()
407 _ip.user_ns['a'] = A()
404 _ip.user_ns['a'] = A()
408 _ip.magic("whos")
405 _ip.magic("whos")
409
406
410 @py3compat.u_format
407 @py3compat.u_format
411 def doctest_precision():
408 def doctest_precision():
412 """doctest for %precision
409 """doctest for %precision
413
410
414 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
411 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
415
412
416 In [2]: %precision 5
413 In [2]: %precision 5
417 Out[2]: {u}'%.5f'
414 Out[2]: {u}'%.5f'
418
415
419 In [3]: f.float_format
416 In [3]: f.float_format
420 Out[3]: {u}'%.5f'
417 Out[3]: {u}'%.5f'
421
418
422 In [4]: %precision %e
419 In [4]: %precision %e
423 Out[4]: {u}'%e'
420 Out[4]: {u}'%e'
424
421
425 In [5]: f(3.1415927)
422 In [5]: f(3.1415927)
426 Out[5]: {u}'3.141593e+00'
423 Out[5]: {u}'3.141593e+00'
427 """
424 """
428
425
429 def test_psearch():
426 def test_psearch():
430 with tt.AssertPrints("dict.fromkeys"):
427 with tt.AssertPrints("dict.fromkeys"):
431 _ip.run_cell("dict.fr*?")
428 _ip.run_cell("dict.fr*?")
432
429
433 def test_timeit_shlex():
430 def test_timeit_shlex():
434 """test shlex issues with timeit (#1109)"""
431 """test shlex issues with timeit (#1109)"""
435 _ip.ex("def f(*a,**kw): pass")
432 _ip.ex("def f(*a,**kw): pass")
436 _ip.magic('timeit -n1 "this is a bug".count(" ")')
433 _ip.magic('timeit -n1 "this is a bug".count(" ")')
437 _ip.magic('timeit -r1 -n1 f(" ", 1)')
434 _ip.magic('timeit -r1 -n1 f(" ", 1)')
438 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
435 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
439 _ip.magic('timeit -r1 -n1 ("a " + "b")')
436 _ip.magic('timeit -r1 -n1 ("a " + "b")')
440 _ip.magic('timeit -r1 -n1 f("a " + "b")')
437 _ip.magic('timeit -r1 -n1 f("a " + "b")')
441 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
438 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
442
439
443
440
444 def test_timeit_arguments():
441 def test_timeit_arguments():
445 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
442 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
446 _ip.magic("timeit ('#')")
443 _ip.magic("timeit ('#')")
447
444
448
445
449 def test_timeit_special_syntax():
446 def test_timeit_special_syntax():
450 "Test %%timeit with IPython special syntax"
447 "Test %%timeit with IPython special syntax"
451 from IPython.core.magic import register_line_magic
448 from IPython.core.magic import register_line_magic
452
449
453 @register_line_magic
450 @register_line_magic
454 def lmagic(line):
451 def lmagic(line):
455 ip = get_ipython()
452 ip = get_ipython()
456 ip.user_ns['lmagic_out'] = line
453 ip.user_ns['lmagic_out'] = line
457
454
458 # line mode test
455 # line mode test
459 _ip.run_line_magic('timeit', '-n1 -r1 %lmagic my line')
456 _ip.run_line_magic('timeit', '-n1 -r1 %lmagic my line')
460 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
457 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
461 # cell mode test
458 # cell mode test
462 _ip.run_cell_magic('timeit', '-n1 -r1', '%lmagic my line2')
459 _ip.run_cell_magic('timeit', '-n1 -r1', '%lmagic my line2')
463 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
460 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
464
461
465
462
466 @dec.skipif(execution.profile is None)
463 @dec.skipif(execution.profile is None)
467 def test_prun_quotes():
464 def test_prun_quotes():
468 "Test that prun does not clobber string escapes (GH #1302)"
465 "Test that prun does not clobber string escapes (GH #1302)"
469 _ip.magic(r"prun -q x = '\t'")
466 _ip.magic(r"prun -q x = '\t'")
470 nt.assert_equal(_ip.user_ns['x'], '\t')
467 nt.assert_equal(_ip.user_ns['x'], '\t')
471
468
472 def test_extension():
469 def test_extension():
473 tmpdir = TemporaryDirectory()
470 tmpdir = TemporaryDirectory()
474 orig_ipython_dir = _ip.ipython_dir
471 orig_ipython_dir = _ip.ipython_dir
475 try:
472 try:
476 _ip.ipython_dir = tmpdir.name
473 _ip.ipython_dir = tmpdir.name
477 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
474 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
478 url = os.path.join(os.path.dirname(__file__), "daft_extension.py")
475 url = os.path.join(os.path.dirname(__file__), "daft_extension.py")
479 _ip.magic("install_ext %s" % url)
476 _ip.magic("install_ext %s" % url)
480 _ip.user_ns.pop('arq', None)
477 _ip.user_ns.pop('arq', None)
481 invalidate_caches() # Clear import caches
478 invalidate_caches() # Clear import caches
482 _ip.magic("load_ext daft_extension")
479 _ip.magic("load_ext daft_extension")
483 nt.assert_equal(_ip.user_ns['arq'], 185)
480 nt.assert_equal(_ip.user_ns['arq'], 185)
484 _ip.magic("unload_ext daft_extension")
481 _ip.magic("unload_ext daft_extension")
485 assert 'arq' not in _ip.user_ns
482 assert 'arq' not in _ip.user_ns
486 finally:
483 finally:
487 _ip.ipython_dir = orig_ipython_dir
484 _ip.ipython_dir = orig_ipython_dir
488 tmpdir.cleanup()
485 tmpdir.cleanup()
489
486
490 def test_notebook_export_json():
487 def test_notebook_export_json():
491 with TemporaryDirectory() as td:
488 with TemporaryDirectory() as td:
492 outfile = os.path.join(td, "nb.ipynb")
489 outfile = os.path.join(td, "nb.ipynb")
493 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
490 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
494 _ip.magic("notebook -e %s" % outfile)
491 _ip.magic("notebook -e %s" % outfile)
495
492
496 def test_notebook_export_py():
493 def test_notebook_export_py():
497 with TemporaryDirectory() as td:
494 with TemporaryDirectory() as td:
498 outfile = os.path.join(td, "nb.py")
495 outfile = os.path.join(td, "nb.py")
499 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
496 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
500 _ip.magic("notebook -e %s" % outfile)
497 _ip.magic("notebook -e %s" % outfile)
501
498
502 def test_notebook_reformat_py():
499 def test_notebook_reformat_py():
503 with TemporaryDirectory() as td:
500 with TemporaryDirectory() as td:
504 infile = os.path.join(td, "nb.ipynb")
501 infile = os.path.join(td, "nb.ipynb")
505 with io.open(infile, 'w', encoding='utf-8') as f:
502 with io.open(infile, 'w', encoding='utf-8') as f:
506 current.write(nb0, f, 'json')
503 current.write(nb0, f, 'json')
507
504
508 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
505 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
509 _ip.magic("notebook -f py %s" % infile)
506 _ip.magic("notebook -f py %s" % infile)
510
507
511 def test_notebook_reformat_json():
508 def test_notebook_reformat_json():
512 with TemporaryDirectory() as td:
509 with TemporaryDirectory() as td:
513 infile = os.path.join(td, "nb.py")
510 infile = os.path.join(td, "nb.py")
514 with io.open(infile, 'w', encoding='utf-8') as f:
511 with io.open(infile, 'w', encoding='utf-8') as f:
515 current.write(nb0, f, 'py')
512 current.write(nb0, f, 'py')
516
513
517 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
514 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
518 _ip.magic("notebook -f ipynb %s" % infile)
515 _ip.magic("notebook -f ipynb %s" % infile)
519 _ip.magic("notebook -f json %s" % infile)
516 _ip.magic("notebook -f json %s" % infile)
520
517
521 def test_env():
518 def test_env():
522 env = _ip.magic("env")
519 env = _ip.magic("env")
523 assert isinstance(env, dict), type(env)
520 assert isinstance(env, dict), type(env)
524
521
525
522
526 class CellMagicTestCase(TestCase):
523 class CellMagicTestCase(TestCase):
527
524
528 def check_ident(self, magic):
525 def check_ident(self, magic):
529 # Manually called, we get the result
526 # Manually called, we get the result
530 out = _ip.run_cell_magic(magic, 'a', 'b')
527 out = _ip.run_cell_magic(magic, 'a', 'b')
531 nt.assert_equal(out, ('a','b'))
528 nt.assert_equal(out, ('a','b'))
532 # Via run_cell, it goes into the user's namespace via displayhook
529 # Via run_cell, it goes into the user's namespace via displayhook
533 _ip.run_cell('%%' + magic +' c\nd')
530 _ip.run_cell('%%' + magic +' c\nd')
534 nt.assert_equal(_ip.user_ns['_'], ('c','d'))
531 nt.assert_equal(_ip.user_ns['_'], ('c','d'))
535
532
536 def test_cell_magic_func_deco(self):
533 def test_cell_magic_func_deco(self):
537 "Cell magic using simple decorator"
534 "Cell magic using simple decorator"
538 @register_cell_magic
535 @register_cell_magic
539 def cellm(line, cell):
536 def cellm(line, cell):
540 return line, cell
537 return line, cell
541
538
542 self.check_ident('cellm')
539 self.check_ident('cellm')
543
540
544 def test_cell_magic_reg(self):
541 def test_cell_magic_reg(self):
545 "Cell magic manually registered"
542 "Cell magic manually registered"
546 def cellm(line, cell):
543 def cellm(line, cell):
547 return line, cell
544 return line, cell
548
545
549 _ip.register_magic_function(cellm, 'cell', 'cellm2')
546 _ip.register_magic_function(cellm, 'cell', 'cellm2')
550 self.check_ident('cellm2')
547 self.check_ident('cellm2')
551
548
552 def test_cell_magic_class(self):
549 def test_cell_magic_class(self):
553 "Cell magics declared via a class"
550 "Cell magics declared via a class"
554 @magics_class
551 @magics_class
555 class MyMagics(Magics):
552 class MyMagics(Magics):
556
553
557 @cell_magic
554 @cell_magic
558 def cellm3(self, line, cell):
555 def cellm3(self, line, cell):
559 return line, cell
556 return line, cell
560
557
561 _ip.register_magics(MyMagics)
558 _ip.register_magics(MyMagics)
562 self.check_ident('cellm3')
559 self.check_ident('cellm3')
563
560
564 def test_cell_magic_class2(self):
561 def test_cell_magic_class2(self):
565 "Cell magics declared via a class, #2"
562 "Cell magics declared via a class, #2"
566 @magics_class
563 @magics_class
567 class MyMagics2(Magics):
564 class MyMagics2(Magics):
568
565
569 @cell_magic('cellm4')
566 @cell_magic('cellm4')
570 def cellm33(self, line, cell):
567 def cellm33(self, line, cell):
571 return line, cell
568 return line, cell
572
569
573 _ip.register_magics(MyMagics2)
570 _ip.register_magics(MyMagics2)
574 self.check_ident('cellm4')
571 self.check_ident('cellm4')
575 # Check that nothing is registered as 'cellm33'
572 # Check that nothing is registered as 'cellm33'
576 c33 = _ip.find_cell_magic('cellm33')
573 c33 = _ip.find_cell_magic('cellm33')
577 nt.assert_equal(c33, None)
574 nt.assert_equal(c33, None)
578
575
579 def test_file():
576 def test_file():
580 """Basic %%file"""
577 """Basic %%file"""
581 ip = get_ipython()
578 ip = get_ipython()
582 with TemporaryDirectory() as td:
579 with TemporaryDirectory() as td:
583 fname = os.path.join(td, 'file1')
580 fname = os.path.join(td, 'file1')
584 ip.run_cell_magic("file", fname, u'\n'.join([
581 ip.run_cell_magic("file", fname, u'\n'.join([
585 'line1',
582 'line1',
586 'line2',
583 'line2',
587 ]))
584 ]))
588 with open(fname) as f:
585 with open(fname) as f:
589 s = f.read()
586 s = f.read()
590 nt.assert_in('line1\n', s)
587 nt.assert_in('line1\n', s)
591 nt.assert_in('line2', s)
588 nt.assert_in('line2', s)
592
589
593 def test_file_var_expand():
590 def test_file_var_expand():
594 """%%file $filename"""
591 """%%file $filename"""
595 ip = get_ipython()
592 ip = get_ipython()
596 with TemporaryDirectory() as td:
593 with TemporaryDirectory() as td:
597 fname = os.path.join(td, 'file1')
594 fname = os.path.join(td, 'file1')
598 ip.user_ns['filename'] = fname
595 ip.user_ns['filename'] = fname
599 ip.run_cell_magic("file", '$filename', u'\n'.join([
596 ip.run_cell_magic("file", '$filename', u'\n'.join([
600 'line1',
597 'line1',
601 'line2',
598 'line2',
602 ]))
599 ]))
603 with open(fname) as f:
600 with open(fname) as f:
604 s = f.read()
601 s = f.read()
605 nt.assert_in('line1\n', s)
602 nt.assert_in('line1\n', s)
606 nt.assert_in('line2', s)
603 nt.assert_in('line2', s)
607
604
608 def test_file_unicode():
605 def test_file_unicode():
609 """%%file with unicode cell"""
606 """%%file with unicode cell"""
610 ip = get_ipython()
607 ip = get_ipython()
611 with TemporaryDirectory() as td:
608 with TemporaryDirectory() as td:
612 fname = os.path.join(td, 'file1')
609 fname = os.path.join(td, 'file1')
613 ip.run_cell_magic("file", fname, u'\n'.join([
610 ip.run_cell_magic("file", fname, u'\n'.join([
614 u'linΓ©1',
611 u'linΓ©1',
615 u'linΓ©2',
612 u'linΓ©2',
616 ]))
613 ]))
617 with io.open(fname, encoding='utf-8') as f:
614 with io.open(fname, encoding='utf-8') as f:
618 s = f.read()
615 s = f.read()
619 nt.assert_in(u'linΓ©1\n', s)
616 nt.assert_in(u'linΓ©1\n', s)
620 nt.assert_in(u'linΓ©2', s)
617 nt.assert_in(u'linΓ©2', s)
621
618
622 def test_file_amend():
619 def test_file_amend():
623 """%%file -a amends files"""
620 """%%file -a amends files"""
624 ip = get_ipython()
621 ip = get_ipython()
625 with TemporaryDirectory() as td:
622 with TemporaryDirectory() as td:
626 fname = os.path.join(td, 'file2')
623 fname = os.path.join(td, 'file2')
627 ip.run_cell_magic("file", fname, u'\n'.join([
624 ip.run_cell_magic("file", fname, u'\n'.join([
628 'line1',
625 'line1',
629 'line2',
626 'line2',
630 ]))
627 ]))
631 ip.run_cell_magic("file", "-a %s" % fname, u'\n'.join([
628 ip.run_cell_magic("file", "-a %s" % fname, u'\n'.join([
632 'line3',
629 'line3',
633 'line4',
630 'line4',
634 ]))
631 ]))
635 with open(fname) as f:
632 with open(fname) as f:
636 s = f.read()
633 s = f.read()
637 nt.assert_in('line1\n', s)
634 nt.assert_in('line1\n', s)
638 nt.assert_in('line3\n', s)
635 nt.assert_in('line3\n', s)
639
636
640
637
641 def test_script_config():
638 def test_script_config():
642 ip = get_ipython()
639 ip = get_ipython()
643 ip.config.ScriptMagics.script_magics = ['whoda']
640 ip.config.ScriptMagics.script_magics = ['whoda']
644 sm = script.ScriptMagics(shell=ip)
641 sm = script.ScriptMagics(shell=ip)
645 nt.assert_in('whoda', sm.magics['cell'])
642 nt.assert_in('whoda', sm.magics['cell'])
646
643
647 @dec.skip_win32
644 @dec.skip_win32
648 def test_script_out():
645 def test_script_out():
649 ip = get_ipython()
646 ip = get_ipython()
650 ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
647 ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
651 nt.assert_equal(ip.user_ns['output'], 'hi\n')
648 nt.assert_equal(ip.user_ns['output'], 'hi\n')
652
649
653 @dec.skip_win32
650 @dec.skip_win32
654 def test_script_err():
651 def test_script_err():
655 ip = get_ipython()
652 ip = get_ipython()
656 ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
653 ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
657 nt.assert_equal(ip.user_ns['error'], 'hello\n')
654 nt.assert_equal(ip.user_ns['error'], 'hello\n')
658
655
659 @dec.skip_win32
656 @dec.skip_win32
660 def test_script_out_err():
657 def test_script_out_err():
661 ip = get_ipython()
658 ip = get_ipython()
662 ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
659 ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
663 nt.assert_equal(ip.user_ns['output'], 'hi\n')
660 nt.assert_equal(ip.user_ns['output'], 'hi\n')
664 nt.assert_equal(ip.user_ns['error'], 'hello\n')
661 nt.assert_equal(ip.user_ns['error'], 'hello\n')
665
662
666 @dec.skip_win32
663 @dec.skip_win32
667 def test_script_bg_out():
664 def test_script_bg_out():
668 ip = get_ipython()
665 ip = get_ipython()
669 ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
666 ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
670 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
667 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
671
668
672 @dec.skip_win32
669 @dec.skip_win32
673 def test_script_bg_err():
670 def test_script_bg_err():
674 ip = get_ipython()
671 ip = get_ipython()
675 ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
672 ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
676 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
673 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
677
674
678 @dec.skip_win32
675 @dec.skip_win32
679 def test_script_bg_out_err():
676 def test_script_bg_out_err():
680 ip = get_ipython()
677 ip = get_ipython()
681 ip.run_cell_magic("script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2")
678 ip.run_cell_magic("script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2")
682 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
679 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
683 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
680 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
684
681
685 def test_script_defaults():
682 def test_script_defaults():
686 ip = get_ipython()
683 ip = get_ipython()
687 for cmd in ['sh', 'bash', 'perl', 'ruby']:
684 for cmd in ['sh', 'bash', 'perl', 'ruby']:
688 try:
685 try:
689 find_cmd(cmd)
686 find_cmd(cmd)
690 except Exception:
687 except Exception:
691 pass
688 pass
692 else:
689 else:
693 nt.assert_in(cmd, ip.magics_manager.magics['cell'])
690 nt.assert_in(cmd, ip.magics_manager.magics['cell'])
694
691
695
692
696 @magics_class
693 @magics_class
697 class FooFoo(Magics):
694 class FooFoo(Magics):
698 """class with both %foo and %%foo magics"""
695 """class with both %foo and %%foo magics"""
699 @line_magic('foo')
696 @line_magic('foo')
700 def line_foo(self, line):
697 def line_foo(self, line):
701 "I am line foo"
698 "I am line foo"
702 pass
699 pass
703
700
704 @cell_magic("foo")
701 @cell_magic("foo")
705 def cell_foo(self, line, cell):
702 def cell_foo(self, line, cell):
706 "I am cell foo, not line foo"
703 "I am cell foo, not line foo"
707 pass
704 pass
708
705
709 def test_line_cell_info():
706 def test_line_cell_info():
710 """%%foo and %foo magics are distinguishable to inspect"""
707 """%%foo and %foo magics are distinguishable to inspect"""
711 ip = get_ipython()
708 ip = get_ipython()
712 ip.magics_manager.register(FooFoo)
709 ip.magics_manager.register(FooFoo)
713 oinfo = ip.object_inspect('foo')
710 oinfo = ip.object_inspect('foo')
714 nt.assert_true(oinfo['found'])
711 nt.assert_true(oinfo['found'])
715 nt.assert_true(oinfo['ismagic'])
712 nt.assert_true(oinfo['ismagic'])
716
713
717 oinfo = ip.object_inspect('%%foo')
714 oinfo = ip.object_inspect('%%foo')
718 nt.assert_true(oinfo['found'])
715 nt.assert_true(oinfo['found'])
719 nt.assert_true(oinfo['ismagic'])
716 nt.assert_true(oinfo['ismagic'])
720 nt.assert_equal(oinfo['docstring'], FooFoo.cell_foo.__doc__)
717 nt.assert_equal(oinfo['docstring'], FooFoo.cell_foo.__doc__)
721
718
722 oinfo = ip.object_inspect('%foo')
719 oinfo = ip.object_inspect('%foo')
723 nt.assert_true(oinfo['found'])
720 nt.assert_true(oinfo['found'])
724 nt.assert_true(oinfo['ismagic'])
721 nt.assert_true(oinfo['ismagic'])
725 nt.assert_equal(oinfo['docstring'], FooFoo.line_foo.__doc__)
722 nt.assert_equal(oinfo['docstring'], FooFoo.line_foo.__doc__)
726
723
727 def test_multiple_magics():
724 def test_multiple_magics():
728 ip = get_ipython()
725 ip = get_ipython()
729 foo1 = FooFoo(ip)
726 foo1 = FooFoo(ip)
730 foo2 = FooFoo(ip)
727 foo2 = FooFoo(ip)
731 mm = ip.magics_manager
728 mm = ip.magics_manager
732 mm.register(foo1)
729 mm.register(foo1)
733 nt.assert_true(mm.magics['line']['foo'].im_self is foo1)
730 nt.assert_true(mm.magics['line']['foo'].im_self is foo1)
734 mm.register(foo2)
731 mm.register(foo2)
735 nt.assert_true(mm.magics['line']['foo'].im_self is foo2)
732 nt.assert_true(mm.magics['line']['foo'].im_self is foo2)
736
733
737 def test_alias_magic():
734 def test_alias_magic():
738 """Test %alias_magic."""
735 """Test %alias_magic."""
739 ip = get_ipython()
736 ip = get_ipython()
740 mm = ip.magics_manager
737 mm = ip.magics_manager
741
738
742 # Basic operation: both cell and line magics are created, if possible.
739 # Basic operation: both cell and line magics are created, if possible.
743 ip.run_line_magic('alias_magic', 'timeit_alias timeit')
740 ip.run_line_magic('alias_magic', 'timeit_alias timeit')
744 nt.assert_true('timeit_alias' in mm.magics['line'])
741 nt.assert_true('timeit_alias' in mm.magics['line'])
745 nt.assert_true('timeit_alias' in mm.magics['cell'])
742 nt.assert_true('timeit_alias' in mm.magics['cell'])
746
743
747 # --cell is specified, line magic not created.
744 # --cell is specified, line magic not created.
748 ip.run_line_magic('alias_magic', '--cell timeit_cell_alias timeit')
745 ip.run_line_magic('alias_magic', '--cell timeit_cell_alias timeit')
749 nt.assert_false('timeit_cell_alias' in mm.magics['line'])
746 nt.assert_false('timeit_cell_alias' in mm.magics['line'])
750 nt.assert_true('timeit_cell_alias' in mm.magics['cell'])
747 nt.assert_true('timeit_cell_alias' in mm.magics['cell'])
751
748
752 # Test that line alias is created successfully.
749 # Test that line alias is created successfully.
753 ip.run_line_magic('alias_magic', '--line env_alias env')
750 ip.run_line_magic('alias_magic', '--line env_alias env')
754 nt.assert_equal(ip.run_line_magic('env', ''),
751 nt.assert_equal(ip.run_line_magic('env', ''),
755 ip.run_line_magic('env_alias', ''))
752 ip.run_line_magic('env_alias', ''))
756
753
757 def test_save():
754 def test_save():
758 """Test %save."""
755 """Test %save."""
759 ip = get_ipython()
756 ip = get_ipython()
760 ip.history_manager.reset() # Clear any existing history.
757 ip.history_manager.reset() # Clear any existing history.
761 cmds = [u"a=1", u"def b():\n return a**2", u"print(a, b())"]
758 cmds = [u"a=1", u"def b():\n return a**2", u"print(a, b())"]
762 for i, cmd in enumerate(cmds, start=1):
759 for i, cmd in enumerate(cmds, start=1):
763 ip.history_manager.store_inputs(i, cmd)
760 ip.history_manager.store_inputs(i, cmd)
764 with TemporaryDirectory() as tmpdir:
761 with TemporaryDirectory() as tmpdir:
765 file = os.path.join(tmpdir, "testsave.py")
762 file = os.path.join(tmpdir, "testsave.py")
766 ip.run_line_magic("save", "%s 1-10" % file)
763 ip.run_line_magic("save", "%s 1-10" % file)
767 with open(file) as f:
764 with open(file) as f:
768 content = f.read()
765 content = f.read()
769 nt.assert_equal(content.count(cmds[0]), 1)
766 nt.assert_equal(content.count(cmds[0]), 1)
770 nt.assert_true('coding: utf-8' in content)
767 nt.assert_true('coding: utf-8' in content)
771 ip.run_line_magic("save", "-a %s 1-10" % file)
768 ip.run_line_magic("save", "-a %s 1-10" % file)
772 with open(file) as f:
769 with open(file) as f:
773 content = f.read()
770 content = f.read()
774 nt.assert_equal(content.count(cmds[0]), 2)
771 nt.assert_equal(content.count(cmds[0]), 2)
775 nt.assert_true('coding: utf-8' in content)
772 nt.assert_true('coding: utf-8' in content)
776
773
777
774
778 def test_store():
775 def test_store():
779 """Test %store."""
776 """Test %store."""
780 ip = get_ipython()
777 ip = get_ipython()
781 ip.run_line_magic('load_ext', 'storemagic')
778 ip.run_line_magic('load_ext', 'storemagic')
782
779
783 # make sure the storage is empty
780 # make sure the storage is empty
784 ip.run_line_magic('store', '-z')
781 ip.run_line_magic('store', '-z')
785 ip.user_ns['var'] = 42
782 ip.user_ns['var'] = 42
786 ip.run_line_magic('store', 'var')
783 ip.run_line_magic('store', 'var')
787 ip.user_ns['var'] = 39
784 ip.user_ns['var'] = 39
788 ip.run_line_magic('store', '-r')
785 ip.run_line_magic('store', '-r')
789 nt.assert_equal(ip.user_ns['var'], 42)
786 nt.assert_equal(ip.user_ns['var'], 42)
790
787
791 ip.run_line_magic('store', '-d var')
788 ip.run_line_magic('store', '-d var')
792 ip.user_ns['var'] = 39
789 ip.user_ns['var'] = 39
793 ip.run_line_magic('store' , '-r')
790 ip.run_line_magic('store' , '-r')
794 nt.assert_equal(ip.user_ns['var'], 39)
791 nt.assert_equal(ip.user_ns['var'], 39)
795
792
796
793
797 def _run_edit_test(arg_s, exp_filename=None,
794 def _run_edit_test(arg_s, exp_filename=None,
798 exp_lineno=-1,
795 exp_lineno=-1,
799 exp_contents=None,
796 exp_contents=None,
800 exp_is_temp=None):
797 exp_is_temp=None):
801 ip = get_ipython()
798 ip = get_ipython()
802 M = code.CodeMagics(ip)
799 M = code.CodeMagics(ip)
803 last_call = ['','']
800 last_call = ['','']
804 opts,args = M.parse_options(arg_s,'prxn:')
801 opts,args = M.parse_options(arg_s,'prxn:')
805 filename, lineno, is_temp = M._find_edit_target(ip, args, opts, last_call)
802 filename, lineno, is_temp = M._find_edit_target(ip, args, opts, last_call)
806
803
807 if exp_filename is not None:
804 if exp_filename is not None:
808 nt.assert_equal(exp_filename, filename)
805 nt.assert_equal(exp_filename, filename)
809 if exp_contents is not None:
806 if exp_contents is not None:
810 with io.open(filename, 'r') as f:
807 with io.open(filename, 'r') as f:
811 contents = f.read()
808 contents = f.read()
812 nt.assert_equal(exp_contents, contents)
809 nt.assert_equal(exp_contents, contents)
813 if exp_lineno != -1:
810 if exp_lineno != -1:
814 nt.assert_equal(exp_lineno, lineno)
811 nt.assert_equal(exp_lineno, lineno)
815 if exp_is_temp is not None:
812 if exp_is_temp is not None:
816 nt.assert_equal(exp_is_temp, is_temp)
813 nt.assert_equal(exp_is_temp, is_temp)
817
814
818
815
819 def test_edit_interactive():
816 def test_edit_interactive():
820 """%edit on interactively defined objects"""
817 """%edit on interactively defined objects"""
821 ip = get_ipython()
818 ip = get_ipython()
822 n = ip.execution_count
819 n = ip.execution_count
823 ip.run_cell(u"def foo(): return 1", store_history=True)
820 ip.run_cell(u"def foo(): return 1", store_history=True)
824
821
825 try:
822 try:
826 _run_edit_test("foo")
823 _run_edit_test("foo")
827 except code.InteractivelyDefined as e:
824 except code.InteractivelyDefined as e:
828 nt.assert_equal(e.index, n)
825 nt.assert_equal(e.index, n)
829 else:
826 else:
830 raise AssertionError("Should have raised InteractivelyDefined")
827 raise AssertionError("Should have raised InteractivelyDefined")
831
828
832
829
833 def test_edit_cell():
830 def test_edit_cell():
834 """%edit [cell id]"""
831 """%edit [cell id]"""
835 ip = get_ipython()
832 ip = get_ipython()
836
833
837 ip.run_cell(u"def foo(): return 1", store_history=True)
834 ip.run_cell(u"def foo(): return 1", store_history=True)
838
835
839 # test
836 # test
840 _run_edit_test("1", exp_contents=ip.user_ns['In'][1], exp_is_temp=True)
837 _run_edit_test("1", exp_contents=ip.user_ns['In'][1], exp_is_temp=True)
General Comments 0
You need to be logged in to leave comments. Login now