diff --git a/CHANGES.rst b/CHANGES.rst index c7aaf663..00c103cd 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -21,6 +21,8 @@ Features - Add a ``missing_msg`` argument to ``SchemaNode`` that specifies the error message to be used when the node is required and missing +- Add ``drop`` functionality to ``Sequence`` type. + Bug Fixes --------- diff --git a/colander/__init__.py b/colander/__init__.py index d2a518be..f344d86d 100644 --- a/colander/__init__.py +++ b/colander/__init__.py @@ -987,13 +987,20 @@ def _impl(self, node, value, callback, accept_scalar): error = None result = [] + subnode = node.children[0] for num, subval in enumerate(value): + if subval is drop or (subval is null and subnode.default is drop): + continue try: - result.append(callback(node.children[0], subval)) + sub_result = callback(subnode, subval) except Invalid as e: if error is None: error = Invalid(node) error.add(e, num) + else: + if sub_result is drop: + continue + result.append(sub_result) if error is not None: raise error diff --git a/colander/tests/test_colander.py b/colander/tests/test_colander.py index 6d05d710..dfb05c62 100644 --- a/colander/tests/test_colander.py +++ b/colander/tests/test_colander.py @@ -1320,6 +1320,14 @@ def test_serialize_null(self): result = typ.serialize(node, colander.null) self.assertEqual(result, colander.null) + def test_serialize_drop(self): + from colander import drop + node = DummySchemaNode(None) + node.children = [DummySchemaNode(None, name='a')] + typ = self._makeOne() + result = typ.serialize(node, (drop,)) + self.assertEqual(result, []) + def test_serialize_not_iterable(self): node = DummySchemaNode(None) typ = self._makeOne() @@ -3319,6 +3327,24 @@ class MySchema(colander.SequenceSchema): e.msg, 'Sequence schemas must have exactly one child node') + def test_deserialize_drop(self): + import colander + class MySchema(colander.SequenceSchema): + a = colander.SchemaNode(colander.String(), missing=colander.drop) + node = MySchema() + result = node.deserialize([None]) + self.assertEqual(result, []) + result = node.deserialize([colander.null]) + self.assertEqual(result, []) + + def test_serialize_drop_default(self): + import colander + class MySchema(colander.SequenceSchema): + a = colander.SchemaNode(colander.String(), default=colander.drop) + node = MySchema() + result = node.serialize([colander.null]) + self.assertEqual(result, []) + class TestTupleSchema(unittest.TestCase): def test_it(self): import colander