[PATCH 3 of 3] extensions: add unwrapfunction to undo wrapfunction
Martijn Pieters
mj at zopatista.com
Fri Jul 1 14:02:14 UTC 2016
On 1 July 2016 at 14:27, Jun Wu <quark at fb.com> wrote:
> 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".
Ah, yes, you are correct. I had the wrong mental model (decorators),
while the actual attribute on the container is a chain of closures
really.
This also invalidates my __wrapper__ argument on the other patch.
--
Martijn Pieters
More information about the Mercurial-devel
mailing list