Add 'colander.List' type, modeled on 'colander.Set'.
Preserves order, allows duplicates, deserializes to a Python 'list'.
This commit is contained in:
@@ -1,10 +1,19 @@
|
|||||||
Unreleased
|
Unreleased
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
Bug Fixes
|
||||||
|
~~~~~~~~~
|
||||||
|
|
||||||
- ``iso8601.py``: Convert ``ValueError`` (raised by ``datetime``) into
|
- ``iso8601.py``: Convert ``ValueError`` (raised by ``datetime``) into
|
||||||
``ParseErrorr`` in ``parse_date``, so that the validation machinery
|
``ParseErrorr`` in ``parse_date``, so that the validation machinery
|
||||||
upstream handles it properly.
|
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)
|
1.0a5 (2013-05-31)
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
@@ -808,6 +808,37 @@ class Set(SchemaType):
|
|||||||
return set(cstruct)
|
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):
|
class SequenceItems(list):
|
||||||
"""
|
"""
|
||||||
List marker subclass for use by Sequence.cstruct_children, which indicates
|
List marker subclass for use by Sequence.cstruct_children, which indicates
|
||||||
|
@@ -1059,6 +1059,58 @@ class TestSet(unittest.TestCase):
|
|||||||
result = typ.deserialize(node, set())
|
result = typ.deserialize(node, set())
|
||||||
self.assertEqual(result, 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):
|
class TestSequence(unittest.TestCase):
|
||||||
def _makeOne(self, **kw):
|
def _makeOne(self, **kw):
|
||||||
from colander import Sequence
|
from colander import Sequence
|
||||||
|
Reference in New Issue
Block a user