Add option to disable validation of user decorator parameters at point decorator is applied to a function.

This commit is contained in:
Graham Dumpleton
2013-08-25 14:03:07 +10:00
parent ff933cd264
commit dec1872faf
2 changed files with 28 additions and 5 deletions

View File

@@ -157,7 +157,7 @@ def _update_adapter(wrapper, target):
WRAPPER_ARGLIST = ('wrapped', 'instance', 'args', 'kwargs')
def decorator(wrapper=None, target=None):
def decorator(wrapper=None, target=None, validate=True):
# The decorator takes some optional keyword parameters to change its
# behaviour. The decorator works out whether parameters have been
# passed based on whether the first positional argument, which is
@@ -165,7 +165,12 @@ def decorator(wrapper=None, target=None):
# supplied. The 'target' argument is used to optionally denote a
# function which is wrapped by an adapter decorator. In that case
# the name attributes are copied from the target function rather
# than those of the adapter function.
# than those of the adapter function. The 'validate' argument, which
# defaults to True, indicates whether validation of decorator
# parameters should be validated at the time the decorator is
# applied, or whether a failure is allow to occur only when the
# wrapped function is later called and the user wrapper function
# thus called.
if wrapper is not None:
# We now need to work out whether the users decorator is
@@ -196,8 +201,9 @@ def decorator(wrapper=None, target=None):
# decorator is used and not only when the
# function is later called.
_validate_parameters(wrapper, wrapper_argspec,
*decorator_args, **decorator_kwargs)
if validate:
_validate_parameters(wrapper, wrapper_argspec,
*decorator_args, **decorator_kwargs)
# Now create and return the final wrapper which
# combines the parameters with the wrapped function.
@@ -235,7 +241,7 @@ def decorator(wrapper=None, target=None):
# a partial using the collected default parameters and the
# adapter function if one is being used.
return partial(decorator, target=target)
return partial(decorator, target=target, validate=validate)
def adapter(target):
@decorator(target=target)

View File

@@ -279,5 +279,22 @@ class TestDecorator(unittest.TestCase):
self.assertEqual(result, (_args, _kwargs))
def test_parameter_missing_no_validation(self):
_args = (1, 2)
_kwargs = { 'one': 1, 'two': 2 }
@wrapt.decorator(validate=False)
def _decorator(wrapped, instance, args, kwargs, p1, p2=2):
return wrapped(*args, **kwargs)
@_decorator()
def _function(*args, **kwargs):
return args, kwargs
def run():
result = _function(*_args, **_kwargs)
self.assertRaises(TypeError, run, ())
if __name__ == '__main__':
unittest.main()