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