Mercurial > hg
view tests/test-extensions-wrapfunction.py @ 42194:0da689a60163
fix: allow fixer tools to return metadata in addition to the file content
With this change, fixer tools can be configured to output a JSON object that
will be parsed and passed to hooks that can be used to print summaries of what
code was formatted or perform other post-fixing work.
The motivation for this change is to allow parallel executions of a
"meta-formatter" tool to report back statistics, which are then aggregated and
processed after all formatting has completed. Providing an extensible mechanism
inside fix.py is far simpler, and more portable, than trying to make a tool
like this communicate through some other channel.
Differential Revision: https://phab.mercurial-scm.org/D6167
author | Danny Hooper <hooper@google.com> |
---|---|
date | Thu, 21 Mar 2019 18:32:45 -0700 |
parents | ac865f020b99 |
children | 2372284d9457 |
line wrap: on
line source
from __future__ import absolute_import, print_function from mercurial import extensions def genwrapper(x): def f(orig, *args, **kwds): return [x] + orig(*args, **kwds) f.x = x return f def getid(wrapper): return getattr(wrapper, 'x', '-') wrappers = [genwrapper(i) for i in range(5)] class dummyclass(object): def getstack(self): return ['orig'] dummy = dummyclass() def batchwrap(wrappers): for w in wrappers: extensions.wrapfunction(dummy, 'getstack', w) print('wrap %d: %s' % (getid(w), dummy.getstack())) def batchunwrap(wrappers): for w in wrappers: result = None try: result = extensions.unwrapfunction(dummy, 'getstack', w) msg = str(dummy.getstack()) except (ValueError, IndexError) as e: msg = e.__class__.__name__ print('unwrap %s: %s: %s' % (getid(w), getid(result), msg)) batchwrap(wrappers + [wrappers[0]]) batchunwrap([(wrappers[i] if i is not None and i >= 0 else None) for i in [3, None, 0, 4, 0, 2, 1, None]]) wrap0 = extensions.wrappedfunction(dummy, 'getstack', wrappers[0]) wrap1 = extensions.wrappedfunction(dummy, 'getstack', wrappers[1]) # Use them in a different order from how they were created to check that # the wrapping happens in __enter__, not in __init__ print('context manager', dummy.getstack()) with wrap1: print('context manager', dummy.getstack()) with wrap0: print('context manager', dummy.getstack()) # Bad programmer forgets to unwrap the function, but the context # managers still unwrap their wrappings. extensions.wrapfunction(dummy, 'getstack', wrappers[2]) print('context manager', dummy.getstack()) print('context manager', dummy.getstack()) print('context manager', dummy.getstack()) # Wrap callable object which has no __name__ class callableobj(object): def __call__(self): return ['orig'] dummy.cobj = callableobj() extensions.wrapfunction(dummy, 'cobj', wrappers[0]) print('wrap callable object', dummy.cobj())