Skip to content

Commit fca677a

Browse files
committed
Fix python#17197: profile/cProfile modules refactored so that code of run() and runctx() utility functions is not duplicated in both modules.
1 parent d7c59e1 commit fca677a

File tree

3 files changed

+46
-59
lines changed

3 files changed

+46
-59
lines changed

Lib/cProfile.py

Lines changed: 6 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,54 +7,20 @@
77
__all__ = ["run", "runctx", "Profile"]
88

99
import _lsprof
10+
import profile as _pyprofile
1011

1112
# ____________________________________________________________
1213
# Simple interface
1314

1415
def run(statement, filename=None, sort=-1):
15-
"""Run statement under profiler optionally saving results in filename
16-
17-
This function takes a single argument that can be passed to the
18-
"exec" statement, and an optional file name. In all cases this
19-
routine attempts to "exec" its first argument and gather profiling
20-
statistics from the execution. If no file name is present, then this
21-
function automatically prints a simple profiling report, sorted by the
22-
standard name string (file/line/function-name) that is presented in
23-
each line.
24-
"""
25-
prof = Profile()
26-
result = None
27-
try:
28-
try:
29-
prof = prof.run(statement)
30-
except SystemExit:
31-
pass
32-
finally:
33-
if filename is not None:
34-
prof.dump_stats(filename)
35-
else:
36-
result = prof.print_stats(sort)
37-
return result
16+
return _pyprofile._Utils(Profile).run(statement, filename, sort)
3817

3918
def runctx(statement, globals, locals, filename=None, sort=-1):
40-
"""Run statement under profiler, supplying your own globals and locals,
41-
optionally saving results in filename.
19+
return _pyprofile._Utils(Profile).runctx(statement, globals, locals,
20+
filename, sort)
4221

43-
statement and filename have the same semantics as profile.run
44-
"""
45-
prof = Profile()
46-
result = None
47-
try:
48-
try:
49-
prof = prof.runctx(statement, globals, locals)
50-
except SystemExit:
51-
pass
52-
finally:
53-
if filename is not None:
54-
prof.dump_stats(filename)
55-
else:
56-
result = prof.print_stats(sort)
57-
return result
22+
run.__doc__ = _pyprofile.run.__doc__
23+
runctx.__doc__ = _pyprofile.runctx.__doc__
5824

5925
# ____________________________________________________________
6026

Lib/profile.py

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,40 @@
4040
# return i_count
4141
#itimes = integer_timer # replace with C coded timer returning integers
4242

43+
class _Utils:
44+
"""Support class for utility functions which are shared by
45+
profile.py and cProfile.py modules.
46+
Not supposed to be used directly.
47+
"""
48+
49+
def __init__(self, profiler):
50+
self.profiler = profiler
51+
52+
def run(self, statement, filename, sort):
53+
prof = self.profiler()
54+
try:
55+
prof.run(statement)
56+
except SystemExit:
57+
pass
58+
finally:
59+
self._show(prof, filename, sort)
60+
61+
def runctx(self, statement, globals, locals, filename, sort):
62+
prof = self.profiler()
63+
try:
64+
prof.runctx(statement, globals, locals)
65+
except SystemExit:
66+
pass
67+
finally:
68+
self._show(prof, filename, sort)
69+
70+
def _show(self, prof, filename, sort):
71+
if filename is not None:
72+
prof.dump_stats(filename)
73+
else:
74+
prof.print_stats(sort)
75+
76+
4377
#**************************************************************************
4478
# The following are the static member functions for the profiler class
4579
# Note that an instance of Profile() is *not* needed to call them.
@@ -56,32 +90,16 @@ def run(statement, filename=None, sort=-1):
5690
standard name string (file/line/function-name) that is presented in
5791
each line.
5892
"""
59-
prof = Profile()
60-
try:
61-
prof = prof.run(statement)
62-
except SystemExit:
63-
pass
64-
if filename is not None:
65-
prof.dump_stats(filename)
66-
else:
67-
return prof.print_stats(sort)
93+
return _Utils(Profile).run(statement, filename, sort)
6894

6995
def runctx(statement, globals, locals, filename=None, sort=-1):
7096
"""Run statement under profiler, supplying your own globals and locals,
7197
optionally saving results in filename.
7298
7399
statement and filename have the same semantics as profile.run
74100
"""
75-
prof = Profile()
76-
try:
77-
prof = prof.runctx(statement, globals, locals)
78-
except SystemExit:
79-
pass
80-
81-
if filename is not None:
82-
prof.dump_stats(filename)
83-
else:
84-
return prof.print_stats(sort)
101+
return _Utils(Profile).runctx(statement, globals, locals, filename, sort)
102+
85103

86104
class Profile:
87105
"""Profiler class.

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,9 @@ Core and Builtins
263263
Library
264264
-------
265265

266+
- Issue #17197: profile/cProfile modules refactored so that code of run() and
267+
runctx() utility functions is not duplicated in both modules.
268+
266269
- Issue #14720: sqlite3: Convert datetime microseconds correctly.
267270
Patch by Lowe Thiderman.
268271

0 commit comments

Comments
 (0)