[Checkins] SVN: zope.schema/trunk/ Added helper methods for schema
validation: `getValidationErrors` and
Christian Zagrodnick
cz at gocept.com
Fri Aug 24 04:47:14 EDT 2007
Log message for revision 79215:
Added helper methods for schema validation: `getValidationErrors` and
`getSchemaValidationErrors`.
Changed:
U zope.schema/trunk/CHANGES.txt
U zope.schema/trunk/src/zope/schema/__init__.py
U zope.schema/trunk/src/zope/schema/_schema.py
U zope.schema/trunk/src/zope/schema/tests/test_docs.py
A zope.schema/trunk/src/zope/schema/validation.txt
-=-
Modified: zope.schema/trunk/CHANGES.txt
===================================================================
--- zope.schema/trunk/CHANGES.txt 2007-08-24 08:45:51 UTC (rev 79214)
+++ zope.schema/trunk/CHANGES.txt 2007-08-24 08:47:13 UTC (rev 79215)
@@ -2,7 +2,13 @@
Changes
=======
+3.5a1
+=====
+ - Added helper methods for schema validation: `getValidationErrors` and
+ `getSchemaValidationErrors`.
+
+
3.4.0b1
=======
Modified: zope.schema/trunk/src/zope/schema/__init__.py
===================================================================
--- zope.schema/trunk/src/zope/schema/__init__.py 2007-08-24 08:45:51 UTC (rev 79214)
+++ zope.schema/trunk/src/zope/schema/__init__.py 2007-08-24 08:47:13 UTC (rev 79215)
@@ -24,7 +24,8 @@
from zope.schema._field import Time, SourceText
from zope.schema._field import Object, URI, Id, DottedName
from zope.schema._field import InterfaceField
-from zope.schema._schema import getFields, getFieldsInOrder
-from zope.schema._schema import getFieldNames, getFieldNamesInOrder
+from zope.schema._schema import (
+ getFields, getFieldsInOrder, getFieldNames, getFieldNamesInOrder,
+ getValidationErrors, getSchemaValidationErrors)
from zope.schema.accessors import accessors
from zope.schema.interfaces import ValidationError
Modified: zope.schema/trunk/src/zope/schema/_schema.py
===================================================================
--- zope.schema/trunk/src/zope/schema/_schema.py 2007-08-24 08:45:51 UTC (rev 79214)
+++ zope.schema/trunk/src/zope/schema/_schema.py 2007-08-24 08:47:13 UTC (rev 79215)
@@ -16,6 +16,9 @@
$Id$
"""
+import zope.interface.verify
+
+
def getFieldNames(schema):
"""Return a list of all the Field names in a schema.
"""
@@ -48,3 +51,46 @@
"""Return a list of all the Field names in a schema in schema order.
"""
return [ name for name, field in getFieldsInOrder(schema) ]
+
+
+def getValidationErrors(schema, object):
+ """Return a list of all validation errors.
+
+ """
+ errors = getSchemaValidationErrors(schema, object)
+ if errors:
+ return errors
+
+ # Only validate invariants if there were no previous errors. Previous
+ # errors could be missing attributes which would most likely make an
+ # invariant raise an AttributeError.
+ invariant_errors = []
+ try:
+ schema.validateInvariants(object, invariant_errors)
+ except zope.interface.exceptions.Invalid:
+ # Just collect errors
+ pass
+ errors = [(None, e) for e in invariant_errors]
+ return errors
+
+
+def getSchemaValidationErrors(schema, object):
+ errors = []
+ for name in schema.names(all=True):
+ if zope.interface.interfaces.IMethod.providedBy(schema[name]):
+ continue
+ attribute = schema[name]
+ if not zope.schema.interfaces.IField.providedBy(attribute):
+ continue
+ try:
+ value = getattr(object, name)
+ except AttributeError, error:
+ # property for the given name is not implemented
+ errors.append((
+ name, zope.schema.interfaces.SchemaNotFullyImplemented(error)))
+ else:
+ try:
+ attribute.bind(object).validate(value)
+ except zope.schema.ValidationError, e:
+ errors.append((name, e))
+ return errors
Modified: zope.schema/trunk/src/zope/schema/tests/test_docs.py
===================================================================
--- zope.schema/trunk/src/zope/schema/tests/test_docs.py 2007-08-24 08:45:51 UTC (rev 79214)
+++ zope.schema/trunk/src/zope/schema/tests/test_docs.py 2007-08-24 08:47:13 UTC (rev 79215)
@@ -13,7 +13,7 @@
##############################################################################
"""Tests for the schema package's documentation files
-$Id: tests.py 29143 2005-02-14 22:43:16Z srichter $
+$Id$
"""
import unittest
from zope.testing import doctest
@@ -23,6 +23,9 @@
doctest.DocFileSuite('../sources.txt', optionflags=doctest.ELLIPSIS),
doctest.DocFileSuite('../fields.txt'),
doctest.DocFileSuite('../README.txt'),
+ doctest.DocFileSuite(
+ '../validation.txt',
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS),
))
if __name__ == '__main__':
Added: zope.schema/trunk/src/zope/schema/validation.txt
===================================================================
--- zope.schema/trunk/src/zope/schema/validation.txt (rev 0)
+++ zope.schema/trunk/src/zope/schema/validation.txt 2007-08-24 08:47:13 UTC (rev 79215)
@@ -0,0 +1,93 @@
+================
+Schema Valiation
+================
+
+
+There are two helper methods to verify schemas and interfaces:
+
+getValidationErrors
+ first validates via the zope.schema field validators. If that succeeds the
+ invariants are checked.
+getSchemaValidationErrors
+ *only* validateds via the zope.schema field validators. The invariants are
+ *not* checked.
+
+
+Create an interface to validate against:
+
+>>> import zope.interface
+>>> import zope.schema
+>>> class ITwoInts(zope.interface.Interface):
+... a = zope.schema.Int(max=10)
+... b = zope.schema.Int(min=5)
+...
+... @zope.interface.invariant
+... def a_greater_b(obj):
+... print "Checking if a > b"
+... if obj.a <= obj.b:
+... raise zope.interface.Invalid("%s<=%s" % (obj.a, obj.b))
+...
+
+Create a silly model:
+
+>>> class TwoInts(object):
+... pass
+
+
+Create an instance of TwoInts but do not set attributes. We get two errors:
+
+>>> ti = TwoInts()
+>>> zope.schema.getValidationErrors(ITwoInts, ti)
+[('a', 'TwoInts' object has no attribute 'a'),
+ ('b', 'TwoInts' object has no attribute 'b')]
+
+The `getSchemaValidationErrors` function returns the same result:
+
+>>> zope.schema.getSchemaValidationErrors(ITwoInts, ti)
+[('a', 'TwoInts' object has no attribute 'a'),
+ ('b', 'TwoInts' object has no attribute 'b')]
+
+Note that see no error from the invariant because the invariants are not
+vaildated if there are other schema errors.
+
+When we set an invalid value for `a` we still get the same error for `b`:
+
+>>> ti.a = 11
+>>> errors = zope.schema.getValidationErrors(ITwoInts, ti)
+>>> errors
+[('a', 11 10),
+ ('b', 'TwoInts' object has no attribute 'b')]
+>>> errors[0][1].doc()
+u'Value is too big'
+
+
+After setting a valid value for `a` there is only the error for the missing `b`
+left:
+
+>>> ti.a = 8
+>>> zope.schema.getValidationErrors(ITwoInts, ti)
+[('b', 'TwoInts' object has no attribute 'b')]
+
+
+After setting valid value for `b` the schema is valid so the invariants are
+checked. As `b>a` the invariant fails:
+
+>>> ti.b = 10
+>>> errors = zope.schema.getValidationErrors(ITwoInts, ti)
+Checking if a > b
+>>> errors
+[(None, <zope.interface.exceptions.Invalid instance at 0x...>)]
+
+
+When using `getSchemaValidationErrors` we do not get an error any more:
+
+>>> zope.schema.getSchemaValidationErrors(ITwoInts, ti)
+[]
+
+
+Set `b=5` so everything is fine:
+
+>>> ti.b = 5
+>>> zope.schema.getValidationErrors(ITwoInts, ti)
+Checking if a > b
+[]
Property changes on: zope.schema/trunk/src/zope/schema/validation.txt
___________________________________________________________________
Name: svn:keywords
+ Id Rev Date
Name: svn:eol-style
+ native
More information about the Checkins
mailing list