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