Skip to content

Commit

Permalink
Set the field and value of ValidationError raised by checking constra…
Browse files Browse the repository at this point in the history
…ints. Fixes #66
  • Loading branch information
jamadden committed Sep 10, 2018
1 parent d7d9193 commit 6f0d5a5
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
5 changes: 4 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
4.6.2 (unreleased)
==================

- Nothing changed yet.
- Fix checking a field's constraint to set the ``field`` and ``value``
properties if the constraint raises a ``ValidationError``. See
`issue 66
<https://github.com/zopefoundation/zope.schema/issues/66>`_.


4.6.1 (2018-09-10)
Expand Down
10 changes: 9 additions & 1 deletion src/zope/schema/_bootstrapfields.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,15 @@ def _validate(self, value):
if self._type is not None and not isinstance(value, self._type):
raise WrongType(value, self._type, self.__name__).with_field_and_value(self, value)

if not self.constraint(value):
try:
constraint = self.constraint(value)
except ValidationError as e:
if e.field is None:
e.field = self
if e.value is None:
e.value = value
raise
if not constraint:
raise ConstraintNotSatisfied(value, self.__name__).with_field_and_value(self, value)

def get(self, object):
Expand Down
24 changes: 24 additions & 0 deletions src/zope/schema/tests/test__bootstrapfields.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,30 @@ def _fail(value):
field._type = int
field.validate(1) # doesn't raise

def test_validate_constraint_raises_custom_exception(self):
from zope.schema._bootstrapinterfaces import ValidationError

def _fail(value):
raise ValidationError
field = self._makeOne(constraint=_fail)
with self.assertRaises(ValidationError) as exc:
field.validate(1)

self.assertIs(exc.exception.field, field)
self.assertEqual(exc.exception.value, 1)

def test_validate_constraint_raises_custom_exception_no_overwrite(self):
from zope.schema._bootstrapinterfaces import ValidationError

def _fail(value):
raise ValidationError(value).with_field_and_value(self, self)
field = self._makeOne(constraint=_fail)
with self.assertRaises(ValidationError) as exc:
field.validate(1)

self.assertIs(exc.exception.field, self)
self.assertIs(exc.exception.value, self)

def test_get_miss(self):
field = self._makeOne(__name__='nonesuch')
inst = DummyInst()
Expand Down

0 comments on commit 6f0d5a5

Please sign in to comment.