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
9 changes: 6 additions & 3 deletions Doc/library/profile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ results to a file by specifying a filename to the :func:`run` function::
The :class:`pstats.Stats` class reads profile results from a file and formats
them in various ways.

The file :mod:`cProfile` can also be invoked as a script to profile another
script. For example::
The files :mod:`cProfile` and :mod:`profile` can also be invoked as a script to
profile another script. For example::

python -m cProfile [-o output_file] [-s sort_order] (-m module | myscript.py)

Expand All @@ -133,7 +133,10 @@ the output by. This only applies when ``-o`` is not supplied.
``-m`` specifies that a module is being profiled instead of a script.

.. versionadded:: 3.7
Added the ``-m`` option.
Added the ``-m`` option to :mod:`cProfile`.

.. versionadded:: 3.8
Comment thread
ncoghlan marked this conversation as resolved.
Added the ``-m`` option to :mod:`profile`.

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
32 changes: 21 additions & 11 deletions Lib/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,11 +553,13 @@ def main():
import os
from optparse import OptionParser

usage = "profile.py [-o output_file_path] [-s sort] scriptfile [arg] ..."
usage = "profile.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('-m', dest="module", action="store_true",
help="Profile a library module.", default=False)
parser.add_option('-s', '--sort', dest="sort",
help="Sort order when printing to stdout, based on pstats.Stats class",
default=-1)
Expand All @@ -570,16 +572,24 @@ 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:
import runpy
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
13 changes: 0 additions & 13 deletions Lib/test/test_cprofile.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,6 @@ 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_profile_enable_disable(self):
prof = self.profilerclass()
# Make sure we clean ourselves up if the test fails for some reason.
Expand Down
13 changes: 13 additions & 0 deletions Lib/test/test_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import profile
from test.profilee import testfunc, timer
from test.support.script_helper import assert_python_failure, assert_python_ok


class ProfileTest(unittest.TestCase):
Expand Down Expand Up @@ -98,6 +99,18 @@ def test_runctx(self):
filename=TESTFN)
self.assertTrue(os.path.exists(TESTFN))

def test_run_profile_as_module(self):
# Test that -m switch needs an argument
assert_python_failure('-m', self.profilermodule.__name__, '-m')

# Test failure for not-existent module
assert_python_failure('-m', self.profilermodule.__name__,
'-m', 'random_module_xyz')

# Test successful run
assert_python_ok('-m', self.profilermodule.__name__,
'-m', 'timeit', '-n', '1')


def regenerate_expected_output(filename, cls):
filename = filename.rstrip('co')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:mod:`profile` CLI accepts `-m module_name` as an alternative to
script path.