Skip to content

Commit

Permalink
provide __getitem__ and get methods of Invalid exception for civilian…
Browse files Browse the repository at this point in the history
… consumption
  • Loading branch information
mcdonc committed Apr 3, 2011
1 parent 3a1b50c commit 9b35f61
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 4 deletions.
35 changes: 31 additions & 4 deletions colander/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
43 changes: 43 additions & 0 deletions colander/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand Down

0 comments on commit 9b35f61

Please sign in to comment.