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