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