diff -r 94cade7f6e21 Doc/library/profile.rst --- a/Doc/library/profile.rst Thu Jan 22 17:53:24 2015 -0800 +++ b/Doc/library/profile.rst Wed Jan 28 04:28:58 2015 +0530 @@ -123,13 +123,15 @@ The file :mod:`cProfile` can also be invoked as a script to profile another script. For example:: - python -m cProfile [-o output_file] [-s sort_order] myscript.py + python -m cProfile [-o output_file] [-s sort_order] [-m module] | myscript.py ``-o`` writes the profile results to a file instead of to stdout ``-s`` specifies one of the :func:`~pstats.Stats.sort_stats` sort values to sort the output by. This only applies when ``-o`` is not supplied. +``-m`` switch marks that a module is being profiled in place of a script + The :mod:`pstats` module's :class:`~pstats.Stats` class has a variety of methods for manipulating and printing the data saved into a profile results file:: diff -r 94cade7f6e21 Lib/cProfile.py --- a/Lib/cProfile.py Thu Jan 22 17:53:24 2015 -0800 +++ b/Lib/cProfile.py Wed Jan 28 04:28:58 2015 +0530 @@ -122,8 +122,10 @@ def main(): import os, sys + import runpy from optparse import OptionParser - usage = "cProfile.py [-o output_file_path] [-s sort] scriptfile [arg] ..." + usage = ("cProfile.py [-o output_file_path] [-s sort] " + "[-m module | scriptfile] [arg] ...") parser = OptionParser(usage=usage) parser.allow_interspersed_args = False parser.add_option('-o', '--outfile', dest="outfile", @@ -131,6 +133,8 @@ parser.add_option('-s', '--sort', dest="sort", help="Sort order when printing to stdout, based on pstats.Stats class", default=-1) + parser.add_option('-m', dest="module", action="store_true", + help="Profile a library module", default=False) if not sys.argv[1:]: parser.print_usage() @@ -140,16 +144,23 @@ sys.argv[:] = args if len(args) > 0: - progname = args[0] - sys.path.insert(0, os.path.dirname(progname)) - with open(progname, 'rb') as fp: - code = compile(fp.read(), progname, 'exec') - globs = { - '__file__': progname, - '__name__': '__main__', - '__package__': None, - '__cached__': None, - } + if options.module: + code = "runpy.run_module(modname, run_name='__main__')" + globs = { + 'runpy': runpy, + 'modname': args[0], + } + else: + progname = args[0] + sys.path.insert(0, os.path.dirname(progname)) + with open(progname, 'rb') as fp: + code = compile(fp.read(), progname, 'exec') + globs = { + '__file__': progname, + '__name__': '__main__', + '__package__': None, + '__cached__': None, + } runctx(code, globs, None, options.outfile, options.sort) else: parser.print_usage() diff -r 94cade7f6e21 Lib/test/test_cprofile.py --- a/Lib/test/test_cprofile.py Thu Jan 22 17:53:24 2015 -0800 +++ b/Lib/test/test_cprofile.py Wed Jan 28 04:28:58 2015 +0530 @@ -7,6 +7,8 @@ import cProfile from test.test_profile import ProfileTest, regenerate_expected_output from test.profilee import testfunc +from test.script_helper import assert_python_failure, assert_python_ok + class CProfileTest(ProfileTest): profilerclass = cProfile.Profile @@ -35,6 +37,18 @@ finally: unlink(TESTFN) + def test_module_switch(self): + # Test expected operations for the '-m' switch + + # Switch needs an argument + assert_python_failure('-m', 'cProfile', '-m') + + # Error while running a nonexistent module + assert_python_failure('-m', 'cProfile', 'fnord43520xyz.py') + + # Ok if module is found and run successfully + assert_python_ok('-m', 'cProfile', '-m', 'timeit', '-n', '1') + def test_main(): run_unittest(CProfileTest)