Source code for serde.validators
"""
This module contains validators for use with `Fields <serde.fields.Field>`.
"""
from serde.exceptions import ValidationError
from serde.utils import is_subclass
[docs]class Validator(object):
"""
An abstract validator class that all validators should subclass.
"""
def __eq__(self, other):
"""
Whether this validator is equal to another validator.
"""
return isinstance(other, self.__class__) and self._attrs() == other._attrs()
def _attrs(self):
"""
Returns a dictionary of all public attributes on this validator.
"""
return {
name: value
for name, value in vars(self).items()
if not name.startswith('_')
}
def __call__(self, value):
"""
Call this validator on a value.
"""
raise NotImplementedError('this method should be overridden')
[docs]class Min(Validator):
"""
A validator that asserts the value is greater than a minimum.
Args:
inclusive (bool): if this is set to `False` then the endpoint value will
not be considered valid.
"""
def __init__(self, endpoint, inclusive=True):
self.endpoint = endpoint
self.inclusive = inclusive
def __call__(self, value):
if self.inclusive:
if value < self.endpoint:
raise ValidationError(
f'expected at least {self.endpoint!r}', value=value
)
else:
if value <= self.endpoint:
raise ValidationError(
f'expected more than {self.endpoint!r}', value=value
)
[docs]class Max(Validator):
"""
A validator that asserts the value is less than a maximum.
Args:
inclusive (bool): if this is set to `False` then the endpoint value will
not be considered valid.
"""
def __init__(self, endpoint, inclusive=True):
self.endpoint = endpoint
self.inclusive = inclusive
def __call__(self, value):
if self.inclusive:
if value > self.endpoint:
raise ValidationError(
f'expected at most {self.endpoint!r}', value=value
)
else:
if value >= self.endpoint:
raise ValidationError(
f'expected less than {self.endpoint!r}', value=value
)
[docs]class Between(Validator):
"""
A validator that asserts the value is between two endpoints.
Args:
inclusive (bool): if this is set to `False` then the endpoint values
will not be considered valid.
"""
def __init__(self, min_endpoint, max_endpoint, inclusive=True):
self.min_validator = Min(min_endpoint, inclusive=inclusive)
self.max_validator = Max(max_endpoint, inclusive=inclusive)
def __call__(self, value):
self.min_validator(value)
self.max_validator(value)
[docs]class Length(Validator):
"""
A validator that asserts the value's length is a specific value.
"""
def __init__(self, length):
self.length = length
def __call__(self, value):
if len(value) != self.length:
raise ValidationError(f'expected length {self.length!r}', value=value)
[docs]class LengthMin(Min):
"""
A validator that asserts the value's length is greater than a minimum.
Args:
inclusive (bool): if this is set to `False` then the endpoint value will
not be considered valid.
"""
def __call__(self, value):
super(LengthMin, self).__call__(len(value))
[docs]class LengthMax(Max):
"""
A validator that asserts the value's length is less than a maximum.
Args:
inclusive (bool): if this is set to `False` then the endpoint value will
not be considered valid.
"""
def __call__(self, value):
super(LengthMax, self).__call__(len(value))
[docs]class LengthBetween(Between):
"""
A validator that asserts the value's length is between two endpoints.
Args:
inclusive (bool): if this is set to `False` then the endpoint values
will not be considered valid.
"""
def __call__(self, value):
return super(LengthBetween, self).__call__(len(value))
__all__ = [name for name, obj in globals().items() if is_subclass(obj, Validator)]