From fca677a26aff3bce34b1b9b7662dd3a95cd285ba Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola' Date: Mon, 25 Feb 2013 11:36:40 +0100 Subject: Fix #17197: profile/cProfile modules refactored so that code of run() and runctx() utility functions is not duplicated in both modules. --- Lib/cProfile.py | 46 ++++++---------------------------------------- Lib/profile.py | 56 +++++++++++++++++++++++++++++++++++++------------------- Misc/NEWS | 3 +++ 3 files changed, 46 insertions(+), 59 deletions(-) diff --git a/Lib/cProfile.py b/Lib/cProfile.py index 81e722b..1184385 100755 --- a/Lib/cProfile.py +++ b/Lib/cProfile.py @@ -7,54 +7,20 @@ __all__ = ["run", "runctx", "Profile"] import _lsprof +import profile as _pyprofile # ____________________________________________________________ # Simple interface def run(statement, filename=None, sort=-1): - """Run statement under profiler optionally saving results in filename - - This function takes a single argument that can be passed to the - "exec" statement, and an optional file name. In all cases this - routine attempts to "exec" its first argument and gather profiling - statistics from the execution. If no file name is present, then this - function automatically prints a simple profiling report, sorted by the - standard name string (file/line/function-name) that is presented in - each line. - """ - prof = Profile() - result = None - try: - try: - prof = prof.run(statement) - except SystemExit: - pass - finally: - if filename is not None: - prof.dump_stats(filename) - else: - result = prof.print_stats(sort) - return result + return _pyprofile._Utils(Profile).run(statement, filename, sort) def runctx(statement, globals, locals, filename=None, sort=-1): - """Run statement under profiler, supplying your own globals and locals, - optionally saving results in filename. + return _pyprofile._Utils(Profile).runctx(statement, globals, locals, + filename, sort) - statement and filename have the same semantics as profile.run - """ - prof = Profile() - result = None - try: - try: - prof = prof.runctx(statement, globals, locals) - except SystemExit: - pass - finally: - if filename is not None: - prof.dump_stats(filename) - else: - result = prof.print_stats(sort) - return result +run.__doc__ = _pyprofile.run.__doc__ +runctx.__doc__ = _pyprofile.runctx.__doc__ # ____________________________________________________________ diff --git a/Lib/profile.py b/Lib/profile.py index 553f210..5d0e968 100755 --- a/Lib/profile.py +++ b/Lib/profile.py @@ -40,6 +40,40 @@ __all__ = ["run", "runctx", "Profile"] # return i_count #itimes = integer_timer # replace with C coded timer returning integers +class _Utils: + """Support class for utility functions which are shared by + profile.py and cProfile.py modules. + Not supposed to be used directly. + """ + + def __init__(self, profiler): + self.profiler = profiler + + def run(self, statement, filename, sort): + prof = self.profiler() + try: + prof.run(statement) + except SystemExit: + pass + finally: + self._show(prof, filename, sort) + + def runctx(self, statement, globals, locals, filename, sort): + prof = self.profiler() + try: + prof.runctx(statement, globals, locals) + except SystemExit: + pass + finally: + self._show(prof, filename, sort) + + def _show(self, prof, filename, sort): + if filename is not None: + prof.dump_stats(filename) + else: + prof.print_stats(sort) + + #************************************************************************** # The following are the static member functions for the profiler class # Note that an instance of Profile() is *not* needed to call them. @@ -56,15 +90,7 @@ def run(statement, filename=None, sort=-1): standard name string (file/line/function-name) that is presented in each line. """ - prof = Profile() - try: - prof = prof.run(statement) - except SystemExit: - pass - if filename is not None: - prof.dump_stats(filename) - else: - return prof.print_stats(sort) + return _Utils(Profile).run(statement, filename, sort) def runctx(statement, globals, locals, filename=None, sort=-1): """Run statement under profiler, supplying your own globals and locals, @@ -72,16 +98,8 @@ def runctx(statement, globals, locals, filename=None, sort=-1): statement and filename have the same semantics as profile.run """ - prof = Profile() - try: - prof = prof.runctx(statement, globals, locals) - except SystemExit: - pass - - if filename is not None: - prof.dump_stats(filename) - else: - return prof.print_stats(sort) + return _Utils(Profile).runctx(statement, globals, locals, filename, sort) + class Profile: """Profiler class. diff --git a/Misc/NEWS b/Misc/NEWS index a003684..814f2f2 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -263,6 +263,9 @@ Core and Builtins Library ------- +- Issue #17197: profile/cProfile modules refactored so that code of run() and + runctx() utility functions is not duplicated in both modules. + - Issue #14720: sqlite3: Convert datetime microseconds correctly. Patch by Lowe Thiderman. -- cgit v0.12