[Checkins] SVN: zope.schema/trunk/ Fix broken Object field validation where the schema contains a Choice with

Roger Ineichen roger at projekt01.ch
Sun Dec 11 23:53:57 UTC 2011


Log message for revision 123694:
  Fix broken Object field validation where the schema contains a Choice with 
  ICountextSourceBinder source. In this case the vocabulary was not iterable 
  because the field was not bound and the source binder didn't return the 
  real vocabulary. Added simple test for IContextSourceBinder validation. But a 
  test with an Object field with a schema using a Choice with 
  IContextSourceBinder is still missing.

Changed:
  U   zope.schema/trunk/CHANGES.txt
  U   zope.schema/trunk/src/zope/schema/_field.py
  U   zope.schema/trunk/src/zope/schema/tests/test_choice.py

-=-
Modified: zope.schema/trunk/CHANGES.txt
===================================================================
--- zope.schema/trunk/CHANGES.txt	2011-12-11 19:15:25 UTC (rev 123693)
+++ zope.schema/trunk/CHANGES.txt	2011-12-11 23:53:56 UTC (rev 123694)
@@ -5,7 +5,12 @@
 4.0.2 (unreleased)
 ------------------
 
-- None yet.
+- Fix broken Object field validation where the schema contains a Choice with
+  ICountextSourceBinder source. In this case the vocabulary was not iterable
+  because the field was not bound and the source binder dien't return the 
+  real vocabulary. Added simple test for IContextSourceBinder validation. But a
+  test with an Object field with a schema using a Choice with
+  IContextSourceBinder is still missing.
 
 4.0.1 (2011-11-14)
 ------------------

Modified: zope.schema/trunk/src/zope/schema/_field.py
===================================================================
--- zope.schema/trunk/src/zope/schema/_field.py	2011-12-11 19:15:25 UTC (rev 123693)
+++ zope.schema/trunk/src/zope/schema/_field.py	2011-12-11 23:53:56 UTC (rev 123694)
@@ -492,7 +492,12 @@
             if not IMethod.providedBy(schema[name]):
                 try:
                     attribute = schema[name]
-                    if IField.providedBy(attribute):
+                    if IChoice.providedBy(attribute):
+                        # Choice must be bound before validation otherwise
+                        # IContextSourceBinder is not iterable in validation
+                        bound = attribute.bind(value)
+                        bound.validate(getattr(value, name))
+                    elif IField.providedBy(attribute):
                         # validate attributes that are fields
                         attribute.validate(getattr(value, name))
                 except ValidationError as error:

Modified: zope.schema/trunk/src/zope/schema/tests/test_choice.py
===================================================================
--- zope.schema/trunk/src/zope/schema/tests/test_choice.py	2011-12-11 19:15:25 UTC (rev 123693)
+++ zope.schema/trunk/src/zope/schema/tests/test_choice.py	2011-12-11 23:53:56 UTC (rev 123694)
@@ -16,11 +16,13 @@
 import unittest
 
 from six import u
+from zope.interface import implements
 from zope.schema import vocabulary
 from zope.schema import Choice
 from zope.schema.interfaces import ConstraintNotSatisfied
 from zope.schema.interfaces import ValidationError
 from zope.schema.interfaces import InvalidValue, NotAContainer, NotUnique
+from zope.schema.interfaces import IContextSourceBinder
 
 from zope.schema.tests.test_vocabulary import SampleVocabulary, DummyRegistry
 
@@ -112,10 +114,37 @@
         self.assertRaises(ValueError, choice.validate, "value")
 
 
+class SampleContextSourceBinder(object):
+    implements(IContextSourceBinder)
+    def __call__(self, context):
+        return SampleVocabulary()
+
+class ContextSourceBinder_ChoiceFieldTests(unittest.TestCase):
+    """Tests of the Choice Field using IContextSourceBinder as source."""
+
+    def setUp(self):
+        vocabulary._clear()
+
+    def tearDown(self):
+        vocabulary._clear()
+
+    def test_validate_source(self):
+        s = SampleContextSourceBinder()
+        choice = Choice(source=s)
+        # raises not iterable with unbound field
+        self.assertRaises(TypeError, choice.validate, 1)
+        o = object()
+        clone = choice.bind(o)
+        clone.validate(1)
+        clone.validate(3)
+        self.assertRaises(ConstraintNotSatisfied, clone.validate, 42)
+
+
 def test_suite():
     suite = unittest.TestSuite()
     suite.addTest(unittest.makeSuite(Vocabulary_ChoiceFieldTests))
     suite.addTest(unittest.makeSuite(Value_ChoiceFieldTests))
+    suite.addTest(unittest.makeSuite(ContextSourceBinder_ChoiceFieldTests))
     return suite
 
 if __name__ == "__main__":



More information about the checkins mailing list