profiling: add a context manager that no-ops if profiling isn't enabled
authorGregory Szorc <gregory.szorc@gmail.com>
Sun, 14 Aug 2016 17:51:12 -0700
changeset 29784 e3501546f7e4
parent 29783 5d44197c208b
child 29785 88d3c1ab03a7
profiling: add a context manager that no-ops if profiling isn't enabled And refactor dispatch.py to use it. As you can see, the resulting code is much simpler. I was tempted to inline _runcommand as part of writing this series. However, a number of extensions wrap _runcommand. So keeping it around is necessary (extensions can't easily wrap runcommand because it calls hooks before and after command execution).
mercurial/dispatch.py
mercurial/help/config.txt
mercurial/profiling.py
tests/test-devel-warnings.t
--- a/mercurial/dispatch.py	Sun Aug 14 18:25:22 2016 -0700
+++ b/mercurial/dispatch.py	Sun Aug 14 17:51:12 2016 -0700
@@ -898,21 +898,12 @@
             repo.close()
 
 def _runcommand(ui, options, cmd, cmdfunc):
-    """Enables the profiler if applicable.
-
-    ``profiling.enabled`` - boolean config that enables or disables profiling
-    """
-    def checkargs():
+    """Run a command function, possibly with profiling enabled."""
+    with profiling.maybeprofile(ui):
         try:
             return cmdfunc()
         except error.SignatureError:
-            raise error.CommandError(cmd, _("invalid arguments"))
-
-    if ui.configbool('profiling', 'enabled'):
-        with profiling.profile(ui):
-            return checkargs()
-    else:
-        return checkargs()
+            raise error.CommandError(cmd, _('invalid arguments'))
 
 def _exceptionwarning(ui):
     """Produce a warning message for the current active exception"""
--- a/mercurial/help/config.txt	Sun Aug 14 18:25:22 2016 -0700
+++ b/mercurial/help/config.txt	Sun Aug 14 17:51:12 2016 -0700
@@ -1393,6 +1393,12 @@
 statistical text report generated from the profiling data. The
 profiling is done using lsprof.
 
+``enabled``
+    Enable the profiler.
+    (default: false)
+
+    This is equivalent to passing ``--profile`` on the command line.
+
 ``type``
     The type of profiler to use.
     (default: ls)
--- a/mercurial/profiling.py	Sun Aug 14 18:25:22 2016 -0700
+++ b/mercurial/profiling.py	Sun Aug 14 17:51:12 2016 -0700
@@ -143,3 +143,20 @@
                 val = val.replace('%', '%%')
                 ui.log('profile', val)
             fp.close()
+
+@contextlib.contextmanager
+def maybeprofile(ui):
+    """Profile if enabled, else do nothing.
+
+    This context manager can be used to optionally profile if profiling
+    is enabled. Otherwise, it does nothing.
+
+    The purpose of this context manager is to make calling code simpler:
+    just use a single code path for calling into code you may want to profile
+    and this function determines whether to start profiling.
+    """
+    if ui.configbool('profiling', 'enabled'):
+        with profile(ui):
+            yield
+    else:
+        yield
--- a/tests/test-devel-warnings.t	Sun Aug 14 18:25:22 2016 -0700
+++ b/tests/test-devel-warnings.t	Sun Aug 14 17:51:12 2016 -0700
@@ -96,7 +96,6 @@
    */mercurial/dispatch.py:* in _dispatch (glob)
    */mercurial/dispatch.py:* in runcommand (glob)
    */mercurial/dispatch.py:* in _runcommand (glob)
-   */mercurial/dispatch.py:* in checkargs (glob)
    */mercurial/dispatch.py:* in <lambda> (glob)
    */mercurial/util.py:* in check (glob)
    $TESTTMP/buggylocking.py:* in buggylocking (glob)
@@ -132,7 +131,6 @@
    */mercurial/dispatch.py:* in _dispatch (glob)
    */mercurial/dispatch.py:* in runcommand (glob)
    */mercurial/dispatch.py:* in _runcommand (glob)
-   */mercurial/dispatch.py:* in checkargs (glob)
    */mercurial/dispatch.py:* in <lambda> (glob)
    */mercurial/util.py:* in check (glob)
    $TESTTMP/buggylocking.py:* in oldanddeprecated (glob)
@@ -156,7 +154,6 @@
    */mercurial/dispatch.py:* in _dispatch (glob)
    */mercurial/dispatch.py:* in runcommand (glob)
    */mercurial/dispatch.py:* in _runcommand (glob)
-   */mercurial/dispatch.py:* in checkargs (glob)
    */mercurial/dispatch.py:* in <lambda> (glob)
    */mercurial/util.py:* in check (glob)
    $TESTTMP/buggylocking.py:* in oldanddeprecated (glob)