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