From 7ac04ee4c7e9435e5a6babf0ceceb7771425713e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 2 May 2010 01:06:28 +0000 Subject: [PATCH] - New argument to ``colander.String`` constructor: ``allow_empty``. This is a boolean representing whether an empty string is a valid value during deserialization, defaulting to ``False``. --- CHANGES.txt | 4 ++++ colander/__init__.py | 21 ++++++++++++++------- colander/tests.py | 10 ++++++++-- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index febadc9..7d8765a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -11,6 +11,10 @@ Next release error message formatting, which may impact you if you were feeding colander an error message template. +- New argument to ``colander.String`` constructor: ``allow_empty``. + This is a boolean representing whether an empty string is a valid + value during deserialization, defaulting to ``False``. + 0.5.2 (2010-04-09) ------------------ diff --git a/colander/__init__.py b/colander/__init__.py index 590bf42..dcaf1de 100644 --- a/colander/__init__.py +++ b/colander/__init__.py @@ -313,8 +313,8 @@ class Mapping(object): unknown ``unknown`` controls the behavior of this type when an unknown key is encountered in the value passed to the - ``deserialize`` method of this instance. The potential - values of ``unknown`` are: + ``deserialize`` method of this instance. All the potential + values of ``unknown`` are strings. They are: - ``ignore`` means that keys that are not present in the schema associated with this type will be ignored during @@ -615,9 +615,15 @@ default_encoding = 'utf-8' class String(object): """ A type representing a Unicode string. - This type constructor accepts a single argument ``encoding``, - representing the encoding which should be applied to object - serialization. It defaults to ``utf-8`` if not provided. + This type constructor accepts a number of arguments: + + ``encoding`` + Represents the encoding which should be applied to object + serialization. It defaults to ``utf-8`` if not provided. + + ``allow_empty`` + Boolean representing whether an empty string input to + deserialize will be accepted. Default: ``False``. Input to ``serialize`` is serialized to a Python ``str`` object, which is encoded in the encoding provided. @@ -630,10 +636,11 @@ class String(object): The subnodes of the :class:`colander.SchemaNode` that wraps this type are ignored. """ - def __init__(self, encoding=None): + def __init__(self, encoding=None, allow_empty=False): if encoding is None: encoding = default_encoding self.encoding = encoding + self.allow_empty = allow_empty def deserialize(self, node, value): try: @@ -643,7 +650,7 @@ class String(object): raise Invalid(node, _('${val} is not a string: %{err}', mapping={'val':value, 'err':e})) - if not value: + if not value and not self.allow_empty: if node.required: raise Invalid(node, _('Required')) value = node.default diff --git a/colander/tests.py b/colander/tests.py index 83c960d..b8d3636 100644 --- a/colander/tests.py +++ b/colander/tests.py @@ -632,9 +632,9 @@ class TestSequence(unittest.TestCase): self.assertEqual(len(e.children), 2) class TestString(unittest.TestCase): - def _makeOne(self, encoding='utf-8'): + def _makeOne(self, encoding='utf-8', allow_empty=False): from colander import String - return String(encoding) + return String(encoding, allow_empty) def test_alias(self): from colander import Str @@ -655,6 +655,12 @@ class TestString(unittest.TestCase): result = typ.deserialize(node, val) self.assertEqual(result, 'default') + def test_deserialize_emptystring_allow_empty(self): + node = DummySchemaNode(None) + typ = self._makeOne(None, True) + result = typ.deserialize(node, '') + self.assertEqual(result, '') + def test_deserialize_uncooperative(self): val = Uncooperative() node = DummySchemaNode(None)