Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add Set schematype (backported from deform.Set) #71

Merged
merged 3 commits into from

2 participants

@domenkozar
Collaborator

No description provided.

@mcdonc

This should probably be checked using "colander.compat.is_nonstr_iter"

Collaborator

Done.

@mcdonc

Although this may be the way it was coded in deform, and other schema types return null when the cstruct evals boolean false, I think this thing should probably return the empty set rather than null (as an empty set is a valid set, and isn't necessarily, null, it's just empty).

Collaborator

The plan was to keep consistency with all the other types, but I agree - empty set is a valid use case.

Collaborator

Done.

@mcdonc mcdonc merged commit f965008 into master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
2  CHANGES.txt
@@ -11,6 +11,8 @@ Bug Fixes
Features
~~~~~~~~
+- Add ``colander.Set`` type, ported from ``deform.Set``
+
- Add Python 3.3 to tox configuration and use newer tox testing regime
(setup.py dev).
View
2  CONTRIBUTORS.txt
@@ -107,4 +107,4 @@ Contributors
- Atsushi Odagiri, 2012/02/04
- Daniel Nouri, 2012/03/28
- Gary van der Merwe, 2012/04/05
-- Domen Kožar, 2012-04-16
+- Domen Kožar, 2012/04/16
View
31 colander/__init__.py
@@ -733,6 +733,37 @@ def get_value(self, node, appstruct, path):
return appstruct[index]
+class Set(SchemaType):
+ """ A type representing a non-overlapping set of items.
+ Deserializes an iterable to a ``set`` 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: 0.9.9.1
+
+ """
+
+ 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 set(cstruct)
+
+
class SequenceItems(list):
"""
List marker subclass for use by Sequence.cstruct_children, which indicates
View
52 colander/tests/test_colander.py
@@ -949,6 +949,58 @@ def test_cstruct_children_justright(self):
result = typ.cstruct_children(node1, ['one', 'two'])
self.assertEqual(result, ['one', 'two'])
+
+class TestSet(unittest.TestCase):
+ def _makeOne(self, **kw):
+ from colander import Set
+ return Set(**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',))
+ self.assertEqual(result, set(('a',)))
+
+ def test_deserialize_empty_set(self):
+ import colander
+ typ = self._makeOne()
+ node = DummySchemaNode(typ)
+ result = typ.deserialize(node, set())
+ self.assertEqual(result, set())
+
class TestSequence(unittest.TestCase):
def _makeOne(self, **kw):
from colander import Sequence
View
2  docs/api.rst
@@ -74,6 +74,8 @@ Types
.. autoclass:: Tuple
+ .. autoclass:: Set
+
.. autoclass:: Sequence
.. autoclass:: Seq
Something went wrong with that request. Please try again.