diff --git a/CHANGES.rst b/CHANGES.rst index 5962a6f..8173d04 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,16 @@ +unreleased +========== + +Bug Fixes +--------- + +- Fix a bug in which ``MappingSchema``, ``SequenceSchema`` and + ``TupleSchema`` would always treat the first arg as the schema type. This + meant that it would fail if passed any nodes to the constructor despite + the default type being implied by the name. It is now possible to do + ``MappingSchema(child1, child2, ...)`` instead of + ``MappingSchema(Mapping(), child1, child2)``. + 1.1 (2016-01-15) ================ diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 23a287e..c3fdf73 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -117,6 +117,7 @@ Contributors - Veeti Paananen, 2013/08/20 - Michael Howitz, 2013/12/05 - Alex Marandon, 2013/12/21 +- Joe Dallago, 2014/2/10 - Jaseem Abid, 2014/06/16 - Cédric Messiant, 2014/06/27 - Gouji Ochiai, 2014/08/21 diff --git a/colander/__init__.py b/colander/__init__.py index 35f0715..5178b49 100644 --- a/colander/__init__.py +++ b/colander/__init__.py @@ -1908,15 +1908,14 @@ class _SchemaNode(object): return node def __init__(self, *arg, **kw): - # bw compat forces us to treat first arg as type always + # bw compat forces us to treat first arg as type if not a _SchemaNode if 'typ' in kw: self.typ = kw.pop('typ') - _add_node_children(self, arg) - elif arg: - self.typ = arg[0] - _add_node_children(self, arg[1:]) + elif arg and not isinstance(arg[0], _SchemaNode): + self.typ, arg = arg[0], arg[1:] else: self.typ = self.schema_type() + _add_node_children(self, arg) # bw compat forces us to manufacture a title if one is not supplied title = kw.get('title', self.title) diff --git a/colander/tests/test_colander.py b/colander/tests/test_colander.py index a35ecd0..6c8cb5a 100644 --- a/colander/tests/test_colander.py +++ b/colander/tests/test_colander.py @@ -3336,6 +3336,13 @@ class TestSchema(unittest.TestCase): result = node.serialize(expected) self.assertEqual(result, expected) + def test_imperative_with_implicit_schema_type(self): + import colander + node = colander.SchemaNode(colander.String()) + schema = colander.Schema(node) + self.assertEqual(schema.schema_type, colander.Mapping) + self.assertEqual(schema.children[0], node) + class TestSequenceSchema(unittest.TestCase): def test_succeed(self): import colander @@ -3369,6 +3376,13 @@ class TestSequenceSchema(unittest.TestCase): e.msg, 'Sequence schemas must have exactly one child node') + def test_imperative_with_implicit_schema_type(self): + import colander + node = colander.SchemaNode(colander.String()) + schema = colander.SequenceSchema(node) + self.assertEqual(schema.schema_type, colander.Sequence) + self.assertEqual(schema.children[0], node) + class TestTupleSchema(unittest.TestCase): def test_it(self): import colander @@ -3380,6 +3394,13 @@ class TestTupleSchema(unittest.TestCase): self.assertEqual(node.typ.__class__, colander.Tuple) self.assertEqual(node.children[0].typ.__class__, colander.String) + def test_imperative_with_implicit_schema_type(self): + import colander + node = colander.SchemaNode(colander.String()) + schema = colander.TupleSchema(node) + self.assertEqual(schema.schema_type, colander.Tuple) + self.assertEqual(schema.children[0], node) + class TestFunctional(object): def test_deserialize_ok(self): import colander.tests