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