##// END OF EJS Templates
Make %time magic work with AST transformations
Thomas Kluyver -
Show More
@@ -1,1043 +1,1056 b''
1 1 """Implementation of execution-related magic functions.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (c) 2012 The IPython Development Team.
5 5 #
6 6 # Distributed under the terms of the Modified BSD License.
7 7 #
8 8 # The full license is in the file COPYING.txt, distributed with this software.
9 9 #-----------------------------------------------------------------------------
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14
15 15 # Stdlib
16 16 import __builtin__ as builtin_mod
17 17 import ast
18 18 import bdb
19 19 import os
20 20 import sys
21 21 import time
22 22 from StringIO import StringIO
23 23
24 24 # cProfile was added in Python2.5
25 25 try:
26 26 import cProfile as profile
27 27 import pstats
28 28 except ImportError:
29 29 # profile isn't bundled by default in Debian for license reasons
30 30 try:
31 31 import profile, pstats
32 32 except ImportError:
33 33 profile = pstats = None
34 34
35 35 # Our own packages
36 36 from IPython.core import debugger, oinspect
37 37 from IPython.core import magic_arguments
38 38 from IPython.core import page
39 39 from IPython.core.error import UsageError
40 40 from IPython.core.macro import Macro
41 41 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
42 42 line_cell_magic, on_off, needs_local_scope)
43 43 from IPython.testing.skipdoctest import skip_doctest
44 44 from IPython.utils import py3compat
45 45 from IPython.utils.io import capture_output
46 46 from IPython.utils.ipstruct import Struct
47 47 from IPython.utils.module_paths import find_mod
48 48 from IPython.utils.path import get_py_filename, unquote_filename
49 49 from IPython.utils.timing import clock, clock2
50 50 from IPython.utils.warn import warn, error
51 51
52 52 #-----------------------------------------------------------------------------
53 53 # Magic implementation classes
54 54 #-----------------------------------------------------------------------------
55 55
56 56 @magics_class
57 57 class ExecutionMagics(Magics):
58 58 """Magics related to code execution, debugging, profiling, etc.
59 59
60 60 """
61 61
62 62 def __init__(self, shell):
63 63 super(ExecutionMagics, self).__init__(shell)
64 64 if profile is None:
65 65 self.prun = self.profile_missing_notice
66 66 # Default execution function used to actually run user code.
67 67 self.default_runner = None
68 68
69 69 def profile_missing_notice(self, *args, **kwargs):
70 70 error("""\
71 71 The profile module could not be found. It has been removed from the standard
72 72 python packages because of its non-free license. To use profiling, install the
73 73 python-profiler package from non-free.""")
74 74
75 75 @skip_doctest
76 76 @line_cell_magic
77 77 def prun(self, parameter_s='', cell=None, user_mode=True,
78 78 opts=None,arg_lst=None,prog_ns=None):
79 79
80 80 """Run a statement through the python code profiler.
81 81
82 82 Usage, in line mode:
83 83 %prun [options] statement
84 84
85 85 Usage, in cell mode:
86 86 %%prun [options] [statement]
87 87 code...
88 88 code...
89 89
90 90 In cell mode, the additional code lines are appended to the (possibly
91 91 empty) statement in the first line. Cell mode allows you to easily
92 92 profile multiline blocks without having to put them in a separate
93 93 function.
94 94
95 95 The given statement (which doesn't require quote marks) is run via the
96 96 python profiler in a manner similar to the profile.run() function.
97 97 Namespaces are internally managed to work correctly; profile.run
98 98 cannot be used in IPython because it makes certain assumptions about
99 99 namespaces which do not hold under IPython.
100 100
101 101 Options:
102 102
103 103 -l <limit>: you can place restrictions on what or how much of the
104 104 profile gets printed. The limit value can be:
105 105
106 106 * A string: only information for function names containing this string
107 107 is printed.
108 108
109 109 * An integer: only these many lines are printed.
110 110
111 111 * A float (between 0 and 1): this fraction of the report is printed
112 112 (for example, use a limit of 0.4 to see the topmost 40% only).
113 113
114 114 You can combine several limits with repeated use of the option. For
115 115 example, '-l __init__ -l 5' will print only the topmost 5 lines of
116 116 information about class constructors.
117 117
118 118 -r: return the pstats.Stats object generated by the profiling. This
119 119 object has all the information about the profile in it, and you can
120 120 later use it for further analysis or in other functions.
121 121
122 122 -s <key>: sort profile by given key. You can provide more than one key
123 123 by using the option several times: '-s key1 -s key2 -s key3...'. The
124 124 default sorting key is 'time'.
125 125
126 126 The following is copied verbatim from the profile documentation
127 127 referenced below:
128 128
129 129 When more than one key is provided, additional keys are used as
130 130 secondary criteria when the there is equality in all keys selected
131 131 before them.
132 132
133 133 Abbreviations can be used for any key names, as long as the
134 134 abbreviation is unambiguous. The following are the keys currently
135 135 defined:
136 136
137 137 Valid Arg Meaning
138 138 "calls" call count
139 139 "cumulative" cumulative time
140 140 "file" file name
141 141 "module" file name
142 142 "pcalls" primitive call count
143 143 "line" line number
144 144 "name" function name
145 145 "nfl" name/file/line
146 146 "stdname" standard name
147 147 "time" internal time
148 148
149 149 Note that all sorts on statistics are in descending order (placing
150 150 most time consuming items first), where as name, file, and line number
151 151 searches are in ascending order (i.e., alphabetical). The subtle
152 152 distinction between "nfl" and "stdname" is that the standard name is a
153 153 sort of the name as printed, which means that the embedded line
154 154 numbers get compared in an odd way. For example, lines 3, 20, and 40
155 155 would (if the file names were the same) appear in the string order
156 156 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
157 157 line numbers. In fact, sort_stats("nfl") is the same as
158 158 sort_stats("name", "file", "line").
159 159
160 160 -T <filename>: save profile results as shown on screen to a text
161 161 file. The profile is still shown on screen.
162 162
163 163 -D <filename>: save (via dump_stats) profile statistics to given
164 164 filename. This data is in a format understood by the pstats module, and
165 165 is generated by a call to the dump_stats() method of profile
166 166 objects. The profile is still shown on screen.
167 167
168 168 -q: suppress output to the pager. Best used with -T and/or -D above.
169 169
170 170 If you want to run complete programs under the profiler's control, use
171 171 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
172 172 contains profiler specific options as described here.
173 173
174 174 You can read the complete documentation for the profile module with::
175 175
176 176 In [1]: import profile; profile.help()
177 177 """
178 178
179 179 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
180 180
181 181 if user_mode: # regular user call
182 182 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:q',
183 183 list_all=True, posix=False)
184 184 namespace = self.shell.user_ns
185 185 if cell is not None:
186 186 arg_str += '\n' + cell
187 187 else: # called to run a program by %run -p
188 188 try:
189 189 filename = get_py_filename(arg_lst[0])
190 190 except IOError as e:
191 191 try:
192 192 msg = str(e)
193 193 except UnicodeError:
194 194 msg = e.message
195 195 error(msg)
196 196 return
197 197
198 198 arg_str = 'execfile(filename,prog_ns)'
199 199 namespace = {
200 200 'execfile': self.shell.safe_execfile,
201 201 'prog_ns': prog_ns,
202 202 'filename': filename
203 203 }
204 204
205 205 opts.merge(opts_def)
206 206
207 207 prof = profile.Profile()
208 208 try:
209 209 prof = prof.runctx(arg_str,namespace,namespace)
210 210 sys_exit = ''
211 211 except SystemExit:
212 212 sys_exit = """*** SystemExit exception caught in code being profiled."""
213 213
214 214 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
215 215
216 216 lims = opts.l
217 217 if lims:
218 218 lims = [] # rebuild lims with ints/floats/strings
219 219 for lim in opts.l:
220 220 try:
221 221 lims.append(int(lim))
222 222 except ValueError:
223 223 try:
224 224 lims.append(float(lim))
225 225 except ValueError:
226 226 lims.append(lim)
227 227
228 228 # Trap output.
229 229 stdout_trap = StringIO()
230 230 stats_stream = stats.stream
231 231 try:
232 232 stats.stream = stdout_trap
233 233 stats.print_stats(*lims)
234 234 finally:
235 235 stats.stream = stats_stream
236 236
237 237 output = stdout_trap.getvalue()
238 238 output = output.rstrip()
239 239
240 240 if 'q' not in opts:
241 241 page.page(output)
242 242 print sys_exit,
243 243
244 244 dump_file = opts.D[0]
245 245 text_file = opts.T[0]
246 246 if dump_file:
247 247 dump_file = unquote_filename(dump_file)
248 248 prof.dump_stats(dump_file)
249 249 print '\n*** Profile stats marshalled to file',\
250 250 repr(dump_file)+'.',sys_exit
251 251 if text_file:
252 252 text_file = unquote_filename(text_file)
253 253 pfile = open(text_file,'w')
254 254 pfile.write(output)
255 255 pfile.close()
256 256 print '\n*** Profile printout saved to text file',\
257 257 repr(text_file)+'.',sys_exit
258 258
259 259 if 'r' in opts:
260 260 return stats
261 261 else:
262 262 return None
263 263
264 264 @line_magic
265 265 def pdb(self, parameter_s=''):
266 266 """Control the automatic calling of the pdb interactive debugger.
267 267
268 268 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
269 269 argument it works as a toggle.
270 270
271 271 When an exception is triggered, IPython can optionally call the
272 272 interactive pdb debugger after the traceback printout. %pdb toggles
273 273 this feature on and off.
274 274
275 275 The initial state of this feature is set in your configuration
276 276 file (the option is ``InteractiveShell.pdb``).
277 277
278 278 If you want to just activate the debugger AFTER an exception has fired,
279 279 without having to type '%pdb on' and rerunning your code, you can use
280 280 the %debug magic."""
281 281
282 282 par = parameter_s.strip().lower()
283 283
284 284 if par:
285 285 try:
286 286 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
287 287 except KeyError:
288 288 print ('Incorrect argument. Use on/1, off/0, '
289 289 'or nothing for a toggle.')
290 290 return
291 291 else:
292 292 # toggle
293 293 new_pdb = not self.shell.call_pdb
294 294
295 295 # set on the shell
296 296 self.shell.call_pdb = new_pdb
297 297 print 'Automatic pdb calling has been turned',on_off(new_pdb)
298 298
299 299 @line_magic
300 300 def debug(self, parameter_s=''):
301 301 """Activate the interactive debugger in post-mortem mode.
302 302
303 303 If an exception has just occurred, this lets you inspect its stack
304 304 frames interactively. Note that this will always work only on the last
305 305 traceback that occurred, so you must call this quickly after an
306 306 exception that you wish to inspect has fired, because if another one
307 307 occurs, it clobbers the previous one.
308 308
309 309 If you want IPython to automatically do this on every exception, see
310 310 the %pdb magic for more details.
311 311 """
312 312 self.shell.debugger(force=True)
313 313
314 314 @line_magic
315 315 def tb(self, s):
316 316 """Print the last traceback with the currently active exception mode.
317 317
318 318 See %xmode for changing exception reporting modes."""
319 319 self.shell.showtraceback()
320 320
321 321 @skip_doctest
322 322 @line_magic
323 323 def run(self, parameter_s='', runner=None,
324 324 file_finder=get_py_filename):
325 325 """Run the named file inside IPython as a program.
326 326
327 327 Usage:\\
328 328 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args]
329 329
330 330 Parameters after the filename are passed as command-line arguments to
331 331 the program (put in sys.argv). Then, control returns to IPython's
332 332 prompt.
333 333
334 334 This is similar to running at a system prompt:\\
335 335 $ python file args\\
336 336 but with the advantage of giving you IPython's tracebacks, and of
337 337 loading all variables into your interactive namespace for further use
338 338 (unless -p is used, see below).
339 339
340 340 The file is executed in a namespace initially consisting only of
341 341 __name__=='__main__' and sys.argv constructed as indicated. It thus
342 342 sees its environment as if it were being run as a stand-alone program
343 343 (except for sharing global objects such as previously imported
344 344 modules). But after execution, the IPython interactive namespace gets
345 345 updated with all variables defined in the program (except for __name__
346 346 and sys.argv). This allows for very convenient loading of code for
347 347 interactive work, while giving each program a 'clean sheet' to run in.
348 348
349 349 Options:
350 350
351 351 -n: __name__ is NOT set to '__main__', but to the running file's name
352 352 without extension (as python does under import). This allows running
353 353 scripts and reloading the definitions in them without calling code
354 354 protected by an ' if __name__ == "__main__" ' clause.
355 355
356 356 -i: run the file in IPython's namespace instead of an empty one. This
357 357 is useful if you are experimenting with code written in a text editor
358 358 which depends on variables defined interactively.
359 359
360 360 -e: ignore sys.exit() calls or SystemExit exceptions in the script
361 361 being run. This is particularly useful if IPython is being used to
362 362 run unittests, which always exit with a sys.exit() call. In such
363 363 cases you are interested in the output of the test results, not in
364 364 seeing a traceback of the unittest module.
365 365
366 366 -t: print timing information at the end of the run. IPython will give
367 367 you an estimated CPU time consumption for your script, which under
368 368 Unix uses the resource module to avoid the wraparound problems of
369 369 time.clock(). Under Unix, an estimate of time spent on system tasks
370 370 is also given (for Windows platforms this is reported as 0.0).
371 371
372 372 If -t is given, an additional -N<N> option can be given, where <N>
373 373 must be an integer indicating how many times you want the script to
374 374 run. The final timing report will include total and per run results.
375 375
376 376 For example (testing the script uniq_stable.py)::
377 377
378 378 In [1]: run -t uniq_stable
379 379
380 380 IPython CPU timings (estimated):\\
381 381 User : 0.19597 s.\\
382 382 System: 0.0 s.\\
383 383
384 384 In [2]: run -t -N5 uniq_stable
385 385
386 386 IPython CPU timings (estimated):\\
387 387 Total runs performed: 5\\
388 388 Times : Total Per run\\
389 389 User : 0.910862 s, 0.1821724 s.\\
390 390 System: 0.0 s, 0.0 s.
391 391
392 392 -d: run your program under the control of pdb, the Python debugger.
393 393 This allows you to execute your program step by step, watch variables,
394 394 etc. Internally, what IPython does is similar to calling:
395 395
396 396 pdb.run('execfile("YOURFILENAME")')
397 397
398 398 with a breakpoint set on line 1 of your file. You can change the line
399 399 number for this automatic breakpoint to be <N> by using the -bN option
400 400 (where N must be an integer). For example::
401 401
402 402 %run -d -b40 myscript
403 403
404 404 will set the first breakpoint at line 40 in myscript.py. Note that
405 405 the first breakpoint must be set on a line which actually does
406 406 something (not a comment or docstring) for it to stop execution.
407 407
408 408 When the pdb debugger starts, you will see a (Pdb) prompt. You must
409 409 first enter 'c' (without quotes) to start execution up to the first
410 410 breakpoint.
411 411
412 412 Entering 'help' gives information about the use of the debugger. You
413 413 can easily see pdb's full documentation with "import pdb;pdb.help()"
414 414 at a prompt.
415 415
416 416 -p: run program under the control of the Python profiler module (which
417 417 prints a detailed report of execution times, function calls, etc).
418 418
419 419 You can pass other options after -p which affect the behavior of the
420 420 profiler itself. See the docs for %prun for details.
421 421
422 422 In this mode, the program's variables do NOT propagate back to the
423 423 IPython interactive namespace (because they remain in the namespace
424 424 where the profiler executes them).
425 425
426 426 Internally this triggers a call to %prun, see its documentation for
427 427 details on the options available specifically for profiling.
428 428
429 429 There is one special usage for which the text above doesn't apply:
430 430 if the filename ends with .ipy, the file is run as ipython script,
431 431 just as if the commands were written on IPython prompt.
432 432
433 433 -m: specify module name to load instead of script path. Similar to
434 434 the -m option for the python interpreter. Use this option last if you
435 435 want to combine with other %run options. Unlike the python interpreter
436 436 only source modules are allowed no .pyc or .pyo files.
437 437 For example::
438 438
439 439 %run -m example
440 440
441 441 will run the example module.
442 442
443 443 """
444 444
445 445 # get arguments and set sys.argv for program to be run.
446 446 opts, arg_lst = self.parse_options(parameter_s, 'nidtN:b:pD:l:rs:T:em:',
447 447 mode='list', list_all=1)
448 448 if "m" in opts:
449 449 modulename = opts["m"][0]
450 450 modpath = find_mod(modulename)
451 451 if modpath is None:
452 452 warn('%r is not a valid modulename on sys.path'%modulename)
453 453 return
454 454 arg_lst = [modpath] + arg_lst
455 455 try:
456 456 filename = file_finder(arg_lst[0])
457 457 except IndexError:
458 458 warn('you must provide at least a filename.')
459 459 print '\n%run:\n', oinspect.getdoc(self.run)
460 460 return
461 461 except IOError as e:
462 462 try:
463 463 msg = str(e)
464 464 except UnicodeError:
465 465 msg = e.message
466 466 error(msg)
467 467 return
468 468
469 469 if filename.lower().endswith('.ipy'):
470 470 self.shell.safe_execfile_ipy(filename)
471 471 return
472 472
473 473 # Control the response to exit() calls made by the script being run
474 474 exit_ignore = 'e' in opts
475 475
476 476 # Make sure that the running script gets a proper sys.argv as if it
477 477 # were run from a system shell.
478 478 save_argv = sys.argv # save it for later restoring
479 479
480 480 # simulate shell expansion on arguments, at least tilde expansion
481 481 args = [ os.path.expanduser(a) for a in arg_lst[1:] ]
482 482
483 483 sys.argv = [filename] + args # put in the proper filename
484 484 # protect sys.argv from potential unicode strings on Python 2:
485 485 if not py3compat.PY3:
486 486 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
487 487
488 488 if 'i' in opts:
489 489 # Run in user's interactive namespace
490 490 prog_ns = self.shell.user_ns
491 491 __name__save = self.shell.user_ns['__name__']
492 492 prog_ns['__name__'] = '__main__'
493 493 main_mod = self.shell.new_main_mod(prog_ns)
494 494 else:
495 495 # Run in a fresh, empty namespace
496 496 if 'n' in opts:
497 497 name = os.path.splitext(os.path.basename(filename))[0]
498 498 else:
499 499 name = '__main__'
500 500
501 501 main_mod = self.shell.new_main_mod()
502 502 prog_ns = main_mod.__dict__
503 503 prog_ns['__name__'] = name
504 504
505 505 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
506 506 # set the __file__ global in the script's namespace
507 507 prog_ns['__file__'] = filename
508 508
509 509 # pickle fix. See interactiveshell for an explanation. But we need to
510 510 # make sure that, if we overwrite __main__, we replace it at the end
511 511 main_mod_name = prog_ns['__name__']
512 512
513 513 if main_mod_name == '__main__':
514 514 restore_main = sys.modules['__main__']
515 515 else:
516 516 restore_main = False
517 517
518 518 # This needs to be undone at the end to prevent holding references to
519 519 # every single object ever created.
520 520 sys.modules[main_mod_name] = main_mod
521 521
522 522 try:
523 523 stats = None
524 524 with self.shell.readline_no_record:
525 525 if 'p' in opts:
526 526 stats = self.prun('', None, False, opts, arg_lst, prog_ns)
527 527 else:
528 528 if 'd' in opts:
529 529 deb = debugger.Pdb(self.shell.colors)
530 530 # reset Breakpoint state, which is moronically kept
531 531 # in a class
532 532 bdb.Breakpoint.next = 1
533 533 bdb.Breakpoint.bplist = {}
534 534 bdb.Breakpoint.bpbynumber = [None]
535 535 # Set an initial breakpoint to stop execution
536 536 maxtries = 10
537 537 bp = int(opts.get('b', [1])[0])
538 538 checkline = deb.checkline(filename, bp)
539 539 if not checkline:
540 540 for bp in range(bp + 1, bp + maxtries + 1):
541 541 if deb.checkline(filename, bp):
542 542 break
543 543 else:
544 544 msg = ("\nI failed to find a valid line to set "
545 545 "a breakpoint\n"
546 546 "after trying up to line: %s.\n"
547 547 "Please set a valid breakpoint manually "
548 548 "with the -b option." % bp)
549 549 error(msg)
550 550 return
551 551 # if we find a good linenumber, set the breakpoint
552 552 deb.do_break('%s:%s' % (filename, bp))
553 553 # Start file run
554 554 print "NOTE: Enter 'c' at the",
555 555 print "%s prompt to start your script." % deb.prompt
556 556 ns = {'execfile': py3compat.execfile, 'prog_ns': prog_ns}
557 557 try:
558 558 deb.run('execfile("%s", prog_ns)' % filename, ns)
559 559
560 560 except:
561 561 etype, value, tb = sys.exc_info()
562 562 # Skip three frames in the traceback: the %run one,
563 563 # one inside bdb.py, and the command-line typed by the
564 564 # user (run by exec in pdb itself).
565 565 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
566 566 else:
567 567 if runner is None:
568 568 runner = self.default_runner
569 569 if runner is None:
570 570 runner = self.shell.safe_execfile
571 571 if 't' in opts:
572 572 # timed execution
573 573 try:
574 574 nruns = int(opts['N'][0])
575 575 if nruns < 1:
576 576 error('Number of runs must be >=1')
577 577 return
578 578 except (KeyError):
579 579 nruns = 1
580 580 twall0 = time.time()
581 581 if nruns == 1:
582 582 t0 = clock2()
583 583 runner(filename, prog_ns, prog_ns,
584 584 exit_ignore=exit_ignore)
585 585 t1 = clock2()
586 586 t_usr = t1[0] - t0[0]
587 587 t_sys = t1[1] - t0[1]
588 588 print "\nIPython CPU timings (estimated):"
589 589 print " User : %10.2f s." % t_usr
590 590 print " System : %10.2f s." % t_sys
591 591 else:
592 592 runs = range(nruns)
593 593 t0 = clock2()
594 594 for nr in runs:
595 595 runner(filename, prog_ns, prog_ns,
596 596 exit_ignore=exit_ignore)
597 597 t1 = clock2()
598 598 t_usr = t1[0] - t0[0]
599 599 t_sys = t1[1] - t0[1]
600 600 print "\nIPython CPU timings (estimated):"
601 601 print "Total runs performed:", nruns
602 602 print " Times : %10.2f %10.2f" % ('Total', 'Per run')
603 603 print " User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns)
604 604 print " System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns)
605 605 twall1 = time.time()
606 606 print "Wall time: %10.2f s." % (twall1 - twall0)
607 607
608 608 else:
609 609 # regular execution
610 610 runner(filename, prog_ns, prog_ns, exit_ignore=exit_ignore)
611 611
612 612 if 'i' in opts:
613 613 self.shell.user_ns['__name__'] = __name__save
614 614 else:
615 615 # The shell MUST hold a reference to prog_ns so after %run
616 616 # exits, the python deletion mechanism doesn't zero it out
617 617 # (leaving dangling references).
618 618 self.shell.cache_main_mod(prog_ns, filename)
619 619 # update IPython interactive namespace
620 620
621 621 # Some forms of read errors on the file may mean the
622 622 # __name__ key was never set; using pop we don't have to
623 623 # worry about a possible KeyError.
624 624 prog_ns.pop('__name__', None)
625 625
626 626 self.shell.user_ns.update(prog_ns)
627 627 finally:
628 628 # It's a bit of a mystery why, but __builtins__ can change from
629 629 # being a module to becoming a dict missing some key data after
630 630 # %run. As best I can see, this is NOT something IPython is doing
631 631 # at all, and similar problems have been reported before:
632 632 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
633 633 # Since this seems to be done by the interpreter itself, the best
634 634 # we can do is to at least restore __builtins__ for the user on
635 635 # exit.
636 636 self.shell.user_ns['__builtins__'] = builtin_mod
637 637
638 638 # Ensure key global structures are restored
639 639 sys.argv = save_argv
640 640 if restore_main:
641 641 sys.modules['__main__'] = restore_main
642 642 else:
643 643 # Remove from sys.modules the reference to main_mod we'd
644 644 # added. Otherwise it will trap references to objects
645 645 # contained therein.
646 646 del sys.modules[main_mod_name]
647 647
648 648 return stats
649 649
650 650 @skip_doctest
651 651 @line_cell_magic
652 652 def timeit(self, line='', cell=None):
653 653 """Time execution of a Python statement or expression
654 654
655 655 Usage, in line mode:
656 656 %timeit [-n<N> -r<R> [-t|-c]] statement
657 657 or in cell mode:
658 658 %%timeit [-n<N> -r<R> [-t|-c]] setup_code
659 659 code
660 660 code...
661 661
662 662 Time execution of a Python statement or expression using the timeit
663 663 module. This function can be used both as a line and cell magic:
664 664
665 665 - In line mode you can time a single-line statement (though multiple
666 666 ones can be chained with using semicolons).
667 667
668 668 - In cell mode, the statement in the first line is used as setup code
669 669 (executed but not timed) and the body of the cell is timed. The cell
670 670 body has access to any variables created in the setup code.
671 671
672 672 Options:
673 673 -n<N>: execute the given statement <N> times in a loop. If this value
674 674 is not given, a fitting value is chosen.
675 675
676 676 -r<R>: repeat the loop iteration <R> times and take the best result.
677 677 Default: 3
678 678
679 679 -t: use time.time to measure the time, which is the default on Unix.
680 680 This function measures wall time.
681 681
682 682 -c: use time.clock to measure the time, which is the default on
683 683 Windows and measures wall time. On Unix, resource.getrusage is used
684 684 instead and returns the CPU user time.
685 685
686 686 -p<P>: use a precision of <P> digits to display the timing result.
687 687 Default: 3
688 688
689 689
690 690 Examples
691 691 --------
692 692 ::
693 693
694 694 In [1]: %timeit pass
695 695 10000000 loops, best of 3: 53.3 ns per loop
696 696
697 697 In [2]: u = None
698 698
699 699 In [3]: %timeit u is None
700 700 10000000 loops, best of 3: 184 ns per loop
701 701
702 702 In [4]: %timeit -r 4 u == None
703 703 1000000 loops, best of 4: 242 ns per loop
704 704
705 705 In [5]: import time
706 706
707 707 In [6]: %timeit -n1 time.sleep(2)
708 708 1 loops, best of 3: 2 s per loop
709 709
710 710
711 711 The times reported by %timeit will be slightly higher than those
712 712 reported by the timeit.py script when variables are accessed. This is
713 713 due to the fact that %timeit executes the statement in the namespace
714 714 of the shell, compared with timeit.py, which uses a single setup
715 715 statement to import function or create variables. Generally, the bias
716 716 does not matter as long as results from timeit.py are not mixed with
717 717 those from %timeit."""
718 718
719 719 import timeit
720 720 import math
721 721
722 722 # XXX: Unfortunately the unicode 'micro' symbol can cause problems in
723 723 # certain terminals. Until we figure out a robust way of
724 724 # auto-detecting if the terminal can deal with it, use plain 'us' for
725 725 # microseconds. I am really NOT happy about disabling the proper
726 726 # 'micro' prefix, but crashing is worse... If anyone knows what the
727 727 # right solution for this is, I'm all ears...
728 728 #
729 729 # Note: using
730 730 #
731 731 # s = u'\xb5'
732 732 # s.encode(sys.getdefaultencoding())
733 733 #
734 734 # is not sufficient, as I've seen terminals where that fails but
735 735 # print s
736 736 #
737 737 # succeeds
738 738 #
739 739 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
740 740
741 741 #units = [u"s", u"ms",u'\xb5',"ns"]
742 742 units = [u"s", u"ms",u'us',"ns"]
743 743
744 744 scaling = [1, 1e3, 1e6, 1e9]
745 745
746 746 opts, stmt = self.parse_options(line,'n:r:tcp:',
747 747 posix=False, strict=False)
748 748 if stmt == "" and cell is None:
749 749 return
750 750 timefunc = timeit.default_timer
751 751 number = int(getattr(opts, "n", 0))
752 752 repeat = int(getattr(opts, "r", timeit.default_repeat))
753 753 precision = int(getattr(opts, "p", 3))
754 754 if hasattr(opts, "t"):
755 755 timefunc = time.time
756 756 if hasattr(opts, "c"):
757 757 timefunc = clock
758 758
759 759 timer = timeit.Timer(timer=timefunc)
760 760 # this code has tight coupling to the inner workings of timeit.Timer,
761 761 # but is there a better way to achieve that the code stmt has access
762 762 # to the shell namespace?
763 763 transform = self.shell.input_splitter.transform_cell
764 764
765 765 if cell is None:
766 766 # called as line magic
767 767 ast_setup = ast.parse("pass")
768 768 ast_stmt = ast.parse(transform(stmt))
769 769 else:
770 770 ast_setup = ast.parse(transform(stmt))
771 771 ast_stmt = ast.parse(transform(cell))
772 772
773 773 ast_setup = self.shell.transform_ast(ast_setup)
774 774 ast_stmt = self.shell.transform_ast(ast_stmt)
775 775
776 776 # This codestring is taken from timeit.template - we fill it in as an
777 777 # AST, so that we can apply our AST transformations to the user code
778 778 # without affecting the timing code.
779 779 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
780 780 ' setup\n'
781 781 ' _t0 = _timer()\n'
782 782 ' for _i in _it:\n'
783 783 ' stmt\n'
784 784 ' _t1 = _timer()\n'
785 785 ' return _t1 - _t0\n')
786 786
787 787 class TimeitTemplateFiller(ast.NodeTransformer):
788 788 "This is quite tightly tied to the template definition above."
789 789 def visit_FunctionDef(self, node):
790 790 "Fill in the setup statement"
791 791 self.generic_visit(node)
792 792 if node.name == "inner":
793 793 node.body[:1] = ast_setup.body
794 794
795 795 return node
796 796
797 797 def visit_For(self, node):
798 798 "Fill in the statement to be timed"
799 799 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
800 800 node.body = ast_stmt.body
801 801 return node
802 802
803 803 timeit_ast = TimeitTemplateFiller().visit(timeit_ast_template)
804 804 timeit_ast = ast.fix_missing_locations(timeit_ast)
805 805
806 806 # Track compilation time so it can be reported if too long
807 807 # Minimum time above which compilation time will be reported
808 808 tc_min = 0.1
809 809
810 810 t0 = clock()
811 811 code = compile(timeit_ast, "<magic-timeit>", "exec")
812 812 tc = clock()-t0
813 813
814 814 ns = {}
815 815 exec code in self.shell.user_ns, ns
816 816 timer.inner = ns["inner"]
817 817
818 818 if number == 0:
819 819 # determine number so that 0.2 <= total time < 2.0
820 820 number = 1
821 821 for i in range(1, 10):
822 822 if timer.timeit(number) >= 0.2:
823 823 break
824 824 number *= 10
825 825
826 826 best = min(timer.repeat(repeat, number)) / number
827 827
828 828 if best > 0.0 and best < 1000.0:
829 829 order = min(-int(math.floor(math.log10(best)) // 3), 3)
830 830 elif best >= 1000.0:
831 831 order = 0
832 832 else:
833 833 order = 3
834 834 print u"%d loops, best of %d: %.*g %s per loop" % (number, repeat,
835 835 precision,
836 836 best * scaling[order],
837 837 units[order])
838 838 if tc > tc_min:
839 839 print "Compiler time: %.2f s" % tc
840 840
841 841 @skip_doctest
842 842 @needs_local_scope
843 843 @line_magic
844 844 def time(self,parameter_s, user_locals):
845 845 """Time execution of a Python statement or expression.
846 846
847 847 The CPU and wall clock times are printed, and the value of the
848 848 expression (if any) is returned. Note that under Win32, system time
849 849 is always reported as 0, since it can not be measured.
850 850
851 851 This function provides very basic timing functionality. In Python
852 852 2.3, the timeit module offers more control and sophistication, so this
853 853 could be rewritten to use it (patches welcome).
854 854
855 855 Examples
856 856 --------
857 857 ::
858 858
859 859 In [1]: time 2**128
860 860 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
861 861 Wall time: 0.00
862 862 Out[1]: 340282366920938463463374607431768211456L
863 863
864 864 In [2]: n = 1000000
865 865
866 866 In [3]: time sum(range(n))
867 867 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
868 868 Wall time: 1.37
869 869 Out[3]: 499999500000L
870 870
871 871 In [4]: time print 'hello world'
872 872 hello world
873 873 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
874 874 Wall time: 0.00
875 875
876 876 Note that the time needed by Python to compile the given expression
877 877 will be reported if it is more than 0.1s. In this example, the
878 878 actual exponentiation is done by Python at compilation time, so while
879 879 the expression can take a noticeable amount of time to compute, that
880 880 time is purely due to the compilation:
881 881
882 882 In [5]: time 3**9999;
883 883 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
884 884 Wall time: 0.00 s
885 885
886 886 In [6]: time 3**999999;
887 887 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
888 888 Wall time: 0.00 s
889 889 Compiler : 0.78 s
890 890 """
891 891
892 892 # fail immediately if the given expression can't be compiled
893 893
894 894 expr = self.shell.prefilter(parameter_s,False)
895
896 # Minimum time above which parse time will be reported
897 tp_min = 0.1
898
899 t0 = clock()
900 expr_ast = ast.parse(expr)
901 tp = clock()-t0
902
903 # Apply AST transformations
904 expr_ast = self.shell.transform_ast(expr_ast)
895 905
896 906 # Minimum time above which compilation time will be reported
897 907 tc_min = 0.1
898 908
899 try:
909 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
900 910 mode = 'eval'
901 t0 = clock()
902 code = compile(expr,'<timed eval>',mode)
903 tc = clock()-t0
904 except SyntaxError:
911 source = '<timed eval>'
912 expr_ast = ast.Expression(expr_ast.body[0].value)
913 else:
905 914 mode = 'exec'
906 t0 = clock()
907 code = compile(expr,'<timed exec>',mode)
908 tc = clock()-t0
915 source = '<timed exec>'
916 t0 = clock()
917 code = compile(expr_ast, source, mode)
918 tc = clock()-t0
919
909 920 # skew measurement as little as possible
910 921 glob = self.shell.user_ns
911 922 wtime = time.time
912 923 # time execution
913 924 wall_st = wtime()
914 925 if mode=='eval':
915 926 st = clock2()
916 927 out = eval(code, glob, user_locals)
917 928 end = clock2()
918 929 else:
919 930 st = clock2()
920 931 exec code in glob, user_locals
921 932 end = clock2()
922 933 out = None
923 934 wall_end = wtime()
924 935 # Compute actual times and report
925 936 wall_time = wall_end-wall_st
926 937 cpu_user = end[0]-st[0]
927 938 cpu_sys = end[1]-st[1]
928 939 cpu_tot = cpu_user+cpu_sys
929 940 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
930 941 (cpu_user,cpu_sys,cpu_tot)
931 942 print "Wall time: %.2f s" % wall_time
932 943 if tc > tc_min:
933 944 print "Compiler : %.2f s" % tc
945 if tp > tp_min:
946 print "Parser : %.2f s" % tp
934 947 return out
935 948
936 949 @skip_doctest
937 950 @line_magic
938 951 def macro(self, parameter_s=''):
939 952 """Define a macro for future re-execution. It accepts ranges of history,
940 953 filenames or string objects.
941 954
942 955 Usage:\\
943 956 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
944 957
945 958 Options:
946 959
947 960 -r: use 'raw' input. By default, the 'processed' history is used,
948 961 so that magics are loaded in their transformed version to valid
949 962 Python. If this option is given, the raw input as typed as the
950 963 command line is used instead.
951 964
952 965 This will define a global variable called `name` which is a string
953 966 made of joining the slices and lines you specify (n1,n2,... numbers
954 967 above) from your input history into a single string. This variable
955 968 acts like an automatic function which re-executes those lines as if
956 969 you had typed them. You just type 'name' at the prompt and the code
957 970 executes.
958 971
959 972 The syntax for indicating input ranges is described in %history.
960 973
961 974 Note: as a 'hidden' feature, you can also use traditional python slice
962 975 notation, where N:M means numbers N through M-1.
963 976
964 977 For example, if your history contains (%hist prints it)::
965 978
966 979 44: x=1
967 980 45: y=3
968 981 46: z=x+y
969 982 47: print x
970 983 48: a=5
971 984 49: print 'x',x,'y',y
972 985
973 986 you can create a macro with lines 44 through 47 (included) and line 49
974 987 called my_macro with::
975 988
976 989 In [55]: %macro my_macro 44-47 49
977 990
978 991 Now, typing `my_macro` (without quotes) will re-execute all this code
979 992 in one pass.
980 993
981 994 You don't need to give the line-numbers in order, and any given line
982 995 number can appear multiple times. You can assemble macros with any
983 996 lines from your input history in any order.
984 997
985 998 The macro is a simple object which holds its value in an attribute,
986 999 but IPython's display system checks for macros and executes them as
987 1000 code instead of printing them when you type their name.
988 1001
989 1002 You can view a macro's contents by explicitly printing it with::
990 1003
991 1004 print macro_name
992 1005
993 1006 """
994 1007 opts,args = self.parse_options(parameter_s,'r',mode='list')
995 1008 if not args: # List existing macros
996 1009 return sorted(k for k,v in self.shell.user_ns.iteritems() if\
997 1010 isinstance(v, Macro))
998 1011 if len(args) == 1:
999 1012 raise UsageError(
1000 1013 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1001 1014 name, codefrom = args[0], " ".join(args[1:])
1002 1015
1003 1016 #print 'rng',ranges # dbg
1004 1017 try:
1005 1018 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1006 1019 except (ValueError, TypeError) as e:
1007 1020 print e.args[0]
1008 1021 return
1009 1022 macro = Macro(lines)
1010 1023 self.shell.define_macro(name, macro)
1011 1024 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
1012 1025 print '=== Macro contents: ==='
1013 1026 print macro,
1014 1027
1015 1028 @magic_arguments.magic_arguments()
1016 1029 @magic_arguments.argument('output', type=str, default='', nargs='?',
1017 1030 help="""The name of the variable in which to store output.
1018 1031 This is a utils.io.CapturedIO object with stdout/err attributes
1019 1032 for the text of the captured output.
1020 1033
1021 1034 CapturedOutput also has a show() method for displaying the output,
1022 1035 and __call__ as well, so you can use that to quickly display the
1023 1036 output.
1024 1037
1025 1038 If unspecified, captured output is discarded.
1026 1039 """
1027 1040 )
1028 1041 @magic_arguments.argument('--no-stderr', action="store_true",
1029 1042 help="""Don't capture stderr."""
1030 1043 )
1031 1044 @magic_arguments.argument('--no-stdout', action="store_true",
1032 1045 help="""Don't capture stdout."""
1033 1046 )
1034 1047 @cell_magic
1035 1048 def capture(self, line, cell):
1036 1049 """run the cell, capturing stdout/err"""
1037 1050 args = magic_arguments.parse_argstring(self.capture, line)
1038 1051 out = not args.no_stdout
1039 1052 err = not args.no_stderr
1040 1053 with capture_output(out, err) as io:
1041 1054 self.shell.run_cell(cell)
1042 1055 if args.output:
1043 1056 self.shell.user_ns[args.output] = io
@@ -1,515 +1,532 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for the key interactiveshell module.
3 3
4 4 Historically the main classes in interactiveshell have been under-tested. This
5 5 module should grow as many single-method tests as possible to trap many of the
6 6 recurring bugs we seem to encounter with high-level interaction.
7 7
8 8 Authors
9 9 -------
10 10 * Fernando Perez
11 11 """
12 12 #-----------------------------------------------------------------------------
13 13 # Copyright (C) 2011 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22 # stdlib
23 23 import ast
24 24 import os
25 25 import shutil
26 26 import sys
27 27 import tempfile
28 28 import unittest
29 29 from os.path import join
30 30 from StringIO import StringIO
31 31
32 32 # third-party
33 33 import nose.tools as nt
34 34
35 35 # Our own
36 36 from IPython.testing.decorators import skipif
37 37 from IPython.testing import tools as tt
38 38 from IPython.utils import io
39 39
40 40 #-----------------------------------------------------------------------------
41 41 # Globals
42 42 #-----------------------------------------------------------------------------
43 43 # This is used by every single test, no point repeating it ad nauseam
44 44 ip = get_ipython()
45 45
46 46 #-----------------------------------------------------------------------------
47 47 # Tests
48 48 #-----------------------------------------------------------------------------
49 49
50 50 class InteractiveShellTestCase(unittest.TestCase):
51 51 def test_naked_string_cells(self):
52 52 """Test that cells with only naked strings are fully executed"""
53 53 # First, single-line inputs
54 54 ip.run_cell('"a"\n')
55 55 self.assertEqual(ip.user_ns['_'], 'a')
56 56 # And also multi-line cells
57 57 ip.run_cell('"""a\nb"""\n')
58 58 self.assertEqual(ip.user_ns['_'], 'a\nb')
59 59
60 60 def test_run_empty_cell(self):
61 61 """Just make sure we don't get a horrible error with a blank
62 62 cell of input. Yes, I did overlook that."""
63 63 old_xc = ip.execution_count
64 64 ip.run_cell('')
65 65 self.assertEqual(ip.execution_count, old_xc)
66 66
67 67 def test_run_cell_multiline(self):
68 68 """Multi-block, multi-line cells must execute correctly.
69 69 """
70 70 src = '\n'.join(["x=1",
71 71 "y=2",
72 72 "if 1:",
73 73 " x += 1",
74 74 " y += 1",])
75 75 ip.run_cell(src)
76 76 self.assertEqual(ip.user_ns['x'], 2)
77 77 self.assertEqual(ip.user_ns['y'], 3)
78 78
79 79 def test_multiline_string_cells(self):
80 80 "Code sprinkled with multiline strings should execute (GH-306)"
81 81 ip.run_cell('tmp=0')
82 82 self.assertEqual(ip.user_ns['tmp'], 0)
83 83 ip.run_cell('tmp=1;"""a\nb"""\n')
84 84 self.assertEqual(ip.user_ns['tmp'], 1)
85 85
86 86 def test_dont_cache_with_semicolon(self):
87 87 "Ending a line with semicolon should not cache the returned object (GH-307)"
88 88 oldlen = len(ip.user_ns['Out'])
89 89 a = ip.run_cell('1;', store_history=True)
90 90 newlen = len(ip.user_ns['Out'])
91 91 self.assertEqual(oldlen, newlen)
92 92 #also test the default caching behavior
93 93 ip.run_cell('1', store_history=True)
94 94 newlen = len(ip.user_ns['Out'])
95 95 self.assertEqual(oldlen+1, newlen)
96 96
97 97 def test_In_variable(self):
98 98 "Verify that In variable grows with user input (GH-284)"
99 99 oldlen = len(ip.user_ns['In'])
100 100 ip.run_cell('1;', store_history=True)
101 101 newlen = len(ip.user_ns['In'])
102 102 self.assertEqual(oldlen+1, newlen)
103 103 self.assertEqual(ip.user_ns['In'][-1],'1;')
104 104
105 105 def test_magic_names_in_string(self):
106 106 ip.run_cell('a = """\n%exit\n"""')
107 107 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
108 108
109 109 def test_alias_crash(self):
110 110 """Errors in prefilter can't crash IPython"""
111 111 ip.run_cell('%alias parts echo first %s second %s')
112 112 # capture stderr:
113 113 save_err = io.stderr
114 114 io.stderr = StringIO()
115 115 ip.run_cell('parts 1')
116 116 err = io.stderr.getvalue()
117 117 io.stderr = save_err
118 118 self.assertEqual(err.split(':')[0], 'ERROR')
119 119
120 120 def test_trailing_newline(self):
121 121 """test that running !(command) does not raise a SyntaxError"""
122 122 ip.run_cell('!(true)\n', False)
123 123 ip.run_cell('!(true)\n\n\n', False)
124 124
125 125 def test_gh_597(self):
126 126 """Pretty-printing lists of objects with non-ascii reprs may cause
127 127 problems."""
128 128 class Spam(object):
129 129 def __repr__(self):
130 130 return "\xe9"*50
131 131 import IPython.core.formatters
132 132 f = IPython.core.formatters.PlainTextFormatter()
133 133 f([Spam(),Spam()])
134 134
135 135
136 136 def test_future_flags(self):
137 137 """Check that future flags are used for parsing code (gh-777)"""
138 138 ip.run_cell('from __future__ import print_function')
139 139 try:
140 140 ip.run_cell('prfunc_return_val = print(1,2, sep=" ")')
141 141 assert 'prfunc_return_val' in ip.user_ns
142 142 finally:
143 143 # Reset compiler flags so we don't mess up other tests.
144 144 ip.compile.reset_compiler_flags()
145 145
146 146 def test_future_unicode(self):
147 147 """Check that unicode_literals is imported from __future__ (gh #786)"""
148 148 try:
149 149 ip.run_cell(u'byte_str = "a"')
150 150 assert isinstance(ip.user_ns['byte_str'], str) # string literals are byte strings by default
151 151 ip.run_cell('from __future__ import unicode_literals')
152 152 ip.run_cell(u'unicode_str = "a"')
153 153 assert isinstance(ip.user_ns['unicode_str'], unicode) # strings literals are now unicode
154 154 finally:
155 155 # Reset compiler flags so we don't mess up other tests.
156 156 ip.compile.reset_compiler_flags()
157 157
158 158 def test_can_pickle(self):
159 159 "Can we pickle objects defined interactively (GH-29)"
160 160 ip = get_ipython()
161 161 ip.reset()
162 162 ip.run_cell(("class Mylist(list):\n"
163 163 " def __init__(self,x=[]):\n"
164 164 " list.__init__(self,x)"))
165 165 ip.run_cell("w=Mylist([1,2,3])")
166 166
167 167 from cPickle import dumps
168 168
169 169 # We need to swap in our main module - this is only necessary
170 170 # inside the test framework, because IPython puts the interactive module
171 171 # in place (but the test framework undoes this).
172 172 _main = sys.modules['__main__']
173 173 sys.modules['__main__'] = ip.user_module
174 174 try:
175 175 res = dumps(ip.user_ns["w"])
176 176 finally:
177 177 sys.modules['__main__'] = _main
178 178 self.assertTrue(isinstance(res, bytes))
179 179
180 180 def test_global_ns(self):
181 181 "Code in functions must be able to access variables outside them."
182 182 ip = get_ipython()
183 183 ip.run_cell("a = 10")
184 184 ip.run_cell(("def f(x):\n"
185 185 " return x + a"))
186 186 ip.run_cell("b = f(12)")
187 187 self.assertEqual(ip.user_ns["b"], 22)
188 188
189 189 def test_bad_custom_tb(self):
190 190 """Check that InteractiveShell is protected from bad custom exception handlers"""
191 191 from IPython.utils import io
192 192 save_stderr = io.stderr
193 193 try:
194 194 # capture stderr
195 195 io.stderr = StringIO()
196 196 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
197 197 self.assertEqual(ip.custom_exceptions, (IOError,))
198 198 ip.run_cell(u'raise IOError("foo")')
199 199 self.assertEqual(ip.custom_exceptions, ())
200 200 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
201 201 finally:
202 202 io.stderr = save_stderr
203 203
204 204 def test_bad_custom_tb_return(self):
205 205 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
206 206 from IPython.utils import io
207 207 save_stderr = io.stderr
208 208 try:
209 209 # capture stderr
210 210 io.stderr = StringIO()
211 211 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
212 212 self.assertEqual(ip.custom_exceptions, (NameError,))
213 213 ip.run_cell(u'a=abracadabra')
214 214 self.assertEqual(ip.custom_exceptions, ())
215 215 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
216 216 finally:
217 217 io.stderr = save_stderr
218 218
219 219 def test_drop_by_id(self):
220 220 myvars = {"a":object(), "b":object(), "c": object()}
221 221 ip.push(myvars, interactive=False)
222 222 for name in myvars:
223 223 assert name in ip.user_ns, name
224 224 assert name in ip.user_ns_hidden, name
225 225 ip.user_ns['b'] = 12
226 226 ip.drop_by_id(myvars)
227 227 for name in ["a", "c"]:
228 228 assert name not in ip.user_ns, name
229 229 assert name not in ip.user_ns_hidden, name
230 230 assert ip.user_ns['b'] == 12
231 231 ip.reset()
232 232
233 233 def test_var_expand(self):
234 234 ip.user_ns['f'] = u'Ca\xf1o'
235 235 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
236 236 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
237 237 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
238 238 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
239 239
240 240 ip.user_ns['f'] = b'Ca\xc3\xb1o'
241 241 # This should not raise any exception:
242 242 ip.var_expand(u'echo $f')
243 243
244 244 def test_var_expand_local(self):
245 245 """Test local variable expansion in !system and %magic calls"""
246 246 # !system
247 247 ip.run_cell('def test():\n'
248 248 ' lvar = "ttt"\n'
249 249 ' ret = !echo {lvar}\n'
250 250 ' return ret[0]\n')
251 251 res = ip.user_ns['test']()
252 252 nt.assert_in('ttt', res)
253 253
254 254 # %magic
255 255 ip.run_cell('def makemacro():\n'
256 256 ' macroname = "macro_var_expand_locals"\n'
257 257 ' %macro {macroname} codestr\n')
258 258 ip.user_ns['codestr'] = "str(12)"
259 259 ip.run_cell('makemacro()')
260 260 nt.assert_in('macro_var_expand_locals', ip.user_ns)
261 261
262 262 def test_bad_var_expand(self):
263 263 """var_expand on invalid formats shouldn't raise"""
264 264 # SyntaxError
265 265 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
266 266 # NameError
267 267 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
268 268 # ZeroDivisionError
269 269 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
270 270
271 271 def test_silent_nopostexec(self):
272 272 """run_cell(silent=True) doesn't invoke post-exec funcs"""
273 273 d = dict(called=False)
274 274 def set_called():
275 275 d['called'] = True
276 276
277 277 ip.register_post_execute(set_called)
278 278 ip.run_cell("1", silent=True)
279 279 self.assertFalse(d['called'])
280 280 # double-check that non-silent exec did what we expected
281 281 # silent to avoid
282 282 ip.run_cell("1")
283 283 self.assertTrue(d['called'])
284 284 # remove post-exec
285 285 ip._post_execute.pop(set_called)
286 286
287 287 def test_silent_noadvance(self):
288 288 """run_cell(silent=True) doesn't advance execution_count"""
289 289 ec = ip.execution_count
290 290 # silent should force store_history=False
291 291 ip.run_cell("1", store_history=True, silent=True)
292 292
293 293 self.assertEqual(ec, ip.execution_count)
294 294 # double-check that non-silent exec did what we expected
295 295 # silent to avoid
296 296 ip.run_cell("1", store_history=True)
297 297 self.assertEqual(ec+1, ip.execution_count)
298 298
299 299 def test_silent_nodisplayhook(self):
300 300 """run_cell(silent=True) doesn't trigger displayhook"""
301 301 d = dict(called=False)
302 302
303 303 trap = ip.display_trap
304 304 save_hook = trap.hook
305 305
306 306 def failing_hook(*args, **kwargs):
307 307 d['called'] = True
308 308
309 309 try:
310 310 trap.hook = failing_hook
311 311 ip.run_cell("1", silent=True)
312 312 self.assertFalse(d['called'])
313 313 # double-check that non-silent exec did what we expected
314 314 # silent to avoid
315 315 ip.run_cell("1")
316 316 self.assertTrue(d['called'])
317 317 finally:
318 318 trap.hook = save_hook
319 319
320 320 @skipif(sys.version_info[0] >= 3, "softspace removed in py3")
321 321 def test_print_softspace(self):
322 322 """Verify that softspace is handled correctly when executing multiple
323 323 statements.
324 324
325 325 In [1]: print 1; print 2
326 326 1
327 327 2
328 328
329 329 In [2]: print 1,; print 2
330 330 1 2
331 331 """
332 332
333 333 def test_ofind_line_magic(self):
334 334 from IPython.core.magic import register_line_magic
335 335
336 336 @register_line_magic
337 337 def lmagic(line):
338 338 "A line magic"
339 339
340 340 # Get info on line magic
341 341 lfind = ip._ofind('lmagic')
342 342 info = dict(found=True, isalias=False, ismagic=True,
343 343 namespace = 'IPython internal', obj= lmagic.__wrapped__,
344 344 parent = None)
345 345 nt.assert_equal(lfind, info)
346 346
347 347 def test_ofind_cell_magic(self):
348 348 from IPython.core.magic import register_cell_magic
349 349
350 350 @register_cell_magic
351 351 def cmagic(line, cell):
352 352 "A cell magic"
353 353
354 354 # Get info on cell magic
355 355 find = ip._ofind('cmagic')
356 356 info = dict(found=True, isalias=False, ismagic=True,
357 357 namespace = 'IPython internal', obj= cmagic.__wrapped__,
358 358 parent = None)
359 359 nt.assert_equal(find, info)
360 360
361 361 def test_custom_exception(self):
362 362 called = []
363 363 def my_handler(shell, etype, value, tb, tb_offset=None):
364 364 called.append(etype)
365 365 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
366 366
367 367 ip.set_custom_exc((ValueError,), my_handler)
368 368 try:
369 369 ip.run_cell("raise ValueError('test')")
370 370 # Check that this was called, and only once.
371 371 self.assertEqual(called, [ValueError])
372 372 finally:
373 373 # Reset the custom exception hook
374 374 ip.set_custom_exc((), None)
375 375
376 376
377 377 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
378 378
379 379 def setUp(self):
380 380 self.BASETESTDIR = tempfile.mkdtemp()
381 381 self.TESTDIR = join(self.BASETESTDIR, u"Γ₯Àâ")
382 382 os.mkdir(self.TESTDIR)
383 383 with open(join(self.TESTDIR, u"Γ₯Àâtestscript.py"), "w") as sfile:
384 384 sfile.write("pass\n")
385 385 self.oldpath = os.getcwdu()
386 386 os.chdir(self.TESTDIR)
387 387 self.fname = u"Γ₯Àâtestscript.py"
388 388
389 389 def tearDown(self):
390 390 os.chdir(self.oldpath)
391 391 shutil.rmtree(self.BASETESTDIR)
392 392
393 393 def test_1(self):
394 394 """Test safe_execfile with non-ascii path
395 395 """
396 396 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
397 397
398 398
399 399 class TestSystemRaw(unittest.TestCase):
400 400 def test_1(self):
401 401 """Test system_raw with non-ascii cmd
402 402 """
403 403 cmd = ur'''python -c "'Γ₯Àâ'" '''
404 404 ip.system_raw(cmd)
405 405
406 406 class TestModules(unittest.TestCase, tt.TempFileMixin):
407 407 def test_extraneous_loads(self):
408 408 """Test we're not loading modules on startup that we shouldn't.
409 409 """
410 410 self.mktmp("import sys\n"
411 411 "print('numpy' in sys.modules)\n"
412 412 "print('IPython.parallel' in sys.modules)\n"
413 413 "print('IPython.zmq' in sys.modules)\n"
414 414 )
415 415 out = "False\nFalse\nFalse\n"
416 416 tt.ipexec_validate(self.fname, out)
417 417
418 418 class Negator(ast.NodeTransformer):
419 419 """Negates all number literals in an AST."""
420 420 def visit_Num(self, node):
421 421 node.n = -node.n
422 422 return node
423 423
424 424 class TestAstTransform(unittest.TestCase):
425 425 def setUp(self):
426 426 self.negator = Negator()
427 427 ip.ast_transformers.append(self.negator)
428 428
429 429 def tearDown(self):
430 430 ip.ast_transformers.remove(self.negator)
431 431
432 432 def test_run_cell(self):
433 433 with tt.AssertPrints('-34'):
434 434 ip.run_cell('print (12 + 22)')
435 435
436 436 # A named reference to a number shouldn't be transformed.
437 437 ip.user_ns['n'] = 55
438 438 with tt.AssertNotPrints('-55'):
439 439 ip.run_cell('print (n)')
440 440
441 441 def test_timeit(self):
442 442 called = set()
443 443 def f(x):
444 444 called.add(x)
445 445 ip.push({'f':f})
446 446
447 447 with tt.AssertPrints("best of "):
448 448 ip.run_line_magic("timeit", "-n1 f(1)")
449 449 self.assertEqual(called, set([-1]))
450 450 called.clear()
451 451
452 452 with tt.AssertPrints("best of "):
453 453 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
454 454 self.assertEqual(called, set([-2, -3]))
455
456 def test_time(self):
457 called = []
458 def f(x):
459 called.append(x)
460 ip.push({'f':f})
461
462 # Test with an expression
463 with tt.AssertPrints("CPU times"):
464 ip.run_line_magic("time", "f(5+9)")
465 self.assertEqual(called, [-14])
466 called[:] = []
467
468 # Test with a statement (different code path)
469 with tt.AssertPrints("CPU times"):
470 ip.run_line_magic("time", "a = f(-3 + -2)")
471 self.assertEqual(called, [5])
455 472
456 473 class IntegerWrapper(ast.NodeTransformer):
457 474 """Wraps all integers in a call to Integer()"""
458 475 def visit_Num(self, node):
459 476 if isinstance(node.n, int):
460 477 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
461 478 args=[node], keywords=[])
462 479
463 480 class TestAstTransform2(unittest.TestCase):
464 481 def setUp(self):
465 482 self.intwrapper = IntegerWrapper()
466 483 ip.ast_transformers.append(self.intwrapper)
467 484
468 485 self.calls = []
469 486 def Integer(*args):
470 487 self.calls.append(args)
471 488 return args
472 489 ip.push({"Integer": Integer})
473 490
474 491 def tearDown(self):
475 492 ip.ast_transformers.remove(self.intwrapper)
476 493 del ip.user_ns['Integer']
477 494
478 495 def test_run_cell(self):
479 496 ip.run_cell("n = 2")
480 497 self.assertEqual(self.calls, [(2,)])
481 498
482 499 def test_timeit(self):
483 500 called = set()
484 501 def f(x):
485 502 called.add(x)
486 503 ip.push({'f':f})
487 504
488 505 with tt.AssertPrints("best of "):
489 506 ip.run_line_magic("timeit", "-n1 f(1)")
490 507 self.assertEqual(called, set([(1,)]))
491 508 called.clear()
492 509
493 510 with tt.AssertPrints("best of "):
494 511 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
495 512 self.assertEqual(called, set([(2,), (3,)]))
496 513
497 514 class ErrorTransformer(ast.NodeTransformer):
498 515 """Throws an error when it sees a number."""
499 516 def visit_Num(self):
500 517 raise ValueError("test")
501 518
502 519 class TestAstTransformError(unittest.TestCase):
503 520 def test_unregistering(self):
504 521 err_transformer = ErrorTransformer()
505 522 ip.ast_transformers.append(err_transformer)
506 523
507 524 with tt.AssertPrints("unregister", channel='stderr'):
508 525 ip.run_cell("1 + 2")
509 526
510 527 # This should have been removed.
511 528 nt.assert_not_in(err_transformer, ip.ast_transformers)
512 529
513 530 def test__IPYTHON__():
514 531 # This shouldn't raise a NameError, that's all
515 532 __IPYTHON__
General Comments 0
You need to be logged in to leave comments. Login now