[Zope3-dev] z3c.form: handling of interface invariants

Michael Howitz mh at gocept.com
Wed Sep 26 09:06:08 EDT 2007


Hi,

on our sprint in Bad Sulza we looked at the handling of interface  
invariants in z3c.form. There we found a problem in the validation.
Look at the following example.

class IMeetingTime(zope.interface.Interface):
     start = zope.schema.Datetime(title=u'start time')
     end = zope.schema.Datetime(title=u'end time')

     @zope.interface.invariant
     def start_before_end(obj):
         if obj.start > obj.end:
             raise zope.interface.Invalid('start time must be before  
end time')

If only the end field is displayed in a form and the end date is set  
to value smaller than start, the invariant does not prevent saving  
the form, so it is possible to save invalid data.

This happens because accessing obj.start leads to an exception  
z3c.form.validator.NoInputData which is swallowed in  
z3c.form.validator.InvariantsValidator.validateObject().

Possible solutions:

- The invariant expects to get an object for checking but it gets a  
z3c.form.validator.Data object which only contains the data the user  
entered. So this Data object could look up the missing value on the  
real object which is accessible on the __context__ attribute on the  
Data object.

- Change the order things are done:

   1. set a save-point (non-optimistic)

   2. write the values the user entered on the object

   3. validate invariants

   4. If an invariant raises an exception, roll back to the save-point.

   This solution requests that the back-end supports non-optimistic  
save-points. But we can get rid of the Data class.

We'll start an implementation of the second approach on a branch of  
z3c.form now to show if it works.

Any thoughts?

-- 
Yours sincerely,
Michael Howitz

gocept gmbh & co. kg · forsterstrasse 29 · 06112 halle/saale
www.gocept.com · fon: +49 345 12298898 · fax: +49 345 12298891





More information about the Zope3-dev mailing list