Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Doc/library/profile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,18 @@ them in various ways.
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`` specifies that a module is being profiled instead of a script.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can add a versionadded tag just after this for the -m option.

.. versionadded:: 3.7
Added the ``-m`` option.

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::

Expand Down
6 changes: 6 additions & 0 deletions Doc/whatsnew/3.7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,12 @@ contextlib
:func:`contextlib.asynccontextmanager` has been added. (Contributed by
Jelle Zijlstra in :issue:`29679`.)

cProfile
--------

cProfile command line now accepts `-m module_name` as an alternative to
script path. (Contributed by Sanyam Khurana in :issue:`21862`.)

crypt
-----

Expand Down
35 changes: 23 additions & 12 deletions Lib/cProfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,20 @@ def label(code):
# ____________________________________________________________

def main():
import os, sys
import os
import 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",
help="Save stats to <outfile>", default=None)
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()
Expand All @@ -140,16 +144,23 @@ def main():
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 = "run_module(modname, run_name='__main__')"
globs = {
'run_module': runpy.run_module,
'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()
Expand Down
14 changes: 14 additions & 0 deletions Lib/test/test_cprofile.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
# rip off all interesting stuff from test_profile
import cProfile
from test.test_profile import ProfileTest, regenerate_expected_output
from test.support.script_helper import assert_python_failure, assert_python_ok


class CProfileTest(ProfileTest):
Expand Down Expand Up @@ -35,6 +36,19 @@ def test_bad_counter_during_dealloc(self):
finally:
unlink(TESTFN)

# Issue 21862
def test_module_path_option(self):
# Test -m switch with modules

# Test that -m switch needs an argument
assert_python_failure('-m', 'cProfile', '-m')

# Test failure for not-existent module
assert_python_failure('-m', 'cProfile', '-m', 'random_module_xyz')

# Test successful run
assert_python_ok('-m', 'cProfile', '-m', 'timeit', '-n', '1')


def test_main():
run_unittest(CProfileTest)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cProfile command line now accepts `-m module_name` as an alternative to
script path. Patch by Sanyam Khurana.