##// END OF EJS Templates
Merge pull request #2855 from JanSchulz/2751_timit...
Thomas Kluyver -
r9483:50cb32f8 merge
parent child Browse files
Show More
@@ -1,1094 +1,1116 b''
1 # -*- coding: utf-8 -*-
1 2 """Implementation of execution-related magic functions.
2 3 """
3 4 #-----------------------------------------------------------------------------
4 5 # Copyright (c) 2012 The IPython Development Team.
5 6 #
6 7 # Distributed under the terms of the Modified BSD License.
7 8 #
8 9 # The full license is in the file COPYING.txt, distributed with this software.
9 10 #-----------------------------------------------------------------------------
10 11
11 12 #-----------------------------------------------------------------------------
12 13 # Imports
13 14 #-----------------------------------------------------------------------------
14 15
15 16 # Stdlib
16 17 import __builtin__ as builtin_mod
17 18 import ast
18 19 import bdb
19 20 import os
20 21 import sys
21 22 import time
22 23 from StringIO import StringIO
23 24
24 25 # cProfile was added in Python2.5
25 26 try:
26 27 import cProfile as profile
27 28 import pstats
28 29 except ImportError:
29 30 # profile isn't bundled by default in Debian for license reasons
30 31 try:
31 32 import profile, pstats
32 33 except ImportError:
33 34 profile = pstats = None
34 35
35 36 # Our own packages
36 37 from IPython.core import debugger, oinspect
37 38 from IPython.core import magic_arguments
38 39 from IPython.core import page
39 40 from IPython.core.error import UsageError
40 41 from IPython.core.macro import Macro
41 42 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
42 43 line_cell_magic, on_off, needs_local_scope)
43 44 from IPython.testing.skipdoctest import skip_doctest
44 45 from IPython.utils import py3compat
45 46 from IPython.utils.contexts import preserve_keys
46 47 from IPython.utils.io import capture_output
47 48 from IPython.utils.ipstruct import Struct
48 49 from IPython.utils.module_paths import find_mod
49 50 from IPython.utils.path import get_py_filename, unquote_filename, shellglob
50 51 from IPython.utils.timing import clock, clock2
51 52 from IPython.utils.warn import warn, error
52 53
53 54
54 55 #-----------------------------------------------------------------------------
55 56 # Magic implementation classes
56 57 #-----------------------------------------------------------------------------
57 58
58 59 @magics_class
59 60 class ExecutionMagics(Magics):
60 61 """Magics related to code execution, debugging, profiling, etc.
61 62
62 63 """
63 64
64 65 def __init__(self, shell):
65 66 super(ExecutionMagics, self).__init__(shell)
66 67 if profile is None:
67 68 self.prun = self.profile_missing_notice
68 69 # Default execution function used to actually run user code.
69 70 self.default_runner = None
70 71
71 72 def profile_missing_notice(self, *args, **kwargs):
72 73 error("""\
73 74 The profile module could not be found. It has been removed from the standard
74 75 python packages because of its non-free license. To use profiling, install the
75 76 python-profiler package from non-free.""")
76 77
77 78 @skip_doctest
78 79 @line_cell_magic
79 80 def prun(self, parameter_s='', cell=None, user_mode=True,
80 81 opts=None,arg_lst=None,prog_ns=None):
81 82
82 83 """Run a statement through the python code profiler.
83 84
84 85 Usage, in line mode:
85 86 %prun [options] statement
86 87
87 88 Usage, in cell mode:
88 89 %%prun [options] [statement]
89 90 code...
90 91 code...
91 92
92 93 In cell mode, the additional code lines are appended to the (possibly
93 94 empty) statement in the first line. Cell mode allows you to easily
94 95 profile multiline blocks without having to put them in a separate
95 96 function.
96 97
97 98 The given statement (which doesn't require quote marks) is run via the
98 99 python profiler in a manner similar to the profile.run() function.
99 100 Namespaces are internally managed to work correctly; profile.run
100 101 cannot be used in IPython because it makes certain assumptions about
101 102 namespaces which do not hold under IPython.
102 103
103 104 Options:
104 105
105 106 -l <limit>: you can place restrictions on what or how much of the
106 107 profile gets printed. The limit value can be:
107 108
108 109 * A string: only information for function names containing this string
109 110 is printed.
110 111
111 112 * An integer: only these many lines are printed.
112 113
113 114 * A float (between 0 and 1): this fraction of the report is printed
114 115 (for example, use a limit of 0.4 to see the topmost 40% only).
115 116
116 117 You can combine several limits with repeated use of the option. For
117 118 example, '-l __init__ -l 5' will print only the topmost 5 lines of
118 119 information about class constructors.
119 120
120 121 -r: return the pstats.Stats object generated by the profiling. This
121 122 object has all the information about the profile in it, and you can
122 123 later use it for further analysis or in other functions.
123 124
124 125 -s <key>: sort profile by given key. You can provide more than one key
125 126 by using the option several times: '-s key1 -s key2 -s key3...'. The
126 127 default sorting key is 'time'.
127 128
128 129 The following is copied verbatim from the profile documentation
129 130 referenced below:
130 131
131 132 When more than one key is provided, additional keys are used as
132 133 secondary criteria when the there is equality in all keys selected
133 134 before them.
134 135
135 136 Abbreviations can be used for any key names, as long as the
136 137 abbreviation is unambiguous. The following are the keys currently
137 138 defined:
138 139
139 140 Valid Arg Meaning
140 141 "calls" call count
141 142 "cumulative" cumulative time
142 143 "file" file name
143 144 "module" file name
144 145 "pcalls" primitive call count
145 146 "line" line number
146 147 "name" function name
147 148 "nfl" name/file/line
148 149 "stdname" standard name
149 150 "time" internal time
150 151
151 152 Note that all sorts on statistics are in descending order (placing
152 153 most time consuming items first), where as name, file, and line number
153 154 searches are in ascending order (i.e., alphabetical). The subtle
154 155 distinction between "nfl" and "stdname" is that the standard name is a
155 156 sort of the name as printed, which means that the embedded line
156 157 numbers get compared in an odd way. For example, lines 3, 20, and 40
157 158 would (if the file names were the same) appear in the string order
158 159 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
159 160 line numbers. In fact, sort_stats("nfl") is the same as
160 161 sort_stats("name", "file", "line").
161 162
162 163 -T <filename>: save profile results as shown on screen to a text
163 164 file. The profile is still shown on screen.
164 165
165 166 -D <filename>: save (via dump_stats) profile statistics to given
166 167 filename. This data is in a format understood by the pstats module, and
167 168 is generated by a call to the dump_stats() method of profile
168 169 objects. The profile is still shown on screen.
169 170
170 171 -q: suppress output to the pager. Best used with -T and/or -D above.
171 172
172 173 If you want to run complete programs under the profiler's control, use
173 174 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
174 175 contains profiler specific options as described here.
175 176
176 177 You can read the complete documentation for the profile module with::
177 178
178 179 In [1]: import profile; profile.help()
179 180 """
180 181
181 182 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
182 183
183 184 if user_mode: # regular user call
184 185 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:q',
185 186 list_all=True, posix=False)
186 187 namespace = self.shell.user_ns
187 188 if cell is not None:
188 189 arg_str += '\n' + cell
189 190 else: # called to run a program by %run -p
190 191 try:
191 192 filename = get_py_filename(arg_lst[0])
192 193 except IOError as e:
193 194 try:
194 195 msg = str(e)
195 196 except UnicodeError:
196 197 msg = e.message
197 198 error(msg)
198 199 return
199 200
200 201 arg_str = 'execfile(filename,prog_ns)'
201 202 namespace = {
202 203 'execfile': self.shell.safe_execfile,
203 204 'prog_ns': prog_ns,
204 205 'filename': filename
205 206 }
206 207
207 208 opts.merge(opts_def)
208 209
209 210 prof = profile.Profile()
210 211 try:
211 212 prof = prof.runctx(arg_str,namespace,namespace)
212 213 sys_exit = ''
213 214 except SystemExit:
214 215 sys_exit = """*** SystemExit exception caught in code being profiled."""
215 216
216 217 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
217 218
218 219 lims = opts.l
219 220 if lims:
220 221 lims = [] # rebuild lims with ints/floats/strings
221 222 for lim in opts.l:
222 223 try:
223 224 lims.append(int(lim))
224 225 except ValueError:
225 226 try:
226 227 lims.append(float(lim))
227 228 except ValueError:
228 229 lims.append(lim)
229 230
230 231 # Trap output.
231 232 stdout_trap = StringIO()
232 233 stats_stream = stats.stream
233 234 try:
234 235 stats.stream = stdout_trap
235 236 stats.print_stats(*lims)
236 237 finally:
237 238 stats.stream = stats_stream
238 239
239 240 output = stdout_trap.getvalue()
240 241 output = output.rstrip()
241 242
242 243 if 'q' not in opts:
243 244 page.page(output)
244 245 print sys_exit,
245 246
246 247 dump_file = opts.D[0]
247 248 text_file = opts.T[0]
248 249 if dump_file:
249 250 dump_file = unquote_filename(dump_file)
250 251 prof.dump_stats(dump_file)
251 252 print '\n*** Profile stats marshalled to file',\
252 253 repr(dump_file)+'.',sys_exit
253 254 if text_file:
254 255 text_file = unquote_filename(text_file)
255 256 pfile = open(text_file,'w')
256 257 pfile.write(output)
257 258 pfile.close()
258 259 print '\n*** Profile printout saved to text file',\
259 260 repr(text_file)+'.',sys_exit
260 261
261 262 if 'r' in opts:
262 263 return stats
263 264 else:
264 265 return None
265 266
266 267 @line_magic
267 268 def pdb(self, parameter_s=''):
268 269 """Control the automatic calling of the pdb interactive debugger.
269 270
270 271 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
271 272 argument it works as a toggle.
272 273
273 274 When an exception is triggered, IPython can optionally call the
274 275 interactive pdb debugger after the traceback printout. %pdb toggles
275 276 this feature on and off.
276 277
277 278 The initial state of this feature is set in your configuration
278 279 file (the option is ``InteractiveShell.pdb``).
279 280
280 281 If you want to just activate the debugger AFTER an exception has fired,
281 282 without having to type '%pdb on' and rerunning your code, you can use
282 283 the %debug magic."""
283 284
284 285 par = parameter_s.strip().lower()
285 286
286 287 if par:
287 288 try:
288 289 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
289 290 except KeyError:
290 291 print ('Incorrect argument. Use on/1, off/0, '
291 292 'or nothing for a toggle.')
292 293 return
293 294 else:
294 295 # toggle
295 296 new_pdb = not self.shell.call_pdb
296 297
297 298 # set on the shell
298 299 self.shell.call_pdb = new_pdb
299 300 print 'Automatic pdb calling has been turned',on_off(new_pdb)
300 301
301 302 @line_magic
302 303 def debug(self, parameter_s=''):
303 304 """Activate the interactive debugger in post-mortem mode.
304 305
305 306 If an exception has just occurred, this lets you inspect its stack
306 307 frames interactively. Note that this will always work only on the last
307 308 traceback that occurred, so you must call this quickly after an
308 309 exception that you wish to inspect has fired, because if another one
309 310 occurs, it clobbers the previous one.
310 311
311 312 If you want IPython to automatically do this on every exception, see
312 313 the %pdb magic for more details.
313 314 """
314 315 self.shell.debugger(force=True)
315 316
316 317 @line_magic
317 318 def tb(self, s):
318 319 """Print the last traceback with the currently active exception mode.
319 320
320 321 See %xmode for changing exception reporting modes."""
321 322 self.shell.showtraceback()
322 323
323 324 @skip_doctest
324 325 @line_magic
325 326 def run(self, parameter_s='', runner=None,
326 327 file_finder=get_py_filename):
327 328 """Run the named file inside IPython as a program.
328 329
329 330 Usage:\\
330 331 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options] -G] file [args]
331 332
332 333 Parameters after the filename are passed as command-line arguments to
333 334 the program (put in sys.argv). Then, control returns to IPython's
334 335 prompt.
335 336
336 337 This is similar to running at a system prompt:\\
337 338 $ python file args\\
338 339 but with the advantage of giving you IPython's tracebacks, and of
339 340 loading all variables into your interactive namespace for further use
340 341 (unless -p is used, see below).
341 342
342 343 The file is executed in a namespace initially consisting only of
343 344 __name__=='__main__' and sys.argv constructed as indicated. It thus
344 345 sees its environment as if it were being run as a stand-alone program
345 346 (except for sharing global objects such as previously imported
346 347 modules). But after execution, the IPython interactive namespace gets
347 348 updated with all variables defined in the program (except for __name__
348 349 and sys.argv). This allows for very convenient loading of code for
349 350 interactive work, while giving each program a 'clean sheet' to run in.
350 351
351 352 Arguments are expanded using shell-like glob match. Patterns
352 353 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
353 354 tilde '~' will be expanded into user's home directory. Unlike
354 355 real shells, quotation does not suppress expansions. Use
355 356 *two* back slashes (e.g., '\\\\*') to suppress expansions.
356 357 To completely disable these expansions, you can use -G flag.
357 358
358 359 Options:
359 360
360 361 -n: __name__ is NOT set to '__main__', but to the running file's name
361 362 without extension (as python does under import). This allows running
362 363 scripts and reloading the definitions in them without calling code
363 364 protected by an ' if __name__ == "__main__" ' clause.
364 365
365 366 -i: run the file in IPython's namespace instead of an empty one. This
366 367 is useful if you are experimenting with code written in a text editor
367 368 which depends on variables defined interactively.
368 369
369 370 -e: ignore sys.exit() calls or SystemExit exceptions in the script
370 371 being run. This is particularly useful if IPython is being used to
371 372 run unittests, which always exit with a sys.exit() call. In such
372 373 cases you are interested in the output of the test results, not in
373 374 seeing a traceback of the unittest module.
374 375
375 376 -t: print timing information at the end of the run. IPython will give
376 377 you an estimated CPU time consumption for your script, which under
377 378 Unix uses the resource module to avoid the wraparound problems of
378 379 time.clock(). Under Unix, an estimate of time spent on system tasks
379 380 is also given (for Windows platforms this is reported as 0.0).
380 381
381 382 If -t is given, an additional -N<N> option can be given, where <N>
382 383 must be an integer indicating how many times you want the script to
383 384 run. The final timing report will include total and per run results.
384 385
385 386 For example (testing the script uniq_stable.py)::
386 387
387 388 In [1]: run -t uniq_stable
388 389
389 390 IPython CPU timings (estimated):\\
390 391 User : 0.19597 s.\\
391 392 System: 0.0 s.\\
392 393
393 394 In [2]: run -t -N5 uniq_stable
394 395
395 396 IPython CPU timings (estimated):\\
396 397 Total runs performed: 5\\
397 398 Times : Total Per run\\
398 399 User : 0.910862 s, 0.1821724 s.\\
399 400 System: 0.0 s, 0.0 s.
400 401
401 402 -d: run your program under the control of pdb, the Python debugger.
402 403 This allows you to execute your program step by step, watch variables,
403 404 etc. Internally, what IPython does is similar to calling:
404 405
405 406 pdb.run('execfile("YOURFILENAME")')
406 407
407 408 with a breakpoint set on line 1 of your file. You can change the line
408 409 number for this automatic breakpoint to be <N> by using the -bN option
409 410 (where N must be an integer). For example::
410 411
411 412 %run -d -b40 myscript
412 413
413 414 will set the first breakpoint at line 40 in myscript.py. Note that
414 415 the first breakpoint must be set on a line which actually does
415 416 something (not a comment or docstring) for it to stop execution.
416 417
417 418 Or you can specify a breakpoint in a different file::
418 419
419 420 %run -d -b myotherfile.py:20 myscript
420 421
421 422 When the pdb debugger starts, you will see a (Pdb) prompt. You must
422 423 first enter 'c' (without quotes) to start execution up to the first
423 424 breakpoint.
424 425
425 426 Entering 'help' gives information about the use of the debugger. You
426 427 can easily see pdb's full documentation with "import pdb;pdb.help()"
427 428 at a prompt.
428 429
429 430 -p: run program under the control of the Python profiler module (which
430 431 prints a detailed report of execution times, function calls, etc).
431 432
432 433 You can pass other options after -p which affect the behavior of the
433 434 profiler itself. See the docs for %prun for details.
434 435
435 436 In this mode, the program's variables do NOT propagate back to the
436 437 IPython interactive namespace (because they remain in the namespace
437 438 where the profiler executes them).
438 439
439 440 Internally this triggers a call to %prun, see its documentation for
440 441 details on the options available specifically for profiling.
441 442
442 443 There is one special usage for which the text above doesn't apply:
443 444 if the filename ends with .ipy, the file is run as ipython script,
444 445 just as if the commands were written on IPython prompt.
445 446
446 447 -m: specify module name to load instead of script path. Similar to
447 448 the -m option for the python interpreter. Use this option last if you
448 449 want to combine with other %run options. Unlike the python interpreter
449 450 only source modules are allowed no .pyc or .pyo files.
450 451 For example::
451 452
452 453 %run -m example
453 454
454 455 will run the example module.
455 456
456 457 -G: disable shell-like glob expansion of arguments.
457 458
458 459 """
459 460
460 461 # get arguments and set sys.argv for program to be run.
461 462 opts, arg_lst = self.parse_options(parameter_s,
462 463 'nidtN:b:pD:l:rs:T:em:G',
463 464 mode='list', list_all=1)
464 465 if "m" in opts:
465 466 modulename = opts["m"][0]
466 467 modpath = find_mod(modulename)
467 468 if modpath is None:
468 469 warn('%r is not a valid modulename on sys.path'%modulename)
469 470 return
470 471 arg_lst = [modpath] + arg_lst
471 472 try:
472 473 filename = file_finder(arg_lst[0])
473 474 except IndexError:
474 475 warn('you must provide at least a filename.')
475 476 print '\n%run:\n', oinspect.getdoc(self.run)
476 477 return
477 478 except IOError as e:
478 479 try:
479 480 msg = str(e)
480 481 except UnicodeError:
481 482 msg = e.message
482 483 error(msg)
483 484 return
484 485
485 486 if filename.lower().endswith('.ipy'):
486 487 with preserve_keys(self.shell.user_ns, '__file__'):
487 488 self.shell.user_ns['__file__'] = filename
488 489 self.shell.safe_execfile_ipy(filename)
489 490 return
490 491
491 492 # Control the response to exit() calls made by the script being run
492 493 exit_ignore = 'e' in opts
493 494
494 495 # Make sure that the running script gets a proper sys.argv as if it
495 496 # were run from a system shell.
496 497 save_argv = sys.argv # save it for later restoring
497 498
498 499 if 'G' in opts:
499 500 args = arg_lst[1:]
500 501 else:
501 502 # tilde and glob expansion
502 503 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
503 504
504 505 sys.argv = [filename] + args # put in the proper filename
505 506 # protect sys.argv from potential unicode strings on Python 2:
506 507 if not py3compat.PY3:
507 508 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
508 509
509 510 if 'i' in opts:
510 511 # Run in user's interactive namespace
511 512 prog_ns = self.shell.user_ns
512 513 __name__save = self.shell.user_ns['__name__']
513 514 prog_ns['__name__'] = '__main__'
514 515 main_mod = self.shell.new_main_mod(prog_ns)
515 516 else:
516 517 # Run in a fresh, empty namespace
517 518 if 'n' in opts:
518 519 name = os.path.splitext(os.path.basename(filename))[0]
519 520 else:
520 521 name = '__main__'
521 522
522 523 main_mod = self.shell.new_main_mod()
523 524 prog_ns = main_mod.__dict__
524 525 prog_ns['__name__'] = name
525 526
526 527 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
527 528 # set the __file__ global in the script's namespace
528 529 prog_ns['__file__'] = filename
529 530
530 531 # pickle fix. See interactiveshell for an explanation. But we need to
531 532 # make sure that, if we overwrite __main__, we replace it at the end
532 533 main_mod_name = prog_ns['__name__']
533 534
534 535 if main_mod_name == '__main__':
535 536 restore_main = sys.modules['__main__']
536 537 else:
537 538 restore_main = False
538 539
539 540 # This needs to be undone at the end to prevent holding references to
540 541 # every single object ever created.
541 542 sys.modules[main_mod_name] = main_mod
542 543
543 544 try:
544 545 stats = None
545 546 with self.shell.readline_no_record:
546 547 if 'p' in opts:
547 548 stats = self.prun('', None, False, opts, arg_lst, prog_ns)
548 549 else:
549 550 if 'd' in opts:
550 551 deb = debugger.Pdb(self.shell.colors)
551 552 # reset Breakpoint state, which is moronically kept
552 553 # in a class
553 554 bdb.Breakpoint.next = 1
554 555 bdb.Breakpoint.bplist = {}
555 556 bdb.Breakpoint.bpbynumber = [None]
556 557 # Set an initial breakpoint to stop execution
557 558 maxtries = 10
558 559 bp_file, bp_line = parse_breakpoint(opts.get('b', ['1'])[0], filename)
559 560 checkline = deb.checkline(bp_file, bp_line)
560 561 if not checkline:
561 562 for bp in range(bp_line + 1, bp_line + maxtries + 1):
562 563 if deb.checkline(bp_file, bp):
563 564 break
564 565 else:
565 566 msg = ("\nI failed to find a valid line to set "
566 567 "a breakpoint\n"
567 568 "after trying up to line: %s.\n"
568 569 "Please set a valid breakpoint manually "
569 570 "with the -b option." % bp)
570 571 error(msg)
571 572 return
572 573 # if we find a good linenumber, set the breakpoint
573 574 deb.do_break('%s:%s' % (bp_file, bp_line))
574 575
575 576 # Mimic Pdb._runscript(...)
576 577 deb._wait_for_mainpyfile = True
577 578 deb.mainpyfile = deb.canonic(filename)
578 579
579 580 # Start file run
580 581 print "NOTE: Enter 'c' at the",
581 582 print "%s prompt to start your script." % deb.prompt
582 583 ns = {'execfile': py3compat.execfile, 'prog_ns': prog_ns}
583 584 try:
584 585 #save filename so it can be used by methods on the deb object
585 586 deb._exec_filename = filename
586 587 deb.run('execfile("%s", prog_ns)' % filename, ns)
587 588
588 589 except:
589 590 etype, value, tb = sys.exc_info()
590 591 # Skip three frames in the traceback: the %run one,
591 592 # one inside bdb.py, and the command-line typed by the
592 593 # user (run by exec in pdb itself).
593 594 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
594 595 else:
595 596 if runner is None:
596 597 runner = self.default_runner
597 598 if runner is None:
598 599 runner = self.shell.safe_execfile
599 600 if 't' in opts:
600 601 # timed execution
601 602 try:
602 603 nruns = int(opts['N'][0])
603 604 if nruns < 1:
604 605 error('Number of runs must be >=1')
605 606 return
606 607 except (KeyError):
607 608 nruns = 1
608 609 twall0 = time.time()
609 610 if nruns == 1:
610 611 t0 = clock2()
611 612 runner(filename, prog_ns, prog_ns,
612 613 exit_ignore=exit_ignore)
613 614 t1 = clock2()
614 615 t_usr = t1[0] - t0[0]
615 616 t_sys = t1[1] - t0[1]
616 617 print "\nIPython CPU timings (estimated):"
617 618 print " User : %10.2f s." % t_usr
618 619 print " System : %10.2f s." % t_sys
619 620 else:
620 621 runs = range(nruns)
621 622 t0 = clock2()
622 623 for nr in runs:
623 624 runner(filename, prog_ns, prog_ns,
624 625 exit_ignore=exit_ignore)
625 626 t1 = clock2()
626 627 t_usr = t1[0] - t0[0]
627 628 t_sys = t1[1] - t0[1]
628 629 print "\nIPython CPU timings (estimated):"
629 630 print "Total runs performed:", nruns
630 631 print " Times : %10s %10s" % ('Total', 'Per run')
631 632 print " User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns)
632 633 print " System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns)
633 634 twall1 = time.time()
634 635 print "Wall time: %10.2f s." % (twall1 - twall0)
635 636
636 637 else:
637 638 # regular execution
638 639 runner(filename, prog_ns, prog_ns, exit_ignore=exit_ignore)
639 640
640 641 if 'i' in opts:
641 642 self.shell.user_ns['__name__'] = __name__save
642 643 else:
643 644 # The shell MUST hold a reference to prog_ns so after %run
644 645 # exits, the python deletion mechanism doesn't zero it out
645 646 # (leaving dangling references).
646 647 self.shell.cache_main_mod(prog_ns, filename)
647 648 # update IPython interactive namespace
648 649
649 650 # Some forms of read errors on the file may mean the
650 651 # __name__ key was never set; using pop we don't have to
651 652 # worry about a possible KeyError.
652 653 prog_ns.pop('__name__', None)
653 654
654 655 with preserve_keys(self.shell.user_ns, '__file__'):
655 656 self.shell.user_ns.update(prog_ns)
656 657 finally:
657 658 # It's a bit of a mystery why, but __builtins__ can change from
658 659 # being a module to becoming a dict missing some key data after
659 660 # %run. As best I can see, this is NOT something IPython is doing
660 661 # at all, and similar problems have been reported before:
661 662 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
662 663 # Since this seems to be done by the interpreter itself, the best
663 664 # we can do is to at least restore __builtins__ for the user on
664 665 # exit.
665 666 self.shell.user_ns['__builtins__'] = builtin_mod
666 667
667 668 # Ensure key global structures are restored
668 669 sys.argv = save_argv
669 670 if restore_main:
670 671 sys.modules['__main__'] = restore_main
671 672 else:
672 673 # Remove from sys.modules the reference to main_mod we'd
673 674 # added. Otherwise it will trap references to objects
674 675 # contained therein.
675 676 del sys.modules[main_mod_name]
676 677
677 678 return stats
678
679
679 680 @skip_doctest
680 681 @line_cell_magic
681 682 def timeit(self, line='', cell=None):
682 683 """Time execution of a Python statement or expression
683 684
684 685 Usage, in line mode:
685 686 %timeit [-n<N> -r<R> [-t|-c]] statement
686 687 or in cell mode:
687 688 %%timeit [-n<N> -r<R> [-t|-c]] setup_code
688 689 code
689 690 code...
690 691
691 692 Time execution of a Python statement or expression using the timeit
692 693 module. This function can be used both as a line and cell magic:
693 694
694 695 - In line mode you can time a single-line statement (though multiple
695 696 ones can be chained with using semicolons).
696 697
697 698 - In cell mode, the statement in the first line is used as setup code
698 699 (executed but not timed) and the body of the cell is timed. The cell
699 700 body has access to any variables created in the setup code.
700 701
701 702 Options:
702 703 -n<N>: execute the given statement <N> times in a loop. If this value
703 704 is not given, a fitting value is chosen.
704 705
705 706 -r<R>: repeat the loop iteration <R> times and take the best result.
706 707 Default: 3
707 708
708 709 -t: use time.time to measure the time, which is the default on Unix.
709 710 This function measures wall time.
710 711
711 712 -c: use time.clock to measure the time, which is the default on
712 713 Windows and measures wall time. On Unix, resource.getrusage is used
713 714 instead and returns the CPU user time.
714 715
715 716 -p<P>: use a precision of <P> digits to display the timing result.
716 717 Default: 3
717 718
718 719
719 720 Examples
720 721 --------
721 722 ::
722 723
723 724 In [1]: %timeit pass
724 725 10000000 loops, best of 3: 53.3 ns per loop
725 726
726 727 In [2]: u = None
727 728
728 729 In [3]: %timeit u is None
729 730 10000000 loops, best of 3: 184 ns per loop
730 731
731 732 In [4]: %timeit -r 4 u == None
732 733 1000000 loops, best of 4: 242 ns per loop
733 734
734 735 In [5]: import time
735 736
736 737 In [6]: %timeit -n1 time.sleep(2)
737 738 1 loops, best of 3: 2 s per loop
738 739
739 740
740 741 The times reported by %timeit will be slightly higher than those
741 742 reported by the timeit.py script when variables are accessed. This is
742 743 due to the fact that %timeit executes the statement in the namespace
743 744 of the shell, compared with timeit.py, which uses a single setup
744 745 statement to import function or create variables. Generally, the bias
745 746 does not matter as long as results from timeit.py are not mixed with
746 747 those from %timeit."""
747 748
748 749 import timeit
749 import math
750
751 # XXX: Unfortunately the unicode 'micro' symbol can cause problems in
752 # certain terminals. Until we figure out a robust way of
753 # auto-detecting if the terminal can deal with it, use plain 'us' for
754 # microseconds. I am really NOT happy about disabling the proper
755 # 'micro' prefix, but crashing is worse... If anyone knows what the
756 # right solution for this is, I'm all ears...
757 #
758 # Note: using
759 #
760 # s = u'\xb5'
761 # s.encode(sys.getdefaultencoding())
762 #
763 # is not sufficient, as I've seen terminals where that fails but
764 # print s
765 #
766 # succeeds
767 #
768 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
769
770 #units = [u"s", u"ms",u'\xb5',"ns"]
771 units = [u"s", u"ms",u'us',"ns"]
772
773 scaling = [1, 1e3, 1e6, 1e9]
774 750
775 751 opts, stmt = self.parse_options(line,'n:r:tcp:',
776 752 posix=False, strict=False)
777 753 if stmt == "" and cell is None:
778 754 return
779 755
780 756 timefunc = timeit.default_timer
781 757 number = int(getattr(opts, "n", 0))
782 758 repeat = int(getattr(opts, "r", timeit.default_repeat))
783 759 precision = int(getattr(opts, "p", 3))
784 760 if hasattr(opts, "t"):
785 761 timefunc = time.time
786 762 if hasattr(opts, "c"):
787 763 timefunc = clock
788 764
789 765 timer = timeit.Timer(timer=timefunc)
790 766 # this code has tight coupling to the inner workings of timeit.Timer,
791 767 # but is there a better way to achieve that the code stmt has access
792 768 # to the shell namespace?
793 769 transform = self.shell.input_splitter.transform_cell
794 770
795 771 if cell is None:
796 772 # called as line magic
797 773 ast_setup = ast.parse("pass")
798 774 ast_stmt = ast.parse(transform(stmt))
799 775 else:
800 776 ast_setup = ast.parse(transform(stmt))
801 777 ast_stmt = ast.parse(transform(cell))
802 778
803 779 ast_setup = self.shell.transform_ast(ast_setup)
804 780 ast_stmt = self.shell.transform_ast(ast_stmt)
805 781
806 782 # This codestring is taken from timeit.template - we fill it in as an
807 783 # AST, so that we can apply our AST transformations to the user code
808 784 # without affecting the timing code.
809 785 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
810 786 ' setup\n'
811 787 ' _t0 = _timer()\n'
812 788 ' for _i in _it:\n'
813 789 ' stmt\n'
814 790 ' _t1 = _timer()\n'
815 791 ' return _t1 - _t0\n')
816 792
817 793 class TimeitTemplateFiller(ast.NodeTransformer):
818 794 "This is quite tightly tied to the template definition above."
819 795 def visit_FunctionDef(self, node):
820 796 "Fill in the setup statement"
821 797 self.generic_visit(node)
822 798 if node.name == "inner":
823 799 node.body[:1] = ast_setup.body
824 800
825 801 return node
826 802
827 803 def visit_For(self, node):
828 804 "Fill in the statement to be timed"
829 805 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
830 806 node.body = ast_stmt.body
831 807 return node
832 808
833 809 timeit_ast = TimeitTemplateFiller().visit(timeit_ast_template)
834 810 timeit_ast = ast.fix_missing_locations(timeit_ast)
835 811
836 812 # Track compilation time so it can be reported if too long
837 813 # Minimum time above which compilation time will be reported
838 814 tc_min = 0.1
839 815
840 816 t0 = clock()
841 817 code = compile(timeit_ast, "<magic-timeit>", "exec")
842 818 tc = clock()-t0
843 819
844 820 ns = {}
845 821 exec code in self.shell.user_ns, ns
846 822 timer.inner = ns["inner"]
847 823
848 824 if number == 0:
849 825 # determine number so that 0.2 <= total time < 2.0
850 826 number = 1
851 827 for i in range(1, 10):
852 828 if timer.timeit(number) >= 0.2:
853 829 break
854 830 number *= 10
855 831
856 832 best = min(timer.repeat(repeat, number)) / number
857 833
858 if best > 0.0 and best < 1000.0:
859 order = min(-int(math.floor(math.log10(best)) // 3), 3)
860 elif best >= 1000.0:
861 order = 0
862 else:
863 order = 3
864 print u"%d loops, best of %d: %.*g %s per loop" % (number, repeat,
865 precision,
866 best * scaling[order],
867 units[order])
834 print u"%d loops, best of %d: %s per loop" % (number, repeat,
835 _format_time(best, precision))
868 836 if tc > tc_min:
869 837 print "Compiler time: %.2f s" % tc
870 838
871 839 @skip_doctest
872 840 @needs_local_scope
873 @line_magic
874 def time(self,parameter_s, local_ns=None):
841 @line_cell_magic
842 def time(self,line='', cell=None, local_ns=None):
875 843 """Time execution of a Python statement or expression.
876 844
877 845 The CPU and wall clock times are printed, and the value of the
878 846 expression (if any) is returned. Note that under Win32, system time
879 847 is always reported as 0, since it can not be measured.
848
849 This function can be used both as a line and cell magic:
850
851 - In line mode you can time a single-line statement (though multiple
852 ones can be chained with using semicolons).
880 853
881 This function provides very basic timing functionality. In Python
882 2.3, the timeit module offers more control and sophistication, so this
883 could be rewritten to use it (patches welcome).
854 - In cell mode, you can time the cell body (a directly
855 following statement raises an error).
856
857 This function provides very basic timing functionality. Use the timeit
858 magic for more controll over the measurement.
884 859
885 860 Examples
886 861 --------
887 862 ::
888 863
889 In [1]: time 2**128
864 In [1]: %time 2**128
890 865 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
891 866 Wall time: 0.00
892 867 Out[1]: 340282366920938463463374607431768211456L
893 868
894 869 In [2]: n = 1000000
895 870
896 In [3]: time sum(range(n))
871 In [3]: %time sum(range(n))
897 872 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
898 873 Wall time: 1.37
899 874 Out[3]: 499999500000L
900 875
901 In [4]: time print 'hello world'
876 In [4]: %time print 'hello world'
902 877 hello world
903 878 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
904 879 Wall time: 0.00
905 880
906 881 Note that the time needed by Python to compile the given expression
907 882 will be reported if it is more than 0.1s. In this example, the
908 883 actual exponentiation is done by Python at compilation time, so while
909 884 the expression can take a noticeable amount of time to compute, that
910 885 time is purely due to the compilation:
911 886
912 In [5]: time 3**9999;
887 In [5]: %time 3**9999;
913 888 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
914 889 Wall time: 0.00 s
915 890
916 In [6]: time 3**999999;
891 In [6]: %time 3**999999;
917 892 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
918 893 Wall time: 0.00 s
919 894 Compiler : 0.78 s
920 895 """
921 896
922 897 # fail immediately if the given expression can't be compiled
923
924 expr = self.shell.prefilter(parameter_s,False)
898
899 if line and cell:
900 raise UsageError("Can't use statement directly after '%%time'!")
901
902 if cell:
903 expr = self.shell.prefilter(cell,False)
904 else:
905 expr = self.shell.prefilter(line,False)
925 906
926 907 # Minimum time above which parse time will be reported
927 908 tp_min = 0.1
928 909
929 910 t0 = clock()
930 911 expr_ast = ast.parse(expr)
931 912 tp = clock()-t0
932 913
933 914 # Apply AST transformations
934 915 expr_ast = self.shell.transform_ast(expr_ast)
935 916
936 917 # Minimum time above which compilation time will be reported
937 918 tc_min = 0.1
938 919
939 920 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
940 921 mode = 'eval'
941 922 source = '<timed eval>'
942 923 expr_ast = ast.Expression(expr_ast.body[0].value)
943 924 else:
944 925 mode = 'exec'
945 926 source = '<timed exec>'
946 927 t0 = clock()
947 928 code = compile(expr_ast, source, mode)
948 929 tc = clock()-t0
949 930
950 931 # skew measurement as little as possible
951 932 glob = self.shell.user_ns
952 933 wtime = time.time
953 934 # time execution
954 935 wall_st = wtime()
955 936 if mode=='eval':
956 937 st = clock2()
957 938 out = eval(code, glob, local_ns)
958 939 end = clock2()
959 940 else:
960 941 st = clock2()
961 942 exec code in glob, local_ns
962 943 end = clock2()
963 944 out = None
964 945 wall_end = wtime()
965 946 # Compute actual times and report
966 947 wall_time = wall_end-wall_st
967 948 cpu_user = end[0]-st[0]
968 949 cpu_sys = end[1]-st[1]
969 950 cpu_tot = cpu_user+cpu_sys
970 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
971 (cpu_user,cpu_sys,cpu_tot)
972 print "Wall time: %.2f s" % wall_time
951 print "CPU times: user %s, sys: %s, total: %s" % \
952 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot))
953 print "Wall time: %s" % _format_time(wall_time)
973 954 if tc > tc_min:
974 print "Compiler : %.2f s" % tc
955 print "Compiler : %s" % _format_time(tc)
975 956 if tp > tp_min:
976 print "Parser : %.2f s" % tp
957 print "Parser : %s" % _format_time(tp)
977 958 return out
978 959
979 960 @skip_doctest
980 961 @line_magic
981 962 def macro(self, parameter_s=''):
982 963 """Define a macro for future re-execution. It accepts ranges of history,
983 964 filenames or string objects.
984 965
985 966 Usage:\\
986 967 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
987 968
988 969 Options:
989 970
990 971 -r: use 'raw' input. By default, the 'processed' history is used,
991 972 so that magics are loaded in their transformed version to valid
992 973 Python. If this option is given, the raw input as typed as the
993 974 command line is used instead.
994 975
995 976 This will define a global variable called `name` which is a string
996 977 made of joining the slices and lines you specify (n1,n2,... numbers
997 978 above) from your input history into a single string. This variable
998 979 acts like an automatic function which re-executes those lines as if
999 980 you had typed them. You just type 'name' at the prompt and the code
1000 981 executes.
1001 982
1002 983 The syntax for indicating input ranges is described in %history.
1003 984
1004 985 Note: as a 'hidden' feature, you can also use traditional python slice
1005 986 notation, where N:M means numbers N through M-1.
1006 987
1007 988 For example, if your history contains (%hist prints it)::
1008 989
1009 990 44: x=1
1010 991 45: y=3
1011 992 46: z=x+y
1012 993 47: print x
1013 994 48: a=5
1014 995 49: print 'x',x,'y',y
1015 996
1016 997 you can create a macro with lines 44 through 47 (included) and line 49
1017 998 called my_macro with::
1018 999
1019 1000 In [55]: %macro my_macro 44-47 49
1020 1001
1021 1002 Now, typing `my_macro` (without quotes) will re-execute all this code
1022 1003 in one pass.
1023 1004
1024 1005 You don't need to give the line-numbers in order, and any given line
1025 1006 number can appear multiple times. You can assemble macros with any
1026 1007 lines from your input history in any order.
1027 1008
1028 1009 The macro is a simple object which holds its value in an attribute,
1029 1010 but IPython's display system checks for macros and executes them as
1030 1011 code instead of printing them when you type their name.
1031 1012
1032 1013 You can view a macro's contents by explicitly printing it with::
1033 1014
1034 1015 print macro_name
1035 1016
1036 1017 """
1037 1018 opts,args = self.parse_options(parameter_s,'r',mode='list')
1038 1019 if not args: # List existing macros
1039 1020 return sorted(k for k,v in self.shell.user_ns.iteritems() if\
1040 1021 isinstance(v, Macro))
1041 1022 if len(args) == 1:
1042 1023 raise UsageError(
1043 1024 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1044 1025 name, codefrom = args[0], " ".join(args[1:])
1045 1026
1046 1027 #print 'rng',ranges # dbg
1047 1028 try:
1048 1029 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1049 1030 except (ValueError, TypeError) as e:
1050 1031 print e.args[0]
1051 1032 return
1052 1033 macro = Macro(lines)
1053 1034 self.shell.define_macro(name, macro)
1054 1035 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
1055 1036 print '=== Macro contents: ==='
1056 1037 print macro,
1057 1038
1058 1039 @magic_arguments.magic_arguments()
1059 1040 @magic_arguments.argument('output', type=str, default='', nargs='?',
1060 1041 help="""The name of the variable in which to store output.
1061 1042 This is a utils.io.CapturedIO object with stdout/err attributes
1062 1043 for the text of the captured output.
1063 1044
1064 1045 CapturedOutput also has a show() method for displaying the output,
1065 1046 and __call__ as well, so you can use that to quickly display the
1066 1047 output.
1067 1048
1068 1049 If unspecified, captured output is discarded.
1069 1050 """
1070 1051 )
1071 1052 @magic_arguments.argument('--no-stderr', action="store_true",
1072 1053 help="""Don't capture stderr."""
1073 1054 )
1074 1055 @magic_arguments.argument('--no-stdout', action="store_true",
1075 1056 help="""Don't capture stdout."""
1076 1057 )
1077 1058 @cell_magic
1078 1059 def capture(self, line, cell):
1079 1060 """run the cell, capturing stdout/err"""
1080 1061 args = magic_arguments.parse_argstring(self.capture, line)
1081 1062 out = not args.no_stdout
1082 1063 err = not args.no_stderr
1083 1064 with capture_output(out, err) as io:
1084 1065 self.shell.run_cell(cell)
1085 1066 if args.output:
1086 1067 self.shell.user_ns[args.output] = io
1087 1068
1088 1069 def parse_breakpoint(text, current_file):
1089 1070 '''Returns (file, line) for file:line and (current_file, line) for line'''
1090 1071 colon = text.find(':')
1091 1072 if colon == -1:
1092 1073 return current_file, int(text)
1093 1074 else:
1094 1075 return text[:colon], int(text[colon+1:])
1076
1077 def _format_time(timespan, precision=3):
1078 """Formats the timespan in a human readable form"""
1079 import math
1080
1081 if timespan >= 60.0:
1082 # we have more than a minute, format that in a human readable form
1083 # Idea from http://snipplr.com/view/5713/
1084 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1085 time = []
1086 leftover = timespan
1087 for suffix, length in parts:
1088 value = int(leftover / length)
1089 if value > 0:
1090 leftover = leftover % length
1091 time.append(u'%s%s' % (str(value), suffix))
1092 if leftover < 1:
1093 break
1094 return " ".join(time)
1095
1096
1097 # Unfortunately the unicode 'micro' symbol can cause problems in
1098 # certain terminals.
1099 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1100 # Try to prevent crashes by being more secure than it needs to
1101 # E.g. eclipse is able to print a Β΅, but has no sys.stdout.encoding set.
1102 units = [u"s", u"ms",u'us',"ns"] # the save value
1103 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1104 try:
1105 u'\xb5'.encode(sys.stdout.encoding)
1106 units = [u"s", u"ms",u'\xb5s',"ns"]
1107 except:
1108 pass
1109 scaling = [1, 1e3, 1e6, 1e9]
1110
1111 if timespan > 0.0:
1112 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1113 else:
1114 order = 3
1115 ret = u"%.*g %s" % (precision, timespan * scaling[order], units[order])
1116 return ret
@@ -1,840 +1,837 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for various magic functions.
3 3
4 4 Needs to be run by nose (to make ipython session available).
5 5 """
6 6 from __future__ import absolute_import
7 7
8 8 #-----------------------------------------------------------------------------
9 9 # Imports
10 10 #-----------------------------------------------------------------------------
11 11
12 12 import io
13 13 import os
14 14 import sys
15 15 from StringIO import StringIO
16 16 from unittest import TestCase
17 17
18 18 try:
19 19 from importlib import invalidate_caches # Required from Python 3.3
20 20 except ImportError:
21 21 def invalidate_caches():
22 22 pass
23 23
24 24 import nose.tools as nt
25 25
26 26 from IPython.core import magic
27 27 from IPython.core.magic import (Magics, magics_class, line_magic,
28 28 cell_magic, line_cell_magic,
29 29 register_line_magic, register_cell_magic,
30 30 register_line_cell_magic)
31 31 from IPython.core.magics import execution, script, code
32 32 from IPython.nbformat.v3.tests.nbexamples import nb0
33 33 from IPython.nbformat import current
34 34 from IPython.testing import decorators as dec
35 35 from IPython.testing import tools as tt
36 36 from IPython.utils import py3compat
37 37 from IPython.utils.tempdir import TemporaryDirectory
38 38 from IPython.utils.process import find_cmd
39 39
40 40 #-----------------------------------------------------------------------------
41 41 # Test functions begin
42 42 #-----------------------------------------------------------------------------
43 43
44 44 @magic.magics_class
45 45 class DummyMagics(magic.Magics): pass
46 46
47 47 def test_rehashx():
48 48 # clear up everything
49 49 _ip = get_ipython()
50 50 _ip.alias_manager.alias_table.clear()
51 51 del _ip.db['syscmdlist']
52 52
53 53 _ip.magic('rehashx')
54 54 # Practically ALL ipython development systems will have more than 10 aliases
55 55
56 56 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
57 57 for key, val in _ip.alias_manager.alias_table.iteritems():
58 58 # we must strip dots from alias names
59 59 nt.assert_true('.' not in key)
60 60
61 61 # rehashx must fill up syscmdlist
62 62 scoms = _ip.db['syscmdlist']
63 63 yield (nt.assert_true, len(scoms) > 10)
64 64
65 65
66 66 def test_magic_parse_options():
67 67 """Test that we don't mangle paths when parsing magic options."""
68 68 ip = get_ipython()
69 69 path = 'c:\\x'
70 70 m = DummyMagics(ip)
71 71 opts = m.parse_options('-f %s' % path,'f:')[0]
72 72 # argv splitting is os-dependent
73 73 if os.name == 'posix':
74 74 expected = 'c:x'
75 75 else:
76 76 expected = path
77 77 nt.assert_equal(opts['f'], expected)
78 78
79 79 def test_magic_parse_long_options():
80 80 """Magic.parse_options can handle --foo=bar long options"""
81 81 ip = get_ipython()
82 82 m = DummyMagics(ip)
83 83 opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=')
84 84 nt.assert_true('foo' in opts)
85 85 nt.assert_true('bar' in opts)
86 86 nt.assert_true(opts['bar'], "bubble")
87 87
88 88
89 89 @dec.skip_without('sqlite3')
90 90 def doctest_hist_f():
91 91 """Test %hist -f with temporary filename.
92 92
93 93 In [9]: import tempfile
94 94
95 95 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
96 96
97 97 In [11]: %hist -nl -f $tfile 3
98 98
99 99 In [13]: import os; os.unlink(tfile)
100 100 """
101 101
102 102
103 103 @dec.skip_without('sqlite3')
104 104 def doctest_hist_r():
105 105 """Test %hist -r
106 106
107 107 XXX - This test is not recording the output correctly. For some reason, in
108 108 testing mode the raw history isn't getting populated. No idea why.
109 109 Disabling the output checking for now, though at least we do run it.
110 110
111 111 In [1]: 'hist' in _ip.lsmagic()
112 112 Out[1]: True
113 113
114 114 In [2]: x=1
115 115
116 116 In [3]: %hist -rl 2
117 117 x=1 # random
118 118 %hist -r 2
119 119 """
120 120
121 121
122 122 @dec.skip_without('sqlite3')
123 123 def doctest_hist_op():
124 124 """Test %hist -op
125 125
126 126 In [1]: class b(float):
127 127 ...: pass
128 128 ...:
129 129
130 130 In [2]: class s(object):
131 131 ...: def __str__(self):
132 132 ...: return 's'
133 133 ...:
134 134
135 135 In [3]:
136 136
137 137 In [4]: class r(b):
138 138 ...: def __repr__(self):
139 139 ...: return 'r'
140 140 ...:
141 141
142 142 In [5]: class sr(s,r): pass
143 143 ...:
144 144
145 145 In [6]:
146 146
147 147 In [7]: bb=b()
148 148
149 149 In [8]: ss=s()
150 150
151 151 In [9]: rr=r()
152 152
153 153 In [10]: ssrr=sr()
154 154
155 155 In [11]: 4.5
156 156 Out[11]: 4.5
157 157
158 158 In [12]: str(ss)
159 159 Out[12]: 's'
160 160
161 161 In [13]:
162 162
163 163 In [14]: %hist -op
164 164 >>> class b:
165 165 ... pass
166 166 ...
167 167 >>> class s(b):
168 168 ... def __str__(self):
169 169 ... return 's'
170 170 ...
171 171 >>>
172 172 >>> class r(b):
173 173 ... def __repr__(self):
174 174 ... return 'r'
175 175 ...
176 176 >>> class sr(s,r): pass
177 177 >>>
178 178 >>> bb=b()
179 179 >>> ss=s()
180 180 >>> rr=r()
181 181 >>> ssrr=sr()
182 182 >>> 4.5
183 183 4.5
184 184 >>> str(ss)
185 185 's'
186 186 >>>
187 187 """
188 188
189 189
190 190 @dec.skip_without('sqlite3')
191 191 def test_macro():
192 192 ip = get_ipython()
193 193 ip.history_manager.reset() # Clear any existing history.
194 194 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
195 195 for i, cmd in enumerate(cmds, start=1):
196 196 ip.history_manager.store_inputs(i, cmd)
197 197 ip.magic("macro test 1-3")
198 198 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
199 199
200 200 # List macros.
201 201 assert "test" in ip.magic("macro")
202 202
203 203
204 204 @dec.skip_without('sqlite3')
205 205 def test_macro_run():
206 206 """Test that we can run a multi-line macro successfully."""
207 207 ip = get_ipython()
208 208 ip.history_manager.reset()
209 209 cmds = ["a=10", "a+=1", py3compat.doctest_refactor_print("print a"),
210 210 "%macro test 2-3"]
211 211 for cmd in cmds:
212 212 ip.run_cell(cmd, store_history=True)
213 213 nt.assert_equal(ip.user_ns["test"].value,
214 214 py3compat.doctest_refactor_print("a+=1\nprint a\n"))
215 215 with tt.AssertPrints("12"):
216 216 ip.run_cell("test")
217 217 with tt.AssertPrints("13"):
218 218 ip.run_cell("test")
219 219
220 220
221 221 @dec.skipif_not_numpy
222 222 def test_numpy_reset_array_undec():
223 223 "Test '%reset array' functionality"
224 224 _ip.ex('import numpy as np')
225 225 _ip.ex('a = np.empty(2)')
226 226 yield (nt.assert_true, 'a' in _ip.user_ns)
227 227 _ip.magic('reset -f array')
228 228 yield (nt.assert_false, 'a' in _ip.user_ns)
229 229
230 230 def test_reset_out():
231 231 "Test '%reset out' magic"
232 232 _ip.run_cell("parrot = 'dead'", store_history=True)
233 233 # test '%reset -f out', make an Out prompt
234 234 _ip.run_cell("parrot", store_history=True)
235 235 nt.assert_true('dead' in [_ip.user_ns[x] for x in '_','__','___'])
236 236 _ip.magic('reset -f out')
237 237 nt.assert_false('dead' in [_ip.user_ns[x] for x in '_','__','___'])
238 238 nt.assert_true(len(_ip.user_ns['Out']) == 0)
239 239
240 240 def test_reset_in():
241 241 "Test '%reset in' magic"
242 242 # test '%reset -f in'
243 243 _ip.run_cell("parrot", store_history=True)
244 244 nt.assert_true('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
245 245 _ip.magic('%reset -f in')
246 246 nt.assert_false('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
247 247 nt.assert_true(len(set(_ip.user_ns['In'])) == 1)
248 248
249 249 def test_reset_dhist():
250 250 "Test '%reset dhist' magic"
251 251 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
252 252 _ip.magic('cd ' + os.path.dirname(nt.__file__))
253 253 _ip.magic('cd -')
254 254 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
255 255 _ip.magic('reset -f dhist')
256 256 nt.assert_true(len(_ip.user_ns['_dh']) == 0)
257 257 _ip.run_cell("_dh = [d for d in tmp]") #restore
258 258
259 259 def test_reset_in_length():
260 260 "Test that '%reset in' preserves In[] length"
261 261 _ip.run_cell("print 'foo'")
262 262 _ip.run_cell("reset -f in")
263 263 nt.assert_true(len(_ip.user_ns['In']) == _ip.displayhook.prompt_count+1)
264 264
265 def test_time():
266 _ip.magic('time None')
267
268 265 def test_tb_syntaxerror():
269 266 """test %tb after a SyntaxError"""
270 267 ip = get_ipython()
271 268 ip.run_cell("for")
272 269
273 270 # trap and validate stdout
274 271 save_stdout = sys.stdout
275 272 try:
276 273 sys.stdout = StringIO()
277 274 ip.run_cell("%tb")
278 275 out = sys.stdout.getvalue()
279 276 finally:
280 277 sys.stdout = save_stdout
281 278 # trim output, and only check the last line
282 279 last_line = out.rstrip().splitlines()[-1].strip()
283 280 nt.assert_equal(last_line, "SyntaxError: invalid syntax")
284 281
285 282
286 283 def test_time():
287 284 ip = get_ipython()
288 285
289 with tt.AssertPrints("CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s"):
286 with tt.AssertPrints("CPU times: user 0 ns, sys: 0 ns, total: 0 ns"):
290 287 ip.run_cell("%time None")
291 288
292 289 ip.run_cell("def f(kmjy):\n"
293 290 " %time print (2*kmjy)")
294 291
295 with tt.AssertPrints("CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s"):
292 with tt.AssertPrints("CPU times: user 0 ns, sys: 0 ns, total: 0 ns"):
296 293 with tt.AssertPrints("hihi", suppress=False):
297 294 ip.run_cell("f('hi')")
298 295
299 296 def test_doctest_mode():
300 297 "Toggle doctest_mode twice, it should be a no-op and run without error"
301 298 _ip.magic('doctest_mode')
302 299 _ip.magic('doctest_mode')
303 300
304 301
305 302 def test_parse_options():
306 303 """Tests for basic options parsing in magics."""
307 304 # These are only the most minimal of tests, more should be added later. At
308 305 # the very least we check that basic text/unicode calls work OK.
309 306 m = DummyMagics(_ip)
310 307 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
311 308 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
312 309
313 310
314 311 def test_dirops():
315 312 """Test various directory handling operations."""
316 313 # curpath = lambda :os.path.splitdrive(os.getcwdu())[1].replace('\\','/')
317 314 curpath = os.getcwdu
318 315 startdir = os.getcwdu()
319 316 ipdir = os.path.realpath(_ip.ipython_dir)
320 317 try:
321 318 _ip.magic('cd "%s"' % ipdir)
322 319 nt.assert_equal(curpath(), ipdir)
323 320 _ip.magic('cd -')
324 321 nt.assert_equal(curpath(), startdir)
325 322 _ip.magic('pushd "%s"' % ipdir)
326 323 nt.assert_equal(curpath(), ipdir)
327 324 _ip.magic('popd')
328 325 nt.assert_equal(curpath(), startdir)
329 326 finally:
330 327 os.chdir(startdir)
331 328
332 329
333 330 def test_xmode():
334 331 # Calling xmode three times should be a no-op
335 332 xmode = _ip.InteractiveTB.mode
336 333 for i in range(3):
337 334 _ip.magic("xmode")
338 335 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
339 336
340 337 def test_reset_hard():
341 338 monitor = []
342 339 class A(object):
343 340 def __del__(self):
344 341 monitor.append(1)
345 342 def __repr__(self):
346 343 return "<A instance>"
347 344
348 345 _ip.user_ns["a"] = A()
349 346 _ip.run_cell("a")
350 347
351 348 nt.assert_equal(monitor, [])
352 349 _ip.magic("reset -f")
353 350 nt.assert_equal(monitor, [1])
354 351
355 352 class TestXdel(tt.TempFileMixin):
356 353 def test_xdel(self):
357 354 """Test that references from %run are cleared by xdel."""
358 355 src = ("class A(object):\n"
359 356 " monitor = []\n"
360 357 " def __del__(self):\n"
361 358 " self.monitor.append(1)\n"
362 359 "a = A()\n")
363 360 self.mktmp(src)
364 361 # %run creates some hidden references...
365 362 _ip.magic("run %s" % self.fname)
366 363 # ... as does the displayhook.
367 364 _ip.run_cell("a")
368 365
369 366 monitor = _ip.user_ns["A"].monitor
370 367 nt.assert_equal(monitor, [])
371 368
372 369 _ip.magic("xdel a")
373 370
374 371 # Check that a's __del__ method has been called.
375 372 nt.assert_equal(monitor, [1])
376 373
377 374 def doctest_who():
378 375 """doctest for %who
379 376
380 377 In [1]: %reset -f
381 378
382 379 In [2]: alpha = 123
383 380
384 381 In [3]: beta = 'beta'
385 382
386 383 In [4]: %who int
387 384 alpha
388 385
389 386 In [5]: %who str
390 387 beta
391 388
392 389 In [6]: %whos
393 390 Variable Type Data/Info
394 391 ----------------------------
395 392 alpha int 123
396 393 beta str beta
397 394
398 395 In [7]: %who_ls
399 396 Out[7]: ['alpha', 'beta']
400 397 """
401 398
402 399 def test_whos():
403 400 """Check that whos is protected against objects where repr() fails."""
404 401 class A(object):
405 402 def __repr__(self):
406 403 raise Exception()
407 404 _ip.user_ns['a'] = A()
408 405 _ip.magic("whos")
409 406
410 407 @py3compat.u_format
411 408 def doctest_precision():
412 409 """doctest for %precision
413 410
414 411 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
415 412
416 413 In [2]: %precision 5
417 414 Out[2]: {u}'%.5f'
418 415
419 416 In [3]: f.float_format
420 417 Out[3]: {u}'%.5f'
421 418
422 419 In [4]: %precision %e
423 420 Out[4]: {u}'%e'
424 421
425 422 In [5]: f(3.1415927)
426 423 Out[5]: {u}'3.141593e+00'
427 424 """
428 425
429 426 def test_psearch():
430 427 with tt.AssertPrints("dict.fromkeys"):
431 428 _ip.run_cell("dict.fr*?")
432 429
433 430 def test_timeit_shlex():
434 431 """test shlex issues with timeit (#1109)"""
435 432 _ip.ex("def f(*a,**kw): pass")
436 433 _ip.magic('timeit -n1 "this is a bug".count(" ")')
437 434 _ip.magic('timeit -r1 -n1 f(" ", 1)')
438 435 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
439 436 _ip.magic('timeit -r1 -n1 ("a " + "b")')
440 437 _ip.magic('timeit -r1 -n1 f("a " + "b")')
441 438 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
442 439
443 440
444 441 def test_timeit_arguments():
445 442 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
446 443 _ip.magic("timeit ('#')")
447 444
448 445
449 446 def test_timeit_special_syntax():
450 447 "Test %%timeit with IPython special syntax"
451 448 from IPython.core.magic import register_line_magic
452 449
453 450 @register_line_magic
454 451 def lmagic(line):
455 452 ip = get_ipython()
456 453 ip.user_ns['lmagic_out'] = line
457 454
458 455 # line mode test
459 456 _ip.run_line_magic('timeit', '-n1 -r1 %lmagic my line')
460 457 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
461 458 # cell mode test
462 459 _ip.run_cell_magic('timeit', '-n1 -r1', '%lmagic my line2')
463 460 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
464 461
465 462
466 463 @dec.skipif(execution.profile is None)
467 464 def test_prun_quotes():
468 465 "Test that prun does not clobber string escapes (GH #1302)"
469 466 _ip.magic(r"prun -q x = '\t'")
470 467 nt.assert_equal(_ip.user_ns['x'], '\t')
471 468
472 469 def test_extension():
473 470 tmpdir = TemporaryDirectory()
474 471 orig_ipython_dir = _ip.ipython_dir
475 472 try:
476 473 _ip.ipython_dir = tmpdir.name
477 474 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
478 475 url = os.path.join(os.path.dirname(__file__), "daft_extension.py")
479 476 _ip.magic("install_ext %s" % url)
480 477 _ip.user_ns.pop('arq', None)
481 478 invalidate_caches() # Clear import caches
482 479 _ip.magic("load_ext daft_extension")
483 480 nt.assert_equal(_ip.user_ns['arq'], 185)
484 481 _ip.magic("unload_ext daft_extension")
485 482 assert 'arq' not in _ip.user_ns
486 483 finally:
487 484 _ip.ipython_dir = orig_ipython_dir
488 485 tmpdir.cleanup()
489 486
490 487 def test_notebook_export_json():
491 488 with TemporaryDirectory() as td:
492 489 outfile = os.path.join(td, "nb.ipynb")
493 490 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
494 491 _ip.magic("notebook -e %s" % outfile)
495 492
496 493 def test_notebook_export_py():
497 494 with TemporaryDirectory() as td:
498 495 outfile = os.path.join(td, "nb.py")
499 496 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
500 497 _ip.magic("notebook -e %s" % outfile)
501 498
502 499 def test_notebook_reformat_py():
503 500 with TemporaryDirectory() as td:
504 501 infile = os.path.join(td, "nb.ipynb")
505 502 with io.open(infile, 'w', encoding='utf-8') as f:
506 503 current.write(nb0, f, 'json')
507 504
508 505 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
509 506 _ip.magic("notebook -f py %s" % infile)
510 507
511 508 def test_notebook_reformat_json():
512 509 with TemporaryDirectory() as td:
513 510 infile = os.path.join(td, "nb.py")
514 511 with io.open(infile, 'w', encoding='utf-8') as f:
515 512 current.write(nb0, f, 'py')
516 513
517 514 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
518 515 _ip.magic("notebook -f ipynb %s" % infile)
519 516 _ip.magic("notebook -f json %s" % infile)
520 517
521 518 def test_env():
522 519 env = _ip.magic("env")
523 520 assert isinstance(env, dict), type(env)
524 521
525 522
526 523 class CellMagicTestCase(TestCase):
527 524
528 525 def check_ident(self, magic):
529 526 # Manually called, we get the result
530 527 out = _ip.run_cell_magic(magic, 'a', 'b')
531 528 nt.assert_equal(out, ('a','b'))
532 529 # Via run_cell, it goes into the user's namespace via displayhook
533 530 _ip.run_cell('%%' + magic +' c\nd')
534 531 nt.assert_equal(_ip.user_ns['_'], ('c','d'))
535 532
536 533 def test_cell_magic_func_deco(self):
537 534 "Cell magic using simple decorator"
538 535 @register_cell_magic
539 536 def cellm(line, cell):
540 537 return line, cell
541 538
542 539 self.check_ident('cellm')
543 540
544 541 def test_cell_magic_reg(self):
545 542 "Cell magic manually registered"
546 543 def cellm(line, cell):
547 544 return line, cell
548 545
549 546 _ip.register_magic_function(cellm, 'cell', 'cellm2')
550 547 self.check_ident('cellm2')
551 548
552 549 def test_cell_magic_class(self):
553 550 "Cell magics declared via a class"
554 551 @magics_class
555 552 class MyMagics(Magics):
556 553
557 554 @cell_magic
558 555 def cellm3(self, line, cell):
559 556 return line, cell
560 557
561 558 _ip.register_magics(MyMagics)
562 559 self.check_ident('cellm3')
563 560
564 561 def test_cell_magic_class2(self):
565 562 "Cell magics declared via a class, #2"
566 563 @magics_class
567 564 class MyMagics2(Magics):
568 565
569 566 @cell_magic('cellm4')
570 567 def cellm33(self, line, cell):
571 568 return line, cell
572 569
573 570 _ip.register_magics(MyMagics2)
574 571 self.check_ident('cellm4')
575 572 # Check that nothing is registered as 'cellm33'
576 573 c33 = _ip.find_cell_magic('cellm33')
577 574 nt.assert_equal(c33, None)
578 575
579 576 def test_file():
580 577 """Basic %%file"""
581 578 ip = get_ipython()
582 579 with TemporaryDirectory() as td:
583 580 fname = os.path.join(td, 'file1')
584 581 ip.run_cell_magic("file", fname, u'\n'.join([
585 582 'line1',
586 583 'line2',
587 584 ]))
588 585 with open(fname) as f:
589 586 s = f.read()
590 587 nt.assert_in('line1\n', s)
591 588 nt.assert_in('line2', s)
592 589
593 590 def test_file_var_expand():
594 591 """%%file $filename"""
595 592 ip = get_ipython()
596 593 with TemporaryDirectory() as td:
597 594 fname = os.path.join(td, 'file1')
598 595 ip.user_ns['filename'] = fname
599 596 ip.run_cell_magic("file", '$filename', u'\n'.join([
600 597 'line1',
601 598 'line2',
602 599 ]))
603 600 with open(fname) as f:
604 601 s = f.read()
605 602 nt.assert_in('line1\n', s)
606 603 nt.assert_in('line2', s)
607 604
608 605 def test_file_unicode():
609 606 """%%file with unicode cell"""
610 607 ip = get_ipython()
611 608 with TemporaryDirectory() as td:
612 609 fname = os.path.join(td, 'file1')
613 610 ip.run_cell_magic("file", fname, u'\n'.join([
614 611 u'linΓ©1',
615 612 u'linΓ©2',
616 613 ]))
617 614 with io.open(fname, encoding='utf-8') as f:
618 615 s = f.read()
619 616 nt.assert_in(u'linΓ©1\n', s)
620 617 nt.assert_in(u'linΓ©2', s)
621 618
622 619 def test_file_amend():
623 620 """%%file -a amends files"""
624 621 ip = get_ipython()
625 622 with TemporaryDirectory() as td:
626 623 fname = os.path.join(td, 'file2')
627 624 ip.run_cell_magic("file", fname, u'\n'.join([
628 625 'line1',
629 626 'line2',
630 627 ]))
631 628 ip.run_cell_magic("file", "-a %s" % fname, u'\n'.join([
632 629 'line3',
633 630 'line4',
634 631 ]))
635 632 with open(fname) as f:
636 633 s = f.read()
637 634 nt.assert_in('line1\n', s)
638 635 nt.assert_in('line3\n', s)
639 636
640 637
641 638 def test_script_config():
642 639 ip = get_ipython()
643 640 ip.config.ScriptMagics.script_magics = ['whoda']
644 641 sm = script.ScriptMagics(shell=ip)
645 642 nt.assert_in('whoda', sm.magics['cell'])
646 643
647 644 @dec.skip_win32
648 645 def test_script_out():
649 646 ip = get_ipython()
650 647 ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
651 648 nt.assert_equal(ip.user_ns['output'], 'hi\n')
652 649
653 650 @dec.skip_win32
654 651 def test_script_err():
655 652 ip = get_ipython()
656 653 ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
657 654 nt.assert_equal(ip.user_ns['error'], 'hello\n')
658 655
659 656 @dec.skip_win32
660 657 def test_script_out_err():
661 658 ip = get_ipython()
662 659 ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
663 660 nt.assert_equal(ip.user_ns['output'], 'hi\n')
664 661 nt.assert_equal(ip.user_ns['error'], 'hello\n')
665 662
666 663 @dec.skip_win32
667 664 def test_script_bg_out():
668 665 ip = get_ipython()
669 666 ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
670 667 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
671 668
672 669 @dec.skip_win32
673 670 def test_script_bg_err():
674 671 ip = get_ipython()
675 672 ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
676 673 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
677 674
678 675 @dec.skip_win32
679 676 def test_script_bg_out_err():
680 677 ip = get_ipython()
681 678 ip.run_cell_magic("script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2")
682 679 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
683 680 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
684 681
685 682 def test_script_defaults():
686 683 ip = get_ipython()
687 684 for cmd in ['sh', 'bash', 'perl', 'ruby']:
688 685 try:
689 686 find_cmd(cmd)
690 687 except Exception:
691 688 pass
692 689 else:
693 690 nt.assert_in(cmd, ip.magics_manager.magics['cell'])
694 691
695 692
696 693 @magics_class
697 694 class FooFoo(Magics):
698 695 """class with both %foo and %%foo magics"""
699 696 @line_magic('foo')
700 697 def line_foo(self, line):
701 698 "I am line foo"
702 699 pass
703 700
704 701 @cell_magic("foo")
705 702 def cell_foo(self, line, cell):
706 703 "I am cell foo, not line foo"
707 704 pass
708 705
709 706 def test_line_cell_info():
710 707 """%%foo and %foo magics are distinguishable to inspect"""
711 708 ip = get_ipython()
712 709 ip.magics_manager.register(FooFoo)
713 710 oinfo = ip.object_inspect('foo')
714 711 nt.assert_true(oinfo['found'])
715 712 nt.assert_true(oinfo['ismagic'])
716 713
717 714 oinfo = ip.object_inspect('%%foo')
718 715 nt.assert_true(oinfo['found'])
719 716 nt.assert_true(oinfo['ismagic'])
720 717 nt.assert_equal(oinfo['docstring'], FooFoo.cell_foo.__doc__)
721 718
722 719 oinfo = ip.object_inspect('%foo')
723 720 nt.assert_true(oinfo['found'])
724 721 nt.assert_true(oinfo['ismagic'])
725 722 nt.assert_equal(oinfo['docstring'], FooFoo.line_foo.__doc__)
726 723
727 724 def test_multiple_magics():
728 725 ip = get_ipython()
729 726 foo1 = FooFoo(ip)
730 727 foo2 = FooFoo(ip)
731 728 mm = ip.magics_manager
732 729 mm.register(foo1)
733 730 nt.assert_true(mm.magics['line']['foo'].im_self is foo1)
734 731 mm.register(foo2)
735 732 nt.assert_true(mm.magics['line']['foo'].im_self is foo2)
736 733
737 734 def test_alias_magic():
738 735 """Test %alias_magic."""
739 736 ip = get_ipython()
740 737 mm = ip.magics_manager
741 738
742 739 # Basic operation: both cell and line magics are created, if possible.
743 740 ip.run_line_magic('alias_magic', 'timeit_alias timeit')
744 741 nt.assert_true('timeit_alias' in mm.magics['line'])
745 742 nt.assert_true('timeit_alias' in mm.magics['cell'])
746 743
747 744 # --cell is specified, line magic not created.
748 745 ip.run_line_magic('alias_magic', '--cell timeit_cell_alias timeit')
749 746 nt.assert_false('timeit_cell_alias' in mm.magics['line'])
750 747 nt.assert_true('timeit_cell_alias' in mm.magics['cell'])
751 748
752 749 # Test that line alias is created successfully.
753 750 ip.run_line_magic('alias_magic', '--line env_alias env')
754 751 nt.assert_equal(ip.run_line_magic('env', ''),
755 752 ip.run_line_magic('env_alias', ''))
756 753
757 754 def test_save():
758 755 """Test %save."""
759 756 ip = get_ipython()
760 757 ip.history_manager.reset() # Clear any existing history.
761 758 cmds = [u"a=1", u"def b():\n return a**2", u"print(a, b())"]
762 759 for i, cmd in enumerate(cmds, start=1):
763 760 ip.history_manager.store_inputs(i, cmd)
764 761 with TemporaryDirectory() as tmpdir:
765 762 file = os.path.join(tmpdir, "testsave.py")
766 763 ip.run_line_magic("save", "%s 1-10" % file)
767 764 with open(file) as f:
768 765 content = f.read()
769 766 nt.assert_equal(content.count(cmds[0]), 1)
770 767 nt.assert_true('coding: utf-8' in content)
771 768 ip.run_line_magic("save", "-a %s 1-10" % file)
772 769 with open(file) as f:
773 770 content = f.read()
774 771 nt.assert_equal(content.count(cmds[0]), 2)
775 772 nt.assert_true('coding: utf-8' in content)
776 773
777 774
778 775 def test_store():
779 776 """Test %store."""
780 777 ip = get_ipython()
781 778 ip.run_line_magic('load_ext', 'storemagic')
782 779
783 780 # make sure the storage is empty
784 781 ip.run_line_magic('store', '-z')
785 782 ip.user_ns['var'] = 42
786 783 ip.run_line_magic('store', 'var')
787 784 ip.user_ns['var'] = 39
788 785 ip.run_line_magic('store', '-r')
789 786 nt.assert_equal(ip.user_ns['var'], 42)
790 787
791 788 ip.run_line_magic('store', '-d var')
792 789 ip.user_ns['var'] = 39
793 790 ip.run_line_magic('store' , '-r')
794 791 nt.assert_equal(ip.user_ns['var'], 39)
795 792
796 793
797 794 def _run_edit_test(arg_s, exp_filename=None,
798 795 exp_lineno=-1,
799 796 exp_contents=None,
800 797 exp_is_temp=None):
801 798 ip = get_ipython()
802 799 M = code.CodeMagics(ip)
803 800 last_call = ['','']
804 801 opts,args = M.parse_options(arg_s,'prxn:')
805 802 filename, lineno, is_temp = M._find_edit_target(ip, args, opts, last_call)
806 803
807 804 if exp_filename is not None:
808 805 nt.assert_equal(exp_filename, filename)
809 806 if exp_contents is not None:
810 807 with io.open(filename, 'r') as f:
811 808 contents = f.read()
812 809 nt.assert_equal(exp_contents, contents)
813 810 if exp_lineno != -1:
814 811 nt.assert_equal(exp_lineno, lineno)
815 812 if exp_is_temp is not None:
816 813 nt.assert_equal(exp_is_temp, is_temp)
817 814
818 815
819 816 def test_edit_interactive():
820 817 """%edit on interactively defined objects"""
821 818 ip = get_ipython()
822 819 n = ip.execution_count
823 820 ip.run_cell(u"def foo(): return 1", store_history=True)
824 821
825 822 try:
826 823 _run_edit_test("foo")
827 824 except code.InteractivelyDefined as e:
828 825 nt.assert_equal(e.index, n)
829 826 else:
830 827 raise AssertionError("Should have raised InteractivelyDefined")
831 828
832 829
833 830 def test_edit_cell():
834 831 """%edit [cell id]"""
835 832 ip = get_ipython()
836 833
837 834 ip.run_cell(u"def foo(): return 1", store_history=True)
838 835
839 836 # test
840 837 _run_edit_test("1", exp_contents=ip.user_ns['In'][1], exp_is_temp=True)
General Comments 0
You need to be logged in to leave comments. Login now