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