summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/profile.rst9
-rwxr-xr-xLib/profile.py32
-rw-r--r--Lib/test/test_cprofile.py13
-rw-r--r--Lib/test/test_profile.py13
-rw-r--r--Misc/NEWS.d/next/Library/2018-01-07-17-43-10.bpo-32512.flC-dE.rst2
5 files changed, 42 insertions, 27 deletions
diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst
index 1a772fb..9ceb816 100644
--- a/Doc/library/profile.rst
+++ b/Doc/library/profile.rst
@@ -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)
@@ -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
+ 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::
diff --git a/Lib/profile.py b/Lib/profile.py
index 0340a79..5df4360 100755
--- a/Lib/profile.py
+++ b/Lib/profile.py
@@ -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)
@@ -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()
diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py
index 406d703..efcf6bc 100644
--- a/Lib/test/test_cprofile.py
+++ b/Lib/test/test_cprofile.py
@@ -37,19 +37,6 @@ class CProfileTest(ProfileTest):
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.
diff --git a/Lib/test/test_profile.py b/Lib/test/test_profile.py
index a998266..01a8a6e 100644
--- a/Lib/test/test_profile.py
+++ b/Lib/test/test_profile.py
@@ -11,6 +11,7 @@ from contextlib import contextmanager
import profile
from test.profilee import testfunc, timer
+from test.support.script_helper import assert_python_failure, assert_python_ok
class ProfileTest(unittest.TestCase):
@@ -98,6 +99,18 @@ class ProfileTest(unittest.TestCase):
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')
diff --git a/Misc/NEWS.d/next/Library/2018-01-07-17-43-10.bpo-32512.flC-dE.rst b/Misc/NEWS.d/next/Library/2018-01-07-17-43-10.bpo-32512.flC-dE.rst
new file mode 100644
index 0000000..0a7763d
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-01-07-17-43-10.bpo-32512.flC-dE.rst
@@ -0,0 +1,2 @@
+:mod:`profile` CLI accepts `-m module_name` as an alternative to
+script path.