Hello, As talked with Chris McDonough at #freenode, here is the patch for adding Regex and Email validators to Colander. He has already implemented the Function validator as discussed.
Thanks! -- Steve Howe howest...@googlemail.com
Index: __init__.py =================================================================== --- __init__.py (revision 8854) +++ __init__.py (working copy) @@ -2,6 +2,7 @@ import itertools import iso8601 import pprint +import re class _missing(object): pass @@ -170,6 +171,37 @@ if isinstance(result, basestring): raise Invalid(node, result) +class Regex(object): + """ Regular expression validator. Initialize it with the string + regular expression ``regex`` that will be compiled and matched + against ``value`` when validator is called. If ``msg`` is + supplied, it will be the error message to be used; otherwise, + defaults to "String does not match expected pattern". + + When calling, if ``value`` matches the regular expression, + validation succeeds; otherwise, :exc:`colander.Invalid` is + raised with the ``msg`` error message. + """ + def __init__(self, regex, msg=None): + self.match_object = re.compile(regex) + if msg is None: + self.msg = "String does not match expected pattern" + else: + self.msg = msg + def __call__(self, node, value): + if self.match_object.match(value) is None: + raise Invalid(self.msg) + +class Email(Regex): + """ Email address validator. If ``msg`` is supplied, it will be + the error message to be used when raising :exc:`colander.Invalid`; + otherwise, defaults to "Invalid email address". + """ + def __init__(self, msg=None): + if msg is None: + msg = "Invalid email address" + super(Email, self).__init__(u'(?i)^[a-z0-9._%+...@[a-z0-9.-]+\.[a-z]{2,4}$', msg=msg) + class Range(object): """ Validator which succeeds if the value it is passed is greater or equal to ``min`` and less than or equal to ``max``. If ``min`` @@ -214,7 +246,6 @@ node, 'Longer than maximum length %s' % self.max) - class OneOf(object): """ Validator which succeeds if the value passed to it is one of a fixed set of values """ Index: tests.py =================================================================== --- tests.py (revision 8854) +++ tests.py (working copy) @@ -194,6 +194,47 @@ e = invalid_exc(validator, None, 2) self.assertEqual(e.msg, '2 is greater than maximum value 1') +class TestRegex(unittest.TestCase): + def _makeOne(self, pattern): + from colander import Regex + return Regex(pattern) + + def test_valid_regex(self): + self.assertEqual(self._makeOne('a')(None, 'a'), None) + self.assertEqual(self._makeOne('[0-9]+')(None, '1111'), None) + self.assertEqual(self._makeOne('')(None, ''), None) + self.assertEqual(self._makeOne('.*')(None, ''), None) + + def test_invalid_regexs(self): + from colander import Invalid + self.assertRaises(Invalid, self._makeOne('[0-9]+'), None, 'a') + self.assertRaises(Invalid, self._makeOne('a{2,4}'), None, 'ba') + +class TestEmail(unittest.TestCase): + def _makeOne(self): + from colander import Email + return Email() + + def test_valid_emails(self): + validator = self._makeOne() + self.assertEqual(validator(None, 'm...@here.com'), None) + self.assertEqual(validator(None, 'm...@here1.com'), None) + self.assertEqual(validator(None, 'n...@here1.us'), None) + self.assertEqual(validator(None, 'n...@here1.info'), None) + + def test_empty_email(self): + validator = self._makeOne() + from colander import Invalid + self.assertRaises(Invalid, validator, None, '') + + def test_invalid_emails(self): + validator = self._makeOne() + from colander import Invalid + self.assertRaises(Invalid, validator, None, 'm...@here.') + self.assertRaises(Invalid, validator, None, 'n...@here.comcom') + self.assertRaises(Invalid, validator, None, '@here.us') + self.assertRaises(Invalid, validator, None, '(name)@here.info') + class TestLength(unittest.TestCase): def _makeOne(self, min=None, max=None): from colander import Length
_______________________________________________ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev