"""
Validators for applying validations in sequence.
"""
from api import *
# @@ ianb 2005-05: should CompoundValidator be included?
__all__ = ['Any', 'All', 'Pipe']
############################################################
## Compound Validators
############################################################
def to_python(validator, value, state):
return validator.to_python(value, state)
def from_python(validator, value, state):
return validator.from_python(value, state)
class CompoundValidator(FancyValidator):
if_invalid = NoDefault
validators = []
__unpackargs__ = ('*', 'validatorArgs')
__mutableattributes__ = ('validators',)
def __classinit__(cls, new_attrs):
toAdd = []
for name, value in new_attrs.items():
if name in ('view',):
continue
if is_validator(value) and value is not Identity:
toAdd.append((name, value))
# @@: Should we really delete too?
delattr(cls, name)
toAdd.sort()
cls.validators.extend([v for n, v in toAdd])
def __init__(self, *args, **kw):
Validator.__init__(self, *args, **kw)
self.validators = self.validators[:]
self.validators.extend(self.validatorArgs)
def _reprVars(names):
return [n for n in Validator._reprVars(names)
if n != 'validatorArgs']
_reprVars = staticmethod(_reprVars)
def attempt_convert(self, value, state, convertFunc):
raise NotImplementedError, "Subclasses must implement attempt_convert"
def _to_python(self, value, state=None):
return self.attempt_convert(value, state,
to_python)
def _from_python(self, value, state=None):
return self.attempt_convert(value, state,
from_python)
def subvalidators(self):
return self.validators
class Any(CompoundValidator):
"""
This class is like an 'or' operator for validators. The first
validator/converter that validates the value will be used. (You
can pass in lists of validators, which will be ANDed)
"""
def attempt_convert(self, value, state, validate):
lastException = None
if validate is to_python:
validators = self.validators[::-1]
else:
validators = self.validators
for validator in validators:
try:
return validate(validator, value, state)
except Invalid, e:
lastException = e
if self.if_invalid is NoDefault:
raise lastException
else:
return self.if_invalid
def not_empty__get(self):
not_empty = True
for validator in self.validators:
not_empty = not_empty and getattr(validator, 'not_empty', False)
return not_empty
not_empty = property(not_empty__get)
class All(CompoundValidator):
"""
This class is like an 'and' operator for validators. All
validators must work, and the results are passed in turn through
all validators for conversion.
"""
def __repr__(self):
return '