- Add a `pos argument to the colander.Invalid.add` method.
				
					
				
			- Add a ``__setitem__`` method to the ``colander.Invalid`` class.
This commit is contained in:
		| @@ -10,6 +10,10 @@ Next release | ||||
| - Allow ``colander.Date`` and ``colander.DateTime`` invalid error | ||||
|   messages to be customized. | ||||
|  | ||||
| - Add a ``pos`` argument to the ``colander.Invalid.add`` method. | ||||
|  | ||||
| - Add a ``__setitem__`` method to the ``colander.Invalid`` class. | ||||
|  | ||||
| 0.5 (2010-03-31) | ||||
| ---------------- | ||||
|  | ||||
|   | ||||
| @@ -27,12 +27,52 @@ class Invalid(Exception): | ||||
|         self.msg = msg | ||||
|         self.children = [] | ||||
|  | ||||
|     def add(self, exc): | ||||
|     def add(self, exc, pos=None): | ||||
|         """ Add a child exception; ``exc`` must be an instance of | ||||
|         :class:`colander.Invalid`""" | ||||
|         :class:`colander.Invalid` or a subclass. | ||||
|  | ||||
|         ``pos`` is a value important for accurate error reporting.  If | ||||
|         it is provided, it must be an integer representing the | ||||
|         position of ``exc`` relative to all other subexceptions of | ||||
|         this exception node.  For example, if the exception being | ||||
|         added is about the third child of the exception which is | ||||
|         ``self``, ``pos`` might be passed as ``3``. | ||||
|  | ||||
|         If ``pos`` is provided, it will be assigned to the ``pos`` | ||||
|         attribute of the provided ``exc`` object. | ||||
|  | ||||
|         The ``parent`` attribute of the provided ``exc`` will be set | ||||
|         as a reference to ``self``. | ||||
|         """ | ||||
|         exc.parent = self | ||||
|         if pos is not None: | ||||
|             exc.pos = pos | ||||
|         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 ``KeyError`` is raised. | ||||
|  | ||||
|         For example, if the exception upon which ``__setitem__`` is | ||||
|         called has a node attribute with children, and that node | ||||
|         attribute has children that have the names ``name`` and | ||||
|         ``title``, you may successfully call ``__setitem__('name', | ||||
|         'Bad name')`` or ``__setitem__('title', 'Bad title')``.  But | ||||
|         calling ``__setitem__('wrong', 'whoops')`` will result in a | ||||
|         KeyError. | ||||
|  | ||||
|         This method is typically only useful if the ``node`` it wraps | ||||
|         is a schema node representing a mapping. | ||||
|         """ | ||||
|         for num, child in enumerate(self.node.children): | ||||
|             if child.name == name: | ||||
|                 exc = Invalid(child, msg) | ||||
|                 self.add(exc, num) | ||||
|                 return | ||||
|         raise KeyError(name) | ||||
|  | ||||
|     def paths(self): | ||||
|         """ Return all paths through the exception graph  """ | ||||
|         def traverse(node, stack): | ||||
| @@ -205,8 +245,7 @@ class Mapping(object): | ||||
|             except Invalid, e: | ||||
|                 if error is None: | ||||
|                     error = Invalid(node) | ||||
|                 e.pos = num | ||||
|                 error.add(e) | ||||
|                 error.add(e, num) | ||||
|  | ||||
|         if self.unknown_keys == 'raise': | ||||
|             if value: | ||||
| @@ -280,8 +319,7 @@ class Tuple(Positional): | ||||
|             except Invalid, e: | ||||
|                 if error is None: | ||||
|                     error = Invalid(node) | ||||
|                 e.pos = num | ||||
|                 error.add(e) | ||||
|                 error.add(e, num) | ||||
|                  | ||||
|         if error is not None: | ||||
|             raise error | ||||
| @@ -339,8 +377,7 @@ class Sequence(Positional): | ||||
|             except Invalid, e: | ||||
|                 if error is None: | ||||
|                     error = Invalid(node) | ||||
|                 e.pos = num | ||||
|                 error.add(e) | ||||
|                 error.add(e, num) | ||||
|                  | ||||
|         if error is not None: | ||||
|             raise error | ||||
|   | ||||
| @@ -99,7 +99,24 @@ class TestInvalid(unittest.TestCase): | ||||
|             result, | ||||
|             "{'node1.node2.3': 'exc1; exc2; exc3', 'node1.node4': 'exc1; exc4'}" | ||||
|             ) | ||||
|          | ||||
|  | ||||
|     def test___setitem__fails(self): | ||||
|         node = DummySchemaNode(None) | ||||
|         exc = self._makeOne(node, 'msg') | ||||
|         self.assertRaises(KeyError, exc.__setitem__, 'notfound', 'msg') | ||||
|  | ||||
|     def test___setitem__succeeds(self): | ||||
|         node = DummySchemaNode(None) | ||||
|         child = DummySchemaNode(None) | ||||
|         child.name = 'found' | ||||
|         node.children = [child] | ||||
|         exc = self._makeOne(node, 'msg') | ||||
|         exc['found'] = 'msg2' | ||||
|         self.assertEqual(len(exc.children), 1) | ||||
|         childexc = exc.children[0] | ||||
|         self.assertEqual(childexc.pos, 0) | ||||
|         self.assertEqual(childexc.node.name, 'found') | ||||
|  | ||||
| class TestAll(unittest.TestCase): | ||||
|     def _makeOne(self, validators): | ||||
|         from colander import All | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Chris McDonough
					Chris McDonough