mirror of https://github.com/mahmoud/boltons.git
fix kwonly arg removal in funcutils.FunctionBuilder, thus fixing funcutils.wraps, which fixes #123
This commit is contained in:
parent
b58ef52a3a
commit
14208cf6e3
|
@ -561,16 +561,24 @@ class FunctionBuilder(object):
|
|||
Raises a :exc:`ValueError` if the argument is not present.
|
||||
|
||||
"""
|
||||
args = self.args
|
||||
d_dict = self.get_defaults_dict()
|
||||
try:
|
||||
self.args.remove(arg_name)
|
||||
args.remove(arg_name)
|
||||
except ValueError:
|
||||
exc = MissingArgument('arg %r not found in %s argument list: %r'
|
||||
% (arg_name, self.name, self.args))
|
||||
exc.arg_name = arg_name
|
||||
raise exc
|
||||
d_dict.pop(arg_name, None)
|
||||
self.defaults = tuple([d_dict[a] for a in self.args if a in d_dict])
|
||||
try:
|
||||
self.kwonlyargs.remove(arg_name)
|
||||
except (AttributeError, ValueError):
|
||||
# py2, or py3 and missing from both
|
||||
exc = MissingArgument('arg %r not found in %s argument list:'
|
||||
' %r' % (arg_name, self.name, args))
|
||||
exc.arg_name = arg_name
|
||||
raise exc
|
||||
else:
|
||||
self.kwonlydefaults.pop(arg_name, None)
|
||||
else:
|
||||
d_dict.pop(arg_name, None)
|
||||
self.defaults = tuple([d_dict[a] for a in args if a in d_dict])
|
||||
return
|
||||
|
||||
def _compile(self, src, execdict):
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
from boltons.funcutils import wraps, FunctionBuilder
|
||||
|
||||
import inspect
|
||||
|
||||
import pytest
|
||||
|
||||
from boltons.funcutils import wraps, FunctionBuilder
|
||||
|
||||
|
||||
def pita_wrap(flag=False):
|
||||
|
||||
|
@ -42,6 +45,39 @@ def test_wraps_py3():
|
|||
True, 'kwonly_non_roundtrippable_repr', 2)
|
||||
|
||||
|
||||
def test_remove_kwonly_arg():
|
||||
# example adapted from https://github.com/mahmoud/boltons/issues/123
|
||||
|
||||
def darkhelm_inject_loop(func):
|
||||
sig = inspect.signature(func)
|
||||
loop_param = sig.parameters['loop'].replace(default=None)
|
||||
sig = sig.replace(parameters=[loop_param])
|
||||
|
||||
def add_loop(args, kwargs):
|
||||
bargs = sig.bind(*args, **kwargs)
|
||||
bargs.apply_defaults()
|
||||
if bargs.arguments['loop'] is None:
|
||||
bargs.arguments['loop'] = "don't look at me, I just use gevent"
|
||||
|
||||
return bargs.arguments
|
||||
|
||||
def wrapper(*args, **kwargs):
|
||||
return func(**add_loop(args, kwargs))
|
||||
|
||||
return wraps(func, injected=['loop'])(wrapper)
|
||||
|
||||
@darkhelm_inject_loop
|
||||
def example(test='default', *, loop='lol'):
|
||||
return loop
|
||||
|
||||
fb_example = FunctionBuilder.from_func(example)
|
||||
assert 'test' in fb_example.args
|
||||
assert fb_example.get_defaults_dict()['test'] == 'default'
|
||||
|
||||
assert 'loop' not in fb_example.kwonlyargs
|
||||
assert 'loop' not in fb_example.kwonlydefaults
|
||||
|
||||
|
||||
@pytest.mark.parametrize('signature,should_match',
|
||||
[('a, *, b', True),
|
||||
('a,*,b', True),
|
||||
|
|
Loading…
Reference in New Issue