Skip to content

Commit a451719

Browse files
committed
Allow statprof to be run as a standalone executable, to profile a separate call
1 parent 3242031 commit a451719

File tree

3 files changed

+51
-0
lines changed

3 files changed

+51
-0
lines changed

README.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ Or with a contextmanager : ::
4141
with statprof.profile():
4242
my_questionable_function()
4343

44+
Or as a separate executable: ::
45+
46+
statprof my_questionable_script
47+
4448
The profiler can be invoked at more than one place inside your code and will
4549
report its findings for all of them at once at the end: ::
4650

setup.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,8 @@ def read(fname):
3030
"Operating System :: Unix",
3131
"Topic :: Utilities",
3232
],
33+
entry_points={
34+
'console_scripts': ['statprof=statprof:main']
35+
},
3336
**extra
3437
)

statprof.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
import signal
107107
import sys
108108

109+
from argparse import ArgumentParser
109110
from collections import defaultdict, namedtuple
110111
from contextlib import contextmanager
111112

@@ -484,3 +485,46 @@ def display_by_csv(fp, sort_order):
484485
row.cum_time_in_proc,
485486
row.cum_secs_in_proc,
486487
))
488+
489+
490+
def main(args=sys.argv):
491+
parser = ArgumentParser()
492+
parser.add_argument('progname', type=str)
493+
494+
formats = {
495+
'line': DisplayFormats.ByLine,
496+
'method': DisplayFormats.ByMethod,
497+
'csv': DisplayFormats.CSV,
498+
}
499+
parser.add_argument('--format', type=str, choices=formats, default='line')
500+
parser.add_argument('--outfile', type=str, default=None)
501+
502+
sorts = {
503+
'cum': SortOrders.ByCumulative,
504+
'self': SortOrders.BySelf,
505+
}
506+
parser.add_argument('--sort', type=str, choices=sorts, default='self')
507+
parser.add_argument('--quiet', action='store_true')
508+
opts, rest = parser.parse_known_args(args[1:])
509+
510+
sys.path.insert(0, os.path.dirname(opts.progname))
511+
with open(opts.progname, 'rb') as fp:
512+
code = compile(fp.read(), opts.progname, 'exec')
513+
globs = {
514+
'__file__': opts.progname,
515+
'__name__': '__main__',
516+
'__package__': None,
517+
}
518+
519+
if opts.outfile is None:
520+
outfile = sys.stdout
521+
else:
522+
outfile = open(opts.outfile('w'))
523+
524+
with profile(not opts.quiet, outfile, formats[opts.format], sorts[opts.sort]):
525+
sys.argv = [opts.progname] + rest
526+
exec code in globs, None
527+
528+
529+
if __name__ == "__main__":
530+
sys.exit(main(sys.argv))

0 commit comments

Comments
 (0)