summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanyam Khurana <8039608+CuriousLearner@users.noreply.github.com>2017-11-08 10:50:56 (GMT)
committerAntoine Pitrou <pitrou@free.fr>2017-11-08 10:50:56 (GMT)
commit7973e279a21999f134aff92dd6d344ec4591fae9 (patch)
treef8007dd3dac2f7cbf905f45ccd148cf4b5a1fd9a
parent4fc4defd1c9bd667635ba4080404e7aa3fcd49ea (diff)
downloadcpython-7973e279a21999f134aff92dd6d344ec4591fae9.zip
cpython-7973e279a21999f134aff92dd6d344ec4591fae9.tar.gz
cpython-7973e279a21999f134aff92dd6d344ec4591fae9.tar.bz2
bpo-21862: Add -m option to cProfile for profiling modules (#4297)
* bpo-21862: Add -m option to cProfile for profiling modules
-rw-r--r--Doc/library/profile.rst7
-rw-r--r--Doc/whatsnew/3.7.rst6
-rwxr-xr-xLib/cProfile.py35
-rw-r--r--Lib/test/test_cprofile.py14
-rw-r--r--Misc/NEWS.d/next/Library/2017-11-07-15-19-52.bpo-21862.RwietE.rst2
5 files changed, 51 insertions, 13 deletions
diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst
index 68f24ab..48426a0 100644
--- a/Doc/library/profile.rst
+++ b/Doc/library/profile.rst
@@ -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.
+
+ .. 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::
diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst
index af722be..9ac7c9d 100644
--- a/Doc/whatsnew/3.7.rst
+++ b/Doc/whatsnew/3.7.rst
@@ -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
-----
diff --git a/Lib/cProfile.py b/Lib/cProfile.py
index 1184385..f166a1c 100755
--- a/Lib/cProfile.py
+++ b/Lib/cProfile.py
@@ -121,9 +121,11 @@ 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",
@@ -131,6 +133,8 @@ def main():
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 @@ 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()
diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py
index 53f8917..1430d22 100644
--- a/Lib/test/test_cprofile.py
+++ b/Lib/test/test_cprofile.py
@@ -6,6 +6,7 @@ from test.support import run_unittest, TESTFN, unlink
# 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):
@@ -35,6 +36,19 @@ 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_main():
run_unittest(CProfileTest)
diff --git a/Misc/NEWS.d/next/Library/2017-11-07-15-19-52.bpo-21862.RwietE.rst b/Misc/NEWS.d/next/Library/2017-11-07-15-19-52.bpo-21862.RwietE.rst
new file mode 100644
index 0000000..6623d19
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2017-11-07-15-19-52.bpo-21862.RwietE.rst
@@ -0,0 +1,2 @@
+cProfile command line now accepts `-m module_name` as an alternative to
+script path. Patch by Sanyam Khurana.