- Subnodes of a schema node are now kept in the `children` attribute

rather than the ``nodes`` attribute.
This commit is contained in:
Chris McDonough
2010-03-26 19:13:57 +00:00
parent a9d94df919
commit cf3f90a0b3
3 changed files with 58 additions and 55 deletions

View File

@@ -4,6 +4,9 @@ Changes
Next release
------------
- Subnodes of a schema node are now kept in the ``children`` attribute
rather than the ``nodes`` attribute.
- Add an ``sdefault`` property to ``colander.SchemaNode`` objects.
- Add a ``clone`` method to ``colander.SchemaNode`` objects.

View File

@@ -187,7 +187,7 @@ class Mapping(object):
error = None
result = {}
for num, subnode in enumerate(node.nodes):
for num, subnode in enumerate(node.children):
name = subnode.name
subval = value.pop(name, _missing)
@@ -256,7 +256,7 @@ class Tuple(Positional):
if not hasattr(value, '__iter__'):
raise Invalid(node, '%r is not iterable' % value)
valuelen, nodelen = len(value), len(node.nodes)
valuelen, nodelen = len(value), len(node.children)
if valuelen != nodelen:
raise Invalid(
@@ -271,7 +271,7 @@ class Tuple(Positional):
error = None
result = []
for num, subnode in enumerate(node.nodes):
for num, subnode in enumerate(node.children):
subval = value[num]
try:
result.append(callback(subnode, subval))
@@ -333,7 +333,7 @@ class Sequence(Positional):
result = []
for num, subval in enumerate(value):
try:
result.append(callback(node.nodes[0], subval))
result.append(callback(node.children[0], subval))
except Invalid, e:
if error is None:
error = Invalid(node)
@@ -590,9 +590,9 @@ class SchemaNode(object):
instance of a class that implements the
:class:`colander.interfaces.Type` interface.
- ``nodes``: a sequence of subnodes. If the subnodes of this node
are not known at construction time, they can later be added via
the ``add`` method.
- ``children``: a sequence of subnodes. If the subnodes of this
node are not known at construction time, they can later be added
via the ``add`` method.
- ``name``: The name of this node.
@@ -621,14 +621,14 @@ class SchemaNode(object):
inst._order = cls._counter.next()
return inst
def __init__(self, typ, *nodes, **kw):
def __init__(self, typ, *children, **kw):
self.typ = typ
self.validator = kw.get('validator', None)
self.default = kw.get('default', _missing)
self.name = kw.get('name', '')
self.title = kw.get('title', self.name.capitalize())
self.description = kw.get('description', '')
self.nodes = list(nodes)
self.children = list(children)
def __repr__(self):
return '<%s object at %x named %r>' % (self.__class__.__name__,
@@ -664,10 +664,10 @@ class SchemaNode(object):
def add(self, node):
""" Add a subnode to this node """
self.nodes.append(node)
self.children.append(node)
def __getitem__(self, name):
for node in self.nodes:
for node in self.children:
if node.name == name:
return node
raise KeyError(name)
@@ -678,7 +678,7 @@ class SchemaNode(object):
dictionaries are preserved."""
cloned = self.__class__(self.typ)
cloned.__dict__.update(self.__dict__)
cloned.nodes = [ node.clone() for node in self.nodes ]
cloned.children = [ node.clone() for node in self.children ]
return cloned
class _SchemaMeta(type):

View File

@@ -225,28 +225,28 @@ class TestMapping(unittest.TestCase):
def test_deserialize_ok(self):
node = DummySchemaNode(None)
node.nodes = [DummySchemaNode(None, name='a')]
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
result = typ.deserialize(node, {'a':1})
self.assertEqual(result, {'a':1})
def test_deserialize_unknown_keys_raise(self):
node = DummySchemaNode(None)
node.nodes = [DummySchemaNode(None, name='a')]
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne('raise')
e = invalid_exc(typ.deserialize, node, {'a':1, 'b':2})
self.assertEqual(e.msg, "Unrecognized keys in mapping: {'b': 2}")
def test_deserialize_unknown_keys_preserve(self):
node = DummySchemaNode(None)
node.nodes = [DummySchemaNode(None, name='a')]
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne('preserve')
result = typ.deserialize(node, {'a':1, 'b':2})
self.assertEqual(result, {'a':1, 'b':2})
def test_deserialize_subnodes_raise(self):
node = DummySchemaNode(None)
node.nodes = [
node.children = [
DummySchemaNode(None, name='a', exc='Wrong 2'),
DummySchemaNode(None, name='b', exc='Wrong 2'),
]
@@ -257,7 +257,7 @@ class TestMapping(unittest.TestCase):
def test_deserialize_subnode_missing_default(self):
node = DummySchemaNode(None)
node.nodes = [
node.children = [
DummySchemaNode(None, name='a'),
DummySchemaNode(None, name='b', default='abc'),
]
@@ -267,7 +267,7 @@ class TestMapping(unittest.TestCase):
def test_deserialize_subnode_missing_nodefault(self):
node = DummySchemaNode(None)
node.nodes = [
node.children = [
DummySchemaNode(None, name='a'),
DummySchemaNode(None, name='b'),
]
@@ -290,28 +290,28 @@ class TestMapping(unittest.TestCase):
def test_serialize_ok(self):
node = DummySchemaNode(None)
node.nodes = [DummySchemaNode(None, name='a')]
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
result = typ.serialize(node, {'a':1})
self.assertEqual(result, {'a':1})
def test_serialize_unknown_keys_raise(self):
node = DummySchemaNode(None)
node.nodes = [DummySchemaNode(None, name='a')]
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne('raise')
e = invalid_exc(typ.serialize, node, {'a':1, 'b':2})
self.assertEqual(e.msg, "Unrecognized keys in mapping: {'b': 2}")
def test_serialize_unknown_keys_preserve(self):
node = DummySchemaNode(None)
node.nodes = [DummySchemaNode(None, name='a')]
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne('preserve')
result = typ.serialize(node, {'a':1, 'b':2})
self.assertEqual(result, {'a':1, 'b':2})
def test_serialize_subnodes_raise(self):
node = DummySchemaNode(None)
node.nodes = [
node.children = [
DummySchemaNode(None, name='a', exc='Wrong 2'),
DummySchemaNode(None, name='b', exc='Wrong 2'),
]
@@ -322,7 +322,7 @@ class TestMapping(unittest.TestCase):
def test_serialize_subnode_missing_default(self):
node = DummySchemaNode(None)
node.nodes = [
node.children = [
DummySchemaNode(None, name='a'),
DummySchemaNode(None, name='b', default='abc'),
]
@@ -332,7 +332,7 @@ class TestMapping(unittest.TestCase):
def test_serialize_subnode_missing_nodefault(self):
node = DummySchemaNode(None)
node.nodes = [
node.children = [
DummySchemaNode(None, name='a'),
DummySchemaNode(None, name='b'),
]
@@ -362,14 +362,14 @@ class TestTuple(unittest.TestCase):
def test_deserialize_ok(self):
node = DummySchemaNode(None)
node.nodes = [DummySchemaNode(None, name='a')]
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
result = typ.deserialize(node, ('a',))
self.assertEqual(result, ('a',))
def test_deserialize_toobig(self):
node = DummySchemaNode(None)
node.nodes = [DummySchemaNode(None, name='a')]
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, ('a','b'))
self.assertEqual(e.msg,
@@ -377,7 +377,7 @@ class TestTuple(unittest.TestCase):
def test_deserialize_toosmall(self):
node = DummySchemaNode(None)
node.nodes = [DummySchemaNode(None, name='a')]
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, ())
self.assertEqual(e.msg,
@@ -385,7 +385,7 @@ class TestTuple(unittest.TestCase):
def test_deserialize_subnodes_raise(self):
node = DummySchemaNode(None)
node.nodes = [
node.children = [
DummySchemaNode(None, name='a', exc='Wrong 2'),
DummySchemaNode(None, name='b', exc='Wrong 2'),
]
@@ -411,14 +411,14 @@ class TestTuple(unittest.TestCase):
def test_serialize_ok(self):
node = DummySchemaNode(None)
node.nodes = [DummySchemaNode(None, name='a')]
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
result = typ.serialize(node, ('a',))
self.assertEqual(result, ('a',))
def test_serialize_toobig(self):
node = DummySchemaNode(None)
node.nodes = [DummySchemaNode(None, name='a')]
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
e = invalid_exc(typ.serialize, node, ('a','b'))
self.assertEqual(e.msg,
@@ -426,7 +426,7 @@ class TestTuple(unittest.TestCase):
def test_serialize_toosmall(self):
node = DummySchemaNode(None)
node.nodes = [DummySchemaNode(None, name='a')]
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
e = invalid_exc(typ.serialize, node, ())
self.assertEqual(e.msg,
@@ -434,7 +434,7 @@ class TestTuple(unittest.TestCase):
def test_serialize_subnodes_raise(self):
node = DummySchemaNode(None)
node.nodes = [
node.children = [
DummySchemaNode(None, name='a', exc='Wrong 2'),
DummySchemaNode(None, name='b', exc='Wrong 2'),
]
@@ -456,7 +456,7 @@ class TestSequence(unittest.TestCase):
def test_deserialize_not_iterable(self):
node = DummySchemaNode(None)
typ = self._makeOne()
node.nodes = [node]
node.children = [node]
e = invalid_exc(typ.deserialize, node, None)
self.assertEqual(
e.msg,
@@ -466,29 +466,29 @@ class TestSequence(unittest.TestCase):
def test_deserialize_not_iterable_accept_scalar(self):
node = DummySchemaNode(None)
typ = self._makeOne(accept_scalar=True)
node.nodes = [node]
node.children = [node]
result = typ.deserialize(node, None)
self.assertEqual(result, [None])
def test_deserialize_no_subnodes(self):
typ = self._makeOne()
node = DummySchemaNode(None)
node.nodes = [node]
node.children = [node]
result = typ.deserialize(node, ())
self.assertEqual(result, [])
def test_deserialize_ok(self):
node = DummySchemaNode(None)
node.nodes = [DummySchemaNode(None, name='a')]
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
node.nodes = [node]
node.children = [node]
result = typ.deserialize(node, ('a',))
self.assertEqual(result, ['a'])
def test_deserialize_subnodes_raise(self):
node = DummySchemaNode(None, exc='Wrong')
typ = self._makeOne()
node.nodes = [node]
node.children = [node]
e = invalid_exc(typ.deserialize, node, ('1', '2'))
self.assertEqual(e.msg, None)
self.assertEqual(len(e.children), 2)
@@ -496,7 +496,7 @@ class TestSequence(unittest.TestCase):
def test_serialize_not_iterable(self):
node = DummySchemaNode(None)
typ = self._makeOne()
node.nodes = [node]
node.children = [node]
e = invalid_exc(typ.serialize, node, None)
self.assertEqual(
e.msg,
@@ -506,20 +506,20 @@ class TestSequence(unittest.TestCase):
def test_serialize_not_iterable_accept_scalar(self):
node = DummySchemaNode(None)
typ = self._makeOne(accept_scalar=True)
node.nodes = [node]
node.children = [node]
result = typ.serialize(node, None)
self.assertEqual(result, [None])
def test_serialize_no_subnodes(self):
node = DummySchemaNode(None)
node.nodes = [node]
node.children = [node]
typ = self._makeOne()
result = typ.serialize(node, ())
self.assertEqual(result, [])
def test_serialize_ok(self):
node = DummySchemaNode(None)
node.nodes = [DummySchemaNode(None, name='a')]
node.children = [DummySchemaNode(None, name='a')]
typ = self._makeOne()
result = typ.serialize(node, ('a',))
self.assertEqual(result, ['a'])
@@ -527,7 +527,7 @@ class TestSequence(unittest.TestCase):
def test_serialize_subnodes_raise(self):
node = DummySchemaNode(None, exc='Wrong')
typ = self._makeOne()
node.nodes = [node]
node.children = [node]
e = invalid_exc(typ.serialize, node, ('1', '2'))
self.assertEqual(e.msg, None)
self.assertEqual(len(e.children), 2)
@@ -911,7 +911,7 @@ class TestSchemaNode(unittest.TestCase):
def test_ctor_no_title(self):
node = self._makeOne(None, 0, validator=1, default=2, name='name')
self.assertEqual(node.typ, None)
self.assertEqual(node.nodes, [0])
self.assertEqual(node.children, [0])
self.assertEqual(node.validator, 1)
self.assertEqual(node.default, 2)
self.assertEqual(node.name, 'name')
@@ -921,7 +921,7 @@ class TestSchemaNode(unittest.TestCase):
node = self._makeOne(None, 0, validator=1, default=2, name='name',
title='title')
self.assertEqual(node.typ, None)
self.assertEqual(node.nodes, [0])
self.assertEqual(node.children, [0])
self.assertEqual(node.validator, 1)
self.assertEqual(node.default, 2)
self.assertEqual(node.name, 'name')
@@ -971,7 +971,7 @@ class TestSchemaNode(unittest.TestCase):
def test_add(self):
node = self._makeOne(None)
node.add(1)
self.assertEqual(node.nodes, [1])
self.assertEqual(node.children, [1])
def test_repr(self):
node = self._makeOne(None, name='flub')
@@ -996,14 +996,14 @@ class TestSchemaNode(unittest.TestCase):
inner_node = self._makeOne(inner_typ, name='inner')
outer_node.foo = 1
inner_node.foo = 2
outer_node.nodes = [inner_node]
outer_node.children = [inner_node]
outer_clone = outer_node.clone()
self.failIf(outer_clone is outer_node)
self.assertEqual(outer_clone.typ, outer_typ)
self.assertEqual(outer_clone.name, 'outer')
self.assertEqual(outer_node.foo, 1)
self.assertEqual(len(outer_clone.nodes), 1)
inner_clone = outer_clone.nodes[0]
self.assertEqual(len(outer_clone.children), 1)
inner_clone = outer_clone.children[0]
self.failIf(inner_clone is inner_node)
self.assertEqual(inner_clone.typ, inner_typ)
self.assertEqual(inner_clone.name, 'inner')
@@ -1025,9 +1025,9 @@ class TestSchema(unittest.TestCase):
self.assertEqual(node.__class__, colander.SchemaNode)
self.assertEqual(node.typ.__class__, colander.Mapping)
self.assertEqual(node.typ.unknown_keys, 'raise')
self.assertEqual(node.nodes[0].typ.__class__, colander.String)
self.assertEqual(node.nodes[0].title, 'Thing')
self.assertEqual(node.nodes[1].title, 'bar')
self.assertEqual(node.children[0].typ.__class__, colander.String)
self.assertEqual(node.children[0].title, 'Thing')
self.assertEqual(node.children[1].title, 'bar')
class TestSequenceSchema(unittest.TestCase):
def test_it(self):
@@ -1039,7 +1039,7 @@ class TestSequenceSchema(unittest.TestCase):
self.failUnless(hasattr(node, '_order'))
self.assertEqual(node.__class__, colander.SchemaNode)
self.assertEqual(node.typ.__class__, colander.Sequence)
self.assertEqual(node.nodes[0], _inner)
self.assertEqual(node.children[0], _inner)
class TestTupleSchema(unittest.TestCase):
def test_it(self):
@@ -1050,7 +1050,7 @@ class TestTupleSchema(unittest.TestCase):
self.failUnless(hasattr(node, '_order'))
self.assertEqual(node.__class__, colander.SchemaNode)
self.assertEqual(node.typ.__class__, colander.Tuple)
self.assertEqual(node.nodes[0].typ.__class__, colander.String)
self.assertEqual(node.children[0].typ.__class__, colander.String)
class TestFunctional(object):
def test_deserialize_ok(self):
@@ -1200,7 +1200,7 @@ class DummySchemaNode(object):
self.exc = exc
self.required = default is None
self.default = default
self.nodes = []
self.children = []
def deserialize(self, val):
from colander import Invalid