Merge branch '146-deserialize-empty-string' of ltvolks/colander into pr/199

This commit is contained in:
Michael Merickel
2016-01-19 10:47:28 -06:00
4 changed files with 25 additions and 4 deletions

View File

@@ -60,6 +60,14 @@ Features
- Add ``normalize`` option to ``Decimal``, stripping the rightmost
trailing zeros.
- ``colander.String`` schema type now supports an optional keyword argument
``allow_empty`` which, when True, deserializes an empty string to an
empty string. When False (default), an empty string deserializes to
``colander.null``. This allows for a node to be explicitly required, but
allow an empty ('') value to be provided.
https://github.com/Pylons/colander/issues/199
Bug Fixes
---------

View File

@@ -124,6 +124,7 @@ Contributors
- Gouji Ochiai, 2014/08/21
- Tim Tisdall, 2014/09/10
- Romain Commandé, 2014/10/11
- Lucas Taylor, 2014/11/26
- Nando Florestan, 2014/11/27
- Amos Latteier, 2014/11/30
- Jimmy Thrasibule, 2014/12/11

View File

@@ -1159,7 +1159,7 @@ Seq = Sequence
class String(SchemaType):
""" A type representing a Unicode string.
This type constructor accepts one argument:
This type constructor accepts two arguments:
``encoding``
Represents the encoding which should be applied to value
@@ -1212,11 +1212,17 @@ class String(SchemaType):
encoding. If this is not true, an :exc:`colander.Invalid`
error will result.
``allow_empty``
Boolean, if True allows deserialization of an empty string. If
False (default), empty strings will deserialize to
:attr:`colander.null`
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):
self.encoding = encoding
self.allow_empty = allow_empty
def serialize(self, node, appstruct):
if appstruct is null:
@@ -1240,6 +1246,9 @@ class String(SchemaType):
mapping={'val':appstruct, 'err':e})
)
def deserialize(self, node, cstruct):
if cstruct == '' and self.allow_empty:
return text_type('')
if not cstruct:
return null

View File

@@ -1466,9 +1466,9 @@ class TestSequence(unittest.TestCase):
self.assertEqual(result, SequenceItems(['a']))
class TestString(unittest.TestCase):
def _makeOne(self, encoding=None):
def _makeOne(self, encoding=None, allow_empty=False):
from colander import String
return String(encoding)
return String(encoding, allow_empty)
def test_alias(self):
from colander import Str
@@ -1481,6 +1481,9 @@ class TestString(unittest.TestCase):
typ = self._makeOne(None)
result = typ.deserialize(node, '')
self.assertEqual(result, null)
typ = self._makeOne(None, allow_empty=True)
result = typ.deserialize(node, '')
self.assertEqual(result, '')
def test_deserialize_uncooperative(self):
val = Uncooperative()