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