Accept tuples in attrs.validators.optional (#1122)
* Accept tuples in attrs.validators.optional Fixes #937 * Add news fragment
This commit is contained in:
parent
5a7d978d8a
commit
7d55876ed3
|
@ -0,0 +1 @@
|
||||||
|
`attrs.validators.optional()` now also accepts a tuple of validators (in addition to lists of validators).
|
|
@ -270,15 +270,16 @@ def optional(validator):
|
||||||
which can be set to ``None`` in addition to satisfying the requirements of
|
which can be set to ``None`` in addition to satisfying the requirements of
|
||||||
the sub-validator.
|
the sub-validator.
|
||||||
|
|
||||||
:param validator: A validator (or a list of validators) that is used for
|
:param Callable | tuple[Callable] | list[Callable] validator: A validator
|
||||||
non-``None`` values.
|
(or validators) that is used for non-``None`` values.
|
||||||
:type validator: callable or `list` of callables.
|
|
||||||
|
|
||||||
.. versionadded:: 15.1.0
|
.. versionadded:: 15.1.0
|
||||||
.. versionchanged:: 17.1.0 *validator* can be a list of validators.
|
.. versionchanged:: 17.1.0 *validator* can be a list of validators.
|
||||||
|
.. versionchanged:: 23.1.0 *validator* can also be a tuple of validators.
|
||||||
"""
|
"""
|
||||||
if isinstance(validator, list):
|
if isinstance(validator, (list, tuple)):
|
||||||
return _OptionalValidator(_AndValidator(validator))
|
return _OptionalValidator(_AndValidator(validator))
|
||||||
|
|
||||||
return _OptionalValidator(validator)
|
return _OptionalValidator(validator)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,9 @@ def instance_of(
|
||||||
def instance_of(type: Tuple[type, ...]) -> _ValidatorType[Any]: ...
|
def instance_of(type: Tuple[type, ...]) -> _ValidatorType[Any]: ...
|
||||||
def provides(interface: Any) -> _ValidatorType[Any]: ...
|
def provides(interface: Any) -> _ValidatorType[Any]: ...
|
||||||
def optional(
|
def optional(
|
||||||
validator: Union[_ValidatorType[_T], List[_ValidatorType[_T]]]
|
validator: Union[
|
||||||
|
_ValidatorType[_T], List[_ValidatorType[_T]], Tuple[_ValidatorType[_T]]
|
||||||
|
]
|
||||||
) -> _ValidatorType[Optional[_T]]: ...
|
) -> _ValidatorType[Optional[_T]]: ...
|
||||||
def in_(options: Container[_T]) -> _ValidatorType[_T]: ...
|
def in_(options: Container[_T]) -> _ValidatorType[_T]: ...
|
||||||
def and_(*validators: _ValidatorType[_T]) -> _ValidatorType[_T]: ...
|
def and_(*validators: _ValidatorType[_T]) -> _ValidatorType[_T]: ...
|
||||||
|
|
|
@ -384,7 +384,12 @@ class TestProvides:
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"validator", [instance_of(int), [always_pass, instance_of(int)]]
|
"validator",
|
||||||
|
[
|
||||||
|
instance_of(int),
|
||||||
|
[always_pass, instance_of(int)],
|
||||||
|
(always_pass, instance_of(int)),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
class TestOptional:
|
class TestOptional:
|
||||||
"""
|
"""
|
||||||
|
@ -437,6 +442,11 @@ class TestOptional:
|
||||||
"<optional validator for _AndValidator(_validators=[{func}, "
|
"<optional validator for _AndValidator(_validators=[{func}, "
|
||||||
"<instance_of validator for type <class 'int'>>]) or None>"
|
"<instance_of validator for type <class 'int'>>]) or None>"
|
||||||
).format(func=repr(always_pass))
|
).format(func=repr(always_pass))
|
||||||
|
elif isinstance(validator, tuple):
|
||||||
|
repr_s = (
|
||||||
|
"<optional validator for _AndValidator(_validators=({func}, "
|
||||||
|
"<instance_of validator for type <class 'int'>>)) or None>"
|
||||||
|
).format(func=repr(always_pass))
|
||||||
else:
|
else:
|
||||||
repr_s = (
|
repr_s = (
|
||||||
"<optional validator for <instance_of validator for type "
|
"<optional validator for <instance_of validator for type "
|
||||||
|
|
|
@ -236,6 +236,15 @@ class Validated:
|
||||||
p: Any = attr.ib(
|
p: Any = attr.ib(
|
||||||
validator=attr.validators.not_(attr.validators.in_("abc"), msg=None)
|
validator=attr.validators.not_(attr.validators.in_("abc"), msg=None)
|
||||||
)
|
)
|
||||||
|
q: Any = attr.ib(
|
||||||
|
validator=attrs.validators.optional(attrs.validators.instance_of(C))
|
||||||
|
)
|
||||||
|
r: Any = attr.ib(
|
||||||
|
validator=attrs.validators.optional([attrs.validators.instance_of(C)])
|
||||||
|
)
|
||||||
|
s: Any = attr.ib(
|
||||||
|
validator=attrs.validators.optional((attrs.validators.instance_of(C),))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@attr.define
|
@attr.define
|
||||||
|
|
Loading…
Reference in New Issue