Patchwork [1,of,3] extensions: set attributes to wrappers so we can trace them back

login
register
mail settings
Submitter Jun Wu
Date July 1, 2016, 12:09 p.m.
Message ID <21e49b9facede184e5d2.1467374943@x1c>
Download mbox | patch
Permalink /patch/15699/
State Superseded
Delegated to: Yuya Nishihara
Headers show

Comments

Jun Wu - July 1, 2016, 12:09 p.m.
# HG changeset patch
# User Jun Wu <quark@fb.com>
# Date 1467370013 -3600
#      Fri Jul 01 11:46:53 2016 +0100
# Node ID 21e49b9facede184e5d262211bd5cc34bddca974
# Parent  7dce56174916e09be39c690278942b4f7567b3f6
# Available At https://bitbucket.org/quark-zju/hg-draft
#              hg pull https://bitbucket.org/quark-zju/hg-draft -r 21e49b9faced
extensions: set attributes to wrappers so we can trace them back

This patch adds two attributes about the original function and the unbound
wrapper. It allows us to get a chain of wrappers. See the next patch.
Martijn Pieters - July 1, 2016, 12:30 p.m.
On 1 July 2016 at 13:09, Jun Wu <quark@fb.com> wrote:
> # HG changeset patch
> # User Jun Wu <quark@fb.com>
> # Date 1467370013 -3600
> #      Fri Jul 01 11:46:53 2016 +0100
> # Node ID 21e49b9facede184e5d262211bd5cc34bddca974
> # Parent  7dce56174916e09be39c690278942b4f7567b3f6
> # Available At https://bitbucket.org/quark-zju/hg-draft
> #              hg pull https://bitbucket.org/quark-zju/hg-draft -r 21e49b9faced
> extensions: set attributes to wrappers so we can trace them back
>
> This patch adds two attributes about the original function and the unbound
> wrapper. It allows us to get a chain of wrappers. See the next patch.
>
> diff --git a/mercurial/extensions.py b/mercurial/extensions.py
> --- a/mercurial/extensions.py
> +++ b/mercurial/extensions.py
> @@ -204,11 +204,13 @@ def bind(func, *args):
>          return func(*(args + a), **kw)
>      return closure
>
> -def _updatewrapper(wrap, origfn):
> -    '''Copy attributes to wrapper function'''
> +def _updatewrapper(wrap, origfn, unboundwrapper):
> +    '''Copy and add some useful attributes to wrapper'''
>      wrap.__module__ = getattr(origfn, '__module__')
>      wrap.__doc__ = getattr(origfn, '__doc__')
>      wrap.__dict__.update(getattr(origfn, '__dict__', {}))
> +    wrap._origfunc = origfn

Python 3.2 and newer use `__wrapped__` as the attribute name (set by
functools.wraps and others), and introspection tools make use of this.
I'd say using that name here fits the usecase for that attribute
exactly.

> +    wrap._unboundwrapper = unboundwrapper
>
>  def wrapcommand(table, command, wrapper, synopsis=None, docstring=None):
>      '''Wrap the command named `command' in table
> @@ -248,7 +250,7 @@ def wrapcommand(table, command, wrapper,
>
>      origfn = entry[0]
>      wrap = bind(util.checksignature(wrapper), util.checksignature(origfn))
> -    _updatewrapper(wrap, origfn)
> +    _updatewrapper(wrap, origfn, wrapper)
>      if docstring is not None:
>          wrap.__doc__ += docstring
>
> @@ -297,7 +299,7 @@ def wrapfunction(container, funcname, wr
>      origfn = getattr(container, funcname)
>      assert callable(origfn)
>      wrap = bind(wrapper, origfn)
> -    _updatewrapper(wrap, origfn)
> +    _updatewrapper(wrap, origfn, wrapper)
>      setattr(container, funcname, wrap)
>      return origfn
>
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Patch

diff --git a/mercurial/extensions.py b/mercurial/extensions.py
--- a/mercurial/extensions.py
+++ b/mercurial/extensions.py
@@ -204,11 +204,13 @@  def bind(func, *args):
         return func(*(args + a), **kw)
     return closure
 
-def _updatewrapper(wrap, origfn):
-    '''Copy attributes to wrapper function'''
+def _updatewrapper(wrap, origfn, unboundwrapper):
+    '''Copy and add some useful attributes to wrapper'''
     wrap.__module__ = getattr(origfn, '__module__')
     wrap.__doc__ = getattr(origfn, '__doc__')
     wrap.__dict__.update(getattr(origfn, '__dict__', {}))
+    wrap._origfunc = origfn
+    wrap._unboundwrapper = unboundwrapper
 
 def wrapcommand(table, command, wrapper, synopsis=None, docstring=None):
     '''Wrap the command named `command' in table
@@ -248,7 +250,7 @@  def wrapcommand(table, command, wrapper,
 
     origfn = entry[0]
     wrap = bind(util.checksignature(wrapper), util.checksignature(origfn))
-    _updatewrapper(wrap, origfn)
+    _updatewrapper(wrap, origfn, wrapper)
     if docstring is not None:
         wrap.__doc__ += docstring
 
@@ -297,7 +299,7 @@  def wrapfunction(container, funcname, wr
     origfn = getattr(container, funcname)
     assert callable(origfn)
     wrap = bind(wrapper, origfn)
-    _updatewrapper(wrap, origfn)
+    _updatewrapper(wrap, origfn, wrapper)
     setattr(container, funcname, wrap)
     return origfn