Permalink
Browse files

provide __getitem__ and get methods of Invalid exception for civilian…

… consumption
  • Loading branch information...
1 parent 3a1b50c commit 9b35f61a9a9bec985ba0d74edc4d2404f65b9b09 @mcdonc mcdonc committed Apr 3, 2011
Showing with 74 additions and 4 deletions.
  1. +31 −4 colander/__init__.py
  2. +43 −0 colander/tests.py
View
@@ -88,10 +88,12 @@ def add(self, exc, pos=None):
self.children.append(exc)
def __setitem__(self, name, msg):
- """ Add a subexception related to a child node with the
- message ``msg``. ``name`` must be present in the names of the
- set of child nodes of this exception's node; if this is not
- so, a :exc:`KeyError` is raised.
+ """ Add a subexception related to a child node. If with the
+ message ``msg``.
+
+ ``name`` must be present in the names of the set of child nodes of
+ this exception's node; if this is not so, a :exc:`KeyError` is
+ raised.
For example, if the exception upon which ``__setitem__`` is
called has a node attribute, and that node attribute has
@@ -112,6 +114,31 @@ def __setitem__(self, name, msg):
return
raise KeyError(name)
+ def __getitem__(self, name):
+ """ Return the child Invalid exception object named ``name``. If
+ ``name`` is an integer, return the Invalid exception object at the
+ child index position represented by ``name``. If the item does not
+ exist, raise an :exc:`KeyError` (if name is a string) or
+ :exc:`IndexError` (if name is an integer)."""
+ result = self.get(name)
+ if result is None:
+ raise KeyError(name)
+ return result
+
+ def get(self, name, default=None):
+ """ Return the child Invalid exception object related to the child
+ schema node named ``name``. If ``name`` is an integer, return the
+ Invalid object at the child index position represented by ``name``.
+ If the item does not exist, return the ``default`` value."""
+ # XXX crazy exponential time
+ for e in self.children:
+ if (e.pos is not None) and (e.pos == name):
+ return e
+ for num, child in enumerate(self.node.children):
+ if (e.pos == num) and (child.name == name):
+ return e
+ return default
+
def paths(self):
""" A generator which returns each path through the exception
graph. Each path is represented as a tuple of exception
View
@@ -126,6 +126,49 @@ def test___setitem__succeeds(self):
self.assertEqual(childexc.pos, 0)
self.assertEqual(childexc.node.name, 'found')
+ def test___getitem__fails(self):
+ node = DummySchemaNode(None)
+ exc = self._makeOne(node, 'msg')
+ self.assertRaises(KeyError, exc.__getitem__, 'notfound')
+
+ def test___getitem__succeeds_byname(self):
+ node = DummySchemaNode(None)
+ child1 = DummySchemaNode(None)
+ child1.name = 'one'
+ child1.pos = None
+ child2 = DummySchemaNode(None)
+ child2.name = 'two'
+ child2.pos = None
+ node.children = [child1, child2]
+ exc = self._makeOne(node, 'msg')
+ exc['one'] = 'one'
+ exc['two'] = 'two'
+ childexc = exc['one']
+ self.assertEqual(childexc.msg, 'one')
+ self.assertEqual(childexc.node.name, 'one')
+ childexc = exc['two']
+ self.assertEqual(childexc.msg, 'two')
+ self.assertEqual(childexc.node.name, 'two')
+
+ def test___getitem__succeeds_bypos(self):
+ node = DummySchemaNode(None)
+ child1 = DummySchemaNode(None)
+ child1.name = 'one'
+ child1.pos = 0
+ child2 = DummySchemaNode(None)
+ child2.name = 'two'
+ child2.pos = 1
+ node.children = [child1, child2]
+ exc = self._makeOne(node, 'msg')
+ exc['one'] = 'one'
+ exc['two'] = 'two'
+ childexc = exc[0]
+ self.assertEqual(childexc.msg, 'one')
+ self.assertEqual(childexc.node.name, 'one')
+ childexc = exc[1]
+ self.assertEqual(childexc.msg, 'two')
+ self.assertEqual(childexc.node.name, 'two')
+
def test_messages_msg_iterable(self):
node = DummySchemaNode(None)
exc = self._makeOne(node, [123, 456])

0 comments on commit 9b35f61

Please sign in to comment.