Merge pull request #227 from bochecha/noneof

New NoneOf validator
This commit is contained in:
Tres Seaver
2015-10-22 10:35:26 -04:00
4 changed files with 47 additions and 0 deletions

View File

@@ -21,6 +21,8 @@ Features
- Add a ``missing_msg`` argument to ``SchemaNode``, allowing customization
of the error message used when the node is required and missing.
- Add `NoneOf` validator wich succeeds if the value is none of the choices.
Bug Fixes
---------

View File

@@ -443,6 +443,33 @@ class OneOf(object):
mapping={'val':value, 'choices':choices})
raise Invalid(node, err)
class NoneOf(object):
""" Validator which succeeds if the value passed to it is none of a
fixed set of values.
``msg_err`` is used to form the ``msg`` of the :exc:`colander.Invalid`
error when reporting a validation failure. If ``msg_err`` is specified,
it must be a string. The string may contain the replacement targets
``${choices}`` and ``${val}``, representing the set of forbidden values
and the provided value respectively.
"""
_MSG_ERR = _('"${val}" must not be one of ${choices}')
def __init__(self, choices, msg_err=_MSG_ERR):
self.forbidden = choices
self.msg_err = msg_err
def __call__(self, node, value):
if value not in self.forbidden:
return
choices = ', '.join(['%s' % x for x in self.forbidden])
err = _(self.msg_err, mapping={'val': value, 'choices': choices})
raise Invalid(node, err)
class ContainsOnly(object):
""" Validator which succeeds if the value passed to is a sequence and each
element in the sequence is also in the sequence passed as ``choices``.

View File

@@ -490,6 +490,22 @@ class TestOneOf(unittest.TestCase):
e = invalid_exc(validator, None, None)
self.assertEqual(e.msg.interpolate(), '"None" is not one of 1, 2')
class TestNoneOf(unittest.TestCase):
def _makeOne(self, values):
from colander import NoneOf
return NoneOf(values)
def test_success(self):
validator = self._makeOne([1, 2])
self.assertEqual(validator(None, 3), None)
def test_failure(self):
validator = self._makeOne([1, 2])
e = invalid_exc(validator, None, 2)
self.assertEqual(e.msg.interpolate(), '"2" must not be one of 1, 2')
class TestContainsOnly(unittest.TestCase):
def _makeOne(self, values):
from colander import ContainsOnly

View File

@@ -64,6 +64,8 @@ Validators
.. autoclass:: OneOf
.. autoclass:: NoneOf
.. autoclass:: ContainsOnly
.. autoclass:: Function