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