extensions: add getwrapperchain to get a list of wrappers
authorJun Wu <quark@fb.com>
Wed, 10 Aug 2016 15:21:42 +0100
changeset 29764 8bf97c4c6c2a
parent 29763 ce6317dcb944
child 29765 19578bb84731
extensions: add getwrapperchain to get a list of wrappers The getwrapperchain returns a list of wrappers + the original function, making it easier to understand what has been wrapped by whom. For example: In : mercurial.extensions.getwrapperchain(mercurial.dispatch, '_runcommand') Out: [<function hgext.pager.pagecmd>, <function hgext.color.colorcmd>, <function hgext.zeroconf.cleanupafterdispatch>, <function mercurial.dispatch._runcommand>] It will also be useful to safely unwrap a function. See the next patch.
mercurial/extensions.py
--- a/mercurial/extensions.py	Wed Aug 10 15:21:42 2016 +0100
+++ b/mercurial/extensions.py	Wed Aug 10 15:21:42 2016 +0100
@@ -309,6 +309,22 @@
     setattr(container, funcname, wrap)
     return origfn
 
+def getwrapperchain(container, funcname):
+    '''get a chain of wrappers of a function
+
+    Return a list of functions: [newest wrapper, ..., oldest wrapper, origfunc]
+
+    The wrapper functions are the ones passed to wrapfunction, whose first
+    argument is origfunc.
+    '''
+    result = []
+    fn = getattr(container, funcname)
+    while fn:
+        assert callable(fn)
+        result.append(getattr(fn, '_unboundwrapper', fn))
+        fn = getattr(fn, '_origfunc', None)
+    return result
+
 def _disabledpaths(strip_init=False):
     '''find paths of disabled extensions. returns a dict of {name: path}
     removes /__init__.py from packages if strip_init is True'''