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