@message('value was not true', cls=TrueInvalid)
@truth def IsTrue(v): """Assert that a value is true, in the Python sense.
>>> validate = Schema(IsTrue())
"In the Python sense" means that implicitly false values, such as empty
lists, dictionaries, etc. are treated as"false":
>>> with raises(MultipleInvalid, "value was not true"):
... validate([])
>>> validate([1])
[1]
>>> with raises(MultipleInvalid, "value was not true"):
... validate(False)
...and so on.
>>> try:
... validate([])
... except MultipleInvalid as e:
... assert isinstance(e.errors[0], TrueInvalid) """ return v
@message('value was not false', cls=FalseInvalid) def IsFalse(v): """Assert that a value is false, in the Python sense.
(see :func:`IsTrue` for more detail)
>>> validate = Schema(IsFalse())
>>> validate([])
[]
>>> with raises(MultipleInvalid, "value was not false"):
... validate(True)
>>> try:
... validate(True)
... except MultipleInvalid as e:
... assert isinstance(e.errors[0], FalseInvalid) """ if v: raise ValueError return v
@message('expected boolean', cls=BooleanInvalid) def Boolean(v): """Convert human-readable boolean values to a bool.
Accepted values are 1, true, yes, on, enable, and their negatives.
Non-string values are cast to bool.
>>> validate = Schema(Boolean())
>>> validate(True) True
>>> validate("1") True
>>> validate("0") False
>>> with raises(MultipleInvalid, "expected boolean"):
... validate('moo')
>>> try:
... validate('moo')
... except MultipleInvalid as e:
... assert isinstance(e.errors[0], BooleanInvalid) """ if isinstance(v, basestring):
v = v.lower() if v in ('1', 'true', 'yes', 'on', 'enable'): returnTrue if v in ('0', 'false', 'no', 'off', 'disable'): returnFalse raise ValueError return bool(v)
class _WithSubValidators(object): """Base class for validators that use sub-validators.
Special class to use as a parent classfor validators using sub-validators.
This class provides the `__voluptuous_compile__` method so the
sub-validators are compiled by the parent `Schema`. """
def __voluptuous_compile__(self, schema):
self._compiled = []
old_required = schema.required
self.schema = schema for v in self.validators:
schema.required = self.required
self._compiled.append(schema._compile(v))
schema.required = old_required return self._run
def _run(self, path, value): if self.discriminant isnotNone:
self._compiled = [
self.schema._compile(v) for v in self.discriminant(value, self.validators)
]
return self._exec(self._compiled, value, path)
def __call__(self, v): return self._exec((Schema(val) for val in self.validators), v)
def __repr__(self): return'%s(%s, msg=%r)' % (
self.__class__.__name__, ", ".join(repr(v) for v in self.validators),
self.msg
)
class Any(_WithSubValidators): """Use the first validated value.
:param msg: Message to deliver to user if validation fails.
:param kwargs: All other keyword arguments are passed to the sub-schema constructors.
:returns: Return value of the first validator that passes.
>>> validate = Schema(Any(1, 2, 3, msg="Expected 1 2 or 3"))
>>> validate(1)
1
>>> with raises(MultipleInvalid, "Expected 1 2 or 3"):
... validate(4) """
def _exec(self, funcs, v, path=None):
error = None for func in funcs: try: if path isNone: return func(v) else: return func(path, v) except Invalid as e: if error isNoneor len(e.path) > len(error.path):
error = e else: if error: raise error if self.msg isNoneelse AnyInvalid(
self.msg, path=path) raise AnyInvalid(self.msg or'no valid value found',
path=path)
# Convenience alias Or = Any
class Union(_WithSubValidators): """Use the first validated value among those selected by discriminant.
:param msg: Message to deliver to user if validation fails.
:param discriminant(value, validators): Returns the filtered list of validators based on the value.
:param kwargs: All other keyword arguments are passed to the sub-schema constructors.
:returns: Return value of the first validator that passes.
>>> validate = Schema(Union({'type':'a', 'a_val':'1'},{'type':'b', 'b_val':'2'},
... discriminant=lambda val, alt: filter(
... lambda v : v['type'] == val['type'] , alt)))
>>> validate({'type':'a', 'a_val':'1'}) == {'type':'a', 'a_val':'1'} True
>>> with raises(MultipleInvalid, "not a valid value for dictionary value @ data['b_val']"):
... validate({'type':'b', 'b_val':'5'})
```discriminant({'type':'b', 'a_val':'5'}, [{'type':'a', 'a_val':'1'},{'type':'b', 'b_val':'2'}])``` is invoked
Without the discriminant, the exception would be "extra keys not allowed @ data['b_val']" """
def _exec(self, funcs, v, path=None):
error = None for func in funcs: try: if path isNone: return func(v) else: return func(path, v) except Invalid as e: if error isNoneor len(e.path) > len(error.path):
error = e else: if error: raise error if self.msg isNoneelse AnyInvalid(
self.msg, path=path) raise AnyInvalid(self.msg or'no valid value found',
path=path)
# Convenience alias
Switch = Union
class All(_WithSubValidators): """Value must pass all validators.
The output of each validator is passed as input to the next.
:param msg: Message to deliver to user if validation fails.
:param kwargs: All other keyword arguments are passed to the sub-schema constructors.
def _exec(self, funcs, v, path=None): try: for func in funcs: if path isNone:
v = func(v) else:
v = func(path, v) except Invalid as e: raise e if self.msg isNoneelse AllInvalid(self.msg, path=path) return v
# Convenience alias And = All
class Match(object): """Value must be a string that matches the regular expression.
>>> validate = Schema(Match(r'^0x[A-F0-9]+$'))
>>> validate('0x123EF4') '0x123EF4'
>>> with raises(MultipleInvalid, "does not match regular expression"):
... validate('123EF4')
>>> with raises(MultipleInvalid, 'expected string or buffer'):
... validate(123)
Pattern may also be a compiled regular expression:
def __call__(self, v): try:
match = self.pattern.match(v) except TypeError: raise MatchInvalid("expected string or buffer") ifnot match: raise MatchInvalid(self.msg or'does not match regular expression') return v
def _url_validation(v):
parsed = urlparse.urlparse(v) ifnot parsed.scheme ornot parsed.netloc: raise UrlInvalid("must have a URL scheme and host") return parsed
@message('expected an email address', cls=EmailInvalid) def Email(v): """Verify that the value is an email address or not.
>>> s = Schema(Email())
>>> with raises(MultipleInvalid, 'expected an email address'):
... s("a.com")
>>> with raises(MultipleInvalid, 'expected an email address'):
... s("a@.com")
>>> with raises(MultipleInvalid, 'expected an email address'):
... s("a@.com")
>>> s('t@x.com') 't@x.com' """ try: ifnot v or"@"notin v: raise EmailInvalid("Invalid email address")
user_part, domain_part = v.rsplit('@', 1)
ifnot (USER_REGEX.match(user_part) and DOMAIN_REGEX.match(domain_part)): raise EmailInvalid("Invalid email address") return v except: raise ValueError
@message('expected a fully qualified domain name URL', cls=UrlInvalid) def FqdnUrl(v): """Verify that the value is a fully qualified domain name URL.
>>> s = Schema(FqdnUrl())
>>> with raises(MultipleInvalid, 'expected a fully qualified domain name URL'):
... s("http://localhost/")
>>> s('http://w3.org') 'http://w3.org' """ try:
parsed_url = _url_validation(v) if"."notin parsed_url.netloc: raise UrlInvalid("must have a domain name in URL") return v except: raise ValueError
@message('expected a URL', cls=UrlInvalid) def Url(v): """Verify that the value is a URL.
>>> s = Schema(Url())
>>> with raises(MultipleInvalid, 'expected a URL'):
... s(1)
>>> s('http://w3.org') 'http://w3.org' """ try:
_url_validation(v) return v except: raise ValueError
@message('Not a file', cls=FileInvalid)
@truth def IsFile(v): """Verify the file exists.
>>> os.path.basename(IsFile()(__file__)).startswith('validators.py') True
>>> with raises(FileInvalid, 'Not a file'):
... IsFile()("random_filename_goes_here.py")
>>> with raises(FileInvalid, 'Not a file'):
... IsFile()(None) """ try: if v:
v = str(v) return os.path.isfile(v) else: raise FileInvalid('Not a file') except TypeError: raise FileInvalid('Not a file')
@message('Not a directory', cls=DirInvalid)
@truth def IsDir(v): """Verify the directory exists.
>>> IsDir()('/') '/'
>>> with raises(DirInvalid, 'Not a directory'):
... IsDir()(None) """ try: if v:
v = str(v) return os.path.isdir(v) else: raise DirInvalid("Not a directory") except TypeError: raise DirInvalid("Not a directory")
@message('path does not exist', cls=PathInvalid)
@truth def PathExists(v): """Verify the path exists, regardless of its type.
>>> os.path.basename(PathExists()(__file__)).startswith('validators.py') True
>>> with raises(Invalid, 'path does not exist'):
... PathExists()("random_filename_goes_here.py")
>>> with raises(PathInvalid, 'Not a Path'):
... PathExists()(None) """ try: if v:
v = str(v) return os.path.exists(v) else: raise PathInvalid("Not a Path") except TypeError: raise PathInvalid("Not a Path")
def Maybe(validator, msg=None): """Validate that the object matches given validator or is None.
:raises Invalid: If the value does not match the given validator andisnot None.
>>> s = Schema(Maybe(int))
>>> s(10)
10
>>> with raises(Invalid):
... s("string")
""" return Any(validator, None, msg=msg)
class Range(object): """Limit a value to a range.
Either min or max may be omitted.
Either min or max can be excluded from the range of accepted values.
:raises Invalid: If the value is outside the range.
>>> s = Schema(Range(min=1, max=10, min_included=False))
>>> s(5)
5
>>> s(10)
10
>>> with raises(MultipleInvalid, 'value must be at most 10'):
... s(20)
>>> with raises(MultipleInvalid, 'value must be higher than 1'):
... s(1)
>>> with raises(MultipleInvalid, 'value must be lower than 10'):
... Schema(Range(max=10, max_included=False))(20) """
def __call__(self, v): try: if self.min_included: if self.min isnotNoneandnot v >= self.min: raise RangeInvalid(
self.msg or'value must be at least %s' % self.min) else: if self.min isnotNoneandnot v > self.min: raise RangeInvalid(
self.msg or'value must be higher than %s' % self.min) if self.max_included: if self.max isnotNoneandnot v <= self.max: raise RangeInvalid(
self.msg or'value must be at most %s' % self.max) else: if self.max isnotNoneandnot v < self.max: raise RangeInvalid(
self.msg or'value must be lower than %s' % self.max)
return v
# Objects that lack a partial ordering, e.g. None or strings will raise TypeError except TypeError: raise RangeInvalid(
self.msg or'invalid value or type (must have a partial ordering)')
def __init__(self, min=None, max=None, msg=None):
self.min = min
self.max = max
self.msg = msg
def __call__(self, v): try: if self.min isnotNoneand v < self.min:
v = self.min if self.max isnotNoneand v > self.max:
v = self.max return v
# Objects that lack a partial ordering, e.g. None or strings will raise TypeError except TypeError: raise RangeInvalid(
self.msg or'invalid value or type (must have a partial ordering)')
class Length(object): """The length of a value must be in a certain range."""
def __init__(self, min=None, max=None, msg=None):
self.min = min
self.max = max
self.msg = msg
def __call__(self, v): try: if self.min isnotNoneand len(v) < self.min: raise LengthInvalid(
self.msg or'length of value must be at least %s' % self.min) if self.max isnotNoneand len(v) > self.max: raise LengthInvalid(
self.msg or'length of value must be at most %s' % self.max) return v
# Objects that havbe no length e.g. None or strings will raise TypeError except TypeError: raise RangeInvalid(
self.msg or'invalid value or type')
def __call__(self, v): try:
check = v notin self.container except TypeError:
check = True if check: raise InInvalid(self.msg or 'value must be one of {}'.format(sorted(self.container))) return v
def __call__(self, v): try:
check = v in self.container except TypeError:
check = True if check: raise NotInInvalid(self.msg or 'value must not be one of {}'.format(sorted(self.container))) return v
def __call__(self, v): try:
check = self.item notin v except TypeError:
check = True if check: raise ContainsInvalid(self.msg or'value is not allowed') return v
def __init__(self, validators, **kwargs):
self.validators = validators
self.msg = kwargs.pop('msg', None)
self._schemas = [Schema(val, **kwargs) for val in validators]
def __call__(self, v): ifnot isinstance(v, (list, tuple)) or len(v) != len(self._schemas): raise ExactSequenceInvalid(self.msg) try:
v = type(v)(schema(x) for x, schema in zip(v, self._schemas)) except Invalid as e: raise e if self.msg isNoneelse ExactSequenceInvalid(self.msg) return v
def __repr__(self): return'ExactSequence([%s])' % (", ".join(repr(v) for v in self.validators))
class Unique(object): """Ensure an iterable does not contain duplicate items.
Only iterables convertable to a set are supported (native types and
objects with correct __eq__).
JSON does not support set, so they need to be presented as arrays.
Unique allows ensuring that such array does not contain dupes.
def __call__(self, v): try:
set_v = set(v) except TypeError as e: raise TypeInvalid(
self.msg or'contains unhashable elements: {0}'.format(e)) if len(set_v) != len(v):
seen = set()
dupes = list(set(x for x in v if x in seen or seen.add(x))) raise Invalid(
self.msg or'contains duplicate items: {0}'.format(dupes)) return v
def __repr__(self): return'Unique()'
class Equal(object): """Ensure that value matches target.
>>> s = Schema(Equal(1))
>>> s(1)
1
>>> with raises(Invalid):
... s(2)
Validators are not supported, match must be exact:
>>> s = Schema(Equal(str))
>>> with raises(Invalid):
... s('foo') """
consumed = set()
missing = [] for index, value in enumerate(v):
found = False for i, s in enumerate(self._schemas): if i in consumed: continue try:
s(value) except Invalid: pass else:
found = True
consumed.add(i) break ifnot found:
missing.append((index, value))
if len(missing) == 1:
el = missing[0] raise Invalid(self.msg or'Element #{} ({}) is not valid against any validator'.format(el[0], el[1])) elif missing: raise MultipleInvalid([Invalid(self.msg or'Element #{} ({}) is not valid against any validator'.format(
el[0], el[1])) for el in missing]) return v
def __repr__(self): return'Unordered([{}])'.format(", ".join(repr(v) for v in self.validators))
class Number(object): """
Verify the number of digits that are present in the number(Precision), and the decimal places(Scale).
:raises Invalid: If the value does not match the provided Precision and Scale.
def __call__(self, v): """
:param v: is a number enclosed with string
:return: Decimal number """
precision, scale, decimal_num = self._get_precision_scale(v)
if self.precision isnotNoneand self.scale isnotNoneand precision != self.precision\ and scale != self.scale: raise Invalid(self.msg or"Precision must be equal to %s, and Scale must be equal to %s" % (self.precision,
self.scale)) else: if self.precision isnotNoneand precision != self.precision: raise Invalid(self.msg or"Precision must be equal to %s" % self.precision)
if self.scale isnotNoneand scale != self.scale: raise Invalid(self.msg or"Scale must be equal to %s" % self.scale)
if self.yield_decimal: return decimal_num else: return v
class SomeOf(_WithSubValidators): """Value must pass at least some validations, determined by the given parameter.
Optionally, number of passed validations can be capped.
The output of each validator is passed as input to the next.
:param min_valid: Minimum number of valid schemas.
:param validators: List of schemas or validators to match input against.
:param max_valid: Maximum number of valid schemas.
:param msg: Message to deliver to user if validation fails.
:param kwargs: All other keyword arguments are passed to the sub-schema constructors.
:raises NotEnoughValid: If the minimum number of validations isn't met.
:raises TooManyValid: If the maximum number of validations is exceeded.
>>> validate = Schema(SomeOf(min_valid=2, validators=[Range(1, 5), Any(float, int), 6.6]))
>>> validate(6.6)
6.6
>>> validate(3)
3
>>> with raises(MultipleInvalid, 'value must be at most 5, not a valid value'):
... validate(6.2) """
def __init__(self, validators, min_valid=None, max_valid=None, **kwargs): assert min_valid isnotNoneor max_valid isnotNone, \ 'when using "%s" you should specify at least one of min_valid and max_valid' % (type(self).__name__,)
self.min_valid = min_valid or 0
self.max_valid = max_valid or len(validators)
super(SomeOf, self).__init__(*validators, **kwargs)
def _exec(self, funcs, v, path=None):
errors = []
funcs = list(funcs) for func in funcs: try: if path isNone:
v = func(v) else:
v = func(path, v) except Invalid as e:
errors.append(e)
passed_count = len(funcs) - len(errors) if self.min_valid <= passed_count <= self.max_valid: return v
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.