##// END OF EJS Templates
Backport PR #12453: Allow spaces when using debug magic
Matthias Bussonnier -
Show More
@@ -1,1506 +1,1512 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 elif not (args.breakpoint or cell):
471 # If there is no breakpoints, the line is just code to execute
472 self._debug_exec(line, None)
470 473 else:
474 # Here we try to reconstruct the code from the output of
475 # parse_argstring. This might not work if the code has spaces
476 # For example this fails for `print("a b")`
471 477 code = "\n".join(args.statement)
472 478 if cell:
473 479 code += "\n" + cell
474 480 self._debug_exec(code, args.breakpoint)
475 481
476 482 def _debug_post_mortem(self):
477 483 self.shell.debugger(force=True)
478 484
479 485 def _debug_exec(self, code, breakpoint):
480 486 if breakpoint:
481 487 (filename, bp_line) = breakpoint.rsplit(':', 1)
482 488 bp_line = int(bp_line)
483 489 else:
484 490 (filename, bp_line) = (None, None)
485 491 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
486 492
487 493 @line_magic
488 494 def tb(self, s):
489 495 """Print the last traceback.
490 496
491 497 Optionally, specify an exception reporting mode, tuning the
492 498 verbosity of the traceback. By default the currently-active exception
493 499 mode is used. See %xmode for changing exception reporting modes.
494 500
495 501 Valid modes: Plain, Context, Verbose, and Minimal.
496 502 """
497 503 interactive_tb = self.shell.InteractiveTB
498 504 if s:
499 505 # Switch exception reporting mode for this one call.
500 506 # Ensure it is switched back.
501 507 def xmode_switch_err(name):
502 508 warn('Error changing %s exception modes.\n%s' %
503 509 (name,sys.exc_info()[1]))
504 510
505 511 new_mode = s.strip().capitalize()
506 512 original_mode = interactive_tb.mode
507 513 try:
508 514 try:
509 515 interactive_tb.set_mode(mode=new_mode)
510 516 except Exception:
511 517 xmode_switch_err('user')
512 518 else:
513 519 self.shell.showtraceback()
514 520 finally:
515 521 interactive_tb.set_mode(mode=original_mode)
516 522 else:
517 523 self.shell.showtraceback()
518 524
519 525 @skip_doctest
520 526 @line_magic
521 527 def run(self, parameter_s='', runner=None,
522 528 file_finder=get_py_filename):
523 529 """Run the named file inside IPython as a program.
524 530
525 531 Usage::
526 532
527 533 %run [-n -i -e -G]
528 534 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
529 535 ( -m mod | file ) [args]
530 536
531 537 Parameters after the filename are passed as command-line arguments to
532 538 the program (put in sys.argv). Then, control returns to IPython's
533 539 prompt.
534 540
535 541 This is similar to running at a system prompt ``python file args``,
536 542 but with the advantage of giving you IPython's tracebacks, and of
537 543 loading all variables into your interactive namespace for further use
538 544 (unless -p is used, see below).
539 545
540 546 The file is executed in a namespace initially consisting only of
541 547 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
542 548 sees its environment as if it were being run as a stand-alone program
543 549 (except for sharing global objects such as previously imported
544 550 modules). But after execution, the IPython interactive namespace gets
545 551 updated with all variables defined in the program (except for __name__
546 552 and sys.argv). This allows for very convenient loading of code for
547 553 interactive work, while giving each program a 'clean sheet' to run in.
548 554
549 555 Arguments are expanded using shell-like glob match. Patterns
550 556 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
551 557 tilde '~' will be expanded into user's home directory. Unlike
552 558 real shells, quotation does not suppress expansions. Use
553 559 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
554 560 To completely disable these expansions, you can use -G flag.
555 561
556 562 On Windows systems, the use of single quotes `'` when specifying
557 563 a file is not supported. Use double quotes `"`.
558 564
559 565 Options:
560 566
561 567 -n
562 568 __name__ is NOT set to '__main__', but to the running file's name
563 569 without extension (as python does under import). This allows running
564 570 scripts and reloading the definitions in them without calling code
565 571 protected by an ``if __name__ == "__main__"`` clause.
566 572
567 573 -i
568 574 run the file in IPython's namespace instead of an empty one. This
569 575 is useful if you are experimenting with code written in a text editor
570 576 which depends on variables defined interactively.
571 577
572 578 -e
573 579 ignore sys.exit() calls or SystemExit exceptions in the script
574 580 being run. This is particularly useful if IPython is being used to
575 581 run unittests, which always exit with a sys.exit() call. In such
576 582 cases you are interested in the output of the test results, not in
577 583 seeing a traceback of the unittest module.
578 584
579 585 -t
580 586 print timing information at the end of the run. IPython will give
581 587 you an estimated CPU time consumption for your script, which under
582 588 Unix uses the resource module to avoid the wraparound problems of
583 589 time.clock(). Under Unix, an estimate of time spent on system tasks
584 590 is also given (for Windows platforms this is reported as 0.0).
585 591
586 592 If -t is given, an additional ``-N<N>`` option can be given, where <N>
587 593 must be an integer indicating how many times you want the script to
588 594 run. The final timing report will include total and per run results.
589 595
590 596 For example (testing the script uniq_stable.py)::
591 597
592 598 In [1]: run -t uniq_stable
593 599
594 600 IPython CPU timings (estimated):
595 601 User : 0.19597 s.
596 602 System: 0.0 s.
597 603
598 604 In [2]: run -t -N5 uniq_stable
599 605
600 606 IPython CPU timings (estimated):
601 607 Total runs performed: 5
602 608 Times : Total Per run
603 609 User : 0.910862 s, 0.1821724 s.
604 610 System: 0.0 s, 0.0 s.
605 611
606 612 -d
607 613 run your program under the control of pdb, the Python debugger.
608 614 This allows you to execute your program step by step, watch variables,
609 615 etc. Internally, what IPython does is similar to calling::
610 616
611 617 pdb.run('execfile("YOURFILENAME")')
612 618
613 619 with a breakpoint set on line 1 of your file. You can change the line
614 620 number for this automatic breakpoint to be <N> by using the -bN option
615 621 (where N must be an integer). For example::
616 622
617 623 %run -d -b40 myscript
618 624
619 625 will set the first breakpoint at line 40 in myscript.py. Note that
620 626 the first breakpoint must be set on a line which actually does
621 627 something (not a comment or docstring) for it to stop execution.
622 628
623 629 Or you can specify a breakpoint in a different file::
624 630
625 631 %run -d -b myotherfile.py:20 myscript
626 632
627 633 When the pdb debugger starts, you will see a (Pdb) prompt. You must
628 634 first enter 'c' (without quotes) to start execution up to the first
629 635 breakpoint.
630 636
631 637 Entering 'help' gives information about the use of the debugger. You
632 638 can easily see pdb's full documentation with "import pdb;pdb.help()"
633 639 at a prompt.
634 640
635 641 -p
636 642 run program under the control of the Python profiler module (which
637 643 prints a detailed report of execution times, function calls, etc).
638 644
639 645 You can pass other options after -p which affect the behavior of the
640 646 profiler itself. See the docs for %prun for details.
641 647
642 648 In this mode, the program's variables do NOT propagate back to the
643 649 IPython interactive namespace (because they remain in the namespace
644 650 where the profiler executes them).
645 651
646 652 Internally this triggers a call to %prun, see its documentation for
647 653 details on the options available specifically for profiling.
648 654
649 655 There is one special usage for which the text above doesn't apply:
650 656 if the filename ends with .ipy[nb], the file is run as ipython script,
651 657 just as if the commands were written on IPython prompt.
652 658
653 659 -m
654 660 specify module name to load instead of script path. Similar to
655 661 the -m option for the python interpreter. Use this option last if you
656 662 want to combine with other %run options. Unlike the python interpreter
657 663 only source modules are allowed no .pyc or .pyo files.
658 664 For example::
659 665
660 666 %run -m example
661 667
662 668 will run the example module.
663 669
664 670 -G
665 671 disable shell-like glob expansion of arguments.
666 672
667 673 """
668 674
669 675 # Logic to handle issue #3664
670 676 # Add '--' after '-m <module_name>' to ignore additional args passed to a module.
671 677 if '-m' in parameter_s and '--' not in parameter_s:
672 678 argv = shlex.split(parameter_s, posix=(os.name == 'posix'))
673 679 for idx, arg in enumerate(argv):
674 680 if arg and arg.startswith('-') and arg != '-':
675 681 if arg == '-m':
676 682 argv.insert(idx + 2, '--')
677 683 break
678 684 else:
679 685 # Positional arg, break
680 686 break
681 687 parameter_s = ' '.join(shlex.quote(arg) for arg in argv)
682 688
683 689 # get arguments and set sys.argv for program to be run.
684 690 opts, arg_lst = self.parse_options(parameter_s,
685 691 'nidtN:b:pD:l:rs:T:em:G',
686 692 mode='list', list_all=1)
687 693 if "m" in opts:
688 694 modulename = opts["m"][0]
689 695 modpath = find_mod(modulename)
690 696 if modpath is None:
691 697 msg = '%r is not a valid modulename on sys.path'%modulename
692 698 raise Exception(msg)
693 699 arg_lst = [modpath] + arg_lst
694 700 try:
695 701 fpath = None # initialize to make sure fpath is in scope later
696 702 fpath = arg_lst[0]
697 703 filename = file_finder(fpath)
698 704 except IndexError:
699 705 msg = 'you must provide at least a filename.'
700 706 raise Exception(msg)
701 707 except IOError as e:
702 708 try:
703 709 msg = str(e)
704 710 except UnicodeError:
705 711 msg = e.message
706 712 if os.name == 'nt' and re.match(r"^'.*'$",fpath):
707 713 warn('For Windows, use double quotes to wrap a filename: %run "mypath\\myfile.py"')
708 714 raise Exception(msg)
709 715 except TypeError:
710 716 if fpath in sys.meta_path:
711 717 filename = ""
712 718 else:
713 719 raise
714 720
715 721 if filename.lower().endswith(('.ipy', '.ipynb')):
716 722 with preserve_keys(self.shell.user_ns, '__file__'):
717 723 self.shell.user_ns['__file__'] = filename
718 724 self.shell.safe_execfile_ipy(filename, raise_exceptions=True)
719 725 return
720 726
721 727 # Control the response to exit() calls made by the script being run
722 728 exit_ignore = 'e' in opts
723 729
724 730 # Make sure that the running script gets a proper sys.argv as if it
725 731 # were run from a system shell.
726 732 save_argv = sys.argv # save it for later restoring
727 733
728 734 if 'G' in opts:
729 735 args = arg_lst[1:]
730 736 else:
731 737 # tilde and glob expansion
732 738 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
733 739
734 740 sys.argv = [filename] + args # put in the proper filename
735 741
736 742 if 'n' in opts:
737 743 name = os.path.splitext(os.path.basename(filename))[0]
738 744 else:
739 745 name = '__main__'
740 746
741 747 if 'i' in opts:
742 748 # Run in user's interactive namespace
743 749 prog_ns = self.shell.user_ns
744 750 __name__save = self.shell.user_ns['__name__']
745 751 prog_ns['__name__'] = name
746 752 main_mod = self.shell.user_module
747 753
748 754 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
749 755 # set the __file__ global in the script's namespace
750 756 # TK: Is this necessary in interactive mode?
751 757 prog_ns['__file__'] = filename
752 758 else:
753 759 # Run in a fresh, empty namespace
754 760
755 761 # The shell MUST hold a reference to prog_ns so after %run
756 762 # exits, the python deletion mechanism doesn't zero it out
757 763 # (leaving dangling references). See interactiveshell for details
758 764 main_mod = self.shell.new_main_mod(filename, name)
759 765 prog_ns = main_mod.__dict__
760 766
761 767 # pickle fix. See interactiveshell for an explanation. But we need to
762 768 # make sure that, if we overwrite __main__, we replace it at the end
763 769 main_mod_name = prog_ns['__name__']
764 770
765 771 if main_mod_name == '__main__':
766 772 restore_main = sys.modules['__main__']
767 773 else:
768 774 restore_main = False
769 775
770 776 # This needs to be undone at the end to prevent holding references to
771 777 # every single object ever created.
772 778 sys.modules[main_mod_name] = main_mod
773 779
774 780 if 'p' in opts or 'd' in opts:
775 781 if 'm' in opts:
776 782 code = 'run_module(modulename, prog_ns)'
777 783 code_ns = {
778 784 'run_module': self.shell.safe_run_module,
779 785 'prog_ns': prog_ns,
780 786 'modulename': modulename,
781 787 }
782 788 else:
783 789 if 'd' in opts:
784 790 # allow exceptions to raise in debug mode
785 791 code = 'execfile(filename, prog_ns, raise_exceptions=True)'
786 792 else:
787 793 code = 'execfile(filename, prog_ns)'
788 794 code_ns = {
789 795 'execfile': self.shell.safe_execfile,
790 796 'prog_ns': prog_ns,
791 797 'filename': get_py_filename(filename),
792 798 }
793 799
794 800 try:
795 801 stats = None
796 802 if 'p' in opts:
797 803 stats = self._run_with_profiler(code, opts, code_ns)
798 804 else:
799 805 if 'd' in opts:
800 806 bp_file, bp_line = parse_breakpoint(
801 807 opts.get('b', ['1'])[0], filename)
802 808 self._run_with_debugger(
803 809 code, code_ns, filename, bp_line, bp_file)
804 810 else:
805 811 if 'm' in opts:
806 812 def run():
807 813 self.shell.safe_run_module(modulename, prog_ns)
808 814 else:
809 815 if runner is None:
810 816 runner = self.default_runner
811 817 if runner is None:
812 818 runner = self.shell.safe_execfile
813 819
814 820 def run():
815 821 runner(filename, prog_ns, prog_ns,
816 822 exit_ignore=exit_ignore)
817 823
818 824 if 't' in opts:
819 825 # timed execution
820 826 try:
821 827 nruns = int(opts['N'][0])
822 828 if nruns < 1:
823 829 error('Number of runs must be >=1')
824 830 return
825 831 except (KeyError):
826 832 nruns = 1
827 833 self._run_with_timing(run, nruns)
828 834 else:
829 835 # regular execution
830 836 run()
831 837
832 838 if 'i' in opts:
833 839 self.shell.user_ns['__name__'] = __name__save
834 840 else:
835 841 # update IPython interactive namespace
836 842
837 843 # Some forms of read errors on the file may mean the
838 844 # __name__ key was never set; using pop we don't have to
839 845 # worry about a possible KeyError.
840 846 prog_ns.pop('__name__', None)
841 847
842 848 with preserve_keys(self.shell.user_ns, '__file__'):
843 849 self.shell.user_ns.update(prog_ns)
844 850 finally:
845 851 # It's a bit of a mystery why, but __builtins__ can change from
846 852 # being a module to becoming a dict missing some key data after
847 853 # %run. As best I can see, this is NOT something IPython is doing
848 854 # at all, and similar problems have been reported before:
849 855 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
850 856 # Since this seems to be done by the interpreter itself, the best
851 857 # we can do is to at least restore __builtins__ for the user on
852 858 # exit.
853 859 self.shell.user_ns['__builtins__'] = builtin_mod
854 860
855 861 # Ensure key global structures are restored
856 862 sys.argv = save_argv
857 863 if restore_main:
858 864 sys.modules['__main__'] = restore_main
859 865 if '__mp_main__' in sys.modules:
860 866 sys.modules['__mp_main__'] = restore_main
861 867 else:
862 868 # Remove from sys.modules the reference to main_mod we'd
863 869 # added. Otherwise it will trap references to objects
864 870 # contained therein.
865 871 del sys.modules[main_mod_name]
866 872
867 873 return stats
868 874
869 875 def _run_with_debugger(self, code, code_ns, filename=None,
870 876 bp_line=None, bp_file=None):
871 877 """
872 878 Run `code` in debugger with a break point.
873 879
874 880 Parameters
875 881 ----------
876 882 code : str
877 883 Code to execute.
878 884 code_ns : dict
879 885 A namespace in which `code` is executed.
880 886 filename : str
881 887 `code` is ran as if it is in `filename`.
882 888 bp_line : int, optional
883 889 Line number of the break point.
884 890 bp_file : str, optional
885 891 Path to the file in which break point is specified.
886 892 `filename` is used if not given.
887 893
888 894 Raises
889 895 ------
890 896 UsageError
891 897 If the break point given by `bp_line` is not valid.
892 898
893 899 """
894 900 deb = self.shell.InteractiveTB.pdb
895 901 if not deb:
896 902 self.shell.InteractiveTB.pdb = self.shell.InteractiveTB.debugger_cls()
897 903 deb = self.shell.InteractiveTB.pdb
898 904
899 905 # deb.checkline() fails if deb.curframe exists but is None; it can
900 906 # handle it not existing. https://github.com/ipython/ipython/issues/10028
901 907 if hasattr(deb, 'curframe'):
902 908 del deb.curframe
903 909
904 910 # reset Breakpoint state, which is moronically kept
905 911 # in a class
906 912 bdb.Breakpoint.next = 1
907 913 bdb.Breakpoint.bplist = {}
908 914 bdb.Breakpoint.bpbynumber = [None]
909 915 deb.clear_all_breaks()
910 916 if bp_line is not None:
911 917 # Set an initial breakpoint to stop execution
912 918 maxtries = 10
913 919 bp_file = bp_file or filename
914 920 checkline = deb.checkline(bp_file, bp_line)
915 921 if not checkline:
916 922 for bp in range(bp_line + 1, bp_line + maxtries + 1):
917 923 if deb.checkline(bp_file, bp):
918 924 break
919 925 else:
920 926 msg = ("\nI failed to find a valid line to set "
921 927 "a breakpoint\n"
922 928 "after trying up to line: %s.\n"
923 929 "Please set a valid breakpoint manually "
924 930 "with the -b option." % bp)
925 931 raise UsageError(msg)
926 932 # if we find a good linenumber, set the breakpoint
927 933 deb.do_break('%s:%s' % (bp_file, bp_line))
928 934
929 935 if filename:
930 936 # Mimic Pdb._runscript(...)
931 937 deb._wait_for_mainpyfile = True
932 938 deb.mainpyfile = deb.canonic(filename)
933 939
934 940 # Start file run
935 941 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
936 942 try:
937 943 if filename:
938 944 # save filename so it can be used by methods on the deb object
939 945 deb._exec_filename = filename
940 946 while True:
941 947 try:
942 948 trace = sys.gettrace()
943 949 deb.run(code, code_ns)
944 950 except Restart:
945 951 print("Restarting")
946 952 if filename:
947 953 deb._wait_for_mainpyfile = True
948 954 deb.mainpyfile = deb.canonic(filename)
949 955 continue
950 956 else:
951 957 break
952 958 finally:
953 959 sys.settrace(trace)
954 960
955 961
956 962 except:
957 963 etype, value, tb = sys.exc_info()
958 964 # Skip three frames in the traceback: the %run one,
959 965 # one inside bdb.py, and the command-line typed by the
960 966 # user (run by exec in pdb itself).
961 967 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
962 968
963 969 @staticmethod
964 970 def _run_with_timing(run, nruns):
965 971 """
966 972 Run function `run` and print timing information.
967 973
968 974 Parameters
969 975 ----------
970 976 run : callable
971 977 Any callable object which takes no argument.
972 978 nruns : int
973 979 Number of times to execute `run`.
974 980
975 981 """
976 982 twall0 = time.perf_counter()
977 983 if nruns == 1:
978 984 t0 = clock2()
979 985 run()
980 986 t1 = clock2()
981 987 t_usr = t1[0] - t0[0]
982 988 t_sys = t1[1] - t0[1]
983 989 print("\nIPython CPU timings (estimated):")
984 990 print(" User : %10.2f s." % t_usr)
985 991 print(" System : %10.2f s." % t_sys)
986 992 else:
987 993 runs = range(nruns)
988 994 t0 = clock2()
989 995 for nr in runs:
990 996 run()
991 997 t1 = clock2()
992 998 t_usr = t1[0] - t0[0]
993 999 t_sys = t1[1] - t0[1]
994 1000 print("\nIPython CPU timings (estimated):")
995 1001 print("Total runs performed:", nruns)
996 1002 print(" Times : %10s %10s" % ('Total', 'Per run'))
997 1003 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
998 1004 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
999 1005 twall1 = time.perf_counter()
1000 1006 print("Wall time: %10.2f s." % (twall1 - twall0))
1001 1007
1002 1008 @skip_doctest
1003 1009 @no_var_expand
1004 1010 @line_cell_magic
1005 1011 @needs_local_scope
1006 1012 def timeit(self, line='', cell=None, local_ns=None):
1007 1013 """Time execution of a Python statement or expression
1008 1014
1009 1015 Usage, in line mode:
1010 1016 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
1011 1017 or in cell mode:
1012 1018 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
1013 1019 code
1014 1020 code...
1015 1021
1016 1022 Time execution of a Python statement or expression using the timeit
1017 1023 module. This function can be used both as a line and cell magic:
1018 1024
1019 1025 - In line mode you can time a single-line statement (though multiple
1020 1026 ones can be chained with using semicolons).
1021 1027
1022 1028 - In cell mode, the statement in the first line is used as setup code
1023 1029 (executed but not timed) and the body of the cell is timed. The cell
1024 1030 body has access to any variables created in the setup code.
1025 1031
1026 1032 Options:
1027 1033 -n<N>: execute the given statement <N> times in a loop. If <N> is not
1028 1034 provided, <N> is determined so as to get sufficient accuracy.
1029 1035
1030 1036 -r<R>: number of repeats <R>, each consisting of <N> loops, and take the
1031 1037 best result.
1032 1038 Default: 7
1033 1039
1034 1040 -t: use time.time to measure the time, which is the default on Unix.
1035 1041 This function measures wall time.
1036 1042
1037 1043 -c: use time.clock to measure the time, which is the default on
1038 1044 Windows and measures wall time. On Unix, resource.getrusage is used
1039 1045 instead and returns the CPU user time.
1040 1046
1041 1047 -p<P>: use a precision of <P> digits to display the timing result.
1042 1048 Default: 3
1043 1049
1044 1050 -q: Quiet, do not print result.
1045 1051
1046 1052 -o: return a TimeitResult that can be stored in a variable to inspect
1047 1053 the result in more details.
1048 1054
1049 1055 .. versionchanged:: 7.3
1050 1056 User variables are no longer expanded,
1051 1057 the magic line is always left unmodified.
1052 1058
1053 1059 Examples
1054 1060 --------
1055 1061 ::
1056 1062
1057 1063 In [1]: %timeit pass
1058 1064 8.26 ns Β± 0.12 ns per loop (mean Β± std. dev. of 7 runs, 100000000 loops each)
1059 1065
1060 1066 In [2]: u = None
1061 1067
1062 1068 In [3]: %timeit u is None
1063 1069 29.9 ns Β± 0.643 ns per loop (mean Β± std. dev. of 7 runs, 10000000 loops each)
1064 1070
1065 1071 In [4]: %timeit -r 4 u == None
1066 1072
1067 1073 In [5]: import time
1068 1074
1069 1075 In [6]: %timeit -n1 time.sleep(2)
1070 1076
1071 1077
1072 1078 The times reported by %timeit will be slightly higher than those
1073 1079 reported by the timeit.py script when variables are accessed. This is
1074 1080 due to the fact that %timeit executes the statement in the namespace
1075 1081 of the shell, compared with timeit.py, which uses a single setup
1076 1082 statement to import function or create variables. Generally, the bias
1077 1083 does not matter as long as results from timeit.py are not mixed with
1078 1084 those from %timeit."""
1079 1085
1080 1086 opts, stmt = self.parse_options(line,'n:r:tcp:qo',
1081 1087 posix=False, strict=False)
1082 1088 if stmt == "" and cell is None:
1083 1089 return
1084 1090
1085 1091 timefunc = timeit.default_timer
1086 1092 number = int(getattr(opts, "n", 0))
1087 1093 default_repeat = 7 if timeit.default_repeat < 7 else timeit.default_repeat
1088 1094 repeat = int(getattr(opts, "r", default_repeat))
1089 1095 precision = int(getattr(opts, "p", 3))
1090 1096 quiet = 'q' in opts
1091 1097 return_result = 'o' in opts
1092 1098 if hasattr(opts, "t"):
1093 1099 timefunc = time.time
1094 1100 if hasattr(opts, "c"):
1095 1101 timefunc = clock
1096 1102
1097 1103 timer = Timer(timer=timefunc)
1098 1104 # this code has tight coupling to the inner workings of timeit.Timer,
1099 1105 # but is there a better way to achieve that the code stmt has access
1100 1106 # to the shell namespace?
1101 1107 transform = self.shell.transform_cell
1102 1108
1103 1109 if cell is None:
1104 1110 # called as line magic
1105 1111 ast_setup = self.shell.compile.ast_parse("pass")
1106 1112 ast_stmt = self.shell.compile.ast_parse(transform(stmt))
1107 1113 else:
1108 1114 ast_setup = self.shell.compile.ast_parse(transform(stmt))
1109 1115 ast_stmt = self.shell.compile.ast_parse(transform(cell))
1110 1116
1111 1117 ast_setup = self.shell.transform_ast(ast_setup)
1112 1118 ast_stmt = self.shell.transform_ast(ast_stmt)
1113 1119
1114 1120 # Check that these compile to valid Python code *outside* the timer func
1115 1121 # Invalid code may become valid when put inside the function & loop,
1116 1122 # which messes up error messages.
1117 1123 # https://github.com/ipython/ipython/issues/10636
1118 1124 self.shell.compile(ast_setup, "<magic-timeit-setup>", "exec")
1119 1125 self.shell.compile(ast_stmt, "<magic-timeit-stmt>", "exec")
1120 1126
1121 1127 # This codestring is taken from timeit.template - we fill it in as an
1122 1128 # AST, so that we can apply our AST transformations to the user code
1123 1129 # without affecting the timing code.
1124 1130 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
1125 1131 ' setup\n'
1126 1132 ' _t0 = _timer()\n'
1127 1133 ' for _i in _it:\n'
1128 1134 ' stmt\n'
1129 1135 ' _t1 = _timer()\n'
1130 1136 ' return _t1 - _t0\n')
1131 1137
1132 1138 timeit_ast = TimeitTemplateFiller(ast_setup, ast_stmt).visit(timeit_ast_template)
1133 1139 timeit_ast = ast.fix_missing_locations(timeit_ast)
1134 1140
1135 1141 # Track compilation time so it can be reported if too long
1136 1142 # Minimum time above which compilation time will be reported
1137 1143 tc_min = 0.1
1138 1144
1139 1145 t0 = clock()
1140 1146 code = self.shell.compile(timeit_ast, "<magic-timeit>", "exec")
1141 1147 tc = clock()-t0
1142 1148
1143 1149 ns = {}
1144 1150 glob = self.shell.user_ns
1145 1151 # handles global vars with same name as local vars. We store them in conflict_globs.
1146 1152 conflict_globs = {}
1147 1153 if local_ns and cell is None:
1148 1154 for var_name, var_val in glob.items():
1149 1155 if var_name in local_ns:
1150 1156 conflict_globs[var_name] = var_val
1151 1157 glob.update(local_ns)
1152 1158
1153 1159 exec(code, glob, ns)
1154 1160 timer.inner = ns["inner"]
1155 1161
1156 1162 # This is used to check if there is a huge difference between the
1157 1163 # best and worst timings.
1158 1164 # Issue: https://github.com/ipython/ipython/issues/6471
1159 1165 if number == 0:
1160 1166 # determine number so that 0.2 <= total time < 2.0
1161 1167 for index in range(0, 10):
1162 1168 number = 10 ** index
1163 1169 time_number = timer.timeit(number)
1164 1170 if time_number >= 0.2:
1165 1171 break
1166 1172
1167 1173 all_runs = timer.repeat(repeat, number)
1168 1174 best = min(all_runs) / number
1169 1175 worst = max(all_runs) / number
1170 1176 timeit_result = TimeitResult(number, repeat, best, worst, all_runs, tc, precision)
1171 1177
1172 1178 # Restore global vars from conflict_globs
1173 1179 if conflict_globs:
1174 1180 glob.update(conflict_globs)
1175 1181
1176 1182 if not quiet :
1177 1183 # Check best timing is greater than zero to avoid a
1178 1184 # ZeroDivisionError.
1179 1185 # In cases where the slowest timing is lesser than a microsecond
1180 1186 # we assume that it does not really matter if the fastest
1181 1187 # timing is 4 times faster than the slowest timing or not.
1182 1188 if worst > 4 * best and best > 0 and worst > 1e-6:
1183 1189 print("The slowest run took %0.2f times longer than the "
1184 1190 "fastest. This could mean that an intermediate result "
1185 1191 "is being cached." % (worst / best))
1186 1192
1187 1193 print( timeit_result )
1188 1194
1189 1195 if tc > tc_min:
1190 1196 print("Compiler time: %.2f s" % tc)
1191 1197 if return_result:
1192 1198 return timeit_result
1193 1199
1194 1200 @skip_doctest
1195 1201 @no_var_expand
1196 1202 @needs_local_scope
1197 1203 @line_cell_magic
1198 1204 def time(self,line='', cell=None, local_ns=None):
1199 1205 """Time execution of a Python statement or expression.
1200 1206
1201 1207 The CPU and wall clock times are printed, and the value of the
1202 1208 expression (if any) is returned. Note that under Win32, system time
1203 1209 is always reported as 0, since it can not be measured.
1204 1210
1205 1211 This function can be used both as a line and cell magic:
1206 1212
1207 1213 - In line mode you can time a single-line statement (though multiple
1208 1214 ones can be chained with using semicolons).
1209 1215
1210 1216 - In cell mode, you can time the cell body (a directly
1211 1217 following statement raises an error).
1212 1218
1213 1219 This function provides very basic timing functionality. Use the timeit
1214 1220 magic for more control over the measurement.
1215 1221
1216 1222 .. versionchanged:: 7.3
1217 1223 User variables are no longer expanded,
1218 1224 the magic line is always left unmodified.
1219 1225
1220 1226 Examples
1221 1227 --------
1222 1228 ::
1223 1229
1224 1230 In [1]: %time 2**128
1225 1231 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1226 1232 Wall time: 0.00
1227 1233 Out[1]: 340282366920938463463374607431768211456L
1228 1234
1229 1235 In [2]: n = 1000000
1230 1236
1231 1237 In [3]: %time sum(range(n))
1232 1238 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1233 1239 Wall time: 1.37
1234 1240 Out[3]: 499999500000L
1235 1241
1236 1242 In [4]: %time print 'hello world'
1237 1243 hello world
1238 1244 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1239 1245 Wall time: 0.00
1240 1246
1241 1247 Note that the time needed by Python to compile the given expression
1242 1248 will be reported if it is more than 0.1s. In this example, the
1243 1249 actual exponentiation is done by Python at compilation time, so while
1244 1250 the expression can take a noticeable amount of time to compute, that
1245 1251 time is purely due to the compilation:
1246 1252
1247 1253 In [5]: %time 3**9999;
1248 1254 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1249 1255 Wall time: 0.00 s
1250 1256
1251 1257 In [6]: %time 3**999999;
1252 1258 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1253 1259 Wall time: 0.00 s
1254 1260 Compiler : 0.78 s
1255 1261 """
1256 1262
1257 1263 # fail immediately if the given expression can't be compiled
1258 1264
1259 1265 if line and cell:
1260 1266 raise UsageError("Can't use statement directly after '%%time'!")
1261 1267
1262 1268 if cell:
1263 1269 expr = self.shell.transform_cell(cell)
1264 1270 else:
1265 1271 expr = self.shell.transform_cell(line)
1266 1272
1267 1273 # Minimum time above which parse time will be reported
1268 1274 tp_min = 0.1
1269 1275
1270 1276 t0 = clock()
1271 1277 expr_ast = self.shell.compile.ast_parse(expr)
1272 1278 tp = clock()-t0
1273 1279
1274 1280 # Apply AST transformations
1275 1281 expr_ast = self.shell.transform_ast(expr_ast)
1276 1282
1277 1283 # Minimum time above which compilation time will be reported
1278 1284 tc_min = 0.1
1279 1285
1280 1286 expr_val=None
1281 1287 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1282 1288 mode = 'eval'
1283 1289 source = '<timed eval>'
1284 1290 expr_ast = ast.Expression(expr_ast.body[0].value)
1285 1291 else:
1286 1292 mode = 'exec'
1287 1293 source = '<timed exec>'
1288 1294 # multi-line %%time case
1289 1295 if len(expr_ast.body) > 1 and isinstance(expr_ast.body[-1], ast.Expr):
1290 1296 expr_val= expr_ast.body[-1]
1291 1297 expr_ast = expr_ast.body[:-1]
1292 1298 expr_ast = Module(expr_ast, [])
1293 1299 expr_val = ast.Expression(expr_val.value)
1294 1300
1295 1301 t0 = clock()
1296 1302 code = self.shell.compile(expr_ast, source, mode)
1297 1303 tc = clock()-t0
1298 1304
1299 1305 # skew measurement as little as possible
1300 1306 glob = self.shell.user_ns
1301 1307 wtime = time.time
1302 1308 # time execution
1303 1309 wall_st = wtime()
1304 1310 if mode=='eval':
1305 1311 st = clock2()
1306 1312 try:
1307 1313 out = eval(code, glob, local_ns)
1308 1314 except:
1309 1315 self.shell.showtraceback()
1310 1316 return
1311 1317 end = clock2()
1312 1318 else:
1313 1319 st = clock2()
1314 1320 try:
1315 1321 exec(code, glob, local_ns)
1316 1322 out=None
1317 1323 # multi-line %%time case
1318 1324 if expr_val is not None:
1319 1325 code_2 = self.shell.compile(expr_val, source, 'eval')
1320 1326 out = eval(code_2, glob, local_ns)
1321 1327 except:
1322 1328 self.shell.showtraceback()
1323 1329 return
1324 1330 end = clock2()
1325 1331
1326 1332 wall_end = wtime()
1327 1333 # Compute actual times and report
1328 1334 wall_time = wall_end-wall_st
1329 1335 cpu_user = end[0]-st[0]
1330 1336 cpu_sys = end[1]-st[1]
1331 1337 cpu_tot = cpu_user+cpu_sys
1332 1338 # On windows cpu_sys is always zero, so no new information to the next print
1333 1339 if sys.platform != 'win32':
1334 1340 print("CPU times: user %s, sys: %s, total: %s" % \
1335 1341 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1336 1342 print("Wall time: %s" % _format_time(wall_time))
1337 1343 if tc > tc_min:
1338 1344 print("Compiler : %s" % _format_time(tc))
1339 1345 if tp > tp_min:
1340 1346 print("Parser : %s" % _format_time(tp))
1341 1347 return out
1342 1348
1343 1349 @skip_doctest
1344 1350 @line_magic
1345 1351 def macro(self, parameter_s=''):
1346 1352 """Define a macro for future re-execution. It accepts ranges of history,
1347 1353 filenames or string objects.
1348 1354
1349 1355 Usage:\\
1350 1356 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1351 1357
1352 1358 Options:
1353 1359
1354 1360 -r: use 'raw' input. By default, the 'processed' history is used,
1355 1361 so that magics are loaded in their transformed version to valid
1356 1362 Python. If this option is given, the raw input as typed at the
1357 1363 command line is used instead.
1358 1364
1359 1365 -q: quiet macro definition. By default, a tag line is printed
1360 1366 to indicate the macro has been created, and then the contents of
1361 1367 the macro are printed. If this option is given, then no printout
1362 1368 is produced once the macro is created.
1363 1369
1364 1370 This will define a global variable called `name` which is a string
1365 1371 made of joining the slices and lines you specify (n1,n2,... numbers
1366 1372 above) from your input history into a single string. This variable
1367 1373 acts like an automatic function which re-executes those lines as if
1368 1374 you had typed them. You just type 'name' at the prompt and the code
1369 1375 executes.
1370 1376
1371 1377 The syntax for indicating input ranges is described in %history.
1372 1378
1373 1379 Note: as a 'hidden' feature, you can also use traditional python slice
1374 1380 notation, where N:M means numbers N through M-1.
1375 1381
1376 1382 For example, if your history contains (print using %hist -n )::
1377 1383
1378 1384 44: x=1
1379 1385 45: y=3
1380 1386 46: z=x+y
1381 1387 47: print x
1382 1388 48: a=5
1383 1389 49: print 'x',x,'y',y
1384 1390
1385 1391 you can create a macro with lines 44 through 47 (included) and line 49
1386 1392 called my_macro with::
1387 1393
1388 1394 In [55]: %macro my_macro 44-47 49
1389 1395
1390 1396 Now, typing `my_macro` (without quotes) will re-execute all this code
1391 1397 in one pass.
1392 1398
1393 1399 You don't need to give the line-numbers in order, and any given line
1394 1400 number can appear multiple times. You can assemble macros with any
1395 1401 lines from your input history in any order.
1396 1402
1397 1403 The macro is a simple object which holds its value in an attribute,
1398 1404 but IPython's display system checks for macros and executes them as
1399 1405 code instead of printing them when you type their name.
1400 1406
1401 1407 You can view a macro's contents by explicitly printing it with::
1402 1408
1403 1409 print macro_name
1404 1410
1405 1411 """
1406 1412 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1407 1413 if not args: # List existing macros
1408 1414 return sorted(k for k,v in self.shell.user_ns.items() if isinstance(v, Macro))
1409 1415 if len(args) == 1:
1410 1416 raise UsageError(
1411 1417 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1412 1418 name, codefrom = args[0], " ".join(args[1:])
1413 1419
1414 1420 #print 'rng',ranges # dbg
1415 1421 try:
1416 1422 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1417 1423 except (ValueError, TypeError) as e:
1418 1424 print(e.args[0])
1419 1425 return
1420 1426 macro = Macro(lines)
1421 1427 self.shell.define_macro(name, macro)
1422 1428 if not ( 'q' in opts) :
1423 1429 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1424 1430 print('=== Macro contents: ===')
1425 1431 print(macro, end=' ')
1426 1432
1427 1433 @magic_arguments.magic_arguments()
1428 1434 @magic_arguments.argument('output', type=str, default='', nargs='?',
1429 1435 help="""The name of the variable in which to store output.
1430 1436 This is a utils.io.CapturedIO object with stdout/err attributes
1431 1437 for the text of the captured output.
1432 1438
1433 1439 CapturedOutput also has a show() method for displaying the output,
1434 1440 and __call__ as well, so you can use that to quickly display the
1435 1441 output.
1436 1442
1437 1443 If unspecified, captured output is discarded.
1438 1444 """
1439 1445 )
1440 1446 @magic_arguments.argument('--no-stderr', action="store_true",
1441 1447 help="""Don't capture stderr."""
1442 1448 )
1443 1449 @magic_arguments.argument('--no-stdout', action="store_true",
1444 1450 help="""Don't capture stdout."""
1445 1451 )
1446 1452 @magic_arguments.argument('--no-display', action="store_true",
1447 1453 help="""Don't capture IPython's rich display."""
1448 1454 )
1449 1455 @cell_magic
1450 1456 def capture(self, line, cell):
1451 1457 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1452 1458 args = magic_arguments.parse_argstring(self.capture, line)
1453 1459 out = not args.no_stdout
1454 1460 err = not args.no_stderr
1455 1461 disp = not args.no_display
1456 1462 with capture_output(out, err, disp) as io:
1457 1463 self.shell.run_cell(cell)
1458 1464 if args.output:
1459 1465 self.shell.user_ns[args.output] = io
1460 1466
1461 1467 def parse_breakpoint(text, current_file):
1462 1468 '''Returns (file, line) for file:line and (current_file, line) for line'''
1463 1469 colon = text.find(':')
1464 1470 if colon == -1:
1465 1471 return current_file, int(text)
1466 1472 else:
1467 1473 return text[:colon], int(text[colon+1:])
1468 1474
1469 1475 def _format_time(timespan, precision=3):
1470 1476 """Formats the timespan in a human readable form"""
1471 1477
1472 1478 if timespan >= 60.0:
1473 1479 # we have more than a minute, format that in a human readable form
1474 1480 # Idea from http://snipplr.com/view/5713/
1475 1481 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1476 1482 time = []
1477 1483 leftover = timespan
1478 1484 for suffix, length in parts:
1479 1485 value = int(leftover / length)
1480 1486 if value > 0:
1481 1487 leftover = leftover % length
1482 1488 time.append(u'%s%s' % (str(value), suffix))
1483 1489 if leftover < 1:
1484 1490 break
1485 1491 return " ".join(time)
1486 1492
1487 1493
1488 1494 # Unfortunately the unicode 'micro' symbol can cause problems in
1489 1495 # certain terminals.
1490 1496 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1491 1497 # Try to prevent crashes by being more secure than it needs to
1492 1498 # E.g. eclipse is able to print a Β΅, but has no sys.stdout.encoding set.
1493 1499 units = [u"s", u"ms",u'us',"ns"] # the save value
1494 1500 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1495 1501 try:
1496 1502 u'\xb5'.encode(sys.stdout.encoding)
1497 1503 units = [u"s", u"ms",u'\xb5s',"ns"]
1498 1504 except:
1499 1505 pass
1500 1506 scaling = [1, 1e3, 1e6, 1e9]
1501 1507
1502 1508 if timespan > 0.0:
1503 1509 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1504 1510 else:
1505 1511 order = 3
1506 1512 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
@@ -1,1225 +1,1238 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for various magic functions.
3 3
4 4 Needs to be run by nose (to make ipython session available).
5 5 """
6 6
7 7 import io
8 8 import os
9 9 import re
10 10 import sys
11 11 import warnings
12 12 from textwrap import dedent
13 13 from unittest import TestCase
14 14 from unittest import mock
15 15 from importlib import invalidate_caches
16 16 from io import StringIO
17 17
18 18 import nose.tools as nt
19 19
20 20 import shlex
21 21
22 22 from IPython import get_ipython
23 23 from IPython.core import magic
24 24 from IPython.core.error import UsageError
25 25 from IPython.core.magic import (Magics, magics_class, line_magic,
26 26 cell_magic,
27 27 register_line_magic, register_cell_magic)
28 28 from IPython.core.magics import execution, script, code, logging, osm
29 29 from IPython.testing import decorators as dec
30 30 from IPython.testing import tools as tt
31 31 from IPython.utils.io import capture_output
32 32 from IPython.utils.tempdir import (TemporaryDirectory,
33 33 TemporaryWorkingDirectory)
34 34 from IPython.utils.process import find_cmd
35 from .test_debugger import PdbTestInput
35 36
36 37
37 38 @magic.magics_class
38 39 class DummyMagics(magic.Magics): pass
39 40
40 41 def test_extract_code_ranges():
41 42 instr = "1 3 5-6 7-9 10:15 17: :10 10- -13 :"
42 43 expected = [(0, 1),
43 44 (2, 3),
44 45 (4, 6),
45 46 (6, 9),
46 47 (9, 14),
47 48 (16, None),
48 49 (None, 9),
49 50 (9, None),
50 51 (None, 13),
51 52 (None, None)]
52 53 actual = list(code.extract_code_ranges(instr))
53 54 nt.assert_equal(actual, expected)
54 55
55 56 def test_extract_symbols():
56 57 source = """import foo\na = 10\ndef b():\n return 42\n\n\nclass A: pass\n\n\n"""
57 58 symbols_args = ["a", "b", "A", "A,b", "A,a", "z"]
58 59 expected = [([], ['a']),
59 60 (["def b():\n return 42\n"], []),
60 61 (["class A: pass\n"], []),
61 62 (["class A: pass\n", "def b():\n return 42\n"], []),
62 63 (["class A: pass\n"], ['a']),
63 64 ([], ['z'])]
64 65 for symbols, exp in zip(symbols_args, expected):
65 66 nt.assert_equal(code.extract_symbols(source, symbols), exp)
66 67
67 68
68 69 def test_extract_symbols_raises_exception_with_non_python_code():
69 70 source = ("=begin A Ruby program :)=end\n"
70 71 "def hello\n"
71 72 "puts 'Hello world'\n"
72 73 "end")
73 74 with nt.assert_raises(SyntaxError):
74 75 code.extract_symbols(source, "hello")
75 76
76 77
77 78 def test_magic_not_found():
78 79 # magic not found raises UsageError
79 80 with nt.assert_raises(UsageError):
80 81 _ip.magic('doesntexist')
81 82
82 83 # ensure result isn't success when a magic isn't found
83 84 result = _ip.run_cell('%doesntexist')
84 85 assert isinstance(result.error_in_exec, UsageError)
85 86
86 87
87 88 def test_cell_magic_not_found():
88 89 # magic not found raises UsageError
89 90 with nt.assert_raises(UsageError):
90 91 _ip.run_cell_magic('doesntexist', 'line', 'cell')
91 92
92 93 # ensure result isn't success when a magic isn't found
93 94 result = _ip.run_cell('%%doesntexist')
94 95 assert isinstance(result.error_in_exec, UsageError)
95 96
96 97
97 98 def test_magic_error_status():
98 99 def fail(shell):
99 100 1/0
100 101 _ip.register_magic_function(fail)
101 102 result = _ip.run_cell('%fail')
102 103 assert isinstance(result.error_in_exec, ZeroDivisionError)
103 104
104 105
105 106 def test_config():
106 107 """ test that config magic does not raise
107 108 can happen if Configurable init is moved too early into
108 109 Magics.__init__ as then a Config object will be registered as a
109 110 magic.
110 111 """
111 112 ## should not raise.
112 113 _ip.magic('config')
113 114
114 115 def test_config_available_configs():
115 116 """ test that config magic prints available configs in unique and
116 117 sorted order. """
117 118 with capture_output() as captured:
118 119 _ip.magic('config')
119 120
120 121 stdout = captured.stdout
121 122 config_classes = stdout.strip().split('\n')[1:]
122 123 nt.assert_list_equal(config_classes, sorted(set(config_classes)))
123 124
124 125 def test_config_print_class():
125 126 """ test that config with a classname prints the class's options. """
126 127 with capture_output() as captured:
127 128 _ip.magic('config TerminalInteractiveShell')
128 129
129 130 stdout = captured.stdout
130 131 if not re.match("TerminalInteractiveShell.* options", stdout.splitlines()[0]):
131 132 print(stdout)
132 133 raise AssertionError("1st line of stdout not like "
133 134 "'TerminalInteractiveShell.* options'")
134 135
135 136 def test_rehashx():
136 137 # clear up everything
137 138 _ip.alias_manager.clear_aliases()
138 139 del _ip.db['syscmdlist']
139 140
140 141 _ip.magic('rehashx')
141 142 # Practically ALL ipython development systems will have more than 10 aliases
142 143
143 144 nt.assert_true(len(_ip.alias_manager.aliases) > 10)
144 145 for name, cmd in _ip.alias_manager.aliases:
145 146 # we must strip dots from alias names
146 147 nt.assert_not_in('.', name)
147 148
148 149 # rehashx must fill up syscmdlist
149 150 scoms = _ip.db['syscmdlist']
150 151 nt.assert_true(len(scoms) > 10)
151 152
152 153
153 154
154 155 def test_magic_parse_options():
155 156 """Test that we don't mangle paths when parsing magic options."""
156 157 ip = get_ipython()
157 158 path = 'c:\\x'
158 159 m = DummyMagics(ip)
159 160 opts = m.parse_options('-f %s' % path,'f:')[0]
160 161 # argv splitting is os-dependent
161 162 if os.name == 'posix':
162 163 expected = 'c:x'
163 164 else:
164 165 expected = path
165 166 nt.assert_equal(opts['f'], expected)
166 167
167 168 def test_magic_parse_long_options():
168 169 """Magic.parse_options can handle --foo=bar long options"""
169 170 ip = get_ipython()
170 171 m = DummyMagics(ip)
171 172 opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=')
172 173 nt.assert_in('foo', opts)
173 174 nt.assert_in('bar', opts)
174 175 nt.assert_equal(opts['bar'], "bubble")
175 176
176 177
177 178 @dec.skip_without('sqlite3')
178 179 def doctest_hist_f():
179 180 """Test %hist -f with temporary filename.
180 181
181 182 In [9]: import tempfile
182 183
183 184 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
184 185
185 186 In [11]: %hist -nl -f $tfile 3
186 187
187 188 In [13]: import os; os.unlink(tfile)
188 189 """
189 190
190 191
191 192 @dec.skip_without('sqlite3')
192 193 def doctest_hist_r():
193 194 """Test %hist -r
194 195
195 196 XXX - This test is not recording the output correctly. For some reason, in
196 197 testing mode the raw history isn't getting populated. No idea why.
197 198 Disabling the output checking for now, though at least we do run it.
198 199
199 200 In [1]: 'hist' in _ip.lsmagic()
200 201 Out[1]: True
201 202
202 203 In [2]: x=1
203 204
204 205 In [3]: %hist -rl 2
205 206 x=1 # random
206 207 %hist -r 2
207 208 """
208 209
209 210
210 211 @dec.skip_without('sqlite3')
211 212 def doctest_hist_op():
212 213 """Test %hist -op
213 214
214 215 In [1]: class b(float):
215 216 ...: pass
216 217 ...:
217 218
218 219 In [2]: class s(object):
219 220 ...: def __str__(self):
220 221 ...: return 's'
221 222 ...:
222 223
223 224 In [3]:
224 225
225 226 In [4]: class r(b):
226 227 ...: def __repr__(self):
227 228 ...: return 'r'
228 229 ...:
229 230
230 231 In [5]: class sr(s,r): pass
231 232 ...:
232 233
233 234 In [6]:
234 235
235 236 In [7]: bb=b()
236 237
237 238 In [8]: ss=s()
238 239
239 240 In [9]: rr=r()
240 241
241 242 In [10]: ssrr=sr()
242 243
243 244 In [11]: 4.5
244 245 Out[11]: 4.5
245 246
246 247 In [12]: str(ss)
247 248 Out[12]: 's'
248 249
249 250 In [13]:
250 251
251 252 In [14]: %hist -op
252 253 >>> class b:
253 254 ... pass
254 255 ...
255 256 >>> class s(b):
256 257 ... def __str__(self):
257 258 ... return 's'
258 259 ...
259 260 >>>
260 261 >>> class r(b):
261 262 ... def __repr__(self):
262 263 ... return 'r'
263 264 ...
264 265 >>> class sr(s,r): pass
265 266 >>>
266 267 >>> bb=b()
267 268 >>> ss=s()
268 269 >>> rr=r()
269 270 >>> ssrr=sr()
270 271 >>> 4.5
271 272 4.5
272 273 >>> str(ss)
273 274 's'
274 275 >>>
275 276 """
276 277
277 278 def test_hist_pof():
278 279 ip = get_ipython()
279 280 ip.run_cell(u"1+2", store_history=True)
280 281 #raise Exception(ip.history_manager.session_number)
281 282 #raise Exception(list(ip.history_manager._get_range_session()))
282 283 with TemporaryDirectory() as td:
283 284 tf = os.path.join(td, 'hist.py')
284 285 ip.run_line_magic('history', '-pof %s' % tf)
285 286 assert os.path.isfile(tf)
286 287
287 288
288 289 @dec.skip_without('sqlite3')
289 290 def test_macro():
290 291 ip = get_ipython()
291 292 ip.history_manager.reset() # Clear any existing history.
292 293 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
293 294 for i, cmd in enumerate(cmds, start=1):
294 295 ip.history_manager.store_inputs(i, cmd)
295 296 ip.magic("macro test 1-3")
296 297 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
297 298
298 299 # List macros
299 300 nt.assert_in("test", ip.magic("macro"))
300 301
301 302
302 303 @dec.skip_without('sqlite3')
303 304 def test_macro_run():
304 305 """Test that we can run a multi-line macro successfully."""
305 306 ip = get_ipython()
306 307 ip.history_manager.reset()
307 308 cmds = ["a=10", "a+=1", "print(a)", "%macro test 2-3"]
308 309 for cmd in cmds:
309 310 ip.run_cell(cmd, store_history=True)
310 311 nt.assert_equal(ip.user_ns["test"].value, "a+=1\nprint(a)\n")
311 312 with tt.AssertPrints("12"):
312 313 ip.run_cell("test")
313 314 with tt.AssertPrints("13"):
314 315 ip.run_cell("test")
315 316
316 317
317 318 def test_magic_magic():
318 319 """Test %magic"""
319 320 ip = get_ipython()
320 321 with capture_output() as captured:
321 322 ip.magic("magic")
322 323
323 324 stdout = captured.stdout
324 325 nt.assert_in('%magic', stdout)
325 326 nt.assert_in('IPython', stdout)
326 327 nt.assert_in('Available', stdout)
327 328
328 329
329 330 @dec.skipif_not_numpy
330 331 def test_numpy_reset_array_undec():
331 332 "Test '%reset array' functionality"
332 333 _ip.ex('import numpy as np')
333 334 _ip.ex('a = np.empty(2)')
334 335 nt.assert_in('a', _ip.user_ns)
335 336 _ip.magic('reset -f array')
336 337 nt.assert_not_in('a', _ip.user_ns)
337 338
338 339 def test_reset_out():
339 340 "Test '%reset out' magic"
340 341 _ip.run_cell("parrot = 'dead'", store_history=True)
341 342 # test '%reset -f out', make an Out prompt
342 343 _ip.run_cell("parrot", store_history=True)
343 344 nt.assert_true('dead' in [_ip.user_ns[x] for x in ('_','__','___')])
344 345 _ip.magic('reset -f out')
345 346 nt.assert_false('dead' in [_ip.user_ns[x] for x in ('_','__','___')])
346 347 nt.assert_equal(len(_ip.user_ns['Out']), 0)
347 348
348 349 def test_reset_in():
349 350 "Test '%reset in' magic"
350 351 # test '%reset -f in'
351 352 _ip.run_cell("parrot", store_history=True)
352 353 nt.assert_true('parrot' in [_ip.user_ns[x] for x in ('_i','_ii','_iii')])
353 354 _ip.magic('%reset -f in')
354 355 nt.assert_false('parrot' in [_ip.user_ns[x] for x in ('_i','_ii','_iii')])
355 356 nt.assert_equal(len(set(_ip.user_ns['In'])), 1)
356 357
357 358 def test_reset_dhist():
358 359 "Test '%reset dhist' magic"
359 360 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
360 361 _ip.magic('cd ' + os.path.dirname(nt.__file__))
361 362 _ip.magic('cd -')
362 363 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
363 364 _ip.magic('reset -f dhist')
364 365 nt.assert_equal(len(_ip.user_ns['_dh']), 0)
365 366 _ip.run_cell("_dh = [d for d in tmp]") #restore
366 367
367 368 def test_reset_in_length():
368 369 "Test that '%reset in' preserves In[] length"
369 370 _ip.run_cell("print 'foo'")
370 371 _ip.run_cell("reset -f in")
371 372 nt.assert_equal(len(_ip.user_ns['In']), _ip.displayhook.prompt_count+1)
372 373
373 374 class TestResetErrors(TestCase):
374 375
375 376 def test_reset_redefine(self):
376 377
377 378 @magics_class
378 379 class KernelMagics(Magics):
379 380 @line_magic
380 381 def less(self, shell): pass
381 382
382 383 _ip.register_magics(KernelMagics)
383 384
384 385 with self.assertLogs() as cm:
385 386 # hack, we want to just capture logs, but assertLogs fails if not
386 387 # logs get produce.
387 388 # so log one things we ignore.
388 389 import logging as log_mod
389 390 log = log_mod.getLogger()
390 391 log.info('Nothing')
391 392 # end hack.
392 393 _ip.run_cell("reset -f")
393 394
394 395 assert len(cm.output) == 1
395 396 for out in cm.output:
396 397 assert "Invalid alias" not in out
397 398
398 399 def test_tb_syntaxerror():
399 400 """test %tb after a SyntaxError"""
400 401 ip = get_ipython()
401 402 ip.run_cell("for")
402 403
403 404 # trap and validate stdout
404 405 save_stdout = sys.stdout
405 406 try:
406 407 sys.stdout = StringIO()
407 408 ip.run_cell("%tb")
408 409 out = sys.stdout.getvalue()
409 410 finally:
410 411 sys.stdout = save_stdout
411 412 # trim output, and only check the last line
412 413 last_line = out.rstrip().splitlines()[-1].strip()
413 414 nt.assert_equal(last_line, "SyntaxError: invalid syntax")
414 415
415 416
416 417 def test_time():
417 418 ip = get_ipython()
418 419
419 420 with tt.AssertPrints("Wall time: "):
420 421 ip.run_cell("%time None")
421 422
422 423 ip.run_cell("def f(kmjy):\n"
423 424 " %time print (2*kmjy)")
424 425
425 426 with tt.AssertPrints("Wall time: "):
426 427 with tt.AssertPrints("hihi", suppress=False):
427 428 ip.run_cell("f('hi')")
428 429
429 430 def test_time_last_not_expression():
430 431 ip.run_cell("%%time\n"
431 432 "var_1 = 1\n"
432 433 "var_2 = 2\n")
433 434 assert ip.user_ns['var_1'] == 1
434 435 del ip.user_ns['var_1']
435 436 assert ip.user_ns['var_2'] == 2
436 437 del ip.user_ns['var_2']
437 438
438 439
439 440 @dec.skip_win32
440 441 def test_time2():
441 442 ip = get_ipython()
442 443
443 444 with tt.AssertPrints("CPU times: user "):
444 445 ip.run_cell("%time None")
445 446
446 447 def test_time3():
447 448 """Erroneous magic function calls, issue gh-3334"""
448 449 ip = get_ipython()
449 450 ip.user_ns.pop('run', None)
450 451
451 452 with tt.AssertNotPrints("not found", channel='stderr'):
452 453 ip.run_cell("%%time\n"
453 454 "run = 0\n"
454 455 "run += 1")
455 456
456 457 def test_multiline_time():
457 458 """Make sure last statement from time return a value."""
458 459 ip = get_ipython()
459 460 ip.user_ns.pop('run', None)
460 461
461 462 ip.run_cell(dedent("""\
462 463 %%time
463 464 a = "ho"
464 465 b = "hey"
465 466 a+b
466 467 """))
467 468 nt.assert_equal(ip.user_ns_hidden['_'], 'hohey')
468 469
469 470 def test_time_local_ns():
470 471 """
471 472 Test that local_ns is actually global_ns when running a cell magic
472 473 """
473 474 ip = get_ipython()
474 475 ip.run_cell("%%time\n"
475 476 "myvar = 1")
476 477 nt.assert_equal(ip.user_ns['myvar'], 1)
477 478 del ip.user_ns['myvar']
478 479
479 480 def test_doctest_mode():
480 481 "Toggle doctest_mode twice, it should be a no-op and run without error"
481 482 _ip.magic('doctest_mode')
482 483 _ip.magic('doctest_mode')
483 484
484 485
485 486 def test_parse_options():
486 487 """Tests for basic options parsing in magics."""
487 488 # These are only the most minimal of tests, more should be added later. At
488 489 # the very least we check that basic text/unicode calls work OK.
489 490 m = DummyMagics(_ip)
490 491 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
491 492 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
492 493
493 494
494 495 def test_dirops():
495 496 """Test various directory handling operations."""
496 497 # curpath = lambda :os.path.splitdrive(os.getcwd())[1].replace('\\','/')
497 498 curpath = os.getcwd
498 499 startdir = os.getcwd()
499 500 ipdir = os.path.realpath(_ip.ipython_dir)
500 501 try:
501 502 _ip.magic('cd "%s"' % ipdir)
502 503 nt.assert_equal(curpath(), ipdir)
503 504 _ip.magic('cd -')
504 505 nt.assert_equal(curpath(), startdir)
505 506 _ip.magic('pushd "%s"' % ipdir)
506 507 nt.assert_equal(curpath(), ipdir)
507 508 _ip.magic('popd')
508 509 nt.assert_equal(curpath(), startdir)
509 510 finally:
510 511 os.chdir(startdir)
511 512
512 513
513 514 def test_cd_force_quiet():
514 515 """Test OSMagics.cd_force_quiet option"""
515 516 _ip.config.OSMagics.cd_force_quiet = True
516 517 osmagics = osm.OSMagics(shell=_ip)
517 518
518 519 startdir = os.getcwd()
519 520 ipdir = os.path.realpath(_ip.ipython_dir)
520 521
521 522 try:
522 523 with tt.AssertNotPrints(ipdir):
523 524 osmagics.cd('"%s"' % ipdir)
524 525 with tt.AssertNotPrints(startdir):
525 526 osmagics.cd('-')
526 527 finally:
527 528 os.chdir(startdir)
528 529
529 530
530 531 def test_xmode():
531 532 # Calling xmode three times should be a no-op
532 533 xmode = _ip.InteractiveTB.mode
533 534 for i in range(4):
534 535 _ip.magic("xmode")
535 536 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
536 537
537 538 def test_reset_hard():
538 539 monitor = []
539 540 class A(object):
540 541 def __del__(self):
541 542 monitor.append(1)
542 543 def __repr__(self):
543 544 return "<A instance>"
544 545
545 546 _ip.user_ns["a"] = A()
546 547 _ip.run_cell("a")
547 548
548 549 nt.assert_equal(monitor, [])
549 550 _ip.magic("reset -f")
550 551 nt.assert_equal(monitor, [1])
551 552
552 553 class TestXdel(tt.TempFileMixin):
553 554 def test_xdel(self):
554 555 """Test that references from %run are cleared by xdel."""
555 556 src = ("class A(object):\n"
556 557 " monitor = []\n"
557 558 " def __del__(self):\n"
558 559 " self.monitor.append(1)\n"
559 560 "a = A()\n")
560 561 self.mktmp(src)
561 562 # %run creates some hidden references...
562 563 _ip.magic("run %s" % self.fname)
563 564 # ... as does the displayhook.
564 565 _ip.run_cell("a")
565 566
566 567 monitor = _ip.user_ns["A"].monitor
567 568 nt.assert_equal(monitor, [])
568 569
569 570 _ip.magic("xdel a")
570 571
571 572 # Check that a's __del__ method has been called.
572 573 nt.assert_equal(monitor, [1])
573 574
574 575 def doctest_who():
575 576 """doctest for %who
576 577
577 578 In [1]: %reset -f
578 579
579 580 In [2]: alpha = 123
580 581
581 582 In [3]: beta = 'beta'
582 583
583 584 In [4]: %who int
584 585 alpha
585 586
586 587 In [5]: %who str
587 588 beta
588 589
589 590 In [6]: %whos
590 591 Variable Type Data/Info
591 592 ----------------------------
592 593 alpha int 123
593 594 beta str beta
594 595
595 596 In [7]: %who_ls
596 597 Out[7]: ['alpha', 'beta']
597 598 """
598 599
599 600 def test_whos():
600 601 """Check that whos is protected against objects where repr() fails."""
601 602 class A(object):
602 603 def __repr__(self):
603 604 raise Exception()
604 605 _ip.user_ns['a'] = A()
605 606 _ip.magic("whos")
606 607
607 608 def doctest_precision():
608 609 """doctest for %precision
609 610
610 611 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
611 612
612 613 In [2]: %precision 5
613 614 Out[2]: '%.5f'
614 615
615 616 In [3]: f.float_format
616 617 Out[3]: '%.5f'
617 618
618 619 In [4]: %precision %e
619 620 Out[4]: '%e'
620 621
621 622 In [5]: f(3.1415927)
622 623 Out[5]: '3.141593e+00'
623 624 """
624 625
626 def test_debug_magic():
627 """Test debugging a small code with %debug
628
629 In [1]: with PdbTestInput(['c']):
630 ...: %debug print("a b") #doctest: +ELLIPSIS
631 ...:
632 ...
633 ipdb> c
634 a b
635 In [2]:
636 """
637
625 638 def test_psearch():
626 639 with tt.AssertPrints("dict.fromkeys"):
627 640 _ip.run_cell("dict.fr*?")
628 641 with tt.AssertPrints("Ο€.is_integer"):
629 642 _ip.run_cell("Ο€ = 3.14;\nΟ€.is_integ*?")
630 643
631 644 def test_timeit_shlex():
632 645 """test shlex issues with timeit (#1109)"""
633 646 _ip.ex("def f(*a,**kw): pass")
634 647 _ip.magic('timeit -n1 "this is a bug".count(" ")')
635 648 _ip.magic('timeit -r1 -n1 f(" ", 1)')
636 649 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
637 650 _ip.magic('timeit -r1 -n1 ("a " + "b")')
638 651 _ip.magic('timeit -r1 -n1 f("a " + "b")')
639 652 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
640 653
641 654
642 655 def test_timeit_special_syntax():
643 656 "Test %%timeit with IPython special syntax"
644 657 @register_line_magic
645 658 def lmagic(line):
646 659 ip = get_ipython()
647 660 ip.user_ns['lmagic_out'] = line
648 661
649 662 # line mode test
650 663 _ip.run_line_magic('timeit', '-n1 -r1 %lmagic my line')
651 664 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
652 665 # cell mode test
653 666 _ip.run_cell_magic('timeit', '-n1 -r1', '%lmagic my line2')
654 667 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
655 668
656 669 def test_timeit_return():
657 670 """
658 671 test whether timeit -o return object
659 672 """
660 673
661 674 res = _ip.run_line_magic('timeit','-n10 -r10 -o 1')
662 675 assert(res is not None)
663 676
664 677 def test_timeit_quiet():
665 678 """
666 679 test quiet option of timeit magic
667 680 """
668 681 with tt.AssertNotPrints("loops"):
669 682 _ip.run_cell("%timeit -n1 -r1 -q 1")
670 683
671 684 def test_timeit_return_quiet():
672 685 with tt.AssertNotPrints("loops"):
673 686 res = _ip.run_line_magic('timeit', '-n1 -r1 -q -o 1')
674 687 assert (res is not None)
675 688
676 689 def test_timeit_invalid_return():
677 690 with nt.assert_raises_regex(SyntaxError, "outside function"):
678 691 _ip.run_line_magic('timeit', 'return')
679 692
680 693 @dec.skipif(execution.profile is None)
681 694 def test_prun_special_syntax():
682 695 "Test %%prun with IPython special syntax"
683 696 @register_line_magic
684 697 def lmagic(line):
685 698 ip = get_ipython()
686 699 ip.user_ns['lmagic_out'] = line
687 700
688 701 # line mode test
689 702 _ip.run_line_magic('prun', '-q %lmagic my line')
690 703 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
691 704 # cell mode test
692 705 _ip.run_cell_magic('prun', '-q', '%lmagic my line2')
693 706 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
694 707
695 708 @dec.skipif(execution.profile is None)
696 709 def test_prun_quotes():
697 710 "Test that prun does not clobber string escapes (GH #1302)"
698 711 _ip.magic(r"prun -q x = '\t'")
699 712 nt.assert_equal(_ip.user_ns['x'], '\t')
700 713
701 714 def test_extension():
702 715 # Debugging information for failures of this test
703 716 print('sys.path:')
704 717 for p in sys.path:
705 718 print(' ', p)
706 719 print('CWD', os.getcwd())
707 720
708 721 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
709 722 daft_path = os.path.join(os.path.dirname(__file__), "daft_extension")
710 723 sys.path.insert(0, daft_path)
711 724 try:
712 725 _ip.user_ns.pop('arq', None)
713 726 invalidate_caches() # Clear import caches
714 727 _ip.magic("load_ext daft_extension")
715 728 nt.assert_equal(_ip.user_ns['arq'], 185)
716 729 _ip.magic("unload_ext daft_extension")
717 730 assert 'arq' not in _ip.user_ns
718 731 finally:
719 732 sys.path.remove(daft_path)
720 733
721 734
722 735 def test_notebook_export_json():
723 736 _ip = get_ipython()
724 737 _ip.history_manager.reset() # Clear any existing history.
725 738 cmds = [u"a=1", u"def b():\n return a**2", u"print('noΓ«l, Γ©tΓ©', b())"]
726 739 for i, cmd in enumerate(cmds, start=1):
727 740 _ip.history_manager.store_inputs(i, cmd)
728 741 with TemporaryDirectory() as td:
729 742 outfile = os.path.join(td, "nb.ipynb")
730 743 _ip.magic("notebook -e %s" % outfile)
731 744
732 745
733 746 class TestEnv(TestCase):
734 747
735 748 def test_env(self):
736 749 env = _ip.magic("env")
737 750 self.assertTrue(isinstance(env, dict))
738 751
739 752 def test_env_secret(self):
740 753 env = _ip.magic("env")
741 754 hidden = "<hidden>"
742 755 with mock.patch.dict(
743 756 os.environ,
744 757 {
745 758 "API_KEY": "abc123",
746 759 "SECRET_THING": "ssshhh",
747 760 "JUPYTER_TOKEN": "",
748 761 "VAR": "abc"
749 762 }
750 763 ):
751 764 env = _ip.magic("env")
752 765 assert env["API_KEY"] == hidden
753 766 assert env["SECRET_THING"] == hidden
754 767 assert env["JUPYTER_TOKEN"] == hidden
755 768 assert env["VAR"] == "abc"
756 769
757 770 def test_env_get_set_simple(self):
758 771 env = _ip.magic("env var val1")
759 772 self.assertEqual(env, None)
760 773 self.assertEqual(os.environ['var'], 'val1')
761 774 self.assertEqual(_ip.magic("env var"), 'val1')
762 775 env = _ip.magic("env var=val2")
763 776 self.assertEqual(env, None)
764 777 self.assertEqual(os.environ['var'], 'val2')
765 778
766 779 def test_env_get_set_complex(self):
767 780 env = _ip.magic("env var 'val1 '' 'val2")
768 781 self.assertEqual(env, None)
769 782 self.assertEqual(os.environ['var'], "'val1 '' 'val2")
770 783 self.assertEqual(_ip.magic("env var"), "'val1 '' 'val2")
771 784 env = _ip.magic('env var=val2 val3="val4')
772 785 self.assertEqual(env, None)
773 786 self.assertEqual(os.environ['var'], 'val2 val3="val4')
774 787
775 788 def test_env_set_bad_input(self):
776 789 self.assertRaises(UsageError, lambda: _ip.magic("set_env var"))
777 790
778 791 def test_env_set_whitespace(self):
779 792 self.assertRaises(UsageError, lambda: _ip.magic("env var A=B"))
780 793
781 794
782 795 class CellMagicTestCase(TestCase):
783 796
784 797 def check_ident(self, magic):
785 798 # Manually called, we get the result
786 799 out = _ip.run_cell_magic(magic, 'a', 'b')
787 800 nt.assert_equal(out, ('a','b'))
788 801 # Via run_cell, it goes into the user's namespace via displayhook
789 802 _ip.run_cell('%%' + magic +' c\nd\n')
790 803 nt.assert_equal(_ip.user_ns['_'], ('c','d\n'))
791 804
792 805 def test_cell_magic_func_deco(self):
793 806 "Cell magic using simple decorator"
794 807 @register_cell_magic
795 808 def cellm(line, cell):
796 809 return line, cell
797 810
798 811 self.check_ident('cellm')
799 812
800 813 def test_cell_magic_reg(self):
801 814 "Cell magic manually registered"
802 815 def cellm(line, cell):
803 816 return line, cell
804 817
805 818 _ip.register_magic_function(cellm, 'cell', 'cellm2')
806 819 self.check_ident('cellm2')
807 820
808 821 def test_cell_magic_class(self):
809 822 "Cell magics declared via a class"
810 823 @magics_class
811 824 class MyMagics(Magics):
812 825
813 826 @cell_magic
814 827 def cellm3(self, line, cell):
815 828 return line, cell
816 829
817 830 _ip.register_magics(MyMagics)
818 831 self.check_ident('cellm3')
819 832
820 833 def test_cell_magic_class2(self):
821 834 "Cell magics declared via a class, #2"
822 835 @magics_class
823 836 class MyMagics2(Magics):
824 837
825 838 @cell_magic('cellm4')
826 839 def cellm33(self, line, cell):
827 840 return line, cell
828 841
829 842 _ip.register_magics(MyMagics2)
830 843 self.check_ident('cellm4')
831 844 # Check that nothing is registered as 'cellm33'
832 845 c33 = _ip.find_cell_magic('cellm33')
833 846 nt.assert_equal(c33, None)
834 847
835 848 def test_file():
836 849 """Basic %%writefile"""
837 850 ip = get_ipython()
838 851 with TemporaryDirectory() as td:
839 852 fname = os.path.join(td, 'file1')
840 853 ip.run_cell_magic("writefile", fname, u'\n'.join([
841 854 'line1',
842 855 'line2',
843 856 ]))
844 857 with open(fname) as f:
845 858 s = f.read()
846 859 nt.assert_in('line1\n', s)
847 860 nt.assert_in('line2', s)
848 861
849 862 @dec.skip_win32
850 863 def test_file_single_quote():
851 864 """Basic %%writefile with embedded single quotes"""
852 865 ip = get_ipython()
853 866 with TemporaryDirectory() as td:
854 867 fname = os.path.join(td, '\'file1\'')
855 868 ip.run_cell_magic("writefile", fname, u'\n'.join([
856 869 'line1',
857 870 'line2',
858 871 ]))
859 872 with open(fname) as f:
860 873 s = f.read()
861 874 nt.assert_in('line1\n', s)
862 875 nt.assert_in('line2', s)
863 876
864 877 @dec.skip_win32
865 878 def test_file_double_quote():
866 879 """Basic %%writefile with embedded double quotes"""
867 880 ip = get_ipython()
868 881 with TemporaryDirectory() as td:
869 882 fname = os.path.join(td, '"file1"')
870 883 ip.run_cell_magic("writefile", fname, u'\n'.join([
871 884 'line1',
872 885 'line2',
873 886 ]))
874 887 with open(fname) as f:
875 888 s = f.read()
876 889 nt.assert_in('line1\n', s)
877 890 nt.assert_in('line2', s)
878 891
879 892 def test_file_var_expand():
880 893 """%%writefile $filename"""
881 894 ip = get_ipython()
882 895 with TemporaryDirectory() as td:
883 896 fname = os.path.join(td, 'file1')
884 897 ip.user_ns['filename'] = fname
885 898 ip.run_cell_magic("writefile", '$filename', u'\n'.join([
886 899 'line1',
887 900 'line2',
888 901 ]))
889 902 with open(fname) as f:
890 903 s = f.read()
891 904 nt.assert_in('line1\n', s)
892 905 nt.assert_in('line2', s)
893 906
894 907 def test_file_unicode():
895 908 """%%writefile with unicode cell"""
896 909 ip = get_ipython()
897 910 with TemporaryDirectory() as td:
898 911 fname = os.path.join(td, 'file1')
899 912 ip.run_cell_magic("writefile", fname, u'\n'.join([
900 913 u'linΓ©1',
901 914 u'linΓ©2',
902 915 ]))
903 916 with io.open(fname, encoding='utf-8') as f:
904 917 s = f.read()
905 918 nt.assert_in(u'linΓ©1\n', s)
906 919 nt.assert_in(u'linΓ©2', s)
907 920
908 921 def test_file_amend():
909 922 """%%writefile -a amends files"""
910 923 ip = get_ipython()
911 924 with TemporaryDirectory() as td:
912 925 fname = os.path.join(td, 'file2')
913 926 ip.run_cell_magic("writefile", fname, u'\n'.join([
914 927 'line1',
915 928 'line2',
916 929 ]))
917 930 ip.run_cell_magic("writefile", "-a %s" % fname, u'\n'.join([
918 931 'line3',
919 932 'line4',
920 933 ]))
921 934 with open(fname) as f:
922 935 s = f.read()
923 936 nt.assert_in('line1\n', s)
924 937 nt.assert_in('line3\n', s)
925 938
926 939 def test_file_spaces():
927 940 """%%file with spaces in filename"""
928 941 ip = get_ipython()
929 942 with TemporaryWorkingDirectory() as td:
930 943 fname = "file name"
931 944 ip.run_cell_magic("file", '"%s"'%fname, u'\n'.join([
932 945 'line1',
933 946 'line2',
934 947 ]))
935 948 with open(fname) as f:
936 949 s = f.read()
937 950 nt.assert_in('line1\n', s)
938 951 nt.assert_in('line2', s)
939 952
940 953 def test_script_config():
941 954 ip = get_ipython()
942 955 ip.config.ScriptMagics.script_magics = ['whoda']
943 956 sm = script.ScriptMagics(shell=ip)
944 957 nt.assert_in('whoda', sm.magics['cell'])
945 958
946 959 @dec.skip_win32
947 960 def test_script_out():
948 961 ip = get_ipython()
949 962 ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
950 963 nt.assert_equal(ip.user_ns['output'], 'hi\n')
951 964
952 965 @dec.skip_win32
953 966 def test_script_err():
954 967 ip = get_ipython()
955 968 ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
956 969 nt.assert_equal(ip.user_ns['error'], 'hello\n')
957 970
958 971 @dec.skip_win32
959 972 def test_script_out_err():
960 973 ip = get_ipython()
961 974 ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
962 975 nt.assert_equal(ip.user_ns['output'], 'hi\n')
963 976 nt.assert_equal(ip.user_ns['error'], 'hello\n')
964 977
965 978 @dec.skip_win32
966 979 def test_script_bg_out():
967 980 ip = get_ipython()
968 981 ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
969 982
970 983 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
971 984 ip.user_ns['output'].close()
972 985
973 986 @dec.skip_win32
974 987 def test_script_bg_err():
975 988 ip = get_ipython()
976 989 ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
977 990 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
978 991 ip.user_ns['error'].close()
979 992
980 993 @dec.skip_win32
981 994 def test_script_bg_out_err():
982 995 ip = get_ipython()
983 996 ip.run_cell_magic("script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2")
984 997 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
985 998 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
986 999 ip.user_ns['output'].close()
987 1000 ip.user_ns['error'].close()
988 1001
989 1002 def test_script_defaults():
990 1003 ip = get_ipython()
991 1004 for cmd in ['sh', 'bash', 'perl', 'ruby']:
992 1005 try:
993 1006 find_cmd(cmd)
994 1007 except Exception:
995 1008 pass
996 1009 else:
997 1010 nt.assert_in(cmd, ip.magics_manager.magics['cell'])
998 1011
999 1012
1000 1013 @magics_class
1001 1014 class FooFoo(Magics):
1002 1015 """class with both %foo and %%foo magics"""
1003 1016 @line_magic('foo')
1004 1017 def line_foo(self, line):
1005 1018 "I am line foo"
1006 1019 pass
1007 1020
1008 1021 @cell_magic("foo")
1009 1022 def cell_foo(self, line, cell):
1010 1023 "I am cell foo, not line foo"
1011 1024 pass
1012 1025
1013 1026 def test_line_cell_info():
1014 1027 """%%foo and %foo magics are distinguishable to inspect"""
1015 1028 ip = get_ipython()
1016 1029 ip.magics_manager.register(FooFoo)
1017 1030 oinfo = ip.object_inspect('foo')
1018 1031 nt.assert_true(oinfo['found'])
1019 1032 nt.assert_true(oinfo['ismagic'])
1020 1033
1021 1034 oinfo = ip.object_inspect('%%foo')
1022 1035 nt.assert_true(oinfo['found'])
1023 1036 nt.assert_true(oinfo['ismagic'])
1024 1037 nt.assert_equal(oinfo['docstring'], FooFoo.cell_foo.__doc__)
1025 1038
1026 1039 oinfo = ip.object_inspect('%foo')
1027 1040 nt.assert_true(oinfo['found'])
1028 1041 nt.assert_true(oinfo['ismagic'])
1029 1042 nt.assert_equal(oinfo['docstring'], FooFoo.line_foo.__doc__)
1030 1043
1031 1044 def test_multiple_magics():
1032 1045 ip = get_ipython()
1033 1046 foo1 = FooFoo(ip)
1034 1047 foo2 = FooFoo(ip)
1035 1048 mm = ip.magics_manager
1036 1049 mm.register(foo1)
1037 1050 nt.assert_true(mm.magics['line']['foo'].__self__ is foo1)
1038 1051 mm.register(foo2)
1039 1052 nt.assert_true(mm.magics['line']['foo'].__self__ is foo2)
1040 1053
1041 1054 def test_alias_magic():
1042 1055 """Test %alias_magic."""
1043 1056 ip = get_ipython()
1044 1057 mm = ip.magics_manager
1045 1058
1046 1059 # Basic operation: both cell and line magics are created, if possible.
1047 1060 ip.run_line_magic('alias_magic', 'timeit_alias timeit')
1048 1061 nt.assert_in('timeit_alias', mm.magics['line'])
1049 1062 nt.assert_in('timeit_alias', mm.magics['cell'])
1050 1063
1051 1064 # --cell is specified, line magic not created.
1052 1065 ip.run_line_magic('alias_magic', '--cell timeit_cell_alias timeit')
1053 1066 nt.assert_not_in('timeit_cell_alias', mm.magics['line'])
1054 1067 nt.assert_in('timeit_cell_alias', mm.magics['cell'])
1055 1068
1056 1069 # Test that line alias is created successfully.
1057 1070 ip.run_line_magic('alias_magic', '--line env_alias env')
1058 1071 nt.assert_equal(ip.run_line_magic('env', ''),
1059 1072 ip.run_line_magic('env_alias', ''))
1060 1073
1061 1074 # Test that line alias with parameters passed in is created successfully.
1062 1075 ip.run_line_magic('alias_magic', '--line history_alias history --params ' + shlex.quote('3'))
1063 1076 nt.assert_in('history_alias', mm.magics['line'])
1064 1077
1065 1078
1066 1079 def test_save():
1067 1080 """Test %save."""
1068 1081 ip = get_ipython()
1069 1082 ip.history_manager.reset() # Clear any existing history.
1070 1083 cmds = [u"a=1", u"def b():\n return a**2", u"print(a, b())"]
1071 1084 for i, cmd in enumerate(cmds, start=1):
1072 1085 ip.history_manager.store_inputs(i, cmd)
1073 1086 with TemporaryDirectory() as tmpdir:
1074 1087 file = os.path.join(tmpdir, "testsave.py")
1075 1088 ip.run_line_magic("save", "%s 1-10" % file)
1076 1089 with open(file) as f:
1077 1090 content = f.read()
1078 1091 nt.assert_equal(content.count(cmds[0]), 1)
1079 1092 nt.assert_in('coding: utf-8', content)
1080 1093 ip.run_line_magic("save", "-a %s 1-10" % file)
1081 1094 with open(file) as f:
1082 1095 content = f.read()
1083 1096 nt.assert_equal(content.count(cmds[0]), 2)
1084 1097 nt.assert_in('coding: utf-8', content)
1085 1098
1086 1099
1087 1100 def test_store():
1088 1101 """Test %store."""
1089 1102 ip = get_ipython()
1090 1103 ip.run_line_magic('load_ext', 'storemagic')
1091 1104
1092 1105 # make sure the storage is empty
1093 1106 ip.run_line_magic('store', '-z')
1094 1107 ip.user_ns['var'] = 42
1095 1108 ip.run_line_magic('store', 'var')
1096 1109 ip.user_ns['var'] = 39
1097 1110 ip.run_line_magic('store', '-r')
1098 1111 nt.assert_equal(ip.user_ns['var'], 42)
1099 1112
1100 1113 ip.run_line_magic('store', '-d var')
1101 1114 ip.user_ns['var'] = 39
1102 1115 ip.run_line_magic('store' , '-r')
1103 1116 nt.assert_equal(ip.user_ns['var'], 39)
1104 1117
1105 1118
1106 1119 def _run_edit_test(arg_s, exp_filename=None,
1107 1120 exp_lineno=-1,
1108 1121 exp_contents=None,
1109 1122 exp_is_temp=None):
1110 1123 ip = get_ipython()
1111 1124 M = code.CodeMagics(ip)
1112 1125 last_call = ['','']
1113 1126 opts,args = M.parse_options(arg_s,'prxn:')
1114 1127 filename, lineno, is_temp = M._find_edit_target(ip, args, opts, last_call)
1115 1128
1116 1129 if exp_filename is not None:
1117 1130 nt.assert_equal(exp_filename, filename)
1118 1131 if exp_contents is not None:
1119 1132 with io.open(filename, 'r', encoding='utf-8') as f:
1120 1133 contents = f.read()
1121 1134 nt.assert_equal(exp_contents, contents)
1122 1135 if exp_lineno != -1:
1123 1136 nt.assert_equal(exp_lineno, lineno)
1124 1137 if exp_is_temp is not None:
1125 1138 nt.assert_equal(exp_is_temp, is_temp)
1126 1139
1127 1140
1128 1141 def test_edit_interactive():
1129 1142 """%edit on interactively defined objects"""
1130 1143 ip = get_ipython()
1131 1144 n = ip.execution_count
1132 1145 ip.run_cell(u"def foo(): return 1", store_history=True)
1133 1146
1134 1147 try:
1135 1148 _run_edit_test("foo")
1136 1149 except code.InteractivelyDefined as e:
1137 1150 nt.assert_equal(e.index, n)
1138 1151 else:
1139 1152 raise AssertionError("Should have raised InteractivelyDefined")
1140 1153
1141 1154
1142 1155 def test_edit_cell():
1143 1156 """%edit [cell id]"""
1144 1157 ip = get_ipython()
1145 1158
1146 1159 ip.run_cell(u"def foo(): return 1", store_history=True)
1147 1160
1148 1161 # test
1149 1162 _run_edit_test("1", exp_contents=ip.user_ns['In'][1], exp_is_temp=True)
1150 1163
1151 1164 def test_bookmark():
1152 1165 ip = get_ipython()
1153 1166 ip.run_line_magic('bookmark', 'bmname')
1154 1167 with tt.AssertPrints('bmname'):
1155 1168 ip.run_line_magic('bookmark', '-l')
1156 1169 ip.run_line_magic('bookmark', '-d bmname')
1157 1170
1158 1171 def test_ls_magic():
1159 1172 ip = get_ipython()
1160 1173 json_formatter = ip.display_formatter.formatters['application/json']
1161 1174 json_formatter.enabled = True
1162 1175 lsmagic = ip.magic('lsmagic')
1163 1176 with warnings.catch_warnings(record=True) as w:
1164 1177 j = json_formatter(lsmagic)
1165 1178 nt.assert_equal(sorted(j), ['cell', 'line'])
1166 1179 nt.assert_equal(w, []) # no warnings
1167 1180
1168 1181 def test_strip_initial_indent():
1169 1182 def sii(s):
1170 1183 lines = s.splitlines()
1171 1184 return '\n'.join(code.strip_initial_indent(lines))
1172 1185
1173 1186 nt.assert_equal(sii(" a = 1\nb = 2"), "a = 1\nb = 2")
1174 1187 nt.assert_equal(sii(" a\n b\nc"), "a\n b\nc")
1175 1188 nt.assert_equal(sii("a\n b"), "a\n b")
1176 1189
1177 1190 def test_logging_magic_quiet_from_arg():
1178 1191 _ip.config.LoggingMagics.quiet = False
1179 1192 lm = logging.LoggingMagics(shell=_ip)
1180 1193 with TemporaryDirectory() as td:
1181 1194 try:
1182 1195 with tt.AssertNotPrints(re.compile("Activating.*")):
1183 1196 lm.logstart('-q {}'.format(
1184 1197 os.path.join(td, "quiet_from_arg.log")))
1185 1198 finally:
1186 1199 _ip.logger.logstop()
1187 1200
1188 1201 def test_logging_magic_quiet_from_config():
1189 1202 _ip.config.LoggingMagics.quiet = True
1190 1203 lm = logging.LoggingMagics(shell=_ip)
1191 1204 with TemporaryDirectory() as td:
1192 1205 try:
1193 1206 with tt.AssertNotPrints(re.compile("Activating.*")):
1194 1207 lm.logstart(os.path.join(td, "quiet_from_config.log"))
1195 1208 finally:
1196 1209 _ip.logger.logstop()
1197 1210
1198 1211
1199 1212 def test_logging_magic_not_quiet():
1200 1213 _ip.config.LoggingMagics.quiet = False
1201 1214 lm = logging.LoggingMagics(shell=_ip)
1202 1215 with TemporaryDirectory() as td:
1203 1216 try:
1204 1217 with tt.AssertPrints(re.compile("Activating.*")):
1205 1218 lm.logstart(os.path.join(td, "not_quiet.log"))
1206 1219 finally:
1207 1220 _ip.logger.logstop()
1208 1221
1209 1222
1210 1223 def test_time_no_var_expand():
1211 1224 _ip.user_ns['a'] = 5
1212 1225 _ip.user_ns['b'] = []
1213 1226 _ip.magic('time b.append("{a}")')
1214 1227 assert _ip.user_ns['b'] == ['{a}']
1215 1228
1216 1229
1217 1230 # this is slow, put at the end for local testing.
1218 1231 def test_timeit_arguments():
1219 1232 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
1220 1233 if sys.version_info < (3,7):
1221 1234 _ip.magic("timeit -n1 -r1 ('#')")
1222 1235 else:
1223 1236 # 3.7 optimize no-op statement like above out, and complain there is
1224 1237 # nothing in the for loop.
1225 1238 _ip.magic("timeit -n1 -r1 a=('#')")
General Comments 0
You need to be logged in to leave comments. Login now