[Checkins] SVN: zope.schema/branches/3.4.1/src/zope/schema/ fix for validation to cover the usecase where the value passed may be wrapped in a Proxy.

Satchidanand Haridas satchit at zope.com
Wed Mar 11 13:42:44 EDT 2009


Log message for revision 97909:
  fix for validation to cover the usecase where the value passed may be wrapped in a Proxy.
  
  

Changed:
  U   zope.schema/branches/3.4.1/src/zope/schema/_bootstrapfields.py
  U   zope.schema/branches/3.4.1/src/zope/schema/tests/test_field.py

-=-
Modified: zope.schema/branches/3.4.1/src/zope/schema/_bootstrapfields.py
===================================================================
--- zope.schema/branches/3.4.1/src/zope/schema/_bootstrapfields.py	2009-03-11 17:09:44 UTC (rev 97908)
+++ zope.schema/branches/3.4.1/src/zope/schema/_bootstrapfields.py	2009-03-11 17:42:44 UTC (rev 97909)
@@ -161,8 +161,16 @@
         return not self.__eq__(other)
 
     def _validate(self, value):
-        if self._type is not None and not isinstance(value, self._type):
-            raise WrongType(value, self._type)
+        if self._type is not None:
+            # the complexity of the next few lines of code is required to make
+            # it proxy aware
+            if isinstance(self._type, tuple):
+                check_mro = [
+                    _type in value.__class__.__mro__ for _type in self._type]
+                if True not in check_mro:
+                    raise WrongType(value, self._type)
+            elif self._type not in value.__class__.__mro__:
+                raise WrongType(value, self._type)
 
         if not self.constraint(value):
             raise ConstraintNotSatisfied(value)

Modified: zope.schema/branches/3.4.1/src/zope/schema/tests/test_field.py
===================================================================
--- zope.schema/branches/3.4.1/src/zope/schema/tests/test_field.py	2009-03-11 17:09:44 UTC (rev 97908)
+++ zope.schema/branches/3.4.1/src/zope/schema/tests/test_field.py	2009-03-11 17:42:44 UTC (rev 97909)
@@ -15,10 +15,11 @@
 
 $Id$
 """
+import decimal
 import re
 
 from unittest import TestCase, TestSuite, main, makeSuite
-from zope.schema import Field, Text, Int
+from zope.schema import Field, Text, Int, Decimal
 from zope.schema.interfaces import ValidationError, RequiredMissing
 from zope.schema.interfaces import ConstraintNotSatisfied
 from zope.testing.doctestunit import DocTestSuite
@@ -138,6 +139,41 @@
         field = MyField(title=u'my')
         self.assert_(field.required)
 
+class StubProxy(object):
+
+    def __init__(self, fld):
+        self.proxied_object = fld
+
+    def __getattribute__(self, name):
+        if name in ['proxied_object']:
+            val = object.__getattribute__(self, name)
+        elif name in ['__class__']:
+            val = StubProxy(getattr(self.proxied_object, name))
+        else:
+            val = getattr(self.proxied_object, name)
+        return val
+
+class ProxiedValuesValidationTest(TestCase):
+    """Test the validate method when the value is wrapped in a proxy.
+
+    A common use case for this is the `Decimal` type that is wrapped in
+    a security proxy because it is not considered as a "rock".
+    """
+
+    def testValidate(self):
+        field = Decimal(
+            title=u'Not required field', description=u'',
+            readonly=False, required=False)
+        field.validate(StubProxy(decimal.Decimal("1000.0003")))
+
+    def testValidateRequired(self):
+        field = Decimal(
+            title=u'Required field', description=u'',
+            readonly=False, required=True)
+        field.validate(StubProxy(decimal.Decimal('12.0')))
+
+
+
 def test_suite():
     checker = renormalizing.RENormalizing([
         (re.compile(r" with base 10: '125.6'"),
@@ -146,6 +182,7 @@
     return TestSuite((
         makeSuite(FieldTest),
         makeSuite(FieldDefaultBehaviour),
+        makeSuite(ProxiedValuesValidationTest),
         DocTestSuite("zope.schema._field"),
         DocTestSuite("zope.schema._bootstrapfields",checker=checker),
         ))



More information about the Checkins mailing list