##// END OF EJS Templates
Recovered trailing whitespace
Pablo Galindo -
Show More
@@ -1,1374 +1,1374 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Implementation of execution-related magic functions."""
2 """Implementation of execution-related magic functions."""
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7 from __future__ import print_function
7 from __future__ import print_function
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import ast
10 import ast
11 import bdb
11 import bdb
12 import gc
12 import gc
13 import itertools
13 import itertools
14 import os
14 import os
15 import sys
15 import sys
16 import time
16 import time
17 import timeit
17 import timeit
18 import math
18 import math
19 from pdb import Restart
19 from pdb import Restart
20
20
21 # cProfile was added in Python2.5
21 # cProfile was added in Python2.5
22 try:
22 try:
23 import cProfile as profile
23 import cProfile as profile
24 import pstats
24 import pstats
25 except ImportError:
25 except ImportError:
26 # profile isn't bundled by default in Debian for license reasons
26 # profile isn't bundled by default in Debian for license reasons
27 try:
27 try:
28 import profile, pstats
28 import profile, pstats
29 except ImportError:
29 except ImportError:
30 profile = pstats = None
30 profile = pstats = None
31
31
32 from IPython.core import oinspect
32 from IPython.core import oinspect
33 from IPython.core import magic_arguments
33 from IPython.core import magic_arguments
34 from IPython.core import page
34 from IPython.core import page
35 from IPython.core.error import UsageError
35 from IPython.core.error import UsageError
36 from IPython.core.macro import Macro
36 from IPython.core.macro import Macro
37 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
37 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
38 line_cell_magic, on_off, needs_local_scope)
38 line_cell_magic, on_off, needs_local_scope)
39 from IPython.testing.skipdoctest import skip_doctest
39 from IPython.testing.skipdoctest import skip_doctest
40 from IPython.utils import py3compat
40 from IPython.utils import py3compat
41 from IPython.utils.py3compat import builtin_mod, iteritems, PY3
41 from IPython.utils.py3compat import builtin_mod, iteritems, PY3
42 from IPython.utils.contexts import preserve_keys
42 from IPython.utils.contexts import preserve_keys
43 from IPython.utils.capture import capture_output
43 from IPython.utils.capture import capture_output
44 from IPython.utils.ipstruct import Struct
44 from IPython.utils.ipstruct import Struct
45 from IPython.utils.module_paths import find_mod
45 from IPython.utils.module_paths import find_mod
46 from IPython.utils.path import get_py_filename, shellglob
46 from IPython.utils.path import get_py_filename, shellglob
47 from IPython.utils.timing import clock, clock2
47 from IPython.utils.timing import clock, clock2
48 from warnings import warn
48 from warnings import warn
49 from logging import error
49 from logging import error
50
50
51 if PY3:
51 if PY3:
52 from io import StringIO
52 from io import StringIO
53 else:
53 else:
54 from StringIO import StringIO
54 from StringIO import StringIO
55
55
56 #-----------------------------------------------------------------------------
56 #-----------------------------------------------------------------------------
57 # Magic implementation classes
57 # Magic implementation classes
58 #-----------------------------------------------------------------------------
58 #-----------------------------------------------------------------------------
59
59
60
60
61 class TimeitResult(object):
61 class TimeitResult(object):
62 """
62 """
63 Object returned by the timeit magic with info about the run.
63 Object returned by the timeit magic with info about the run.
64
64
65 Contains the following attributes :
65 Contains the following attributes :
66
66
67 loops: (int) number of loops done per measurement
67 loops: (int) number of loops done per measurement
68 repeat: (int) number of times the measurement has been repeated
68 repeat: (int) number of times the measurement has been repeated
69 best: (float) best execution time / number
69 best: (float) best execution time / number
70 all_runs: (list of float) execution time of each run (in s)
70 all_runs: (list of float) execution time of each run (in s)
71 compile_time: (float) time of statement compilation (s)
71 compile_time: (float) time of statement compilation (s)
72
72
73 """
73 """
74
74
75 def __init__(self, loops, repeat, average, stdev, all_runs, compile_time, precision):
75 def __init__(self, loops, repeat, average, stdev, all_runs, compile_time, precision):
76 self.loops = loops
76 self.loops = loops
77 self.repeat = repeat
77 self.repeat = repeat
78 self.average = average
78 self.average = average
79 self.stdev = stdev
79 self.stdev = stdev
80 self.all_runs = all_runs
80 self.all_runs = all_runs
81 self.compile_time = compile_time
81 self.compile_time = compile_time
82 self._precision = precision
82 self._precision = precision
83
83
84 def _repr_pretty_(self, p , cycle):
84 def _repr_pretty_(self, p , cycle):
85 if self.loops == 1: # No s at "loops" if only one loop
85 if self.loops == 1: # No s at "loops" if only one loop
86 unic = (u"%s loop, average of %d: %s +- %s per loop (using standard deviation)"
86 unic = (u"%s loop, average of %d: %s +- %s per loop (using standard deviation)"
87 % (self.loops, self.repeat,
87 % (self.loops, self.repeat,
88 _format_time(self.average, self._precision),
88 _format_time(self.average, self._precision),
89 _format_time(self.stdev, self._precision)))
89 _format_time(self.stdev, self._precision)))
90 else:
90 else:
91 unic = (u"%s loops, average of %d: %s +- %s per loop (using standard deviation)"
91 unic = (u"%s loops, average of %d: %s +- %s per loop (using standard deviation)"
92 % (self.loops, self.repeat,
92 % (self.loops, self.repeat,
93 _format_time(self.average, self._precision),
93 _format_time(self.average, self._precision),
94 _format_time(self.stdev, self._precision)))
94 _format_time(self.stdev, self._precision)))
95 p.text(u'<TimeitResult : '+unic+u'>')
95 p.text(u'<TimeitResult : '+unic+u'>')
96
96
97
97
98 class TimeitTemplateFiller(ast.NodeTransformer):
98 class TimeitTemplateFiller(ast.NodeTransformer):
99 """Fill in the AST template for timing execution.
99 """Fill in the AST template for timing execution.
100
100
101 This is quite closely tied to the template definition, which is in
101 This is quite closely tied to the template definition, which is in
102 :meth:`ExecutionMagics.timeit`.
102 :meth:`ExecutionMagics.timeit`.
103 """
103 """
104 def __init__(self, ast_setup, ast_stmt):
104 def __init__(self, ast_setup, ast_stmt):
105 self.ast_setup = ast_setup
105 self.ast_setup = ast_setup
106 self.ast_stmt = ast_stmt
106 self.ast_stmt = ast_stmt
107
107
108 def visit_FunctionDef(self, node):
108 def visit_FunctionDef(self, node):
109 "Fill in the setup statement"
109 "Fill in the setup statement"
110 self.generic_visit(node)
110 self.generic_visit(node)
111 if node.name == "inner":
111 if node.name == "inner":
112 node.body[:1] = self.ast_setup.body
112 node.body[:1] = self.ast_setup.body
113
113
114 return node
114 return node
115
115
116 def visit_For(self, node):
116 def visit_For(self, node):
117 "Fill in the statement to be timed"
117 "Fill in the statement to be timed"
118 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
118 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
119 node.body = self.ast_stmt.body
119 node.body = self.ast_stmt.body
120 return node
120 return node
121
121
122
122
123 class Timer(timeit.Timer):
123 class Timer(timeit.Timer):
124 """Timer class that explicitly uses self.inner
124 """Timer class that explicitly uses self.inner
125
125
126 which is an undocumented implementation detail of CPython,
126 which is an undocumented implementation detail of CPython,
127 not shared by PyPy.
127 not shared by PyPy.
128 """
128 """
129 # Timer.timeit copied from CPython 3.4.2
129 # Timer.timeit copied from CPython 3.4.2
130 def timeit(self, number=timeit.default_number):
130 def timeit(self, number=timeit.default_number):
131 """Time 'number' executions of the main statement.
131 """Time 'number' executions of the main statement.
132
132
133 To be precise, this executes the setup statement once, and
133 To be precise, this executes the setup statement once, and
134 then returns the time it takes to execute the main statement
134 then returns the time it takes to execute the main statement
135 a number of times, as a float measured in seconds. The
135 a number of times, as a float measured in seconds. The
136 argument is the number of times through the loop, defaulting
136 argument is the number of times through the loop, defaulting
137 to one million. The main statement, the setup statement and
137 to one million. The main statement, the setup statement and
138 the timer function to be used are passed to the constructor.
138 the timer function to be used are passed to the constructor.
139 """
139 """
140 it = itertools.repeat(None, number)
140 it = itertools.repeat(None, number)
141 gcold = gc.isenabled()
141 gcold = gc.isenabled()
142 gc.disable()
142 gc.disable()
143 try:
143 try:
144 timing = self.inner(it, self.timer)
144 timing = self.inner(it, self.timer)
145 finally:
145 finally:
146 if gcold:
146 if gcold:
147 gc.enable()
147 gc.enable()
148 return timing
148 return timing
149
149
150
150
151 @magics_class
151 @magics_class
152 class ExecutionMagics(Magics):
152 class ExecutionMagics(Magics):
153 """Magics related to code execution, debugging, profiling, etc.
153 """Magics related to code execution, debugging, profiling, etc.
154
154
155 """
155 """
156
156
157 def __init__(self, shell):
157 def __init__(self, shell):
158 super(ExecutionMagics, self).__init__(shell)
158 super(ExecutionMagics, self).__init__(shell)
159 if profile is None:
159 if profile is None:
160 self.prun = self.profile_missing_notice
160 self.prun = self.profile_missing_notice
161 # Default execution function used to actually run user code.
161 # Default execution function used to actually run user code.
162 self.default_runner = None
162 self.default_runner = None
163
163
164 def profile_missing_notice(self, *args, **kwargs):
164 def profile_missing_notice(self, *args, **kwargs):
165 error("""\
165 error("""\
166 The profile module could not be found. It has been removed from the standard
166 The profile module could not be found. It has been removed from the standard
167 python packages because of its non-free license. To use profiling, install the
167 python packages because of its non-free license. To use profiling, install the
168 python-profiler package from non-free.""")
168 python-profiler package from non-free.""")
169
169
170 @skip_doctest
170 @skip_doctest
171 @line_cell_magic
171 @line_cell_magic
172 def prun(self, parameter_s='', cell=None):
172 def prun(self, parameter_s='', cell=None):
173
173
174 """Run a statement through the python code profiler.
174 """Run a statement through the python code profiler.
175
175
176 Usage, in line mode:
176 Usage, in line mode:
177 %prun [options] statement
177 %prun [options] statement
178
178
179 Usage, in cell mode:
179 Usage, in cell mode:
180 %%prun [options] [statement]
180 %%prun [options] [statement]
181 code...
181 code...
182 code...
182 code...
183
183
184 In cell mode, the additional code lines are appended to the (possibly
184 In cell mode, the additional code lines are appended to the (possibly
185 empty) statement in the first line. Cell mode allows you to easily
185 empty) statement in the first line. Cell mode allows you to easily
186 profile multiline blocks without having to put them in a separate
186 profile multiline blocks without having to put them in a separate
187 function.
187 function.
188
188
189 The given statement (which doesn't require quote marks) is run via the
189 The given statement (which doesn't require quote marks) is run via the
190 python profiler in a manner similar to the profile.run() function.
190 python profiler in a manner similar to the profile.run() function.
191 Namespaces are internally managed to work correctly; profile.run
191 Namespaces are internally managed to work correctly; profile.run
192 cannot be used in IPython because it makes certain assumptions about
192 cannot be used in IPython because it makes certain assumptions about
193 namespaces which do not hold under IPython.
193 namespaces which do not hold under IPython.
194
194
195 Options:
195 Options:
196
196
197 -l <limit>
197 -l <limit>
198 you can place restrictions on what or how much of the
198 you can place restrictions on what or how much of the
199 profile gets printed. The limit value can be:
199 profile gets printed. The limit value can be:
200
200
201 * A string: only information for function names containing this string
201 * A string: only information for function names containing this string
202 is printed.
202 is printed.
203
203
204 * An integer: only these many lines are printed.
204 * An integer: only these many lines are printed.
205
205
206 * A float (between 0 and 1): this fraction of the report is printed
206 * A float (between 0 and 1): this fraction of the report is printed
207 (for example, use a limit of 0.4 to see the topmost 40% only).
207 (for example, use a limit of 0.4 to see the topmost 40% only).
208
208
209 You can combine several limits with repeated use of the option. For
209 You can combine several limits with repeated use of the option. For
210 example, ``-l __init__ -l 5`` will print only the topmost 5 lines of
210 example, ``-l __init__ -l 5`` will print only the topmost 5 lines of
211 information about class constructors.
211 information about class constructors.
212
212
213 -r
213 -r
214 return the pstats.Stats object generated by the profiling. This
214 return the pstats.Stats object generated by the profiling. This
215 object has all the information about the profile in it, and you can
215 object has all the information about the profile in it, and you can
216 later use it for further analysis or in other functions.
216 later use it for further analysis or in other functions.
217
217
218 -s <key>
218 -s <key>
219 sort profile by given key. You can provide more than one key
219 sort profile by given key. You can provide more than one key
220 by using the option several times: '-s key1 -s key2 -s key3...'. The
220 by using the option several times: '-s key1 -s key2 -s key3...'. The
221 default sorting key is 'time'.
221 default sorting key is 'time'.
222
222
223 The following is copied verbatim from the profile documentation
223 The following is copied verbatim from the profile documentation
224 referenced below:
224 referenced below:
225
225
226 When more than one key is provided, additional keys are used as
226 When more than one key is provided, additional keys are used as
227 secondary criteria when the there is equality in all keys selected
227 secondary criteria when the there is equality in all keys selected
228 before them.
228 before them.
229
229
230 Abbreviations can be used for any key names, as long as the
230 Abbreviations can be used for any key names, as long as the
231 abbreviation is unambiguous. The following are the keys currently
231 abbreviation is unambiguous. The following are the keys currently
232 defined:
232 defined:
233
233
234 ============ =====================
234 ============ =====================
235 Valid Arg Meaning
235 Valid Arg Meaning
236 ============ =====================
236 ============ =====================
237 "calls" call count
237 "calls" call count
238 "cumulative" cumulative time
238 "cumulative" cumulative time
239 "file" file name
239 "file" file name
240 "module" file name
240 "module" file name
241 "pcalls" primitive call count
241 "pcalls" primitive call count
242 "line" line number
242 "line" line number
243 "name" function name
243 "name" function name
244 "nfl" name/file/line
244 "nfl" name/file/line
245 "stdname" standard name
245 "stdname" standard name
246 "time" internal time
246 "time" internal time
247 ============ =====================
247 ============ =====================
248
248
249 Note that all sorts on statistics are in descending order (placing
249 Note that all sorts on statistics are in descending order (placing
250 most time consuming items first), where as name, file, and line number
250 most time consuming items first), where as name, file, and line number
251 searches are in ascending order (i.e., alphabetical). The subtle
251 searches are in ascending order (i.e., alphabetical). The subtle
252 distinction between "nfl" and "stdname" is that the standard name is a
252 distinction between "nfl" and "stdname" is that the standard name is a
253 sort of the name as printed, which means that the embedded line
253 sort of the name as printed, which means that the embedded line
254 numbers get compared in an odd way. For example, lines 3, 20, and 40
254 numbers get compared in an odd way. For example, lines 3, 20, and 40
255 would (if the file names were the same) appear in the string order
255 would (if the file names were the same) appear in the string order
256 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
256 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
257 line numbers. In fact, sort_stats("nfl") is the same as
257 line numbers. In fact, sort_stats("nfl") is the same as
258 sort_stats("name", "file", "line").
258 sort_stats("name", "file", "line").
259
259
260 -T <filename>
260 -T <filename>
261 save profile results as shown on screen to a text
261 save profile results as shown on screen to a text
262 file. The profile is still shown on screen.
262 file. The profile is still shown on screen.
263
263
264 -D <filename>
264 -D <filename>
265 save (via dump_stats) profile statistics to given
265 save (via dump_stats) profile statistics to given
266 filename. This data is in a format understood by the pstats module, and
266 filename. This data is in a format understood by the pstats module, and
267 is generated by a call to the dump_stats() method of profile
267 is generated by a call to the dump_stats() method of profile
268 objects. The profile is still shown on screen.
268 objects. The profile is still shown on screen.
269
269
270 -q
270 -q
271 suppress output to the pager. Best used with -T and/or -D above.
271 suppress output to the pager. Best used with -T and/or -D above.
272
272
273 If you want to run complete programs under the profiler's control, use
273 If you want to run complete programs under the profiler's control, use
274 ``%run -p [prof_opts] filename.py [args to program]`` where prof_opts
274 ``%run -p [prof_opts] filename.py [args to program]`` where prof_opts
275 contains profiler specific options as described here.
275 contains profiler specific options as described here.
276
276
277 You can read the complete documentation for the profile module with::
277 You can read the complete documentation for the profile module with::
278
278
279 In [1]: import profile; profile.help()
279 In [1]: import profile; profile.help()
280 """
280 """
281 opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q',
281 opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q',
282 list_all=True, posix=False)
282 list_all=True, posix=False)
283 if cell is not None:
283 if cell is not None:
284 arg_str += '\n' + cell
284 arg_str += '\n' + cell
285 arg_str = self.shell.input_splitter.transform_cell(arg_str)
285 arg_str = self.shell.input_splitter.transform_cell(arg_str)
286 return self._run_with_profiler(arg_str, opts, self.shell.user_ns)
286 return self._run_with_profiler(arg_str, opts, self.shell.user_ns)
287
287
288 def _run_with_profiler(self, code, opts, namespace):
288 def _run_with_profiler(self, code, opts, namespace):
289 """
289 """
290 Run `code` with profiler. Used by ``%prun`` and ``%run -p``.
290 Run `code` with profiler. Used by ``%prun`` and ``%run -p``.
291
291
292 Parameters
292 Parameters
293 ----------
293 ----------
294 code : str
294 code : str
295 Code to be executed.
295 Code to be executed.
296 opts : Struct
296 opts : Struct
297 Options parsed by `self.parse_options`.
297 Options parsed by `self.parse_options`.
298 namespace : dict
298 namespace : dict
299 A dictionary for Python namespace (e.g., `self.shell.user_ns`).
299 A dictionary for Python namespace (e.g., `self.shell.user_ns`).
300
300
301 """
301 """
302
302
303 # Fill default values for unspecified options:
303 # Fill default values for unspecified options:
304 opts.merge(Struct(D=[''], l=[], s=['time'], T=['']))
304 opts.merge(Struct(D=[''], l=[], s=['time'], T=['']))
305
305
306 prof = profile.Profile()
306 prof = profile.Profile()
307 try:
307 try:
308 prof = prof.runctx(code, namespace, namespace)
308 prof = prof.runctx(code, namespace, namespace)
309 sys_exit = ''
309 sys_exit = ''
310 except SystemExit:
310 except SystemExit:
311 sys_exit = """*** SystemExit exception caught in code being profiled."""
311 sys_exit = """*** SystemExit exception caught in code being profiled."""
312
312
313 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
313 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
314
314
315 lims = opts.l
315 lims = opts.l
316 if lims:
316 if lims:
317 lims = [] # rebuild lims with ints/floats/strings
317 lims = [] # rebuild lims with ints/floats/strings
318 for lim in opts.l:
318 for lim in opts.l:
319 try:
319 try:
320 lims.append(int(lim))
320 lims.append(int(lim))
321 except ValueError:
321 except ValueError:
322 try:
322 try:
323 lims.append(float(lim))
323 lims.append(float(lim))
324 except ValueError:
324 except ValueError:
325 lims.append(lim)
325 lims.append(lim)
326
326
327 # Trap output.
327 # Trap output.
328 stdout_trap = StringIO()
328 stdout_trap = StringIO()
329 stats_stream = stats.stream
329 stats_stream = stats.stream
330 try:
330 try:
331 stats.stream = stdout_trap
331 stats.stream = stdout_trap
332 stats.print_stats(*lims)
332 stats.print_stats(*lims)
333 finally:
333 finally:
334 stats.stream = stats_stream
334 stats.stream = stats_stream
335
335
336 output = stdout_trap.getvalue()
336 output = stdout_trap.getvalue()
337 output = output.rstrip()
337 output = output.rstrip()
338
338
339 if 'q' not in opts:
339 if 'q' not in opts:
340 page.page(output)
340 page.page(output)
341 print(sys_exit, end=' ')
341 print(sys_exit, end=' ')
342
342
343 dump_file = opts.D[0]
343 dump_file = opts.D[0]
344 text_file = opts.T[0]
344 text_file = opts.T[0]
345 if dump_file:
345 if dump_file:
346 prof.dump_stats(dump_file)
346 prof.dump_stats(dump_file)
347 print('\n*** Profile stats marshalled to file',\
347 print('\n*** Profile stats marshalled to file',\
348 repr(dump_file)+'.',sys_exit)
348 repr(dump_file)+'.',sys_exit)
349 if text_file:
349 if text_file:
350 pfile = open(text_file,'w')
350 pfile = open(text_file,'w')
351 pfile.write(output)
351 pfile.write(output)
352 pfile.close()
352 pfile.close()
353 print('\n*** Profile printout saved to text file',\
353 print('\n*** Profile printout saved to text file',\
354 repr(text_file)+'.',sys_exit)
354 repr(text_file)+'.',sys_exit)
355
355
356 if 'r' in opts:
356 if 'r' in opts:
357 return stats
357 return stats
358 else:
358 else:
359 return None
359 return None
360
360
361 @line_magic
361 @line_magic
362 def pdb(self, parameter_s=''):
362 def pdb(self, parameter_s=''):
363 """Control the automatic calling of the pdb interactive debugger.
363 """Control the automatic calling of the pdb interactive debugger.
364
364
365 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
365 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
366 argument it works as a toggle.
366 argument it works as a toggle.
367
367
368 When an exception is triggered, IPython can optionally call the
368 When an exception is triggered, IPython can optionally call the
369 interactive pdb debugger after the traceback printout. %pdb toggles
369 interactive pdb debugger after the traceback printout. %pdb toggles
370 this feature on and off.
370 this feature on and off.
371
371
372 The initial state of this feature is set in your configuration
372 The initial state of this feature is set in your configuration
373 file (the option is ``InteractiveShell.pdb``).
373 file (the option is ``InteractiveShell.pdb``).
374
374
375 If you want to just activate the debugger AFTER an exception has fired,
375 If you want to just activate the debugger AFTER an exception has fired,
376 without having to type '%pdb on' and rerunning your code, you can use
376 without having to type '%pdb on' and rerunning your code, you can use
377 the %debug magic."""
377 the %debug magic."""
378
378
379 par = parameter_s.strip().lower()
379 par = parameter_s.strip().lower()
380
380
381 if par:
381 if par:
382 try:
382 try:
383 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
383 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
384 except KeyError:
384 except KeyError:
385 print ('Incorrect argument. Use on/1, off/0, '
385 print ('Incorrect argument. Use on/1, off/0, '
386 'or nothing for a toggle.')
386 'or nothing for a toggle.')
387 return
387 return
388 else:
388 else:
389 # toggle
389 # toggle
390 new_pdb = not self.shell.call_pdb
390 new_pdb = not self.shell.call_pdb
391
391
392 # set on the shell
392 # set on the shell
393 self.shell.call_pdb = new_pdb
393 self.shell.call_pdb = new_pdb
394 print('Automatic pdb calling has been turned',on_off(new_pdb))
394 print('Automatic pdb calling has been turned',on_off(new_pdb))
395
395
396 @skip_doctest
396 @skip_doctest
397 @magic_arguments.magic_arguments()
397 @magic_arguments.magic_arguments()
398 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
398 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
399 help="""
399 help="""
400 Set break point at LINE in FILE.
400 Set break point at LINE in FILE.
401 """
401 """
402 )
402 )
403 @magic_arguments.argument('statement', nargs='*',
403 @magic_arguments.argument('statement', nargs='*',
404 help="""
404 help="""
405 Code to run in debugger.
405 Code to run in debugger.
406 You can omit this in cell magic mode.
406 You can omit this in cell magic mode.
407 """
407 """
408 )
408 )
409 @line_cell_magic
409 @line_cell_magic
410 def debug(self, line='', cell=None):
410 def debug(self, line='', cell=None):
411 """Activate the interactive debugger.
411 """Activate the interactive debugger.
412
412
413 This magic command support two ways of activating debugger.
413 This magic command support two ways of activating debugger.
414 One is to activate debugger before executing code. This way, you
414 One is to activate debugger before executing code. This way, you
415 can set a break point, to step through the code from the point.
415 can set a break point, to step through the code from the point.
416 You can use this mode by giving statements to execute and optionally
416 You can use this mode by giving statements to execute and optionally
417 a breakpoint.
417 a breakpoint.
418
418
419 The other one is to activate debugger in post-mortem mode. You can
419 The other one is to activate debugger in post-mortem mode. You can
420 activate this mode simply running %debug without any argument.
420 activate this mode simply running %debug without any argument.
421 If an exception has just occurred, this lets you inspect its stack
421 If an exception has just occurred, this lets you inspect its stack
422 frames interactively. Note that this will always work only on the last
422 frames interactively. Note that this will always work only on the last
423 traceback that occurred, so you must call this quickly after an
423 traceback that occurred, so you must call this quickly after an
424 exception that you wish to inspect has fired, because if another one
424 exception that you wish to inspect has fired, because if another one
425 occurs, it clobbers the previous one.
425 occurs, it clobbers the previous one.
426
426
427 If you want IPython to automatically do this on every exception, see
427 If you want IPython to automatically do this on every exception, see
428 the %pdb magic for more details.
428 the %pdb magic for more details.
429 """
429 """
430 args = magic_arguments.parse_argstring(self.debug, line)
430 args = magic_arguments.parse_argstring(self.debug, line)
431
431
432 if not (args.breakpoint or args.statement or cell):
432 if not (args.breakpoint or args.statement or cell):
433 self._debug_post_mortem()
433 self._debug_post_mortem()
434 else:
434 else:
435 code = "\n".join(args.statement)
435 code = "\n".join(args.statement)
436 if cell:
436 if cell:
437 code += "\n" + cell
437 code += "\n" + cell
438 self._debug_exec(code, args.breakpoint)
438 self._debug_exec(code, args.breakpoint)
439
439
440 def _debug_post_mortem(self):
440 def _debug_post_mortem(self):
441 self.shell.debugger(force=True)
441 self.shell.debugger(force=True)
442
442
443 def _debug_exec(self, code, breakpoint):
443 def _debug_exec(self, code, breakpoint):
444 if breakpoint:
444 if breakpoint:
445 (filename, bp_line) = breakpoint.rsplit(':', 1)
445 (filename, bp_line) = breakpoint.rsplit(':', 1)
446 bp_line = int(bp_line)
446 bp_line = int(bp_line)
447 else:
447 else:
448 (filename, bp_line) = (None, None)
448 (filename, bp_line) = (None, None)
449 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
449 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
450
450
451 @line_magic
451 @line_magic
452 def tb(self, s):
452 def tb(self, s):
453 """Print the last traceback with the currently active exception mode.
453 """Print the last traceback with the currently active exception mode.
454
454
455 See %xmode for changing exception reporting modes."""
455 See %xmode for changing exception reporting modes."""
456 self.shell.showtraceback()
456 self.shell.showtraceback()
457
457
458 @skip_doctest
458 @skip_doctest
459 @line_magic
459 @line_magic
460 def run(self, parameter_s='', runner=None,
460 def run(self, parameter_s='', runner=None,
461 file_finder=get_py_filename):
461 file_finder=get_py_filename):
462 """Run the named file inside IPython as a program.
462 """Run the named file inside IPython as a program.
463
463
464 Usage::
464 Usage::
465
465
466 %run [-n -i -e -G]
466 %run [-n -i -e -G]
467 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
467 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
468 ( -m mod | file ) [args]
468 ( -m mod | file ) [args]
469
469
470 Parameters after the filename are passed as command-line arguments to
470 Parameters after the filename are passed as command-line arguments to
471 the program (put in sys.argv). Then, control returns to IPython's
471 the program (put in sys.argv). Then, control returns to IPython's
472 prompt.
472 prompt.
473
473
474 This is similar to running at a system prompt ``python file args``,
474 This is similar to running at a system prompt ``python file args``,
475 but with the advantage of giving you IPython's tracebacks, and of
475 but with the advantage of giving you IPython's tracebacks, and of
476 loading all variables into your interactive namespace for further use
476 loading all variables into your interactive namespace for further use
477 (unless -p is used, see below).
477 (unless -p is used, see below).
478
478
479 The file is executed in a namespace initially consisting only of
479 The file is executed in a namespace initially consisting only of
480 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
480 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
481 sees its environment as if it were being run as a stand-alone program
481 sees its environment as if it were being run as a stand-alone program
482 (except for sharing global objects such as previously imported
482 (except for sharing global objects such as previously imported
483 modules). But after execution, the IPython interactive namespace gets
483 modules). But after execution, the IPython interactive namespace gets
484 updated with all variables defined in the program (except for __name__
484 updated with all variables defined in the program (except for __name__
485 and sys.argv). This allows for very convenient loading of code for
485 and sys.argv). This allows for very convenient loading of code for
486 interactive work, while giving each program a 'clean sheet' to run in.
486 interactive work, while giving each program a 'clean sheet' to run in.
487
487
488 Arguments are expanded using shell-like glob match. Patterns
488 Arguments are expanded using shell-like glob match. Patterns
489 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
489 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
490 tilde '~' will be expanded into user's home directory. Unlike
490 tilde '~' will be expanded into user's home directory. Unlike
491 real shells, quotation does not suppress expansions. Use
491 real shells, quotation does not suppress expansions. Use
492 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
492 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
493 To completely disable these expansions, you can use -G flag.
493 To completely disable these expansions, you can use -G flag.
494
494
495 Options:
495 Options:
496
496
497 -n
497 -n
498 __name__ is NOT set to '__main__', but to the running file's name
498 __name__ is NOT set to '__main__', but to the running file's name
499 without extension (as python does under import). This allows running
499 without extension (as python does under import). This allows running
500 scripts and reloading the definitions in them without calling code
500 scripts and reloading the definitions in them without calling code
501 protected by an ``if __name__ == "__main__"`` clause.
501 protected by an ``if __name__ == "__main__"`` clause.
502
502
503 -i
503 -i
504 run the file in IPython's namespace instead of an empty one. This
504 run the file in IPython's namespace instead of an empty one. This
505 is useful if you are experimenting with code written in a text editor
505 is useful if you are experimenting with code written in a text editor
506 which depends on variables defined interactively.
506 which depends on variables defined interactively.
507
507
508 -e
508 -e
509 ignore sys.exit() calls or SystemExit exceptions in the script
509 ignore sys.exit() calls or SystemExit exceptions in the script
510 being run. This is particularly useful if IPython is being used to
510 being run. This is particularly useful if IPython is being used to
511 run unittests, which always exit with a sys.exit() call. In such
511 run unittests, which always exit with a sys.exit() call. In such
512 cases you are interested in the output of the test results, not in
512 cases you are interested in the output of the test results, not in
513 seeing a traceback of the unittest module.
513 seeing a traceback of the unittest module.
514
514
515 -t
515 -t
516 print timing information at the end of the run. IPython will give
516 print timing information at the end of the run. IPython will give
517 you an estimated CPU time consumption for your script, which under
517 you an estimated CPU time consumption for your script, which under
518 Unix uses the resource module to avoid the wraparound problems of
518 Unix uses the resource module to avoid the wraparound problems of
519 time.clock(). Under Unix, an estimate of time spent on system tasks
519 time.clock(). Under Unix, an estimate of time spent on system tasks
520 is also given (for Windows platforms this is reported as 0.0).
520 is also given (for Windows platforms this is reported as 0.0).
521
521
522 If -t is given, an additional ``-N<N>`` option can be given, where <N>
522 If -t is given, an additional ``-N<N>`` option can be given, where <N>
523 must be an integer indicating how many times you want the script to
523 must be an integer indicating how many times you want the script to
524 run. The final timing report will include total and per run results.
524 run. The final timing report will include total and per run results.
525
525
526 For example (testing the script uniq_stable.py)::
526 For example (testing the script uniq_stable.py)::
527
527
528 In [1]: run -t uniq_stable
528 In [1]: run -t uniq_stable
529
529
530 IPython CPU timings (estimated):
530 IPython CPU timings (estimated):
531 User : 0.19597 s.
531 User : 0.19597 s.
532 System: 0.0 s.
532 System: 0.0 s.
533
533
534 In [2]: run -t -N5 uniq_stable
534 In [2]: run -t -N5 uniq_stable
535
535
536 IPython CPU timings (estimated):
536 IPython CPU timings (estimated):
537 Total runs performed: 5
537 Total runs performed: 5
538 Times : Total Per run
538 Times : Total Per run
539 User : 0.910862 s, 0.1821724 s.
539 User : 0.910862 s, 0.1821724 s.
540 System: 0.0 s, 0.0 s.
540 System: 0.0 s, 0.0 s.
541
541
542 -d
542 -d
543 run your program under the control of pdb, the Python debugger.
543 run your program under the control of pdb, the Python debugger.
544 This allows you to execute your program step by step, watch variables,
544 This allows you to execute your program step by step, watch variables,
545 etc. Internally, what IPython does is similar to calling::
545 etc. Internally, what IPython does is similar to calling::
546
546
547 pdb.run('execfile("YOURFILENAME")')
547 pdb.run('execfile("YOURFILENAME")')
548
548
549 with a breakpoint set on line 1 of your file. You can change the line
549 with a breakpoint set on line 1 of your file. You can change the line
550 number for this automatic breakpoint to be <N> by using the -bN option
550 number for this automatic breakpoint to be <N> by using the -bN option
551 (where N must be an integer). For example::
551 (where N must be an integer). For example::
552
552
553 %run -d -b40 myscript
553 %run -d -b40 myscript
554
554
555 will set the first breakpoint at line 40 in myscript.py. Note that
555 will set the first breakpoint at line 40 in myscript.py. Note that
556 the first breakpoint must be set on a line which actually does
556 the first breakpoint must be set on a line which actually does
557 something (not a comment or docstring) for it to stop execution.
557 something (not a comment or docstring) for it to stop execution.
558
558
559 Or you can specify a breakpoint in a different file::
559 Or you can specify a breakpoint in a different file::
560
560
561 %run -d -b myotherfile.py:20 myscript
561 %run -d -b myotherfile.py:20 myscript
562
562
563 When the pdb debugger starts, you will see a (Pdb) prompt. You must
563 When the pdb debugger starts, you will see a (Pdb) prompt. You must
564 first enter 'c' (without quotes) to start execution up to the first
564 first enter 'c' (without quotes) to start execution up to the first
565 breakpoint.
565 breakpoint.
566
566
567 Entering 'help' gives information about the use of the debugger. You
567 Entering 'help' gives information about the use of the debugger. You
568 can easily see pdb's full documentation with "import pdb;pdb.help()"
568 can easily see pdb's full documentation with "import pdb;pdb.help()"
569 at a prompt.
569 at a prompt.
570
570
571 -p
571 -p
572 run program under the control of the Python profiler module (which
572 run program under the control of the Python profiler module (which
573 prints a detailed report of execution times, function calls, etc).
573 prints a detailed report of execution times, function calls, etc).
574
574
575 You can pass other options after -p which affect the behavior of the
575 You can pass other options after -p which affect the behavior of the
576 profiler itself. See the docs for %prun for details.
576 profiler itself. See the docs for %prun for details.
577
577
578 In this mode, the program's variables do NOT propagate back to the
578 In this mode, the program's variables do NOT propagate back to the
579 IPython interactive namespace (because they remain in the namespace
579 IPython interactive namespace (because they remain in the namespace
580 where the profiler executes them).
580 where the profiler executes them).
581
581
582 Internally this triggers a call to %prun, see its documentation for
582 Internally this triggers a call to %prun, see its documentation for
583 details on the options available specifically for profiling.
583 details on the options available specifically for profiling.
584
584
585 There is one special usage for which the text above doesn't apply:
585 There is one special usage for which the text above doesn't apply:
586 if the filename ends with .ipy[nb], the file is run as ipython script,
586 if the filename ends with .ipy[nb], the file is run as ipython script,
587 just as if the commands were written on IPython prompt.
587 just as if the commands were written on IPython prompt.
588
588
589 -m
589 -m
590 specify module name to load instead of script path. Similar to
590 specify module name to load instead of script path. Similar to
591 the -m option for the python interpreter. Use this option last if you
591 the -m option for the python interpreter. Use this option last if you
592 want to combine with other %run options. Unlike the python interpreter
592 want to combine with other %run options. Unlike the python interpreter
593 only source modules are allowed no .pyc or .pyo files.
593 only source modules are allowed no .pyc or .pyo files.
594 For example::
594 For example::
595
595
596 %run -m example
596 %run -m example
597
597
598 will run the example module.
598 will run the example module.
599
599
600 -G
600 -G
601 disable shell-like glob expansion of arguments.
601 disable shell-like glob expansion of arguments.
602
602
603 """
603 """
604
604
605 # get arguments and set sys.argv for program to be run.
605 # get arguments and set sys.argv for program to be run.
606 opts, arg_lst = self.parse_options(parameter_s,
606 opts, arg_lst = self.parse_options(parameter_s,
607 'nidtN:b:pD:l:rs:T:em:G',
607 'nidtN:b:pD:l:rs:T:em:G',
608 mode='list', list_all=1)
608 mode='list', list_all=1)
609 if "m" in opts:
609 if "m" in opts:
610 modulename = opts["m"][0]
610 modulename = opts["m"][0]
611 modpath = find_mod(modulename)
611 modpath = find_mod(modulename)
612 if modpath is None:
612 if modpath is None:
613 warn('%r is not a valid modulename on sys.path'%modulename)
613 warn('%r is not a valid modulename on sys.path'%modulename)
614 return
614 return
615 arg_lst = [modpath] + arg_lst
615 arg_lst = [modpath] + arg_lst
616 try:
616 try:
617 filename = file_finder(arg_lst[0])
617 filename = file_finder(arg_lst[0])
618 except IndexError:
618 except IndexError:
619 warn('you must provide at least a filename.')
619 warn('you must provide at least a filename.')
620 print('\n%run:\n', oinspect.getdoc(self.run))
620 print('\n%run:\n', oinspect.getdoc(self.run))
621 return
621 return
622 except IOError as e:
622 except IOError as e:
623 try:
623 try:
624 msg = str(e)
624 msg = str(e)
625 except UnicodeError:
625 except UnicodeError:
626 msg = e.message
626 msg = e.message
627 error(msg)
627 error(msg)
628 return
628 return
629
629
630 if filename.lower().endswith(('.ipy', '.ipynb')):
630 if filename.lower().endswith(('.ipy', '.ipynb')):
631 with preserve_keys(self.shell.user_ns, '__file__'):
631 with preserve_keys(self.shell.user_ns, '__file__'):
632 self.shell.user_ns['__file__'] = filename
632 self.shell.user_ns['__file__'] = filename
633 self.shell.safe_execfile_ipy(filename)
633 self.shell.safe_execfile_ipy(filename)
634 return
634 return
635
635
636 # Control the response to exit() calls made by the script being run
636 # Control the response to exit() calls made by the script being run
637 exit_ignore = 'e' in opts
637 exit_ignore = 'e' in opts
638
638
639 # Make sure that the running script gets a proper sys.argv as if it
639 # Make sure that the running script gets a proper sys.argv as if it
640 # were run from a system shell.
640 # were run from a system shell.
641 save_argv = sys.argv # save it for later restoring
641 save_argv = sys.argv # save it for later restoring
642
642
643 if 'G' in opts:
643 if 'G' in opts:
644 args = arg_lst[1:]
644 args = arg_lst[1:]
645 else:
645 else:
646 # tilde and glob expansion
646 # tilde and glob expansion
647 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
647 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
648
648
649 sys.argv = [filename] + args # put in the proper filename
649 sys.argv = [filename] + args # put in the proper filename
650 # protect sys.argv from potential unicode strings on Python 2:
650 # protect sys.argv from potential unicode strings on Python 2:
651 if not py3compat.PY3:
651 if not py3compat.PY3:
652 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
652 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
653
653
654 if 'i' in opts:
654 if 'i' in opts:
655 # Run in user's interactive namespace
655 # Run in user's interactive namespace
656 prog_ns = self.shell.user_ns
656 prog_ns = self.shell.user_ns
657 __name__save = self.shell.user_ns['__name__']
657 __name__save = self.shell.user_ns['__name__']
658 prog_ns['__name__'] = '__main__'
658 prog_ns['__name__'] = '__main__'
659 main_mod = self.shell.user_module
659 main_mod = self.shell.user_module
660
660
661 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
661 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
662 # set the __file__ global in the script's namespace
662 # set the __file__ global in the script's namespace
663 # TK: Is this necessary in interactive mode?
663 # TK: Is this necessary in interactive mode?
664 prog_ns['__file__'] = filename
664 prog_ns['__file__'] = filename
665 else:
665 else:
666 # Run in a fresh, empty namespace
666 # Run in a fresh, empty namespace
667 if 'n' in opts:
667 if 'n' in opts:
668 name = os.path.splitext(os.path.basename(filename))[0]
668 name = os.path.splitext(os.path.basename(filename))[0]
669 else:
669 else:
670 name = '__main__'
670 name = '__main__'
671
671
672 # The shell MUST hold a reference to prog_ns so after %run
672 # The shell MUST hold a reference to prog_ns so after %run
673 # exits, the python deletion mechanism doesn't zero it out
673 # exits, the python deletion mechanism doesn't zero it out
674 # (leaving dangling references). See interactiveshell for details
674 # (leaving dangling references). See interactiveshell for details
675 main_mod = self.shell.new_main_mod(filename, name)
675 main_mod = self.shell.new_main_mod(filename, name)
676 prog_ns = main_mod.__dict__
676 prog_ns = main_mod.__dict__
677
677
678 # pickle fix. See interactiveshell for an explanation. But we need to
678 # pickle fix. See interactiveshell for an explanation. But we need to
679 # make sure that, if we overwrite __main__, we replace it at the end
679 # make sure that, if we overwrite __main__, we replace it at the end
680 main_mod_name = prog_ns['__name__']
680 main_mod_name = prog_ns['__name__']
681
681
682 if main_mod_name == '__main__':
682 if main_mod_name == '__main__':
683 restore_main = sys.modules['__main__']
683 restore_main = sys.modules['__main__']
684 else:
684 else:
685 restore_main = False
685 restore_main = False
686
686
687 # This needs to be undone at the end to prevent holding references to
687 # This needs to be undone at the end to prevent holding references to
688 # every single object ever created.
688 # every single object ever created.
689 sys.modules[main_mod_name] = main_mod
689 sys.modules[main_mod_name] = main_mod
690
690
691 if 'p' in opts or 'd' in opts:
691 if 'p' in opts or 'd' in opts:
692 if 'm' in opts:
692 if 'm' in opts:
693 code = 'run_module(modulename, prog_ns)'
693 code = 'run_module(modulename, prog_ns)'
694 code_ns = {
694 code_ns = {
695 'run_module': self.shell.safe_run_module,
695 'run_module': self.shell.safe_run_module,
696 'prog_ns': prog_ns,
696 'prog_ns': prog_ns,
697 'modulename': modulename,
697 'modulename': modulename,
698 }
698 }
699 else:
699 else:
700 if 'd' in opts:
700 if 'd' in opts:
701 # allow exceptions to raise in debug mode
701 # allow exceptions to raise in debug mode
702 code = 'execfile(filename, prog_ns, raise_exceptions=True)'
702 code = 'execfile(filename, prog_ns, raise_exceptions=True)'
703 else:
703 else:
704 code = 'execfile(filename, prog_ns)'
704 code = 'execfile(filename, prog_ns)'
705 code_ns = {
705 code_ns = {
706 'execfile': self.shell.safe_execfile,
706 'execfile': self.shell.safe_execfile,
707 'prog_ns': prog_ns,
707 'prog_ns': prog_ns,
708 'filename': get_py_filename(filename),
708 'filename': get_py_filename(filename),
709 }
709 }
710
710
711 try:
711 try:
712 stats = None
712 stats = None
713 if 'p' in opts:
713 if 'p' in opts:
714 stats = self._run_with_profiler(code, opts, code_ns)
714 stats = self._run_with_profiler(code, opts, code_ns)
715 else:
715 else:
716 if 'd' in opts:
716 if 'd' in opts:
717 bp_file, bp_line = parse_breakpoint(
717 bp_file, bp_line = parse_breakpoint(
718 opts.get('b', ['1'])[0], filename)
718 opts.get('b', ['1'])[0], filename)
719 self._run_with_debugger(
719 self._run_with_debugger(
720 code, code_ns, filename, bp_line, bp_file)
720 code, code_ns, filename, bp_line, bp_file)
721 else:
721 else:
722 if 'm' in opts:
722 if 'm' in opts:
723 def run():
723 def run():
724 self.shell.safe_run_module(modulename, prog_ns)
724 self.shell.safe_run_module(modulename, prog_ns)
725 else:
725 else:
726 if runner is None:
726 if runner is None:
727 runner = self.default_runner
727 runner = self.default_runner
728 if runner is None:
728 if runner is None:
729 runner = self.shell.safe_execfile
729 runner = self.shell.safe_execfile
730
730
731 def run():
731 def run():
732 runner(filename, prog_ns, prog_ns,
732 runner(filename, prog_ns, prog_ns,
733 exit_ignore=exit_ignore)
733 exit_ignore=exit_ignore)
734
734
735 if 't' in opts:
735 if 't' in opts:
736 # timed execution
736 # timed execution
737 try:
737 try:
738 nruns = int(opts['N'][0])
738 nruns = int(opts['N'][0])
739 if nruns < 1:
739 if nruns < 1:
740 error('Number of runs must be >=1')
740 error('Number of runs must be >=1')
741 return
741 return
742 except (KeyError):
742 except (KeyError):
743 nruns = 1
743 nruns = 1
744 self._run_with_timing(run, nruns)
744 self._run_with_timing(run, nruns)
745 else:
745 else:
746 # regular execution
746 # regular execution
747 run()
747 run()
748
748
749 if 'i' in opts:
749 if 'i' in opts:
750 self.shell.user_ns['__name__'] = __name__save
750 self.shell.user_ns['__name__'] = __name__save
751 else:
751 else:
752 # update IPython interactive namespace
752 # update IPython interactive namespace
753
753
754 # Some forms of read errors on the file may mean the
754 # Some forms of read errors on the file may mean the
755 # __name__ key was never set; using pop we don't have to
755 # __name__ key was never set; using pop we don't have to
756 # worry about a possible KeyError.
756 # worry about a possible KeyError.
757 prog_ns.pop('__name__', None)
757 prog_ns.pop('__name__', None)
758
758
759 with preserve_keys(self.shell.user_ns, '__file__'):
759 with preserve_keys(self.shell.user_ns, '__file__'):
760 self.shell.user_ns.update(prog_ns)
760 self.shell.user_ns.update(prog_ns)
761 finally:
761 finally:
762 # It's a bit of a mystery why, but __builtins__ can change from
762 # It's a bit of a mystery why, but __builtins__ can change from
763 # being a module to becoming a dict missing some key data after
763 # being a module to becoming a dict missing some key data after
764 # %run. As best I can see, this is NOT something IPython is doing
764 # %run. As best I can see, this is NOT something IPython is doing
765 # at all, and similar problems have been reported before:
765 # at all, and similar problems have been reported before:
766 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
766 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
767 # Since this seems to be done by the interpreter itself, the best
767 # Since this seems to be done by the interpreter itself, the best
768 # we can do is to at least restore __builtins__ for the user on
768 # we can do is to at least restore __builtins__ for the user on
769 # exit.
769 # exit.
770 self.shell.user_ns['__builtins__'] = builtin_mod
770 self.shell.user_ns['__builtins__'] = builtin_mod
771
771
772 # Ensure key global structures are restored
772 # Ensure key global structures are restored
773 sys.argv = save_argv
773 sys.argv = save_argv
774 if restore_main:
774 if restore_main:
775 sys.modules['__main__'] = restore_main
775 sys.modules['__main__'] = restore_main
776 else:
776 else:
777 # Remove from sys.modules the reference to main_mod we'd
777 # Remove from sys.modules the reference to main_mod we'd
778 # added. Otherwise it will trap references to objects
778 # added. Otherwise it will trap references to objects
779 # contained therein.
779 # contained therein.
780 del sys.modules[main_mod_name]
780 del sys.modules[main_mod_name]
781
781
782 return stats
782 return stats
783
783
784 def _run_with_debugger(self, code, code_ns, filename=None,
784 def _run_with_debugger(self, code, code_ns, filename=None,
785 bp_line=None, bp_file=None):
785 bp_line=None, bp_file=None):
786 """
786 """
787 Run `code` in debugger with a break point.
787 Run `code` in debugger with a break point.
788
788
789 Parameters
789 Parameters
790 ----------
790 ----------
791 code : str
791 code : str
792 Code to execute.
792 Code to execute.
793 code_ns : dict
793 code_ns : dict
794 A namespace in which `code` is executed.
794 A namespace in which `code` is executed.
795 filename : str
795 filename : str
796 `code` is ran as if it is in `filename`.
796 `code` is ran as if it is in `filename`.
797 bp_line : int, optional
797 bp_line : int, optional
798 Line number of the break point.
798 Line number of the break point.
799 bp_file : str, optional
799 bp_file : str, optional
800 Path to the file in which break point is specified.
800 Path to the file in which break point is specified.
801 `filename` is used if not given.
801 `filename` is used if not given.
802
802
803 Raises
803 Raises
804 ------
804 ------
805 UsageError
805 UsageError
806 If the break point given by `bp_line` is not valid.
806 If the break point given by `bp_line` is not valid.
807
807
808 """
808 """
809 deb = self.shell.InteractiveTB.pdb
809 deb = self.shell.InteractiveTB.pdb
810 if not deb:
810 if not deb:
811 self.shell.InteractiveTB.pdb = self.shell.InteractiveTB.debugger_cls()
811 self.shell.InteractiveTB.pdb = self.shell.InteractiveTB.debugger_cls()
812 deb = self.shell.InteractiveTB.pdb
812 deb = self.shell.InteractiveTB.pdb
813
813
814 # reset Breakpoint state, which is moronically kept
814 # reset Breakpoint state, which is moronically kept
815 # in a class
815 # in a class
816 bdb.Breakpoint.next = 1
816 bdb.Breakpoint.next = 1
817 bdb.Breakpoint.bplist = {}
817 bdb.Breakpoint.bplist = {}
818 bdb.Breakpoint.bpbynumber = [None]
818 bdb.Breakpoint.bpbynumber = [None]
819 if bp_line is not None:
819 if bp_line is not None:
820 # Set an initial breakpoint to stop execution
820 # Set an initial breakpoint to stop execution
821 maxtries = 10
821 maxtries = 10
822 bp_file = bp_file or filename
822 bp_file = bp_file or filename
823 checkline = deb.checkline(bp_file, bp_line)
823 checkline = deb.checkline(bp_file, bp_line)
824 if not checkline:
824 if not checkline:
825 for bp in range(bp_line + 1, bp_line + maxtries + 1):
825 for bp in range(bp_line + 1, bp_line + maxtries + 1):
826 if deb.checkline(bp_file, bp):
826 if deb.checkline(bp_file, bp):
827 break
827 break
828 else:
828 else:
829 msg = ("\nI failed to find a valid line to set "
829 msg = ("\nI failed to find a valid line to set "
830 "a breakpoint\n"
830 "a breakpoint\n"
831 "after trying up to line: %s.\n"
831 "after trying up to line: %s.\n"
832 "Please set a valid breakpoint manually "
832 "Please set a valid breakpoint manually "
833 "with the -b option." % bp)
833 "with the -b option." % bp)
834 raise UsageError(msg)
834 raise UsageError(msg)
835 # if we find a good linenumber, set the breakpoint
835 # if we find a good linenumber, set the breakpoint
836 deb.do_break('%s:%s' % (bp_file, bp_line))
836 deb.do_break('%s:%s' % (bp_file, bp_line))
837
837
838 if filename:
838 if filename:
839 # Mimic Pdb._runscript(...)
839 # Mimic Pdb._runscript(...)
840 deb._wait_for_mainpyfile = True
840 deb._wait_for_mainpyfile = True
841 deb.mainpyfile = deb.canonic(filename)
841 deb.mainpyfile = deb.canonic(filename)
842
842
843 # Start file run
843 # Start file run
844 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
844 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
845 try:
845 try:
846 if filename:
846 if filename:
847 # save filename so it can be used by methods on the deb object
847 # save filename so it can be used by methods on the deb object
848 deb._exec_filename = filename
848 deb._exec_filename = filename
849 while True:
849 while True:
850 try:
850 try:
851 deb.run(code, code_ns)
851 deb.run(code, code_ns)
852 except Restart:
852 except Restart:
853 print("Restarting")
853 print("Restarting")
854 if filename:
854 if filename:
855 deb._wait_for_mainpyfile = True
855 deb._wait_for_mainpyfile = True
856 deb.mainpyfile = deb.canonic(filename)
856 deb.mainpyfile = deb.canonic(filename)
857 continue
857 continue
858 else:
858 else:
859 break
859 break
860
860
861
861
862 except:
862 except:
863 etype, value, tb = sys.exc_info()
863 etype, value, tb = sys.exc_info()
864 # Skip three frames in the traceback: the %run one,
864 # Skip three frames in the traceback: the %run one,
865 # one inside bdb.py, and the command-line typed by the
865 # one inside bdb.py, and the command-line typed by the
866 # user (run by exec in pdb itself).
866 # user (run by exec in pdb itself).
867 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
867 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
868
868
869 @staticmethod
869 @staticmethod
870 def _run_with_timing(run, nruns):
870 def _run_with_timing(run, nruns):
871 """
871 """
872 Run function `run` and print timing information.
872 Run function `run` and print timing information.
873
873
874 Parameters
874 Parameters
875 ----------
875 ----------
876 run : callable
876 run : callable
877 Any callable object which takes no argument.
877 Any callable object which takes no argument.
878 nruns : int
878 nruns : int
879 Number of times to execute `run`.
879 Number of times to execute `run`.
880
880
881 """
881 """
882 twall0 = time.time()
882 twall0 = time.time()
883 if nruns == 1:
883 if nruns == 1:
884 t0 = clock2()
884 t0 = clock2()
885 run()
885 run()
886 t1 = clock2()
886 t1 = clock2()
887 t_usr = t1[0] - t0[0]
887 t_usr = t1[0] - t0[0]
888 t_sys = t1[1] - t0[1]
888 t_sys = t1[1] - t0[1]
889 print("\nIPython CPU timings (estimated):")
889 print("\nIPython CPU timings (estimated):")
890 print(" User : %10.2f s." % t_usr)
890 print(" User : %10.2f s." % t_usr)
891 print(" System : %10.2f s." % t_sys)
891 print(" System : %10.2f s." % t_sys)
892 else:
892 else:
893 runs = range(nruns)
893 runs = range(nruns)
894 t0 = clock2()
894 t0 = clock2()
895 for nr in runs:
895 for nr in runs:
896 run()
896 run()
897 t1 = clock2()
897 t1 = clock2()
898 t_usr = t1[0] - t0[0]
898 t_usr = t1[0] - t0[0]
899 t_sys = t1[1] - t0[1]
899 t_sys = t1[1] - t0[1]
900 print("\nIPython CPU timings (estimated):")
900 print("\nIPython CPU timings (estimated):")
901 print("Total runs performed:", nruns)
901 print("Total runs performed:", nruns)
902 print(" Times : %10s %10s" % ('Total', 'Per run'))
902 print(" Times : %10s %10s" % ('Total', 'Per run'))
903 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
903 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
904 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
904 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
905 twall1 = time.time()
905 twall1 = time.time()
906 print("Wall time: %10.2f s." % (twall1 - twall0))
906 print("Wall time: %10.2f s." % (twall1 - twall0))
907
907
908 @skip_doctest
908 @skip_doctest
909 @line_cell_magic
909 @line_cell_magic
910 def timeit(self, line='', cell=None):
910 def timeit(self, line='', cell=None):
911 """Time execution of a Python statement or expression
911 """Time execution of a Python statement or expression
912
912
913 Usage, in line mode:
913 Usage, in line mode:
914 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
914 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
915 or in cell mode:
915 or in cell mode:
916 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
916 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
917 code
917 code
918 code...
918 code...
919
919
920 Time execution of a Python statement or expression using the timeit
920 Time execution of a Python statement or expression using the timeit
921 module. This function can be used both as a line and cell magic:
921 module. This function can be used both as a line and cell magic:
922
922
923 - In line mode you can time a single-line statement (though multiple
923 - In line mode you can time a single-line statement (though multiple
924 ones can be chained with using semicolons).
924 ones can be chained with using semicolons).
925
925
926 - In cell mode, the statement in the first line is used as setup code
926 - In cell mode, the statement in the first line is used as setup code
927 (executed but not timed) and the body of the cell is timed. The cell
927 (executed but not timed) and the body of the cell is timed. The cell
928 body has access to any variables created in the setup code.
928 body has access to any variables created in the setup code.
929
929
930 Options:
930 Options:
931 -n<N>: execute the given statement <N> times in a loop. If this value
931 -n<N>: execute the given statement <N> times in a loop. If this value
932 is not given, a fitting value is chosen.
932 is not given, a fitting value is chosen.
933
933
934 -r<R>: repeat the loop iteration <R> times and take the best result.
934 -r<R>: repeat the loop iteration <R> times and take the best result.
935 Default: 3
935 Default: 3
936
936
937 -t: use time.time to measure the time, which is the default on Unix.
937 -t: use time.time to measure the time, which is the default on Unix.
938 This function measures wall time.
938 This function measures wall time.
939
939
940 -c: use time.clock to measure the time, which is the default on
940 -c: use time.clock to measure the time, which is the default on
941 Windows and measures wall time. On Unix, resource.getrusage is used
941 Windows and measures wall time. On Unix, resource.getrusage is used
942 instead and returns the CPU user time.
942 instead and returns the CPU user time.
943
943
944 -p<P>: use a precision of <P> digits to display the timing result.
944 -p<P>: use a precision of <P> digits to display the timing result.
945 Default: 3
945 Default: 3
946
946
947 -q: Quiet, do not print result.
947 -q: Quiet, do not print result.
948
948
949 -o: return a TimeitResult that can be stored in a variable to inspect
949 -o: return a TimeitResult that can be stored in a variable to inspect
950 the result in more details.
950 the result in more details.
951
951
952
952
953 Examples
953 Examples
954 --------
954 --------
955 ::
955 ::
956
956
957 In [1]: %timeit pass
957 In [1]: %timeit pass
958 100000000 loops, average of 7: 5.48 ns +- 0.354 ns per loop (using standard deviation)
958 100000000 loops, average of 7: 5.48 ns +- 0.354 ns per loop (using standard deviation)
959
959
960 In [2]: u = None
960 In [2]: u = None
961
961
962 In [3]: %timeit u is None
962 In [3]: %timeit u is None
963 10000000 loops, average of 7: 22.7 ns +- 2.33 ns per loop (using standard deviation)
963 10000000 loops, average of 7: 22.7 ns +- 2.33 ns per loop (using standard deviation)
964
964
965 In [4]: %timeit -r 4 u == None
965 In [4]: %timeit -r 4 u == None
966 10000000 loops, average of 4: 27.5 ns +- 2.91 ns per loop (using standard deviation)
966 10000000 loops, average of 4: 27.5 ns +- 2.91 ns per loop (using standard deviation)
967
967
968 In [5]: import time
968 In [5]: import time
969
969
970 In [6]: %timeit -n1 time.sleep(2)
970 In [6]: %timeit -n1 time.sleep(2)
971 1 loop, average of 7: 2 s +- 4.71 Β΅s per loop (using standard deviation)
971 1 loop, average of 7: 2 s +- 4.71 Β΅s per loop (using standard deviation)
972
972
973
973
974 The times reported by %timeit will be slightly higher than those
974 The times reported by %timeit will be slightly higher than those
975 reported by the timeit.py script when variables are accessed. This is
975 reported by the timeit.py script when variables are accessed. This is
976 due to the fact that %timeit executes the statement in the namespace
976 due to the fact that %timeit executes the statement in the namespace
977 of the shell, compared with timeit.py, which uses a single setup
977 of the shell, compared with timeit.py, which uses a single setup
978 statement to import function or create variables. Generally, the bias
978 statement to import function or create variables. Generally, the bias
979 does not matter as long as results from timeit.py are not mixed with
979 does not matter as long as results from timeit.py are not mixed with
980 those from %timeit."""
980 those from %timeit."""
981
981
982 opts, stmt = self.parse_options(line,'n:r:tcp:qo',
982 opts, stmt = self.parse_options(line,'n:r:tcp:qo',
983 posix=False, strict=False)
983 posix=False, strict=False)
984 if stmt == "" and cell is None:
984 if stmt == "" and cell is None:
985 return
985 return
986
986
987 timefunc = timeit.default_timer
987 timefunc = timeit.default_timer
988 number = int(getattr(opts, "n", 0))
988 number = int(getattr(opts, "n", 0))
989 default_repeat = 7 if timeit.default_repeat < 7 else timeit.default_repeat
989 default_repeat = 7 if timeit.default_repeat < 7 else timeit.default_repeat
990 repeat = int(getattr(opts, "r", default_repeat))
990 repeat = int(getattr(opts, "r", default_repeat))
991 precision = int(getattr(opts, "p", 3))
991 precision = int(getattr(opts, "p", 3))
992 quiet = 'q' in opts
992 quiet = 'q' in opts
993 return_result = 'o' in opts
993 return_result = 'o' in opts
994 if hasattr(opts, "t"):
994 if hasattr(opts, "t"):
995 timefunc = time.time
995 timefunc = time.time
996 if hasattr(opts, "c"):
996 if hasattr(opts, "c"):
997 timefunc = clock
997 timefunc = clock
998
998
999 timer = Timer(timer=timefunc)
999 timer = Timer(timer=timefunc)
1000 # this code has tight coupling to the inner workings of timeit.Timer,
1000 # this code has tight coupling to the inner workings of timeit.Timer,
1001 # but is there a better way to achieve that the code stmt has access
1001 # but is there a better way to achieve that the code stmt has access
1002 # to the shell namespace?
1002 # to the shell namespace?
1003 transform = self.shell.input_splitter.transform_cell
1003 transform = self.shell.input_splitter.transform_cell
1004
1004
1005 if cell is None:
1005 if cell is None:
1006 # called as line magic
1006 # called as line magic
1007 ast_setup = self.shell.compile.ast_parse("pass")
1007 ast_setup = self.shell.compile.ast_parse("pass")
1008 ast_stmt = self.shell.compile.ast_parse(transform(stmt))
1008 ast_stmt = self.shell.compile.ast_parse(transform(stmt))
1009 else:
1009 else:
1010 ast_setup = self.shell.compile.ast_parse(transform(stmt))
1010 ast_setup = self.shell.compile.ast_parse(transform(stmt))
1011 ast_stmt = self.shell.compile.ast_parse(transform(cell))
1011 ast_stmt = self.shell.compile.ast_parse(transform(cell))
1012
1012
1013 ast_setup = self.shell.transform_ast(ast_setup)
1013 ast_setup = self.shell.transform_ast(ast_setup)
1014 ast_stmt = self.shell.transform_ast(ast_stmt)
1014 ast_stmt = self.shell.transform_ast(ast_stmt)
1015
1015
1016 # This codestring is taken from timeit.template - we fill it in as an
1016 # This codestring is taken from timeit.template - we fill it in as an
1017 # AST, so that we can apply our AST transformations to the user code
1017 # AST, so that we can apply our AST transformations to the user code
1018 # without affecting the timing code.
1018 # without affecting the timing code.
1019 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
1019 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
1020 ' setup\n'
1020 ' setup\n'
1021 ' _t0 = _timer()\n'
1021 ' _t0 = _timer()\n'
1022 ' for _i in _it:\n'
1022 ' for _i in _it:\n'
1023 ' stmt\n'
1023 ' stmt\n'
1024 ' _t1 = _timer()\n'
1024 ' _t1 = _timer()\n'
1025 ' return _t1 - _t0\n')
1025 ' return _t1 - _t0\n')
1026
1026
1027 timeit_ast = TimeitTemplateFiller(ast_setup, ast_stmt).visit(timeit_ast_template)
1027 timeit_ast = TimeitTemplateFiller(ast_setup, ast_stmt).visit(timeit_ast_template)
1028 timeit_ast = ast.fix_missing_locations(timeit_ast)
1028 timeit_ast = ast.fix_missing_locations(timeit_ast)
1029
1029
1030 # Track compilation time so it can be reported if too long
1030 # Track compilation time so it can be reported if too long
1031 # Minimum time above which compilation time will be reported
1031 # Minimum time above which compilation time will be reported
1032 tc_min = 0.1
1032 tc_min = 0.1
1033
1033
1034 t0 = clock()
1034 t0 = clock()
1035 code = self.shell.compile(timeit_ast, "<magic-timeit>", "exec")
1035 code = self.shell.compile(timeit_ast, "<magic-timeit>", "exec")
1036 tc = clock()-t0
1036 tc = clock()-t0
1037
1037
1038 ns = {}
1038 ns = {}
1039 exec(code, self.shell.user_ns, ns)
1039 exec(code, self.shell.user_ns, ns)
1040 timer.inner = ns["inner"]
1040 timer.inner = ns["inner"]
1041
1041
1042 # This is used to check if there is a huge difference between the
1042 # This is used to check if there is a huge difference between the
1043 # best and worst timings.
1043 # best and worst timings.
1044 # Issue: https://github.com/ipython/ipython/issues/6471
1044 # Issue: https://github.com/ipython/ipython/issues/6471
1045 if number == 0:
1045 if number == 0:
1046 # determine number so that 0.2 <= total time < 2.0
1046 # determine number so that 0.2 <= total time < 2.0
1047 for index in range(0, 10):
1047 for index in range(0, 10):
1048 number = 10 ** index
1048 number = 10 ** index
1049 time_number = timer.timeit(number)
1049 time_number = timer.timeit(number)
1050 if time_number >= 0.2:
1050 if time_number >= 0.2:
1051 break
1051 break
1052
1052
1053 all_runs = timer.repeat(repeat, number)
1053 all_runs = timer.repeat(repeat, number)
1054 timings = [ dt / number for dt in all_runs]
1054 timings = [ dt / number for dt in all_runs]
1055
1055
1056 def _avg(numbers):
1056 def _avg(numbers):
1057 return math.fsum(numbers) / len(numbers)
1057 return math.fsum(numbers) / len(numbers)
1058
1058
1059 def _stdev(numbers):
1059 def _stdev(numbers):
1060 mean = _avg(numbers)
1060 mean = _avg(numbers)
1061 return (math.fsum([(x - mean) ** 2 for x in numbers]) / len(numbers)) ** 0.5
1061 return (math.fsum([(x - mean) ** 2 for x in numbers]) / len(numbers)) ** 0.5
1062
1062
1063 average = _avg(timings)
1063 average = _avg(timings)
1064 stdev = _stdev(timings)
1064 stdev = _stdev(timings)
1065
1065
1066 if not quiet :
1066 if not quiet :
1067 # Check best timing is greater than zero to avoid a
1067 # Check best timing is greater than zero to avoid a
1068 # ZeroDivisionError.
1068 # ZeroDivisionError.
1069 # In cases where the slowest timing is lesser than a micosecond
1069 # In cases where the slowest timing is lesser than a micosecond
1070 # we assume that it does not really matter if the fastest
1070 # we assume that it does not really matter if the fastest
1071 # timing is 4 times faster than the slowest timing or not.
1071 # timing is 4 times faster than the slowest timing or not.
1072 if number == 1: # No s at "loops" if only one loop
1072 if number == 1: # No s at "loops" if only one loop
1073 print(u"%s loop, average of %d: %s +- %s per loop (using standard deviation)"
1073 print(u"%s loop, average of %d: %s +- %s per loop (using standard deviation)"
1074 % (number, repeat,
1074 % (number, repeat,
1075 _format_time(average, precision),
1075 _format_time(average, precision),
1076 _format_time(stdev, precision)))
1076 _format_time(stdev, precision)))
1077 else:
1077 else:
1078 print(u"%s loops, average of %d: %s +- %s per loop (using standard deviation)"
1078 print(u"%s loops, average of %d: %s +- %s per loop (using standard deviation)"
1079 % (number, repeat,
1079 % (number, repeat,
1080 _format_time(average, precision),
1080 _format_time(average, precision),
1081 _format_time(stdev, precision)))
1081 _format_time(stdev, precision)))
1082 if tc > tc_min:
1082 if tc > tc_min:
1083 print("Compiler time: %.2f s" % tc)
1083 print("Compiler time: %.2f s" % tc)
1084 if return_result:
1084 if return_result:
1085 return TimeitResult(number, repeat, average, stdev, all_runs, tc, precision)
1085 return TimeitResult(number, repeat, average, stdev, all_runs, tc, precision)
1086
1086
1087 @skip_doctest
1087 @skip_doctest
1088 @needs_local_scope
1088 @needs_local_scope
1089 @line_cell_magic
1089 @line_cell_magic
1090 def time(self,line='', cell=None, local_ns=None):
1090 def time(self,line='', cell=None, local_ns=None):
1091 """Time execution of a Python statement or expression.
1091 """Time execution of a Python statement or expression.
1092
1092
1093 The CPU and wall clock times are printed, and the value of the
1093 The CPU and wall clock times are printed, and the value of the
1094 expression (if any) is returned. Note that under Win32, system time
1094 expression (if any) is returned. Note that under Win32, system time
1095 is always reported as 0, since it can not be measured.
1095 is always reported as 0, since it can not be measured.
1096
1096
1097 This function can be used both as a line and cell magic:
1097 This function can be used both as a line and cell magic:
1098
1098
1099 - In line mode you can time a single-line statement (though multiple
1099 - In line mode you can time a single-line statement (though multiple
1100 ones can be chained with using semicolons).
1100 ones can be chained with using semicolons).
1101
1101
1102 - In cell mode, you can time the cell body (a directly
1102 - In cell mode, you can time the cell body (a directly
1103 following statement raises an error).
1103 following statement raises an error).
1104
1104
1105 This function provides very basic timing functionality. Use the timeit
1105 This function provides very basic timing functionality. Use the timeit
1106 magic for more control over the measurement.
1106 magic for more control over the measurement.
1107
1107
1108 Examples
1108 Examples
1109 --------
1109 --------
1110 ::
1110 ::
1111
1111
1112 In [1]: %time 2**128
1112 In [1]: %time 2**128
1113 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1113 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1114 Wall time: 0.00
1114 Wall time: 0.00
1115 Out[1]: 340282366920938463463374607431768211456L
1115 Out[1]: 340282366920938463463374607431768211456L
1116
1116
1117 In [2]: n = 1000000
1117 In [2]: n = 1000000
1118
1118
1119 In [3]: %time sum(range(n))
1119 In [3]: %time sum(range(n))
1120 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1120 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1121 Wall time: 1.37
1121 Wall time: 1.37
1122 Out[3]: 499999500000L
1122 Out[3]: 499999500000L
1123
1123
1124 In [4]: %time print 'hello world'
1124 In [4]: %time print 'hello world'
1125 hello world
1125 hello world
1126 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1126 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1127 Wall time: 0.00
1127 Wall time: 0.00
1128
1128
1129 Note that the time needed by Python to compile the given expression
1129 Note that the time needed by Python to compile the given expression
1130 will be reported if it is more than 0.1s. In this example, the
1130 will be reported if it is more than 0.1s. In this example, the
1131 actual exponentiation is done by Python at compilation time, so while
1131 actual exponentiation is done by Python at compilation time, so while
1132 the expression can take a noticeable amount of time to compute, that
1132 the expression can take a noticeable amount of time to compute, that
1133 time is purely due to the compilation:
1133 time is purely due to the compilation:
1134
1134
1135 In [5]: %time 3**9999;
1135 In [5]: %time 3**9999;
1136 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1136 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1137 Wall time: 0.00 s
1137 Wall time: 0.00 s
1138
1138
1139 In [6]: %time 3**999999;
1139 In [6]: %time 3**999999;
1140 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1140 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1141 Wall time: 0.00 s
1141 Wall time: 0.00 s
1142 Compiler : 0.78 s
1142 Compiler : 0.78 s
1143 """
1143 """
1144
1144
1145 # fail immediately if the given expression can't be compiled
1145 # fail immediately if the given expression can't be compiled
1146
1146
1147 if line and cell:
1147 if line and cell:
1148 raise UsageError("Can't use statement directly after '%%time'!")
1148 raise UsageError("Can't use statement directly after '%%time'!")
1149
1149
1150 if cell:
1150 if cell:
1151 expr = self.shell.input_transformer_manager.transform_cell(cell)
1151 expr = self.shell.input_transformer_manager.transform_cell(cell)
1152 else:
1152 else:
1153 expr = self.shell.input_transformer_manager.transform_cell(line)
1153 expr = self.shell.input_transformer_manager.transform_cell(line)
1154
1154
1155 # Minimum time above which parse time will be reported
1155 # Minimum time above which parse time will be reported
1156 tp_min = 0.1
1156 tp_min = 0.1
1157
1157
1158 t0 = clock()
1158 t0 = clock()
1159 expr_ast = self.shell.compile.ast_parse(expr)
1159 expr_ast = self.shell.compile.ast_parse(expr)
1160 tp = clock()-t0
1160 tp = clock()-t0
1161
1161
1162 # Apply AST transformations
1162 # Apply AST transformations
1163 expr_ast = self.shell.transform_ast(expr_ast)
1163 expr_ast = self.shell.transform_ast(expr_ast)
1164
1164
1165 # Minimum time above which compilation time will be reported
1165 # Minimum time above which compilation time will be reported
1166 tc_min = 0.1
1166 tc_min = 0.1
1167
1167
1168 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1168 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1169 mode = 'eval'
1169 mode = 'eval'
1170 source = '<timed eval>'
1170 source = '<timed eval>'
1171 expr_ast = ast.Expression(expr_ast.body[0].value)
1171 expr_ast = ast.Expression(expr_ast.body[0].value)
1172 else:
1172 else:
1173 mode = 'exec'
1173 mode = 'exec'
1174 source = '<timed exec>'
1174 source = '<timed exec>'
1175 t0 = clock()
1175 t0 = clock()
1176 code = self.shell.compile(expr_ast, source, mode)
1176 code = self.shell.compile(expr_ast, source, mode)
1177 tc = clock()-t0
1177 tc = clock()-t0
1178
1178
1179 # skew measurement as little as possible
1179 # skew measurement as little as possible
1180 glob = self.shell.user_ns
1180 glob = self.shell.user_ns
1181 wtime = time.time
1181 wtime = time.time
1182 # time execution
1182 # time execution
1183 wall_st = wtime()
1183 wall_st = wtime()
1184 if mode=='eval':
1184 if mode=='eval':
1185 st = clock2()
1185 st = clock2()
1186 out = eval(code, glob, local_ns)
1186 out = eval(code, glob, local_ns)
1187 end = clock2()
1187 end = clock2()
1188 else:
1188 else:
1189 st = clock2()
1189 st = clock2()
1190 exec(code, glob, local_ns)
1190 exec(code, glob, local_ns)
1191 end = clock2()
1191 end = clock2()
1192 out = None
1192 out = None
1193 wall_end = wtime()
1193 wall_end = wtime()
1194 # Compute actual times and report
1194 # Compute actual times and report
1195 wall_time = wall_end-wall_st
1195 wall_time = wall_end-wall_st
1196 cpu_user = end[0]-st[0]
1196 cpu_user = end[0]-st[0]
1197 cpu_sys = end[1]-st[1]
1197 cpu_sys = end[1]-st[1]
1198 cpu_tot = cpu_user+cpu_sys
1198 cpu_tot = cpu_user+cpu_sys
1199 # On windows cpu_sys is always zero, so no new information to the next print
1199 # On windows cpu_sys is always zero, so no new information to the next print
1200 if sys.platform != 'win32':
1200 if sys.platform != 'win32':
1201 print("CPU times: user %s, sys: %s, total: %s" % \
1201 print("CPU times: user %s, sys: %s, total: %s" % \
1202 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1202 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1203 print("Wall time: %s" % _format_time(wall_time))
1203 print("Wall time: %s" % _format_time(wall_time))
1204 if tc > tc_min:
1204 if tc > tc_min:
1205 print("Compiler : %s" % _format_time(tc))
1205 print("Compiler : %s" % _format_time(tc))
1206 if tp > tp_min:
1206 if tp > tp_min:
1207 print("Parser : %s" % _format_time(tp))
1207 print("Parser : %s" % _format_time(tp))
1208 return out
1208 return out
1209
1209
1210 @skip_doctest
1210 @skip_doctest
1211 @line_magic
1211 @line_magic
1212 def macro(self, parameter_s=''):
1212 def macro(self, parameter_s=''):
1213 """Define a macro for future re-execution. It accepts ranges of history,
1213 """Define a macro for future re-execution. It accepts ranges of history,
1214 filenames or string objects.
1214 filenames or string objects.
1215
1215
1216 Usage:\\
1216 Usage:\\
1217 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1217 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1218
1218
1219 Options:
1219 Options:
1220
1220
1221 -r: use 'raw' input. By default, the 'processed' history is used,
1221 -r: use 'raw' input. By default, the 'processed' history is used,
1222 so that magics are loaded in their transformed version to valid
1222 so that magics are loaded in their transformed version to valid
1223 Python. If this option is given, the raw input as typed at the
1223 Python. If this option is given, the raw input as typed at the
1224 command line is used instead.
1224 command line is used instead.
1225
1225
1226 -q: quiet macro definition. By default, a tag line is printed
1226 -q: quiet macro definition. By default, a tag line is printed
1227 to indicate the macro has been created, and then the contents of
1227 to indicate the macro has been created, and then the contents of
1228 the macro are printed. If this option is given, then no printout
1228 the macro are printed. If this option is given, then no printout
1229 is produced once the macro is created.
1229 is produced once the macro is created.
1230
1230
1231 This will define a global variable called `name` which is a string
1231 This will define a global variable called `name` which is a string
1232 made of joining the slices and lines you specify (n1,n2,... numbers
1232 made of joining the slices and lines you specify (n1,n2,... numbers
1233 above) from your input history into a single string. This variable
1233 above) from your input history into a single string. This variable
1234 acts like an automatic function which re-executes those lines as if
1234 acts like an automatic function which re-executes those lines as if
1235 you had typed them. You just type 'name' at the prompt and the code
1235 you had typed them. You just type 'name' at the prompt and the code
1236 executes.
1236 executes.
1237
1237
1238 The syntax for indicating input ranges is described in %history.
1238 The syntax for indicating input ranges is described in %history.
1239
1239
1240 Note: as a 'hidden' feature, you can also use traditional python slice
1240 Note: as a 'hidden' feature, you can also use traditional python slice
1241 notation, where N:M means numbers N through M-1.
1241 notation, where N:M means numbers N through M-1.
1242
1242
1243 For example, if your history contains (print using %hist -n )::
1243 For example, if your history contains (print using %hist -n )::
1244
1244
1245 44: x=1
1245 44: x=1
1246 45: y=3
1246 45: y=3
1247 46: z=x+y
1247 46: z=x+y
1248 47: print x
1248 47: print x
1249 48: a=5
1249 48: a=5
1250 49: print 'x',x,'y',y
1250 49: print 'x',x,'y',y
1251
1251
1252 you can create a macro with lines 44 through 47 (included) and line 49
1252 you can create a macro with lines 44 through 47 (included) and line 49
1253 called my_macro with::
1253 called my_macro with::
1254
1254
1255 In [55]: %macro my_macro 44-47 49
1255 In [55]: %macro my_macro 44-47 49
1256
1256
1257 Now, typing `my_macro` (without quotes) will re-execute all this code
1257 Now, typing `my_macro` (without quotes) will re-execute all this code
1258 in one pass.
1258 in one pass.
1259
1259
1260 You don't need to give the line-numbers in order, and any given line
1260 You don't need to give the line-numbers in order, and any given line
1261 number can appear multiple times. You can assemble macros with any
1261 number can appear multiple times. You can assemble macros with any
1262 lines from your input history in any order.
1262 lines from your input history in any order.
1263
1263
1264 The macro is a simple object which holds its value in an attribute,
1264 The macro is a simple object which holds its value in an attribute,
1265 but IPython's display system checks for macros and executes them as
1265 but IPython's display system checks for macros and executes them as
1266 code instead of printing them when you type their name.
1266 code instead of printing them when you type their name.
1267
1267
1268 You can view a macro's contents by explicitly printing it with::
1268 You can view a macro's contents by explicitly printing it with::
1269
1269
1270 print macro_name
1270 print macro_name
1271
1271
1272 """
1272 """
1273 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1273 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1274 if not args: # List existing macros
1274 if not args: # List existing macros
1275 return sorted(k for k,v in iteritems(self.shell.user_ns) if\
1275 return sorted(k for k,v in iteritems(self.shell.user_ns) if\
1276 isinstance(v, Macro))
1276 isinstance(v, Macro))
1277 if len(args) == 1:
1277 if len(args) == 1:
1278 raise UsageError(
1278 raise UsageError(
1279 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1279 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1280 name, codefrom = args[0], " ".join(args[1:])
1280 name, codefrom = args[0], " ".join(args[1:])
1281
1281
1282 #print 'rng',ranges # dbg
1282 #print 'rng',ranges # dbg
1283 try:
1283 try:
1284 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1284 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1285 except (ValueError, TypeError) as e:
1285 except (ValueError, TypeError) as e:
1286 print(e.args[0])
1286 print(e.args[0])
1287 return
1287 return
1288 macro = Macro(lines)
1288 macro = Macro(lines)
1289 self.shell.define_macro(name, macro)
1289 self.shell.define_macro(name, macro)
1290 if not ( 'q' in opts) :
1290 if not ( 'q' in opts) :
1291 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1291 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1292 print('=== Macro contents: ===')
1292 print('=== Macro contents: ===')
1293 print(macro, end=' ')
1293 print(macro, end=' ')
1294
1294
1295 @magic_arguments.magic_arguments()
1295 @magic_arguments.magic_arguments()
1296 @magic_arguments.argument('output', type=str, default='', nargs='?',
1296 @magic_arguments.argument('output', type=str, default='', nargs='?',
1297 help="""The name of the variable in which to store output.
1297 help="""The name of the variable in which to store output.
1298 This is a utils.io.CapturedIO object with stdout/err attributes
1298 This is a utils.io.CapturedIO object with stdout/err attributes
1299 for the text of the captured output.
1299 for the text of the captured output.
1300
1300
1301 CapturedOutput also has a show() method for displaying the output,
1301 CapturedOutput also has a show() method for displaying the output,
1302 and __call__ as well, so you can use that to quickly display the
1302 and __call__ as well, so you can use that to quickly display the
1303 output.
1303 output.
1304
1304
1305 If unspecified, captured output is discarded.
1305 If unspecified, captured output is discarded.
1306 """
1306 """
1307 )
1307 )
1308 @magic_arguments.argument('--no-stderr', action="store_true",
1308 @magic_arguments.argument('--no-stderr', action="store_true",
1309 help="""Don't capture stderr."""
1309 help="""Don't capture stderr."""
1310 )
1310 )
1311 @magic_arguments.argument('--no-stdout', action="store_true",
1311 @magic_arguments.argument('--no-stdout', action="store_true",
1312 help="""Don't capture stdout."""
1312 help="""Don't capture stdout."""
1313 )
1313 )
1314 @magic_arguments.argument('--no-display', action="store_true",
1314 @magic_arguments.argument('--no-display', action="store_true",
1315 help="""Don't capture IPython's rich display."""
1315 help="""Don't capture IPython's rich display."""
1316 )
1316 )
1317 @cell_magic
1317 @cell_magic
1318 def capture(self, line, cell):
1318 def capture(self, line, cell):
1319 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1319 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1320 args = magic_arguments.parse_argstring(self.capture, line)
1320 args = magic_arguments.parse_argstring(self.capture, line)
1321 out = not args.no_stdout
1321 out = not args.no_stdout
1322 err = not args.no_stderr
1322 err = not args.no_stderr
1323 disp = not args.no_display
1323 disp = not args.no_display
1324 with capture_output(out, err, disp) as io:
1324 with capture_output(out, err, disp) as io:
1325 self.shell.run_cell(cell)
1325 self.shell.run_cell(cell)
1326 if args.output:
1326 if args.output:
1327 self.shell.user_ns[args.output] = io
1327 self.shell.user_ns[args.output] = io
1328
1328
1329 def parse_breakpoint(text, current_file):
1329 def parse_breakpoint(text, current_file):
1330 '''Returns (file, line) for file:line and (current_file, line) for line'''
1330 '''Returns (file, line) for file:line and (current_file, line) for line'''
1331 colon = text.find(':')
1331 colon = text.find(':')
1332 if colon == -1:
1332 if colon == -1:
1333 return current_file, int(text)
1333 return current_file, int(text)
1334 else:
1334 else:
1335 return text[:colon], int(text[colon+1:])
1335 return text[:colon], int(text[colon+1:])
1336
1336
1337 def _format_time(timespan, precision=3):
1337 def _format_time(timespan, precision=3):
1338 """Formats the timespan in a human readable form"""
1338 """Formats the timespan in a human readable form"""
1339
1339
1340 if timespan >= 60.0:
1340 if timespan >= 60.0:
1341 # we have more than a minute, format that in a human readable form
1341 # we have more than a minute, format that in a human readable form
1342 # Idea from http://snipplr.com/view/5713/
1342 # Idea from http://snipplr.com/view/5713/
1343 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1343 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1344 time = []
1344 time = []
1345 leftover = timespan
1345 leftover = timespan
1346 for suffix, length in parts:
1346 for suffix, length in parts:
1347 value = int(leftover / length)
1347 value = int(leftover / length)
1348 if value > 0:
1348 if value > 0:
1349 leftover = leftover % length
1349 leftover = leftover % length
1350 time.append(u'%s%s' % (str(value), suffix))
1350 time.append(u'%s%s' % (str(value), suffix))
1351 if leftover < 1:
1351 if leftover < 1:
1352 break
1352 break
1353 return " ".join(time)
1353 return " ".join(time)
1354
1354
1355
1355
1356 # Unfortunately the unicode 'micro' symbol can cause problems in
1356 # Unfortunately the unicode 'micro' symbol can cause problems in
1357 # certain terminals.
1357 # certain terminals.
1358 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1358 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1359 # Try to prevent crashes by being more secure than it needs to
1359 # Try to prevent crashes by being more secure than it needs to
1360 # E.g. eclipse is able to print a Β΅, but has no sys.stdout.encoding set.
1360 # E.g. eclipse is able to print a Β΅, but has no sys.stdout.encoding set.
1361 units = [u"s", u"ms",u'us',"ns"] # the save value
1361 units = [u"s", u"ms",u'us',"ns"] # the save value
1362 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1362 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1363 try:
1363 try:
1364 u'\xb5'.encode(sys.stdout.encoding)
1364 u'\xb5'.encode(sys.stdout.encoding)
1365 units = [u"s", u"ms",u'\xb5s',"ns"]
1365 units = [u"s", u"ms",u'\xb5s',"ns"]
1366 except:
1366 except:
1367 pass
1367 pass
1368 scaling = [1, 1e3, 1e6, 1e9]
1368 scaling = [1, 1e3, 1e6, 1e9]
1369
1369
1370 if timespan > 0.0:
1370 if timespan > 0.0:
1371 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1371 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1372 else:
1372 else:
1373 order = 3
1373 order = 3
1374 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
1374 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
@@ -1,950 +1,950 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for the key interactiveshell module.
2 """Tests for the key interactiveshell module.
3
3
4 Historically the main classes in interactiveshell have been under-tested. This
4 Historically the main classes in interactiveshell have been under-tested. This
5 module should grow as many single-method tests as possible to trap many of the
5 module should grow as many single-method tests as possible to trap many of the
6 recurring bugs we seem to encounter with high-level interaction.
6 recurring bugs we seem to encounter with high-level interaction.
7 """
7 """
8
8
9 # Copyright (c) IPython Development Team.
9 # Copyright (c) IPython Development Team.
10 # Distributed under the terms of the Modified BSD License.
10 # Distributed under the terms of the Modified BSD License.
11
11
12 import ast
12 import ast
13 import os
13 import os
14 import signal
14 import signal
15 import shutil
15 import shutil
16 import sys
16 import sys
17 import tempfile
17 import tempfile
18 import unittest
18 import unittest
19 try:
19 try:
20 from unittest import mock
20 from unittest import mock
21 except ImportError:
21 except ImportError:
22 import mock
22 import mock
23 from os.path import join
23 from os.path import join
24
24
25 import nose.tools as nt
25 import nose.tools as nt
26
26
27 from IPython.core.error import InputRejected
27 from IPython.core.error import InputRejected
28 from IPython.core.inputtransformer import InputTransformer
28 from IPython.core.inputtransformer import InputTransformer
29 from IPython.testing.decorators import (
29 from IPython.testing.decorators import (
30 skipif, skip_win32, onlyif_unicode_paths, onlyif_cmds_exist,
30 skipif, skip_win32, onlyif_unicode_paths, onlyif_cmds_exist,
31 )
31 )
32 from IPython.testing import tools as tt
32 from IPython.testing import tools as tt
33 from IPython.utils.process import find_cmd
33 from IPython.utils.process import find_cmd
34 from IPython.utils import py3compat
34 from IPython.utils import py3compat
35 from IPython.utils.py3compat import unicode_type, PY3
35 from IPython.utils.py3compat import unicode_type, PY3
36
36
37 if PY3:
37 if PY3:
38 from io import StringIO
38 from io import StringIO
39 else:
39 else:
40 from StringIO import StringIO
40 from StringIO import StringIO
41
41
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43 # Globals
43 # Globals
44 #-----------------------------------------------------------------------------
44 #-----------------------------------------------------------------------------
45 # This is used by every single test, no point repeating it ad nauseam
45 # This is used by every single test, no point repeating it ad nauseam
46 ip = get_ipython()
46 ip = get_ipython()
47
47
48 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
49 # Tests
49 # Tests
50 #-----------------------------------------------------------------------------
50 #-----------------------------------------------------------------------------
51
51
52 class DerivedInterrupt(KeyboardInterrupt):
52 class DerivedInterrupt(KeyboardInterrupt):
53 pass
53 pass
54
54
55 class InteractiveShellTestCase(unittest.TestCase):
55 class InteractiveShellTestCase(unittest.TestCase):
56 def test_naked_string_cells(self):
56 def test_naked_string_cells(self):
57 """Test that cells with only naked strings are fully executed"""
57 """Test that cells with only naked strings are fully executed"""
58 # First, single-line inputs
58 # First, single-line inputs
59 ip.run_cell('"a"\n')
59 ip.run_cell('"a"\n')
60 self.assertEqual(ip.user_ns['_'], 'a')
60 self.assertEqual(ip.user_ns['_'], 'a')
61 # And also multi-line cells
61 # And also multi-line cells
62 ip.run_cell('"""a\nb"""\n')
62 ip.run_cell('"""a\nb"""\n')
63 self.assertEqual(ip.user_ns['_'], 'a\nb')
63 self.assertEqual(ip.user_ns['_'], 'a\nb')
64
64
65 def test_run_empty_cell(self):
65 def test_run_empty_cell(self):
66 """Just make sure we don't get a horrible error with a blank
66 """Just make sure we don't get a horrible error with a blank
67 cell of input. Yes, I did overlook that."""
67 cell of input. Yes, I did overlook that."""
68 old_xc = ip.execution_count
68 old_xc = ip.execution_count
69 res = ip.run_cell('')
69 res = ip.run_cell('')
70 self.assertEqual(ip.execution_count, old_xc)
70 self.assertEqual(ip.execution_count, old_xc)
71 self.assertEqual(res.execution_count, None)
71 self.assertEqual(res.execution_count, None)
72
72
73 def test_run_cell_multiline(self):
73 def test_run_cell_multiline(self):
74 """Multi-block, multi-line cells must execute correctly.
74 """Multi-block, multi-line cells must execute correctly.
75 """
75 """
76 src = '\n'.join(["x=1",
76 src = '\n'.join(["x=1",
77 "y=2",
77 "y=2",
78 "if 1:",
78 "if 1:",
79 " x += 1",
79 " x += 1",
80 " y += 1",])
80 " y += 1",])
81 res = ip.run_cell(src)
81 res = ip.run_cell(src)
82 self.assertEqual(ip.user_ns['x'], 2)
82 self.assertEqual(ip.user_ns['x'], 2)
83 self.assertEqual(ip.user_ns['y'], 3)
83 self.assertEqual(ip.user_ns['y'], 3)
84 self.assertEqual(res.success, True)
84 self.assertEqual(res.success, True)
85 self.assertEqual(res.result, None)
85 self.assertEqual(res.result, None)
86
86
87 def test_multiline_string_cells(self):
87 def test_multiline_string_cells(self):
88 "Code sprinkled with multiline strings should execute (GH-306)"
88 "Code sprinkled with multiline strings should execute (GH-306)"
89 ip.run_cell('tmp=0')
89 ip.run_cell('tmp=0')
90 self.assertEqual(ip.user_ns['tmp'], 0)
90 self.assertEqual(ip.user_ns['tmp'], 0)
91 res = ip.run_cell('tmp=1;"""a\nb"""\n')
91 res = ip.run_cell('tmp=1;"""a\nb"""\n')
92 self.assertEqual(ip.user_ns['tmp'], 1)
92 self.assertEqual(ip.user_ns['tmp'], 1)
93 self.assertEqual(res.success, True)
93 self.assertEqual(res.success, True)
94 self.assertEqual(res.result, "a\nb")
94 self.assertEqual(res.result, "a\nb")
95
95
96 def test_dont_cache_with_semicolon(self):
96 def test_dont_cache_with_semicolon(self):
97 "Ending a line with semicolon should not cache the returned object (GH-307)"
97 "Ending a line with semicolon should not cache the returned object (GH-307)"
98 oldlen = len(ip.user_ns['Out'])
98 oldlen = len(ip.user_ns['Out'])
99 for cell in ['1;', '1;1;']:
99 for cell in ['1;', '1;1;']:
100 res = ip.run_cell(cell, store_history=True)
100 res = ip.run_cell(cell, store_history=True)
101 newlen = len(ip.user_ns['Out'])
101 newlen = len(ip.user_ns['Out'])
102 self.assertEqual(oldlen, newlen)
102 self.assertEqual(oldlen, newlen)
103 self.assertIsNone(res.result)
103 self.assertIsNone(res.result)
104 i = 0
104 i = 0
105 #also test the default caching behavior
105 #also test the default caching behavior
106 for cell in ['1', '1;1']:
106 for cell in ['1', '1;1']:
107 ip.run_cell(cell, store_history=True)
107 ip.run_cell(cell, store_history=True)
108 newlen = len(ip.user_ns['Out'])
108 newlen = len(ip.user_ns['Out'])
109 i += 1
109 i += 1
110 self.assertEqual(oldlen+i, newlen)
110 self.assertEqual(oldlen+i, newlen)
111
111
112 def test_syntax_error(self):
112 def test_syntax_error(self):
113 res = ip.run_cell("raise = 3")
113 res = ip.run_cell("raise = 3")
114 self.assertIsInstance(res.error_before_exec, SyntaxError)
114 self.assertIsInstance(res.error_before_exec, SyntaxError)
115
115
116 def test_In_variable(self):
116 def test_In_variable(self):
117 "Verify that In variable grows with user input (GH-284)"
117 "Verify that In variable grows with user input (GH-284)"
118 oldlen = len(ip.user_ns['In'])
118 oldlen = len(ip.user_ns['In'])
119 ip.run_cell('1;', store_history=True)
119 ip.run_cell('1;', store_history=True)
120 newlen = len(ip.user_ns['In'])
120 newlen = len(ip.user_ns['In'])
121 self.assertEqual(oldlen+1, newlen)
121 self.assertEqual(oldlen+1, newlen)
122 self.assertEqual(ip.user_ns['In'][-1],'1;')
122 self.assertEqual(ip.user_ns['In'][-1],'1;')
123
123
124 def test_magic_names_in_string(self):
124 def test_magic_names_in_string(self):
125 ip.run_cell('a = """\n%exit\n"""')
125 ip.run_cell('a = """\n%exit\n"""')
126 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
126 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
127
127
128 def test_trailing_newline(self):
128 def test_trailing_newline(self):
129 """test that running !(command) does not raise a SyntaxError"""
129 """test that running !(command) does not raise a SyntaxError"""
130 ip.run_cell('!(true)\n', False)
130 ip.run_cell('!(true)\n', False)
131 ip.run_cell('!(true)\n\n\n', False)
131 ip.run_cell('!(true)\n\n\n', False)
132
132
133 def test_gh_597(self):
133 def test_gh_597(self):
134 """Pretty-printing lists of objects with non-ascii reprs may cause
134 """Pretty-printing lists of objects with non-ascii reprs may cause
135 problems."""
135 problems."""
136 class Spam(object):
136 class Spam(object):
137 def __repr__(self):
137 def __repr__(self):
138 return "\xe9"*50
138 return "\xe9"*50
139 import IPython.core.formatters
139 import IPython.core.formatters
140 f = IPython.core.formatters.PlainTextFormatter()
140 f = IPython.core.formatters.PlainTextFormatter()
141 f([Spam(),Spam()])
141 f([Spam(),Spam()])
142
142
143
143
144 def test_future_flags(self):
144 def test_future_flags(self):
145 """Check that future flags are used for parsing code (gh-777)"""
145 """Check that future flags are used for parsing code (gh-777)"""
146 ip.run_cell('from __future__ import print_function')
146 ip.run_cell('from __future__ import print_function')
147 try:
147 try:
148 ip.run_cell('prfunc_return_val = print(1,2, sep=" ")')
148 ip.run_cell('prfunc_return_val = print(1,2, sep=" ")')
149 assert 'prfunc_return_val' in ip.user_ns
149 assert 'prfunc_return_val' in ip.user_ns
150 finally:
150 finally:
151 # Reset compiler flags so we don't mess up other tests.
151 # Reset compiler flags so we don't mess up other tests.
152 ip.compile.reset_compiler_flags()
152 ip.compile.reset_compiler_flags()
153
153
154 def test_future_unicode(self):
154 def test_future_unicode(self):
155 """Check that unicode_literals is imported from __future__ (gh #786)"""
155 """Check that unicode_literals is imported from __future__ (gh #786)"""
156 try:
156 try:
157 ip.run_cell(u'byte_str = "a"')
157 ip.run_cell(u'byte_str = "a"')
158 assert isinstance(ip.user_ns['byte_str'], str) # string literals are byte strings by default
158 assert isinstance(ip.user_ns['byte_str'], str) # string literals are byte strings by default
159 ip.run_cell('from __future__ import unicode_literals')
159 ip.run_cell('from __future__ import unicode_literals')
160 ip.run_cell(u'unicode_str = "a"')
160 ip.run_cell(u'unicode_str = "a"')
161 assert isinstance(ip.user_ns['unicode_str'], unicode_type) # strings literals are now unicode
161 assert isinstance(ip.user_ns['unicode_str'], unicode_type) # strings literals are now unicode
162 finally:
162 finally:
163 # Reset compiler flags so we don't mess up other tests.
163 # Reset compiler flags so we don't mess up other tests.
164 ip.compile.reset_compiler_flags()
164 ip.compile.reset_compiler_flags()
165
165
166 def test_can_pickle(self):
166 def test_can_pickle(self):
167 "Can we pickle objects defined interactively (GH-29)"
167 "Can we pickle objects defined interactively (GH-29)"
168 ip = get_ipython()
168 ip = get_ipython()
169 ip.reset()
169 ip.reset()
170 ip.run_cell(("class Mylist(list):\n"
170 ip.run_cell(("class Mylist(list):\n"
171 " def __init__(self,x=[]):\n"
171 " def __init__(self,x=[]):\n"
172 " list.__init__(self,x)"))
172 " list.__init__(self,x)"))
173 ip.run_cell("w=Mylist([1,2,3])")
173 ip.run_cell("w=Mylist([1,2,3])")
174
174
175 from pickle import dumps
175 from pickle import dumps
176
176
177 # We need to swap in our main module - this is only necessary
177 # We need to swap in our main module - this is only necessary
178 # inside the test framework, because IPython puts the interactive module
178 # inside the test framework, because IPython puts the interactive module
179 # in place (but the test framework undoes this).
179 # in place (but the test framework undoes this).
180 _main = sys.modules['__main__']
180 _main = sys.modules['__main__']
181 sys.modules['__main__'] = ip.user_module
181 sys.modules['__main__'] = ip.user_module
182 try:
182 try:
183 res = dumps(ip.user_ns["w"])
183 res = dumps(ip.user_ns["w"])
184 finally:
184 finally:
185 sys.modules['__main__'] = _main
185 sys.modules['__main__'] = _main
186 self.assertTrue(isinstance(res, bytes))
186 self.assertTrue(isinstance(res, bytes))
187
187
188 def test_global_ns(self):
188 def test_global_ns(self):
189 "Code in functions must be able to access variables outside them."
189 "Code in functions must be able to access variables outside them."
190 ip = get_ipython()
190 ip = get_ipython()
191 ip.run_cell("a = 10")
191 ip.run_cell("a = 10")
192 ip.run_cell(("def f(x):\n"
192 ip.run_cell(("def f(x):\n"
193 " return x + a"))
193 " return x + a"))
194 ip.run_cell("b = f(12)")
194 ip.run_cell("b = f(12)")
195 self.assertEqual(ip.user_ns["b"], 22)
195 self.assertEqual(ip.user_ns["b"], 22)
196
196
197 def test_bad_custom_tb(self):
197 def test_bad_custom_tb(self):
198 """Check that InteractiveShell is protected from bad custom exception handlers"""
198 """Check that InteractiveShell is protected from bad custom exception handlers"""
199 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
199 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
200 self.assertEqual(ip.custom_exceptions, (IOError,))
200 self.assertEqual(ip.custom_exceptions, (IOError,))
201 with tt.AssertPrints("Custom TB Handler failed", channel='stderr'):
201 with tt.AssertPrints("Custom TB Handler failed", channel='stderr'):
202 ip.run_cell(u'raise IOError("foo")')
202 ip.run_cell(u'raise IOError("foo")')
203 self.assertEqual(ip.custom_exceptions, ())
203 self.assertEqual(ip.custom_exceptions, ())
204
204
205 def test_bad_custom_tb_return(self):
205 def test_bad_custom_tb_return(self):
206 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
206 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
207 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
207 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
208 self.assertEqual(ip.custom_exceptions, (NameError,))
208 self.assertEqual(ip.custom_exceptions, (NameError,))
209 with tt.AssertPrints("Custom TB Handler failed", channel='stderr'):
209 with tt.AssertPrints("Custom TB Handler failed", channel='stderr'):
210 ip.run_cell(u'a=abracadabra')
210 ip.run_cell(u'a=abracadabra')
211 self.assertEqual(ip.custom_exceptions, ())
211 self.assertEqual(ip.custom_exceptions, ())
212
212
213 def test_drop_by_id(self):
213 def test_drop_by_id(self):
214 myvars = {"a":object(), "b":object(), "c": object()}
214 myvars = {"a":object(), "b":object(), "c": object()}
215 ip.push(myvars, interactive=False)
215 ip.push(myvars, interactive=False)
216 for name in myvars:
216 for name in myvars:
217 assert name in ip.user_ns, name
217 assert name in ip.user_ns, name
218 assert name in ip.user_ns_hidden, name
218 assert name in ip.user_ns_hidden, name
219 ip.user_ns['b'] = 12
219 ip.user_ns['b'] = 12
220 ip.drop_by_id(myvars)
220 ip.drop_by_id(myvars)
221 for name in ["a", "c"]:
221 for name in ["a", "c"]:
222 assert name not in ip.user_ns, name
222 assert name not in ip.user_ns, name
223 assert name not in ip.user_ns_hidden, name
223 assert name not in ip.user_ns_hidden, name
224 assert ip.user_ns['b'] == 12
224 assert ip.user_ns['b'] == 12
225 ip.reset()
225 ip.reset()
226
226
227 def test_var_expand(self):
227 def test_var_expand(self):
228 ip.user_ns['f'] = u'Ca\xf1o'
228 ip.user_ns['f'] = u'Ca\xf1o'
229 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
229 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
230 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
230 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
231 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
231 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
232 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
232 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
233
233
234 ip.user_ns['f'] = b'Ca\xc3\xb1o'
234 ip.user_ns['f'] = b'Ca\xc3\xb1o'
235 # This should not raise any exception:
235 # This should not raise any exception:
236 ip.var_expand(u'echo $f')
236 ip.var_expand(u'echo $f')
237
237
238 def test_var_expand_local(self):
238 def test_var_expand_local(self):
239 """Test local variable expansion in !system and %magic calls"""
239 """Test local variable expansion in !system and %magic calls"""
240 # !system
240 # !system
241 ip.run_cell('def test():\n'
241 ip.run_cell('def test():\n'
242 ' lvar = "ttt"\n'
242 ' lvar = "ttt"\n'
243 ' ret = !echo {lvar}\n'
243 ' ret = !echo {lvar}\n'
244 ' return ret[0]\n')
244 ' return ret[0]\n')
245 res = ip.user_ns['test']()
245 res = ip.user_ns['test']()
246 nt.assert_in('ttt', res)
246 nt.assert_in('ttt', res)
247
247
248 # %magic
248 # %magic
249 ip.run_cell('def makemacro():\n'
249 ip.run_cell('def makemacro():\n'
250 ' macroname = "macro_var_expand_locals"\n'
250 ' macroname = "macro_var_expand_locals"\n'
251 ' %macro {macroname} codestr\n')
251 ' %macro {macroname} codestr\n')
252 ip.user_ns['codestr'] = "str(12)"
252 ip.user_ns['codestr'] = "str(12)"
253 ip.run_cell('makemacro()')
253 ip.run_cell('makemacro()')
254 nt.assert_in('macro_var_expand_locals', ip.user_ns)
254 nt.assert_in('macro_var_expand_locals', ip.user_ns)
255
255
256 def test_var_expand_self(self):
256 def test_var_expand_self(self):
257 """Test variable expansion with the name 'self', which was failing.
257 """Test variable expansion with the name 'self', which was failing.
258
258
259 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
259 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
260 """
260 """
261 ip.run_cell('class cTest:\n'
261 ip.run_cell('class cTest:\n'
262 ' classvar="see me"\n'
262 ' classvar="see me"\n'
263 ' def test(self):\n'
263 ' def test(self):\n'
264 ' res = !echo Variable: {self.classvar}\n'
264 ' res = !echo Variable: {self.classvar}\n'
265 ' return res[0]\n')
265 ' return res[0]\n')
266 nt.assert_in('see me', ip.user_ns['cTest']().test())
266 nt.assert_in('see me', ip.user_ns['cTest']().test())
267
267
268 def test_bad_var_expand(self):
268 def test_bad_var_expand(self):
269 """var_expand on invalid formats shouldn't raise"""
269 """var_expand on invalid formats shouldn't raise"""
270 # SyntaxError
270 # SyntaxError
271 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
271 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
272 # NameError
272 # NameError
273 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
273 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
274 # ZeroDivisionError
274 # ZeroDivisionError
275 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
275 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
276
276
277 def test_silent_postexec(self):
277 def test_silent_postexec(self):
278 """run_cell(silent=True) doesn't invoke pre/post_run_cell callbacks"""
278 """run_cell(silent=True) doesn't invoke pre/post_run_cell callbacks"""
279 pre_explicit = mock.Mock()
279 pre_explicit = mock.Mock()
280 pre_always = mock.Mock()
280 pre_always = mock.Mock()
281 post_explicit = mock.Mock()
281 post_explicit = mock.Mock()
282 post_always = mock.Mock()
282 post_always = mock.Mock()
283
283
284 ip.events.register('pre_run_cell', pre_explicit)
284 ip.events.register('pre_run_cell', pre_explicit)
285 ip.events.register('pre_execute', pre_always)
285 ip.events.register('pre_execute', pre_always)
286 ip.events.register('post_run_cell', post_explicit)
286 ip.events.register('post_run_cell', post_explicit)
287 ip.events.register('post_execute', post_always)
287 ip.events.register('post_execute', post_always)
288
288
289 try:
289 try:
290 ip.run_cell("1", silent=True)
290 ip.run_cell("1", silent=True)
291 assert pre_always.called
291 assert pre_always.called
292 assert not pre_explicit.called
292 assert not pre_explicit.called
293 assert post_always.called
293 assert post_always.called
294 assert not post_explicit.called
294 assert not post_explicit.called
295 # double-check that non-silent exec did what we expected
295 # double-check that non-silent exec did what we expected
296 # silent to avoid
296 # silent to avoid
297 ip.run_cell("1")
297 ip.run_cell("1")
298 assert pre_explicit.called
298 assert pre_explicit.called
299 assert post_explicit.called
299 assert post_explicit.called
300 finally:
300 finally:
301 # remove post-exec
301 # remove post-exec
302 ip.events.unregister('pre_run_cell', pre_explicit)
302 ip.events.unregister('pre_run_cell', pre_explicit)
303 ip.events.unregister('pre_execute', pre_always)
303 ip.events.unregister('pre_execute', pre_always)
304 ip.events.unregister('post_run_cell', post_explicit)
304 ip.events.unregister('post_run_cell', post_explicit)
305 ip.events.unregister('post_execute', post_always)
305 ip.events.unregister('post_execute', post_always)
306
306
307 def test_silent_noadvance(self):
307 def test_silent_noadvance(self):
308 """run_cell(silent=True) doesn't advance execution_count"""
308 """run_cell(silent=True) doesn't advance execution_count"""
309 ec = ip.execution_count
309 ec = ip.execution_count
310 # silent should force store_history=False
310 # silent should force store_history=False
311 ip.run_cell("1", store_history=True, silent=True)
311 ip.run_cell("1", store_history=True, silent=True)
312
312
313 self.assertEqual(ec, ip.execution_count)
313 self.assertEqual(ec, ip.execution_count)
314 # double-check that non-silent exec did what we expected
314 # double-check that non-silent exec did what we expected
315 # silent to avoid
315 # silent to avoid
316 ip.run_cell("1", store_history=True)
316 ip.run_cell("1", store_history=True)
317 self.assertEqual(ec+1, ip.execution_count)
317 self.assertEqual(ec+1, ip.execution_count)
318
318
319 def test_silent_nodisplayhook(self):
319 def test_silent_nodisplayhook(self):
320 """run_cell(silent=True) doesn't trigger displayhook"""
320 """run_cell(silent=True) doesn't trigger displayhook"""
321 d = dict(called=False)
321 d = dict(called=False)
322
322
323 trap = ip.display_trap
323 trap = ip.display_trap
324 save_hook = trap.hook
324 save_hook = trap.hook
325
325
326 def failing_hook(*args, **kwargs):
326 def failing_hook(*args, **kwargs):
327 d['called'] = True
327 d['called'] = True
328
328
329 try:
329 try:
330 trap.hook = failing_hook
330 trap.hook = failing_hook
331 res = ip.run_cell("1", silent=True)
331 res = ip.run_cell("1", silent=True)
332 self.assertFalse(d['called'])
332 self.assertFalse(d['called'])
333 self.assertIsNone(res.result)
333 self.assertIsNone(res.result)
334 # double-check that non-silent exec did what we expected
334 # double-check that non-silent exec did what we expected
335 # silent to avoid
335 # silent to avoid
336 ip.run_cell("1")
336 ip.run_cell("1")
337 self.assertTrue(d['called'])
337 self.assertTrue(d['called'])
338 finally:
338 finally:
339 trap.hook = save_hook
339 trap.hook = save_hook
340
340
341 @skipif(sys.version_info[0] >= 3, "softspace removed in py3")
341 @skipif(sys.version_info[0] >= 3, "softspace removed in py3")
342 def test_print_softspace(self):
342 def test_print_softspace(self):
343 """Verify that softspace is handled correctly when executing multiple
343 """Verify that softspace is handled correctly when executing multiple
344 statements.
344 statements.
345
345
346 In [1]: print 1; print 2
346 In [1]: print 1; print 2
347 1
347 1
348 2
348 2
349
349
350 In [2]: print 1,; print 2
350 In [2]: print 1,; print 2
351 1 2
351 1 2
352 """
352 """
353
353
354 def test_ofind_line_magic(self):
354 def test_ofind_line_magic(self):
355 from IPython.core.magic import register_line_magic
355 from IPython.core.magic import register_line_magic
356
356
357 @register_line_magic
357 @register_line_magic
358 def lmagic(line):
358 def lmagic(line):
359 "A line magic"
359 "A line magic"
360
360
361 # Get info on line magic
361 # Get info on line magic
362 lfind = ip._ofind('lmagic')
362 lfind = ip._ofind('lmagic')
363 info = dict(found=True, isalias=False, ismagic=True,
363 info = dict(found=True, isalias=False, ismagic=True,
364 namespace = 'IPython internal', obj= lmagic.__wrapped__,
364 namespace = 'IPython internal', obj= lmagic.__wrapped__,
365 parent = None)
365 parent = None)
366 nt.assert_equal(lfind, info)
366 nt.assert_equal(lfind, info)
367
367
368 def test_ofind_cell_magic(self):
368 def test_ofind_cell_magic(self):
369 from IPython.core.magic import register_cell_magic
369 from IPython.core.magic import register_cell_magic
370
370
371 @register_cell_magic
371 @register_cell_magic
372 def cmagic(line, cell):
372 def cmagic(line, cell):
373 "A cell magic"
373 "A cell magic"
374
374
375 # Get info on cell magic
375 # Get info on cell magic
376 find = ip._ofind('cmagic')
376 find = ip._ofind('cmagic')
377 info = dict(found=True, isalias=False, ismagic=True,
377 info = dict(found=True, isalias=False, ismagic=True,
378 namespace = 'IPython internal', obj= cmagic.__wrapped__,
378 namespace = 'IPython internal', obj= cmagic.__wrapped__,
379 parent = None)
379 parent = None)
380 nt.assert_equal(find, info)
380 nt.assert_equal(find, info)
381
381
382 def test_ofind_property_with_error(self):
382 def test_ofind_property_with_error(self):
383 class A(object):
383 class A(object):
384 @property
384 @property
385 def foo(self):
385 def foo(self):
386 raise NotImplementedError()
386 raise NotImplementedError()
387 a = A()
387 a = A()
388
388
389 found = ip._ofind('a.foo', [('locals', locals())])
389 found = ip._ofind('a.foo', [('locals', locals())])
390 info = dict(found=True, isalias=False, ismagic=False,
390 info = dict(found=True, isalias=False, ismagic=False,
391 namespace='locals', obj=A.foo, parent=a)
391 namespace='locals', obj=A.foo, parent=a)
392 nt.assert_equal(found, info)
392 nt.assert_equal(found, info)
393
393
394 def test_ofind_multiple_attribute_lookups(self):
394 def test_ofind_multiple_attribute_lookups(self):
395 class A(object):
395 class A(object):
396 @property
396 @property
397 def foo(self):
397 def foo(self):
398 raise NotImplementedError()
398 raise NotImplementedError()
399
399
400 a = A()
400 a = A()
401 a.a = A()
401 a.a = A()
402 a.a.a = A()
402 a.a.a = A()
403
403
404 found = ip._ofind('a.a.a.foo', [('locals', locals())])
404 found = ip._ofind('a.a.a.foo', [('locals', locals())])
405 info = dict(found=True, isalias=False, ismagic=False,
405 info = dict(found=True, isalias=False, ismagic=False,
406 namespace='locals', obj=A.foo, parent=a.a.a)
406 namespace='locals', obj=A.foo, parent=a.a.a)
407 nt.assert_equal(found, info)
407 nt.assert_equal(found, info)
408
408
409 def test_ofind_slotted_attributes(self):
409 def test_ofind_slotted_attributes(self):
410 class A(object):
410 class A(object):
411 __slots__ = ['foo']
411 __slots__ = ['foo']
412 def __init__(self):
412 def __init__(self):
413 self.foo = 'bar'
413 self.foo = 'bar'
414
414
415 a = A()
415 a = A()
416 found = ip._ofind('a.foo', [('locals', locals())])
416 found = ip._ofind('a.foo', [('locals', locals())])
417 info = dict(found=True, isalias=False, ismagic=False,
417 info = dict(found=True, isalias=False, ismagic=False,
418 namespace='locals', obj=a.foo, parent=a)
418 namespace='locals', obj=a.foo, parent=a)
419 nt.assert_equal(found, info)
419 nt.assert_equal(found, info)
420
420
421 found = ip._ofind('a.bar', [('locals', locals())])
421 found = ip._ofind('a.bar', [('locals', locals())])
422 info = dict(found=False, isalias=False, ismagic=False,
422 info = dict(found=False, isalias=False, ismagic=False,
423 namespace=None, obj=None, parent=a)
423 namespace=None, obj=None, parent=a)
424 nt.assert_equal(found, info)
424 nt.assert_equal(found, info)
425
425
426 def test_ofind_prefers_property_to_instance_level_attribute(self):
426 def test_ofind_prefers_property_to_instance_level_attribute(self):
427 class A(object):
427 class A(object):
428 @property
428 @property
429 def foo(self):
429 def foo(self):
430 return 'bar'
430 return 'bar'
431 a = A()
431 a = A()
432 a.__dict__['foo'] = 'baz'
432 a.__dict__['foo'] = 'baz'
433 nt.assert_equal(a.foo, 'bar')
433 nt.assert_equal(a.foo, 'bar')
434 found = ip._ofind('a.foo', [('locals', locals())])
434 found = ip._ofind('a.foo', [('locals', locals())])
435 nt.assert_is(found['obj'], A.foo)
435 nt.assert_is(found['obj'], A.foo)
436
436
437 def test_custom_syntaxerror_exception(self):
437 def test_custom_syntaxerror_exception(self):
438 called = []
438 called = []
439 def my_handler(shell, etype, value, tb, tb_offset=None):
439 def my_handler(shell, etype, value, tb, tb_offset=None):
440 called.append(etype)
440 called.append(etype)
441 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
441 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
442
442
443 ip.set_custom_exc((SyntaxError,), my_handler)
443 ip.set_custom_exc((SyntaxError,), my_handler)
444 try:
444 try:
445 ip.run_cell("1f")
445 ip.run_cell("1f")
446 # Check that this was called, and only once.
446 # Check that this was called, and only once.
447 self.assertEqual(called, [SyntaxError])
447 self.assertEqual(called, [SyntaxError])
448 finally:
448 finally:
449 # Reset the custom exception hook
449 # Reset the custom exception hook
450 ip.set_custom_exc((), None)
450 ip.set_custom_exc((), None)
451
451
452 def test_custom_exception(self):
452 def test_custom_exception(self):
453 called = []
453 called = []
454 def my_handler(shell, etype, value, tb, tb_offset=None):
454 def my_handler(shell, etype, value, tb, tb_offset=None):
455 called.append(etype)
455 called.append(etype)
456 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
456 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
457
457
458 ip.set_custom_exc((ValueError,), my_handler)
458 ip.set_custom_exc((ValueError,), my_handler)
459 try:
459 try:
460 res = ip.run_cell("raise ValueError('test')")
460 res = ip.run_cell("raise ValueError('test')")
461 # Check that this was called, and only once.
461 # Check that this was called, and only once.
462 self.assertEqual(called, [ValueError])
462 self.assertEqual(called, [ValueError])
463 # Check that the error is on the result object
463 # Check that the error is on the result object
464 self.assertIsInstance(res.error_in_exec, ValueError)
464 self.assertIsInstance(res.error_in_exec, ValueError)
465 finally:
465 finally:
466 # Reset the custom exception hook
466 # Reset the custom exception hook
467 ip.set_custom_exc((), None)
467 ip.set_custom_exc((), None)
468
468
469 @skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
469 @skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
470 def test_future_environment(self):
470 def test_future_environment(self):
471 "Can we run code with & without the shell's __future__ imports?"
471 "Can we run code with & without the shell's __future__ imports?"
472 ip.run_cell("from __future__ import division")
472 ip.run_cell("from __future__ import division")
473 ip.run_cell("a = 1/2", shell_futures=True)
473 ip.run_cell("a = 1/2", shell_futures=True)
474 self.assertEqual(ip.user_ns['a'], 0.5)
474 self.assertEqual(ip.user_ns['a'], 0.5)
475 ip.run_cell("b = 1/2", shell_futures=False)
475 ip.run_cell("b = 1/2", shell_futures=False)
476 self.assertEqual(ip.user_ns['b'], 0)
476 self.assertEqual(ip.user_ns['b'], 0)
477
477
478 ip.compile.reset_compiler_flags()
478 ip.compile.reset_compiler_flags()
479 # This shouldn't leak to the shell's compiler
479 # This shouldn't leak to the shell's compiler
480 ip.run_cell("from __future__ import division \nc=1/2", shell_futures=False)
480 ip.run_cell("from __future__ import division \nc=1/2", shell_futures=False)
481 self.assertEqual(ip.user_ns['c'], 0.5)
481 self.assertEqual(ip.user_ns['c'], 0.5)
482 ip.run_cell("d = 1/2", shell_futures=True)
482 ip.run_cell("d = 1/2", shell_futures=True)
483 self.assertEqual(ip.user_ns['d'], 0)
483 self.assertEqual(ip.user_ns['d'], 0)
484
484
485 def test_mktempfile(self):
485 def test_mktempfile(self):
486 filename = ip.mktempfile()
486 filename = ip.mktempfile()
487 # Check that we can open the file again on Windows
487 # Check that we can open the file again on Windows
488 with open(filename, 'w') as f:
488 with open(filename, 'w') as f:
489 f.write('abc')
489 f.write('abc')
490
490
491 filename = ip.mktempfile(data='blah')
491 filename = ip.mktempfile(data='blah')
492 with open(filename, 'r') as f:
492 with open(filename, 'r') as f:
493 self.assertEqual(f.read(), 'blah')
493 self.assertEqual(f.read(), 'blah')
494
494
495 def test_new_main_mod(self):
495 def test_new_main_mod(self):
496 # Smoketest to check that this accepts a unicode module name
496 # Smoketest to check that this accepts a unicode module name
497 name = u'jiefmw'
497 name = u'jiefmw'
498 mod = ip.new_main_mod(u'%s.py' % name, name)
498 mod = ip.new_main_mod(u'%s.py' % name, name)
499 self.assertEqual(mod.__name__, name)
499 self.assertEqual(mod.__name__, name)
500
500
501 def test_get_exception_only(self):
501 def test_get_exception_only(self):
502 try:
502 try:
503 raise KeyboardInterrupt
503 raise KeyboardInterrupt
504 except KeyboardInterrupt:
504 except KeyboardInterrupt:
505 msg = ip.get_exception_only()
505 msg = ip.get_exception_only()
506 self.assertEqual(msg, 'KeyboardInterrupt\n')
506 self.assertEqual(msg, 'KeyboardInterrupt\n')
507
507
508 try:
508 try:
509 raise DerivedInterrupt("foo")
509 raise DerivedInterrupt("foo")
510 except KeyboardInterrupt:
510 except KeyboardInterrupt:
511 msg = ip.get_exception_only()
511 msg = ip.get_exception_only()
512 if sys.version_info[0] <= 2:
512 if sys.version_info[0] <= 2:
513 self.assertEqual(msg, 'DerivedInterrupt: foo\n')
513 self.assertEqual(msg, 'DerivedInterrupt: foo\n')
514 else:
514 else:
515 self.assertEqual(msg, 'IPython.core.tests.test_interactiveshell.DerivedInterrupt: foo\n')
515 self.assertEqual(msg, 'IPython.core.tests.test_interactiveshell.DerivedInterrupt: foo\n')
516
516
517 def test_inspect_text(self):
517 def test_inspect_text(self):
518 ip.run_cell('a = 5')
518 ip.run_cell('a = 5')
519 text = ip.object_inspect_text('a')
519 text = ip.object_inspect_text('a')
520 self.assertIsInstance(text, unicode_type)
520 self.assertIsInstance(text, unicode_type)
521
521
522
522
523 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
523 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
524
524
525 @onlyif_unicode_paths
525 @onlyif_unicode_paths
526 def setUp(self):
526 def setUp(self):
527 self.BASETESTDIR = tempfile.mkdtemp()
527 self.BASETESTDIR = tempfile.mkdtemp()
528 self.TESTDIR = join(self.BASETESTDIR, u"Γ₯Àâ")
528 self.TESTDIR = join(self.BASETESTDIR, u"Γ₯Àâ")
529 os.mkdir(self.TESTDIR)
529 os.mkdir(self.TESTDIR)
530 with open(join(self.TESTDIR, u"Γ₯Àâtestscript.py"), "w") as sfile:
530 with open(join(self.TESTDIR, u"Γ₯Àâtestscript.py"), "w") as sfile:
531 sfile.write("pass\n")
531 sfile.write("pass\n")
532 self.oldpath = py3compat.getcwd()
532 self.oldpath = py3compat.getcwd()
533 os.chdir(self.TESTDIR)
533 os.chdir(self.TESTDIR)
534 self.fname = u"Γ₯Àâtestscript.py"
534 self.fname = u"Γ₯Àâtestscript.py"
535
535
536 def tearDown(self):
536 def tearDown(self):
537 os.chdir(self.oldpath)
537 os.chdir(self.oldpath)
538 shutil.rmtree(self.BASETESTDIR)
538 shutil.rmtree(self.BASETESTDIR)
539
539
540 @onlyif_unicode_paths
540 @onlyif_unicode_paths
541 def test_1(self):
541 def test_1(self):
542 """Test safe_execfile with non-ascii path
542 """Test safe_execfile with non-ascii path
543 """
543 """
544 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
544 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
545
545
546 class ExitCodeChecks(tt.TempFileMixin):
546 class ExitCodeChecks(tt.TempFileMixin):
547 def test_exit_code_ok(self):
547 def test_exit_code_ok(self):
548 self.system('exit 0')
548 self.system('exit 0')
549 self.assertEqual(ip.user_ns['_exit_code'], 0)
549 self.assertEqual(ip.user_ns['_exit_code'], 0)
550
550
551 def test_exit_code_error(self):
551 def test_exit_code_error(self):
552 self.system('exit 1')
552 self.system('exit 1')
553 self.assertEqual(ip.user_ns['_exit_code'], 1)
553 self.assertEqual(ip.user_ns['_exit_code'], 1)
554
554
555 @skipif(not hasattr(signal, 'SIGALRM'))
555 @skipif(not hasattr(signal, 'SIGALRM'))
556 def test_exit_code_signal(self):
556 def test_exit_code_signal(self):
557 self.mktmp("import signal, time\n"
557 self.mktmp("import signal, time\n"
558 "signal.setitimer(signal.ITIMER_REAL, 0.1)\n"
558 "signal.setitimer(signal.ITIMER_REAL, 0.1)\n"
559 "time.sleep(1)\n")
559 "time.sleep(1)\n")
560 self.system("%s %s" % (sys.executable, self.fname))
560 self.system("%s %s" % (sys.executable, self.fname))
561 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGALRM)
561 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGALRM)
562
562
563 @onlyif_cmds_exist("csh")
563 @onlyif_cmds_exist("csh")
564 def test_exit_code_signal_csh(self):
564 def test_exit_code_signal_csh(self):
565 SHELL = os.environ.get('SHELL', None)
565 SHELL = os.environ.get('SHELL', None)
566 os.environ['SHELL'] = find_cmd("csh")
566 os.environ['SHELL'] = find_cmd("csh")
567 try:
567 try:
568 self.test_exit_code_signal()
568 self.test_exit_code_signal()
569 finally:
569 finally:
570 if SHELL is not None:
570 if SHELL is not None:
571 os.environ['SHELL'] = SHELL
571 os.environ['SHELL'] = SHELL
572 else:
572 else:
573 del os.environ['SHELL']
573 del os.environ['SHELL']
574
574
575 class TestSystemRaw(unittest.TestCase, ExitCodeChecks):
575 class TestSystemRaw(unittest.TestCase, ExitCodeChecks):
576 system = ip.system_raw
576 system = ip.system_raw
577
577
578 @onlyif_unicode_paths
578 @onlyif_unicode_paths
579 def test_1(self):
579 def test_1(self):
580 """Test system_raw with non-ascii cmd
580 """Test system_raw with non-ascii cmd
581 """
581 """
582 cmd = u'''python -c "'Γ₯Àâ'" '''
582 cmd = u'''python -c "'Γ₯Àâ'" '''
583 ip.system_raw(cmd)
583 ip.system_raw(cmd)
584
584
585 @mock.patch('subprocess.call', side_effect=KeyboardInterrupt)
585 @mock.patch('subprocess.call', side_effect=KeyboardInterrupt)
586 @mock.patch('os.system', side_effect=KeyboardInterrupt)
586 @mock.patch('os.system', side_effect=KeyboardInterrupt)
587 def test_control_c(self, *mocks):
587 def test_control_c(self, *mocks):
588 try:
588 try:
589 self.system("sleep 1 # wont happen")
589 self.system("sleep 1 # wont happen")
590 except KeyboardInterrupt:
590 except KeyboardInterrupt:
591 self.fail("system call should intercept "
591 self.fail("system call should intercept "
592 "keyboard interrupt from subprocess.call")
592 "keyboard interrupt from subprocess.call")
593 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGINT)
593 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGINT)
594
594
595 # TODO: Exit codes are currently ignored on Windows.
595 # TODO: Exit codes are currently ignored on Windows.
596 class TestSystemPipedExitCode(unittest.TestCase, ExitCodeChecks):
596 class TestSystemPipedExitCode(unittest.TestCase, ExitCodeChecks):
597 system = ip.system_piped
597 system = ip.system_piped
598
598
599 @skip_win32
599 @skip_win32
600 def test_exit_code_ok(self):
600 def test_exit_code_ok(self):
601 ExitCodeChecks.test_exit_code_ok(self)
601 ExitCodeChecks.test_exit_code_ok(self)
602
602
603 @skip_win32
603 @skip_win32
604 def test_exit_code_error(self):
604 def test_exit_code_error(self):
605 ExitCodeChecks.test_exit_code_error(self)
605 ExitCodeChecks.test_exit_code_error(self)
606
606
607 @skip_win32
607 @skip_win32
608 def test_exit_code_signal(self):
608 def test_exit_code_signal(self):
609 ExitCodeChecks.test_exit_code_signal(self)
609 ExitCodeChecks.test_exit_code_signal(self)
610
610
611 class TestModules(unittest.TestCase, tt.TempFileMixin):
611 class TestModules(unittest.TestCase, tt.TempFileMixin):
612 def test_extraneous_loads(self):
612 def test_extraneous_loads(self):
613 """Test we're not loading modules on startup that we shouldn't.
613 """Test we're not loading modules on startup that we shouldn't.
614 """
614 """
615 self.mktmp("import sys\n"
615 self.mktmp("import sys\n"
616 "print('numpy' in sys.modules)\n"
616 "print('numpy' in sys.modules)\n"
617 "print('ipyparallel' in sys.modules)\n"
617 "print('ipyparallel' in sys.modules)\n"
618 "print('ipykernel' in sys.modules)\n"
618 "print('ipykernel' in sys.modules)\n"
619 )
619 )
620 out = "False\nFalse\nFalse\n"
620 out = "False\nFalse\nFalse\n"
621 tt.ipexec_validate(self.fname, out)
621 tt.ipexec_validate(self.fname, out)
622
622
623 class Negator(ast.NodeTransformer):
623 class Negator(ast.NodeTransformer):
624 """Negates all number literals in an AST."""
624 """Negates all number literals in an AST."""
625 def visit_Num(self, node):
625 def visit_Num(self, node):
626 node.n = -node.n
626 node.n = -node.n
627 return node
627 return node
628
628
629 class TestAstTransform(unittest.TestCase):
629 class TestAstTransform(unittest.TestCase):
630 def setUp(self):
630 def setUp(self):
631 self.negator = Negator()
631 self.negator = Negator()
632 ip.ast_transformers.append(self.negator)
632 ip.ast_transformers.append(self.negator)
633
633
634 def tearDown(self):
634 def tearDown(self):
635 ip.ast_transformers.remove(self.negator)
635 ip.ast_transformers.remove(self.negator)
636
636
637 def test_run_cell(self):
637 def test_run_cell(self):
638 with tt.AssertPrints('-34'):
638 with tt.AssertPrints('-34'):
639 ip.run_cell('print (12 + 22)')
639 ip.run_cell('print (12 + 22)')
640
640
641 # A named reference to a number shouldn't be transformed.
641 # A named reference to a number shouldn't be transformed.
642 ip.user_ns['n'] = 55
642 ip.user_ns['n'] = 55
643 with tt.AssertNotPrints('-55'):
643 with tt.AssertNotPrints('-55'):
644 ip.run_cell('print (n)')
644 ip.run_cell('print (n)')
645
645
646 def test_timeit(self):
646 def test_timeit(self):
647 called = set()
647 called = set()
648 def f(x):
648 def f(x):
649 called.add(x)
649 called.add(x)
650 ip.push({'f':f})
650 ip.push({'f':f})
651
651
652 with tt.AssertPrints("average of "):
652 with tt.AssertPrints("best of "):
653 ip.run_line_magic("timeit", "-n1 f(1)")
653 ip.run_line_magic("timeit", "-n1 f(1)")
654 self.assertEqual(called, {-1})
654 self.assertEqual(called, {-1})
655 called.clear()
655 called.clear()
656
656
657 with tt.AssertPrints("average of "):
657 with tt.AssertPrints("average of "):
658 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
658 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
659 self.assertEqual(called, {-2, -3})
659 self.assertEqual(called, {-2, -3})
660
660
661 def test_time(self):
661 def test_time(self):
662 called = []
662 called = []
663 def f(x):
663 def f(x):
664 called.append(x)
664 called.append(x)
665 ip.push({'f':f})
665 ip.push({'f':f})
666
666
667 # Test with an expression
667 # Test with an expression
668 with tt.AssertPrints("Wall time: "):
668 with tt.AssertPrints("Wall time: "):
669 ip.run_line_magic("time", "f(5+9)")
669 ip.run_line_magic("time", "f(5+9)")
670 self.assertEqual(called, [-14])
670 self.assertEqual(called, [-14])
671 called[:] = []
671 called[:] = []
672
672
673 # Test with a statement (different code path)
673 # Test with a statement (different code path)
674 with tt.AssertPrints("Wall time: "):
674 with tt.AssertPrints("Wall time: "):
675 ip.run_line_magic("time", "a = f(-3 + -2)")
675 ip.run_line_magic("time", "a = f(-3 + -2)")
676 self.assertEqual(called, [5])
676 self.assertEqual(called, [5])
677
677
678 def test_macro(self):
678 def test_macro(self):
679 ip.push({'a':10})
679 ip.push({'a':10})
680 # The AST transformation makes this do a+=-1
680 # The AST transformation makes this do a+=-1
681 ip.define_macro("amacro", "a+=1\nprint(a)")
681 ip.define_macro("amacro", "a+=1\nprint(a)")
682
682
683 with tt.AssertPrints("9"):
683 with tt.AssertPrints("9"):
684 ip.run_cell("amacro")
684 ip.run_cell("amacro")
685 with tt.AssertPrints("8"):
685 with tt.AssertPrints("8"):
686 ip.run_cell("amacro")
686 ip.run_cell("amacro")
687
687
688 class IntegerWrapper(ast.NodeTransformer):
688 class IntegerWrapper(ast.NodeTransformer):
689 """Wraps all integers in a call to Integer()"""
689 """Wraps all integers in a call to Integer()"""
690 def visit_Num(self, node):
690 def visit_Num(self, node):
691 if isinstance(node.n, int):
691 if isinstance(node.n, int):
692 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
692 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
693 args=[node], keywords=[])
693 args=[node], keywords=[])
694 return node
694 return node
695
695
696 class TestAstTransform2(unittest.TestCase):
696 class TestAstTransform2(unittest.TestCase):
697 def setUp(self):
697 def setUp(self):
698 self.intwrapper = IntegerWrapper()
698 self.intwrapper = IntegerWrapper()
699 ip.ast_transformers.append(self.intwrapper)
699 ip.ast_transformers.append(self.intwrapper)
700
700
701 self.calls = []
701 self.calls = []
702 def Integer(*args):
702 def Integer(*args):
703 self.calls.append(args)
703 self.calls.append(args)
704 return args
704 return args
705 ip.push({"Integer": Integer})
705 ip.push({"Integer": Integer})
706
706
707 def tearDown(self):
707 def tearDown(self):
708 ip.ast_transformers.remove(self.intwrapper)
708 ip.ast_transformers.remove(self.intwrapper)
709 del ip.user_ns['Integer']
709 del ip.user_ns['Integer']
710
710
711 def test_run_cell(self):
711 def test_run_cell(self):
712 ip.run_cell("n = 2")
712 ip.run_cell("n = 2")
713 self.assertEqual(self.calls, [(2,)])
713 self.assertEqual(self.calls, [(2,)])
714
714
715 # This shouldn't throw an error
715 # This shouldn't throw an error
716 ip.run_cell("o = 2.0")
716 ip.run_cell("o = 2.0")
717 self.assertEqual(ip.user_ns['o'], 2.0)
717 self.assertEqual(ip.user_ns['o'], 2.0)
718
718
719 def test_timeit(self):
719 def test_timeit(self):
720 called = set()
720 called = set()
721 def f(x):
721 def f(x):
722 called.add(x)
722 called.add(x)
723 ip.push({'f':f})
723 ip.push({'f':f})
724
724
725 with tt.AssertPrints("average of "):
725 with tt.AssertPrints("average of "):
726 ip.run_line_magic("timeit", "-n1 f(1)")
726 ip.run_line_magic("timeit", "-n1 f(1)")
727 self.assertEqual(called, {(1,)})
727 self.assertEqual(called, {(1,)})
728 called.clear()
728 called.clear()
729
729
730 with tt.AssertPrints("average of "):
730 with tt.AssertPrints("average of "):
731 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
731 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
732 self.assertEqual(called, {(2,), (3,)})
732 self.assertEqual(called, {(2,), (3,)})
733
733
734 class ErrorTransformer(ast.NodeTransformer):
734 class ErrorTransformer(ast.NodeTransformer):
735 """Throws an error when it sees a number."""
735 """Throws an error when it sees a number."""
736 def visit_Num(self, node):
736 def visit_Num(self, node):
737 raise ValueError("test")
737 raise ValueError("test")
738
738
739 class TestAstTransformError(unittest.TestCase):
739 class TestAstTransformError(unittest.TestCase):
740 def test_unregistering(self):
740 def test_unregistering(self):
741 err_transformer = ErrorTransformer()
741 err_transformer = ErrorTransformer()
742 ip.ast_transformers.append(err_transformer)
742 ip.ast_transformers.append(err_transformer)
743
743
744 with tt.AssertPrints("unregister", channel='stderr'):
744 with tt.AssertPrints("unregister", channel='stderr'):
745 ip.run_cell("1 + 2")
745 ip.run_cell("1 + 2")
746
746
747 # This should have been removed.
747 # This should have been removed.
748 nt.assert_not_in(err_transformer, ip.ast_transformers)
748 nt.assert_not_in(err_transformer, ip.ast_transformers)
749
749
750
750
751 class StringRejector(ast.NodeTransformer):
751 class StringRejector(ast.NodeTransformer):
752 """Throws an InputRejected when it sees a string literal.
752 """Throws an InputRejected when it sees a string literal.
753
753
754 Used to verify that NodeTransformers can signal that a piece of code should
754 Used to verify that NodeTransformers can signal that a piece of code should
755 not be executed by throwing an InputRejected.
755 not be executed by throwing an InputRejected.
756 """
756 """
757
757
758 def visit_Str(self, node):
758 def visit_Str(self, node):
759 raise InputRejected("test")
759 raise InputRejected("test")
760
760
761
761
762 class TestAstTransformInputRejection(unittest.TestCase):
762 class TestAstTransformInputRejection(unittest.TestCase):
763
763
764 def setUp(self):
764 def setUp(self):
765 self.transformer = StringRejector()
765 self.transformer = StringRejector()
766 ip.ast_transformers.append(self.transformer)
766 ip.ast_transformers.append(self.transformer)
767
767
768 def tearDown(self):
768 def tearDown(self):
769 ip.ast_transformers.remove(self.transformer)
769 ip.ast_transformers.remove(self.transformer)
770
770
771 def test_input_rejection(self):
771 def test_input_rejection(self):
772 """Check that NodeTransformers can reject input."""
772 """Check that NodeTransformers can reject input."""
773
773
774 expect_exception_tb = tt.AssertPrints("InputRejected: test")
774 expect_exception_tb = tt.AssertPrints("InputRejected: test")
775 expect_no_cell_output = tt.AssertNotPrints("'unsafe'", suppress=False)
775 expect_no_cell_output = tt.AssertNotPrints("'unsafe'", suppress=False)
776
776
777 # Run the same check twice to verify that the transformer is not
777 # Run the same check twice to verify that the transformer is not
778 # disabled after raising.
778 # disabled after raising.
779 with expect_exception_tb, expect_no_cell_output:
779 with expect_exception_tb, expect_no_cell_output:
780 ip.run_cell("'unsafe'")
780 ip.run_cell("'unsafe'")
781
781
782 with expect_exception_tb, expect_no_cell_output:
782 with expect_exception_tb, expect_no_cell_output:
783 res = ip.run_cell("'unsafe'")
783 res = ip.run_cell("'unsafe'")
784
784
785 self.assertIsInstance(res.error_before_exec, InputRejected)
785 self.assertIsInstance(res.error_before_exec, InputRejected)
786
786
787 def test__IPYTHON__():
787 def test__IPYTHON__():
788 # This shouldn't raise a NameError, that's all
788 # This shouldn't raise a NameError, that's all
789 __IPYTHON__
789 __IPYTHON__
790
790
791
791
792 class DummyRepr(object):
792 class DummyRepr(object):
793 def __repr__(self):
793 def __repr__(self):
794 return "DummyRepr"
794 return "DummyRepr"
795
795
796 def _repr_html_(self):
796 def _repr_html_(self):
797 return "<b>dummy</b>"
797 return "<b>dummy</b>"
798
798
799 def _repr_javascript_(self):
799 def _repr_javascript_(self):
800 return "console.log('hi');", {'key': 'value'}
800 return "console.log('hi');", {'key': 'value'}
801
801
802
802
803 def test_user_variables():
803 def test_user_variables():
804 # enable all formatters
804 # enable all formatters
805 ip.display_formatter.active_types = ip.display_formatter.format_types
805 ip.display_formatter.active_types = ip.display_formatter.format_types
806
806
807 ip.user_ns['dummy'] = d = DummyRepr()
807 ip.user_ns['dummy'] = d = DummyRepr()
808 keys = {'dummy', 'doesnotexist'}
808 keys = {'dummy', 'doesnotexist'}
809 r = ip.user_expressions({ key:key for key in keys})
809 r = ip.user_expressions({ key:key for key in keys})
810
810
811 nt.assert_equal(keys, set(r.keys()))
811 nt.assert_equal(keys, set(r.keys()))
812 dummy = r['dummy']
812 dummy = r['dummy']
813 nt.assert_equal({'status', 'data', 'metadata'}, set(dummy.keys()))
813 nt.assert_equal({'status', 'data', 'metadata'}, set(dummy.keys()))
814 nt.assert_equal(dummy['status'], 'ok')
814 nt.assert_equal(dummy['status'], 'ok')
815 data = dummy['data']
815 data = dummy['data']
816 metadata = dummy['metadata']
816 metadata = dummy['metadata']
817 nt.assert_equal(data.get('text/html'), d._repr_html_())
817 nt.assert_equal(data.get('text/html'), d._repr_html_())
818 js, jsmd = d._repr_javascript_()
818 js, jsmd = d._repr_javascript_()
819 nt.assert_equal(data.get('application/javascript'), js)
819 nt.assert_equal(data.get('application/javascript'), js)
820 nt.assert_equal(metadata.get('application/javascript'), jsmd)
820 nt.assert_equal(metadata.get('application/javascript'), jsmd)
821
821
822 dne = r['doesnotexist']
822 dne = r['doesnotexist']
823 nt.assert_equal(dne['status'], 'error')
823 nt.assert_equal(dne['status'], 'error')
824 nt.assert_equal(dne['ename'], 'NameError')
824 nt.assert_equal(dne['ename'], 'NameError')
825
825
826 # back to text only
826 # back to text only
827 ip.display_formatter.active_types = ['text/plain']
827 ip.display_formatter.active_types = ['text/plain']
828
828
829 def test_user_expression():
829 def test_user_expression():
830 # enable all formatters
830 # enable all formatters
831 ip.display_formatter.active_types = ip.display_formatter.format_types
831 ip.display_formatter.active_types = ip.display_formatter.format_types
832 query = {
832 query = {
833 'a' : '1 + 2',
833 'a' : '1 + 2',
834 'b' : '1/0',
834 'b' : '1/0',
835 }
835 }
836 r = ip.user_expressions(query)
836 r = ip.user_expressions(query)
837 import pprint
837 import pprint
838 pprint.pprint(r)
838 pprint.pprint(r)
839 nt.assert_equal(set(r.keys()), set(query.keys()))
839 nt.assert_equal(set(r.keys()), set(query.keys()))
840 a = r['a']
840 a = r['a']
841 nt.assert_equal({'status', 'data', 'metadata'}, set(a.keys()))
841 nt.assert_equal({'status', 'data', 'metadata'}, set(a.keys()))
842 nt.assert_equal(a['status'], 'ok')
842 nt.assert_equal(a['status'], 'ok')
843 data = a['data']
843 data = a['data']
844 metadata = a['metadata']
844 metadata = a['metadata']
845 nt.assert_equal(data.get('text/plain'), '3')
845 nt.assert_equal(data.get('text/plain'), '3')
846
846
847 b = r['b']
847 b = r['b']
848 nt.assert_equal(b['status'], 'error')
848 nt.assert_equal(b['status'], 'error')
849 nt.assert_equal(b['ename'], 'ZeroDivisionError')
849 nt.assert_equal(b['ename'], 'ZeroDivisionError')
850
850
851 # back to text only
851 # back to text only
852 ip.display_formatter.active_types = ['text/plain']
852 ip.display_formatter.active_types = ['text/plain']
853
853
854
854
855
855
856
856
857
857
858 class TestSyntaxErrorTransformer(unittest.TestCase):
858 class TestSyntaxErrorTransformer(unittest.TestCase):
859 """Check that SyntaxError raised by an input transformer is handled by run_cell()"""
859 """Check that SyntaxError raised by an input transformer is handled by run_cell()"""
860
860
861 class SyntaxErrorTransformer(InputTransformer):
861 class SyntaxErrorTransformer(InputTransformer):
862
862
863 def push(self, line):
863 def push(self, line):
864 pos = line.find('syntaxerror')
864 pos = line.find('syntaxerror')
865 if pos >= 0:
865 if pos >= 0:
866 e = SyntaxError('input contains "syntaxerror"')
866 e = SyntaxError('input contains "syntaxerror"')
867 e.text = line
867 e.text = line
868 e.offset = pos + 1
868 e.offset = pos + 1
869 raise e
869 raise e
870 return line
870 return line
871
871
872 def reset(self):
872 def reset(self):
873 pass
873 pass
874
874
875 def setUp(self):
875 def setUp(self):
876 self.transformer = TestSyntaxErrorTransformer.SyntaxErrorTransformer()
876 self.transformer = TestSyntaxErrorTransformer.SyntaxErrorTransformer()
877 ip.input_splitter.python_line_transforms.append(self.transformer)
877 ip.input_splitter.python_line_transforms.append(self.transformer)
878 ip.input_transformer_manager.python_line_transforms.append(self.transformer)
878 ip.input_transformer_manager.python_line_transforms.append(self.transformer)
879
879
880 def tearDown(self):
880 def tearDown(self):
881 ip.input_splitter.python_line_transforms.remove(self.transformer)
881 ip.input_splitter.python_line_transforms.remove(self.transformer)
882 ip.input_transformer_manager.python_line_transforms.remove(self.transformer)
882 ip.input_transformer_manager.python_line_transforms.remove(self.transformer)
883
883
884 def test_syntaxerror_input_transformer(self):
884 def test_syntaxerror_input_transformer(self):
885 with tt.AssertPrints('1234'):
885 with tt.AssertPrints('1234'):
886 ip.run_cell('1234')
886 ip.run_cell('1234')
887 with tt.AssertPrints('SyntaxError: invalid syntax'):
887 with tt.AssertPrints('SyntaxError: invalid syntax'):
888 ip.run_cell('1 2 3') # plain python syntax error
888 ip.run_cell('1 2 3') # plain python syntax error
889 with tt.AssertPrints('SyntaxError: input contains "syntaxerror"'):
889 with tt.AssertPrints('SyntaxError: input contains "syntaxerror"'):
890 ip.run_cell('2345 # syntaxerror') # input transformer syntax error
890 ip.run_cell('2345 # syntaxerror') # input transformer syntax error
891 with tt.AssertPrints('3456'):
891 with tt.AssertPrints('3456'):
892 ip.run_cell('3456')
892 ip.run_cell('3456')
893
893
894
894
895
895
896 def test_warning_suppression():
896 def test_warning_suppression():
897 ip.run_cell("import warnings")
897 ip.run_cell("import warnings")
898 try:
898 try:
899 with tt.AssertPrints("UserWarning: asdf", channel="stderr"):
899 with tt.AssertPrints("UserWarning: asdf", channel="stderr"):
900 ip.run_cell("warnings.warn('asdf')")
900 ip.run_cell("warnings.warn('asdf')")
901 # Here's the real test -- if we run that again, we should get the
901 # Here's the real test -- if we run that again, we should get the
902 # warning again. Traditionally, each warning was only issued once per
902 # warning again. Traditionally, each warning was only issued once per
903 # IPython session (approximately), even if the user typed in new and
903 # IPython session (approximately), even if the user typed in new and
904 # different code that should have also triggered the warning, leading
904 # different code that should have also triggered the warning, leading
905 # to much confusion.
905 # to much confusion.
906 with tt.AssertPrints("UserWarning: asdf", channel="stderr"):
906 with tt.AssertPrints("UserWarning: asdf", channel="stderr"):
907 ip.run_cell("warnings.warn('asdf')")
907 ip.run_cell("warnings.warn('asdf')")
908 finally:
908 finally:
909 ip.run_cell("del warnings")
909 ip.run_cell("del warnings")
910
910
911
911
912 def test_deprecation_warning():
912 def test_deprecation_warning():
913 ip.run_cell("""
913 ip.run_cell("""
914 import warnings
914 import warnings
915 def wrn():
915 def wrn():
916 warnings.warn(
916 warnings.warn(
917 "I AM A WARNING",
917 "I AM A WARNING",
918 DeprecationWarning
918 DeprecationWarning
919 )
919 )
920 """)
920 """)
921 try:
921 try:
922 with tt.AssertPrints("I AM A WARNING", channel="stderr"):
922 with tt.AssertPrints("I AM A WARNING", channel="stderr"):
923 ip.run_cell("wrn()")
923 ip.run_cell("wrn()")
924 finally:
924 finally:
925 ip.run_cell("del warnings")
925 ip.run_cell("del warnings")
926 ip.run_cell("del wrn")
926 ip.run_cell("del wrn")
927
927
928
928
929 class TestImportNoDeprecate(tt.TempFileMixin):
929 class TestImportNoDeprecate(tt.TempFileMixin):
930
930
931 def setup(self):
931 def setup(self):
932 """Make a valid python temp file."""
932 """Make a valid python temp file."""
933 self.mktmp("""
933 self.mktmp("""
934 import warnings
934 import warnings
935 def wrn():
935 def wrn():
936 warnings.warn(
936 warnings.warn(
937 "I AM A WARNING",
937 "I AM A WARNING",
938 DeprecationWarning
938 DeprecationWarning
939 )
939 )
940 """)
940 """)
941
941
942 def test_no_dep(self):
942 def test_no_dep(self):
943 """
943 """
944 No deprecation warning should be raised from imported functions
944 No deprecation warning should be raised from imported functions
945 """
945 """
946 ip.run_cell("from {} import wrn".format(self.fname))
946 ip.run_cell("from {} import wrn".format(self.fname))
947
947
948 with tt.AssertNotPrints("I AM A WARNING"):
948 with tt.AssertNotPrints("I AM A WARNING"):
949 ip.run_cell("wrn()")
949 ip.run_cell("wrn()")
950 ip.run_cell("del wrn")
950 ip.run_cell("del wrn")
General Comments 0
You need to be logged in to leave comments. Login now