[Zope3-dev] class Object(Field) and the function _validate_fields
Dominik Huber
dominik at projekt01.ch
Fri Nov 21 13:04:21 EST 2003
I would like to change the class Object(Field) and the function
_validate_fields of the module zope.schema._field.py because I think the
current implementation is buggy.
I'm not very comfortable with all zope3 principles and policies so I would
appreciate if an advanced zoper could check my suggestion and could answer
my questions before committing this to cvs.
thanks!
dominik
Questions:
What's the exception policy?
- Should I raise only ValidationErrors or are other Exceptions allowed too?
- The IField and IObject interface gives no appropriate answer. Do I have to
extend the comment?
- What's the policy for the raised exception messages
(i18n, default errormessages, ...)
How to suport the missing_value story properly? (-> see
test_validate_TestData)
############################
suggested changes: _field.py
############################
from zope.interface.interfaces import IMethod
from zope.interface import Interface
def _validate_fields(schema, value, errors=None):
if errors is None:
errors = []
for name in schema.names(all=True):
if not IMethod.isImplementedBy(schema[name]):
try:
field = schema[name]
field.validate(getattr(value, name))
except ValidationError, error:
errors.append(error)
except AttributeError, error:
# attribute is not implemented yet
raise error # XXX exception handling suffers
return errors
class Object(Field):
__doc__ = IObject.__doc__
implements(IObject)
def __init__(self, schema, **kw):
if not (schema == None or Interface.isImplementedBy(schema)):
raise TypeError # XXX exception handling suffers
self.schema = schema
super(Object, self).__init__(**kw)
def _validate(self, value):
super(Object, self)._validate(value)
# always valid if no schema provided
if self.schema == None:
return
# schema has to be implemented by value
if not self.schema.isImplementedBy(value):
raise TypeError # XXX exception handling suffers
# check the value against the schema
errors = _validate_fields(self.schema, value)
if errors:
raise ValidationError(WrongContainedType, errors)
##############################
suggestion: test_objectfield.py
##############################
from unittest import TestSuite, main, makeSuite
from zope.i18n import MessageIDFactory
from zope.interface import Interface, implements
from zope.schema import Object, TextLine
from zope.schema import errornames
from zope.schema.fieldproperty import FieldProperty
from zope.schema.interfaces import ValidationError
from zope.schema.tests.test_field import FieldTestBase
_ = MessageIDFactory('zope')
class ITestSchema(Interface):
"""A test schema"""
foo = TextLine(
title=_(u"Foo"),
description=_(u"Foo description"),
default=u"",
required=True)
bar = TextLine(
title=_(u"Bar"),
description=_(u"Bar description"),
default=u"",
required=False)
class TestClass(object):
implements(ITestSchema)
foo = FieldProperty(ITestSchema['foo'])
bar = FieldProperty(ITestSchema['bar'])
class WrongTestClass(object):
implements(ITestSchema)
foo = FieldProperty(ITestSchema['foo'])
# bar = FieldProperty(ITestSchema['bar'])
class ObjectTest(FieldTestBase):
"""Test the Object Field."""
def makeTestObject(self, **kw):
kw['schema'] = kw.get('schema', None)
return Object(**kw)
_Field_Factory = makeTestObject
def makeTestData(self):
return TestClass()
def makeWrongTestData(self):
return WrongTestClass()
def badSchema(self):
return ['foo', 1, {}, []]
def goodSchema(self):
return [None, Interface, ITestSchema]
def test_init(self):
for good in self.goodSchema():
field = Object(schema=good)
for bad in self.badSchema():
self.assertRaises(TypeError, Object, schema=bad)
def test_validate_None(self):
field = self.makeTestObject(required=False)
field.validate(None)
field = self.makeTestObject()
self.assertRaises(ValidationError, field.validate, None)
field.validate(self.makeTestData())
def test_validate_TestData(self):
field = self.makeTestObject(schema=ITestSchema, required=False)
field.validate(self.makeTestData())
#self.assertRaises(TypeError, field.validate, None)
field.validate(None) # should fail! -> Field self.missing_value
self.assertRaises(TypeError, field.validate, 'foo')
def test_validate_WrongTestData(self):
field = self.makeTestObject(schema=ITestSchema, required=False)
data = self.makeWrongTestData()
self.assertRaises(AttributeError, field.validate, data)
def test_validate_required(self):
field = self.makeTestObject(schema=ITestSchema, required=False)
data = self.makeTestData()
self.assertRaises(ValidationError, setattr, data, 'foo', None)
self.assertRaises(ValidationError, setattr, data, 'foo', '')
data.foo = u'bar'
def test_suite():
suite = TestSuite()
suite.addTest(makeSuite(ObjectTest))
return suite
if __name__ == '__main__':
main(defaultTest='test_suite')
More information about the Zope3-dev
mailing list