[PATCH 3 of 3] extensions: add unwrapfunction to undo wrapfunction

Jun Wu quark at fb.com
Fri Jul 1 09:27:14 EDT 2016

Yes the current code is not optimized for performance (as mentioned in
commit message). The optimized code would be re-inventing getwrapperchain
and I want to avoid duplication. getwrapperchain is exposed as an API
because I plan to have something like "debugwraps" to visualize the wrapped
functions in the future.

> You could just use a stack of functions to rewrap; this avoids having
> to re-do the whole chain:
>     chain = getwrapperchain(container, funcname)[::-1]
>     rewrap = []
>     while chain:
>         wrapper = chain.pop()
>         if wrapper == origfn:
>             break
>         rewrap.append(wrapper)
>     if chain:
>         # we found the original and removed it; rewrap whatever we had to remove
>                  # to find it.
>         setattr(container, funcname, chain[-1])
>         while rewrap:
>             wrapfunction(container, funcname, rewrap.pop())

I don't think this works. There are two different wrappers:

  1. the one you passed to wrapfunction, say it's "f"
  2. f.bind(origfunc), say it's "g"

getwrapperchain returns "f"s to make them comparable and hides "g"s for
simplicity. We need to setattr to a "g".

More information about the Mercurial-devel mailing list