Skip to content

Commit 82092dd

Browse files
committed
Move core profiling module into a package
This allows adding a new 'sample' submodule and enables invoking the sampling profiler through 'python -m profile.sample', while retaining backwards compatibility when using 'profile'.
1 parent da79ac9 commit 82092dd

3 files changed

Lines changed: 75 additions & 63 deletions

File tree

Lib/profile/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from .profile import run
2+
from .profile import runctx
3+
from .profile import Profile
4+
from .profile import _Utils
5+
6+
__all__ = ['run', 'runctx', 'Profile']

Lib/profile/__main__.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import io
2+
import importlib.machinery
3+
import os
4+
import sys
5+
from optparse import OptionParser
6+
7+
from .profile import runctx
8+
9+
10+
def main():
11+
12+
usage = "profile.py [-o output_file_path] [-s sort] [-m module | scriptfile] [arg] ..."
13+
parser = OptionParser(usage=usage)
14+
parser.allow_interspersed_args = False
15+
parser.add_option('-o', '--outfile', dest="outfile",
16+
help="Save stats to <outfile>", default=None)
17+
parser.add_option('-m', dest="module", action="store_true",
18+
help="Profile a library module.", default=False)
19+
parser.add_option('-s', '--sort', dest="sort",
20+
help="Sort order when printing to stdout, based on pstats.Stats class",
21+
default=-1)
22+
23+
if not sys.argv[1:]:
24+
parser.print_usage()
25+
sys.exit(2)
26+
27+
(options, args) = parser.parse_args()
28+
sys.argv[:] = args
29+
30+
# The script that we're profiling may chdir, so capture the absolute path
31+
# to the output file at startup.
32+
if options.outfile is not None:
33+
options.outfile = os.path.abspath(options.outfile)
34+
35+
if len(args) > 0:
36+
if options.module:
37+
import runpy
38+
code = "run_module(modname, run_name='__main__')"
39+
globs = {
40+
'run_module': runpy.run_module,
41+
'modname': args[0]
42+
}
43+
else:
44+
progname = args[0]
45+
sys.path.insert(0, os.path.dirname(progname))
46+
with io.open_code(progname) as fp:
47+
code = compile(fp.read(), progname, 'exec')
48+
spec = importlib.machinery.ModuleSpec(name='__main__', loader=None,
49+
origin=progname)
50+
globs = {
51+
'__spec__': spec,
52+
'__file__': spec.origin,
53+
'__name__': spec.name,
54+
'__package__': None,
55+
'__cached__': None,
56+
}
57+
try:
58+
runctx(code, globs, None, options.outfile, options.sort)
59+
except BrokenPipeError as exc:
60+
# Prevent "Exception ignored" during interpreter shutdown.
61+
sys.stdout = None
62+
sys.exit(exc.errno)
63+
else:
64+
parser.print_usage()
65+
return parser
66+
67+
# When invoked as main program, invoke the profiler on a script
68+
if __name__ == '__main__':
69+
main()

Lib/profile.py renamed to Lib/profile/profile.py

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -550,66 +550,3 @@ def f(m, f1=f1):
550550
return mean
551551

552552
#****************************************************************************
553-
554-
def main():
555-
import os
556-
from optparse import OptionParser
557-
558-
usage = "profile.py [-o output_file_path] [-s sort] [-m module | scriptfile] [arg] ..."
559-
parser = OptionParser(usage=usage)
560-
parser.allow_interspersed_args = False
561-
parser.add_option('-o', '--outfile', dest="outfile",
562-
help="Save stats to <outfile>", default=None)
563-
parser.add_option('-m', dest="module", action="store_true",
564-
help="Profile a library module.", default=False)
565-
parser.add_option('-s', '--sort', dest="sort",
566-
help="Sort order when printing to stdout, based on pstats.Stats class",
567-
default=-1)
568-
569-
if not sys.argv[1:]:
570-
parser.print_usage()
571-
sys.exit(2)
572-
573-
(options, args) = parser.parse_args()
574-
sys.argv[:] = args
575-
576-
# The script that we're profiling may chdir, so capture the absolute path
577-
# to the output file at startup.
578-
if options.outfile is not None:
579-
options.outfile = os.path.abspath(options.outfile)
580-
581-
if len(args) > 0:
582-
if options.module:
583-
import runpy
584-
code = "run_module(modname, run_name='__main__')"
585-
globs = {
586-
'run_module': runpy.run_module,
587-
'modname': args[0]
588-
}
589-
else:
590-
progname = args[0]
591-
sys.path.insert(0, os.path.dirname(progname))
592-
with io.open_code(progname) as fp:
593-
code = compile(fp.read(), progname, 'exec')
594-
spec = importlib.machinery.ModuleSpec(name='__main__', loader=None,
595-
origin=progname)
596-
globs = {
597-
'__spec__': spec,
598-
'__file__': spec.origin,
599-
'__name__': spec.name,
600-
'__package__': None,
601-
'__cached__': None,
602-
}
603-
try:
604-
runctx(code, globs, None, options.outfile, options.sort)
605-
except BrokenPipeError as exc:
606-
# Prevent "Exception ignored" during interpreter shutdown.
607-
sys.stdout = None
608-
sys.exit(exc.errno)
609-
else:
610-
parser.print_usage()
611-
return parser
612-
613-
# When invoked as main program, invoke the profiler on a script
614-
if __name__ == '__main__':
615-
main()

0 commit comments

Comments
 (0)