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