[PATCH] extensions: extract partial application into a bind() function

Eric Sumner ericsumner at fb.com
Wed Apr 15 11:27:14 CDT 2015


# HG changeset patch
# User Eric Sumner <ericsumner at fb.com>
# Date 1429114685 14400
#      Wed Apr 15 12:18:05 2015 -0400
# Node ID a8fd41a5a5c1568efa8c1de185a888d6c558f067
# Parent  c560d8c687916cb70a6d54c2c9ddcb5c9e457be2
extensions: extract partial application into a bind() function

We use partial function application for wrapping existing Mercurial functions,
and it's implemented separately each time.  This patch extracts the partial
application into a new bind() function that can be used on its own by extensions
when appropriate.

In particular, the evolve extension needs to wrap functions in the various
bundle2 processing dictionaries, which the pre-existing methods don't support.

diff --git a/mercurial/extensions.py b/mercurial/extensions.py
--- a/mercurial/extensions.py
+++ b/mercurial/extensions.py
@@ -152,6 +152,18 @@
     else:
         _aftercallbacks.setdefault(extension, []).append(callback)
 
+def bind(func, *args):
+    '''Partial function application
+
+      Returns a new function that is the partial application of args and kwargs
+      to func.  For example,
+      
+          f(1, 2, bar=3) === bind(f, 1)(2, bar=3)'''
+    assert callable(func)
+    def closure(*a, **kw):
+        return func(*(args + a), **kw)
+    return closure
+
 def wrapcommand(table, command, wrapper, synopsis=None, docstring=None):
     '''Wrap the command named `command' in table
 
@@ -189,9 +201,7 @@
             break
 
     origfn = entry[0]
-    def wrap(*args, **kwargs):
-        return util.checksignature(wrapper)(
-            util.checksignature(origfn), *args, **kwargs)
+    wrap = bind(util.checksignature(wrapper), util.checksignature(origfn))
 
     wrap.__module__ = getattr(origfn, '__module__')
 
@@ -241,12 +251,10 @@
     subclass trick.
     '''
     assert callable(wrapper)
-    def wrap(*args, **kwargs):
-        return wrapper(origfn, *args, **kwargs)
 
     origfn = getattr(container, funcname)
     assert callable(origfn)
-    setattr(container, funcname, wrap)
+    setattr(container, funcname, bind(wrapper, origfn))
     return origfn
 
 def _disabledpaths(strip_init=False):


More information about the Mercurial-devel mailing list