# HG changeset patch # User Eric Sumner # Date 2015-04-15 16:18:05 # Node ID fb6cb1b82f4fb6409b21447b2902d266e1a63266 # Parent c00e4338fa4b316a73a35d39ea57a3d8e7d407e0 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 @@ def afterloaded(extension, callback): 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 @@ def wrapcommand(table, command, wrapper, 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 @@ def wrapfunction(container, funcname, wr 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):