diff options
| author | Michele Simionato <michele.simionato@gmail.com> | 2020-03-16 06:43:47 +0100 |
|---|---|---|
| committer | Michele Simionato <michele.simionato@gmail.com> | 2020-03-16 06:43:47 +0100 |
| commit | ca5bbdd2efa85cc1cc8859efb90a84306055271b (patch) | |
| tree | f8a3506bff377b200d2b1633d536205b2e7626a5 | |
| parent | e6de7a108ad9837655c33f80723a9adcf07aa69f (diff) | |
| download | python-decorator-git-ca5bbdd2efa85cc1cc8859efb90a84306055271b.tar.gz | |
Removed exec in decorator
| -rw-r--r-- | src/decorator.py | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/src/decorator.py b/src/decorator.py index ce8644c..8a4b62d 100644 --- a/src/decorator.py +++ b/src/decorator.py @@ -75,6 +75,7 @@ except ImportError: DEF = re.compile(r'\s*def\s*([_\w][_\w\d]*)\s*\(') +POS = inspect.Parameter.POSITIONAL_OR_KEYWORD # basic functionality @@ -228,13 +229,6 @@ def decorate(func, caller, extras=()): If the caller is a generator function, the resulting function will be a generator function. """ - evaldict = dict(_call_=caller, _func_=func) - es = '' - for i, extra in enumerate(extras): - ex = '_e%d_' % i - evaldict[ex] = extra - es += ex + ', ' - if iscoroutinefunction(caller): async def fun(*args, **kw): return await caller(func, *(extras + args), **kw) @@ -245,6 +239,7 @@ def decorate(func, caller, extras=()): else: def fun(*args, **kw): return caller(func, *(extras + args), **kw) + fun.__name__ = func.__name__ fun.__signature__ = inspect.signature(func) fun.__wrapped__ = func if hasattr(func, '__qualname__'): # >= Python 3.3 @@ -260,7 +255,7 @@ def decorator(caller, _func=None): # this is obsolete behavior; you should use decorate instead return decorate(_func, caller) # else return a decorator function - defaultargs, defaults = '', () + defaultargs = '' if inspect.isclass(caller): name = caller.__name__.lower() doc = 'decorator(%s) converts functions/generators into ' \ @@ -276,18 +271,27 @@ def decorator(caller, _func=None): defaultargs = ', '.join(caller.__code__.co_varnames[nargs-ndefs:nargs]) if defaultargs: defaultargs += ',' - defaults = caller.__defaults__ else: # assume caller is an object with a __call__ method name = caller.__class__.__name__.lower() doc = caller.__call__.__doc__ - evaldict = dict(_call=caller, _decorate_=decorate) - dec = FunctionMaker.create( - '%s(func, %s)' % (name, defaultargs), - 'if func is None: return lambda func: _decorate_(func, _call, (%s))\n' - 'return _decorate_(func, _call, (%s))' % (defaultargs, defaultargs), - evaldict, doc=doc, module=caller.__module__, __wrapped__=caller) - if defaults: - dec.__defaults__ = (None,) + defaults + sig = inspect.signature(caller) + dec_params = [p for p in sig.parameters.values() if p.kind is POS] + + def dec(func=None, *args, **kw): + na = len(args) + 1 + extras = args + tuple(kw.get(p.name, p.default) + for p in dec_params[na:]) + if func is None: + return lambda func: decorate(func, caller, extras) + else: + return decorate(func, caller, extras) + dec.__signature__ = sig.replace(parameters=dec_params) + dec.__name__ = name + dec.__doc__ = doc + dec.__wrapped__ = caller + if hasattr(caller, '__qualname__'): # >= Python 3.3 + dec.__qualname__ = caller.__qualname__ + dec.__dict__.update(caller.__dict__) return dec |
