bpo-21862: Add -m option to cProfile for profiling modules (#4297) · python/cpython@7973e27
@@ -121,16 +121,20 @@ def label(code):
121121# ____________________________________________________________
122122123123def main():
124-import os, sys
124+import os
125+import sys
126+import runpy
125127from optparse import OptionParser
126-usage = "cProfile.py [-o output_file_path] [-s sort] scriptfile [arg] ..."
128+usage = "cProfile.py [-o output_file_path] [-s sort] [-m module | scriptfile] [arg] ..."
127129parser = OptionParser(usage=usage)
128130parser.allow_interspersed_args = False
129131parser.add_option('-o', '--outfile', dest="outfile",
130132help="Save stats to <outfile>", default=None)
131133parser.add_option('-s', '--sort', dest="sort",
132134help="Sort order when printing to stdout, based on pstats.Stats class",
133135default=-1)
136+parser.add_option('-m', dest="module", action="store_true",
137+help="Profile a library module", default=False)
134138135139if not sys.argv[1:]:
136140parser.print_usage()
@@ -140,16 +144,23 @@ def main():
140144sys.argv[:] = args
141145142146if len(args) > 0:
143-progname = args[0]
144-sys.path.insert(0, os.path.dirname(progname))
145-with open(progname, 'rb') as fp:
146-code = compile(fp.read(), progname, 'exec')
147-globs = {
148-'__file__': progname,
149-'__name__': '__main__',
150-'__package__': None,
151-'__cached__': None,
152- }
147+if options.module:
148+code = "run_module(modname, run_name='__main__')"
149+globs = {
150+'run_module': runpy.run_module,
151+'modname': args[0]
152+ }
153+else:
154+progname = args[0]
155+sys.path.insert(0, os.path.dirname(progname))
156+with open(progname, 'rb') as fp:
157+code = compile(fp.read(), progname, 'exec')
158+globs = {
159+'__file__': progname,
160+'__name__': '__main__',
161+'__package__': None,
162+'__cached__': None,
163+ }
153164runctx(code, globs, None, options.outfile, options.sort)
154165else:
155166parser.print_usage()