Skip to content

Commit

Permalink
Merge branch 'pr/199'
Browse files Browse the repository at this point in the history
  • Loading branch information
mmerickel committed Jan 19, 2016
2 parents a258b08 + a29f035 commit 85d2fa5
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 4 deletions.
10 changes: 10 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
unreleased
==========

- ``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

1.2 (2016-01-18)
================

Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 11 additions & 2 deletions colander/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1159,7 +1159,7 @@ def get_value(self, node, appstruct, path):
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
Expand Down Expand Up @@ -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:
Expand All @@ -1240,6 +1246,9 @@ def serialize(self, node, appstruct):
mapping={'val':appstruct, 'err':e})
)
def deserialize(self, node, cstruct):
if cstruct == '' and self.allow_empty:
return text_type('')

if not cstruct:
return null

Expand Down
7 changes: 5 additions & 2 deletions colander/tests/test_colander.py
Original file line number Diff line number Diff line change
Expand Up @@ -1466,9 +1466,9 @@ def test_cstruct_children_cstruct_is_non_null(self):
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
Expand All @@ -1481,6 +1481,9 @@ def test_deserialize_emptystring(self):
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()
Expand Down

0 comments on commit 85d2fa5

Please sign in to comment.