Merge pull request #113 from Pylons/add_list_type

Add 'colander.List' type, modeled on 'colander.Set'.
This commit is contained in:
Tres Seaver
2013-06-14 07:53:57 -07:00
3 changed files with 92 additions and 0 deletions

View File

@@ -1,10 +1,19 @@
Unreleased
----------
Bug Fixes
~~~~~~~~~
- ``iso8601.py``: Convert ``ValueError`` (raised by ``datetime``) into
``ParseErrorr`` in ``parse_date``, so that the validation machinery
upstream handles it properly.
Features
~~~~~~~~
- Add ``colander.List`` type, modeled on ``deform.List``: this type
preserves ordering, and allows duplicates.
1.0a5 (2013-05-31)
------------------

View File

@@ -808,6 +808,37 @@ class Set(SchemaType):
return set(cstruct)
class List(SchemaType):
""" Type representing an ordered sequence of items.
Desrializes an iterable to a ``list`` object.
If the :attr:`colander.null` value is passed to the serialize
method of this class, the :attr:`colander.null` value will be
returned.
.. versionadded: 1.0a6
"""
def serialize(self, node, appstruct):
if appstruct is null:
return null
return appstruct
def deserialize(self, node, cstruct):
if cstruct is null:
return null
if not is_nonstr_iter(cstruct):
raise Invalid(
node,
_('${cstruct} is not iterable', mapping={'cstruct': cstruct})
)
return list(cstruct)
class SequenceItems(list):
"""
List marker subclass for use by Sequence.cstruct_children, which indicates

View File

@@ -1059,6 +1059,58 @@ class TestSet(unittest.TestCase):
result = typ.deserialize(node, set())
self.assertEqual(result, set())
class TestList(unittest.TestCase):
def _makeOne(self, **kw):
from colander import List
return List(**kw)
def test_serialize(self):
typ = self._makeOne()
node = DummySchemaNode(typ)
provided = []
result = typ.serialize(node, provided)
self.assertTrue(result is provided)
def test_serialize_null(self):
from colander import null
typ = self._makeOne()
node = DummySchemaNode(typ)
result = typ.serialize(node, null)
self.assertTrue(result is null)
def test_deserialize_no_iter(self):
typ = self._makeOne()
node = DummySchemaNode(typ)
e = invalid_exc(typ.deserialize, node, 1)
self.assertEqual(e.msg, '${cstruct} is not iterable')
def test_deserialize_str_no_iter(self):
typ = self._makeOne()
node = DummySchemaNode(typ)
e = invalid_exc(typ.deserialize, node, "foo")
self.assertEqual(e.msg, '${cstruct} is not iterable')
def test_deserialize_null(self):
from colander import null
typ = self._makeOne()
node = DummySchemaNode(typ)
result = typ.deserialize(node, null)
self.assertEqual(result, null)
def test_deserialize_valid(self):
typ = self._makeOne()
node = DummySchemaNode(typ)
result = typ.deserialize(node, ('a', 'z', 'b'))
self.assertEqual(result, ['a', 'z', 'b'])
def test_deserialize_empty_set(self):
import colander
typ = self._makeOne()
node = DummySchemaNode(typ)
result = typ.deserialize(node, ())
self.assertEqual(result, [])
class TestSequence(unittest.TestCase):
def _makeOne(self, **kw):
from colander import Sequence