ยปCore Development>Code coverage>Lib/cProfile.py

Python code coverage for Lib/cProfile.py

#countcontent
1n/a#! /usr/bin/env python3
2n/a
3n/a"""Python interface for the 'lsprof' profiler.
4n/a Compatible with the 'profile' module.
5n/a"""
6n/a
7n/a__all__ = ["run", "runctx", "Profile"]
8n/a
9n/aimport _lsprof
10n/aimport profile as _pyprofile
11n/a
12n/a# ____________________________________________________________
13n/a# Simple interface
14n/a
15n/adef run(statement, filename=None, sort=-1):
16n/a return _pyprofile._Utils(Profile).run(statement, filename, sort)
17n/a
18n/adef runctx(statement, globals, locals, filename=None, sort=-1):
19n/a return _pyprofile._Utils(Profile).runctx(statement, globals, locals,
20n/a filename, sort)
21n/a
22n/arun.__doc__ = _pyprofile.run.__doc__
23n/arunctx.__doc__ = _pyprofile.runctx.__doc__
24n/a
25n/a# ____________________________________________________________
26n/a
27n/aclass Profile(_lsprof.Profiler):
28n/a """Profile(custom_timer=None, time_unit=None, subcalls=True, builtins=True)
29n/a
30n/a Builds a profiler object using the specified timer function.
31n/a The default timer is a fast built-in one based on real time.
32n/a For custom timer functions returning integers, time_unit can
33n/a be a float specifying a scale (i.e. how long each integer unit
34n/a is, in seconds).
35n/a """
36n/a
37n/a # Most of the functionality is in the base class.
38n/a # This subclass only adds convenient and backward-compatible methods.
39n/a
40n/a def print_stats(self, sort=-1):
41n/a import pstats
42n/a pstats.Stats(self).strip_dirs().sort_stats(sort).print_stats()
43n/a
44n/a def dump_stats(self, file):
45n/a import marshal
46n/a with open(file, 'wb') as f:
47n/a self.create_stats()
48n/a marshal.dump(self.stats, f)
49n/a
50n/a def create_stats(self):
51n/a self.disable()
52n/a self.snapshot_stats()
53n/a
54n/a def snapshot_stats(self):
55n/a entries = self.getstats()
56n/a self.stats = {}
57n/a callersdicts = {}
58n/a # call information
59n/a for entry in entries:
60n/a func = label(entry.code)
61n/a nc = entry.callcount # ncalls column of pstats (before '/')
62n/a cc = nc - entry.reccallcount # ncalls column of pstats (after '/')
63n/a tt = entry.inlinetime # tottime column of pstats
64n/a ct = entry.totaltime # cumtime column of pstats
65n/a callers = {}
66n/a callersdicts[id(entry.code)] = callers
67n/a self.stats[func] = cc, nc, tt, ct, callers
68n/a # subcall information
69n/a for entry in entries:
70n/a if entry.calls:
71n/a func = label(entry.code)
72n/a for subentry in entry.calls:
73n/a try:
74n/a callers = callersdicts[id(subentry.code)]
75n/a except KeyError:
76n/a continue
77n/a nc = subentry.callcount
78n/a cc = nc - subentry.reccallcount
79n/a tt = subentry.inlinetime
80n/a ct = subentry.totaltime
81n/a if func in callers:
82n/a prev = callers[func]
83n/a nc += prev[0]
84n/a cc += prev[1]
85n/a tt += prev[2]
86n/a ct += prev[3]
87n/a callers[func] = nc, cc, tt, ct
88n/a
89n/a # The following two methods can be called by clients to use
90n/a # a profiler to profile a statement, given as a string.
91n/a
92n/a def run(self, cmd):
93n/a import __main__
94n/a dict = __main__.__dict__
95n/a return self.runctx(cmd, dict, dict)
96n/a
97n/a def runctx(self, cmd, globals, locals):
98n/a self.enable()
99n/a try:
100n/a exec(cmd, globals, locals)
101n/a finally:
102n/a self.disable()
103n/a return self
104n/a
105n/a # This method is more useful to profile a single function call.
106n/a def runcall(self, func, *args, **kw):
107n/a self.enable()
108n/a try:
109n/a return func(*args, **kw)
110n/a finally:
111n/a self.disable()
112n/a
113n/a# ____________________________________________________________
114n/a
115n/adef label(code):
116n/a if isinstance(code, str):
117n/a return ('~', 0, code) # built-in functions ('~' sorts at the end)
118n/a else:
119n/a return (code.co_filename, code.co_firstlineno, code.co_name)
120n/a
121n/a# ____________________________________________________________
122n/a
123n/adef main():
124n/a import os, sys
125n/a from optparse import OptionParser
126n/a usage = "cProfile.py [-o output_file_path] [-s sort] scriptfile [arg] ..."
127n/a parser = OptionParser(usage=usage)
128n/a parser.allow_interspersed_args = False
129n/a parser.add_option('-o', '--outfile', dest="outfile",
130n/a help="Save stats to <outfile>", default=None)
131n/a parser.add_option('-s', '--sort', dest="sort",
132n/a help="Sort order when printing to stdout, based on pstats.Stats class",
133n/a default=-1)
134n/a
135n/a if not sys.argv[1:]:
136n/a parser.print_usage()
137n/a sys.exit(2)
138n/a
139n/a (options, args) = parser.parse_args()
140n/a sys.argv[:] = args
141n/a
142n/a if len(args) > 0:
143n/a progname = args[0]
144n/a sys.path.insert(0, os.path.dirname(progname))
145n/a with open(progname, 'rb') as fp:
146n/a code = compile(fp.read(), progname, 'exec')
147n/a globs = {
148n/a '__file__': progname,
149n/a '__name__': '__main__',
150n/a '__package__': None,
151n/a '__cached__': None,
152n/a }
153n/a runctx(code, globs, None, options.outfile, options.sort)
154n/a else:
155n/a parser.print_usage()
156n/a return parser
157n/a
158n/a# When invoked as main program, invoke the profiler on a script
159n/aif __name__ == '__main__':
160n/a main()