[Zope3-checkins] CVS: Zope3/src/zope/schema - __init__.py:1.9 _bootstrapfields.py:1.10 _field.py:1.8 interfaces.py:1.8

Fred L. Drake, Jr. fred@zope.com
Mon, 14 Apr 2003 12:14:13 -0400


Update of /cvs-repository/Zope3/src/zope/schema
In directory cvs.zope.org:/tmp/cvs-serv11578

Modified Files:
	__init__.py _bootstrapfields.py _field.py interfaces.py 
Log Message:
Start a change of the relationhip of the IValueSet interface to other
field constraints:

- Introduce new field types: IEnumeratedTextLine, IEnumeratedInt,
  IEnumeratedFloat, IEnumeratedDatetime; these should be used any time
  the allowed_values option for a field is used, instead of requiring
  the base field type to support it.

- Updated tests, docstrings, to reflect future removal of the
  IValueSet "mixin" interface from ITextLine, IInt, IField, IDatetime,
  and several others where it simply doesn't make sense.

- Modify tests to consistent use _Field_Factory to generate field
  objects.


=== Zope3/src/zope/schema/__init__.py 1.8 => 1.9 ===
--- Zope3/src/zope/schema/__init__.py:1.8	Mon Apr 14 04:21:16 2003
+++ Zope3/src/zope/schema/__init__.py	Mon Apr 14 12:13:42 2003
@@ -20,6 +20,8 @@
 from zope.schema._field import MinMaxLen, ValueSet, Sequence, Bytes, BytesLine
 from zope.schema._field import Text, TextLine, Bool, Int, Float, Tuple, List
 from zope.schema._field import Password, Dict, Datetime, SourceText
+from zope.schema._field import EnumeratedTextLine, EnumeratedInt
+from zope.schema._field import EnumeratedDatetime, EnumeratedFloat
 from zope.schema._schema import getFields, getFieldsInOrder
 from zope.schema._schema import getFieldNames, getFieldNamesInOrder
 from zope.schema.accessors import accessors


=== Zope3/src/zope/schema/_bootstrapfields.py 1.9 => 1.10 ===
--- Zope3/src/zope/schema/_bootstrapfields.py:1.9	Mon Apr 14 04:21:16 2003
+++ Zope3/src/zope/schema/_bootstrapfields.py	Mon Apr 14 12:13:42 2003
@@ -16,6 +16,8 @@
 """
 __metaclass__ = type
 
+import warnings
+
 from zope.interface import Attribute
 from zope.interface.implements import visitImplements
 
@@ -218,6 +220,18 @@
 
 class ValueSet(Field):
 
+    def __init__(self, allowed_values=None, default=None, **kw):
+        # Set allowed_values to None so that we can validate if
+        # one of the super methods invoke validation.
+        self.__dict__['allowed_values'] = None
+        super(ValueSet, self).__init__(**kw)
+        if allowed_values is not None:
+            self.allowed_values = allowed_values
+
+        # We've taken over setting default so it can be limited by min
+        # and max.
+        self.default = default
+
     def allowed_values(self, values):
         # This method checks that each of the given allowed values
         # are valid potential values.
@@ -239,22 +253,8 @@
 
     allowed_values = ValidatedProperty('allowed_values', allowed_values)
 
-    def __init__(self, allowed_values=None, default=None, **kw):
-
-        # Set allowed_values to None so that we can validate if
-        # one of the super methods invoke validation.
-        self.__dict__['allowed_values'] = None
-        super(ValueSet, self).__init__(**kw)
-        if allowed_values is not None:
-            self.allowed_values = allowed_values
-
-        # We've taken over setting default so it can be limited by min
-        # and max.
-        self.default = default
-
     def _validate(self, value):
         super(ValueSet, self)._validate(value)
-
         if self.allowed_values:
             if not value in self.allowed_values:
                 raise ValidationError(errornames.InvalidValue, value,
@@ -265,13 +265,23 @@
     """A field containing text used for human discourse."""
     _type = unicode
 
+    def __init__(self, *args, **kw):
+        if (  kw.get("allowed_values") is not None
+              and self.__class__ in (Text, TextLine)):
+            clsname = self.__class__.__name__
+            warnings.warn("Support for allowed_values will be removed from %s;"
+                          " use Enumerated%s instead" % (clsname, clsname),
+                          DeprecationWarning, stacklevel=2)
+        super(Text, self).__init__(*args, **kw)
 
 class TextLine(Text):
     """A text field with no newlines."""
 
     def constraint(self, value):
-        # XXX we should probably use a more general definition of newlines
-        return '\n' not in value
+        return '\n' not in value and '\r' not in value
+
+class EnumeratedTextLine(ValueSet, TextLine):
+    """TextLine with a value from a list of allowed values."""
 
 class Password(TextLine):
     """A text field containing a text used as a password."""
@@ -284,3 +294,14 @@
     """A field representing an Integer."""
     _type = int, long
 
+    def __init__(self, *args, **kw):
+        if (  kw.get("allowed_values") is not None
+              and self.__class__ is Int):
+            clsname = self.__class__.__name__
+            warnings.warn("Support for allowed_values will be removed from %s;"
+                          " use Enumerated%s instead" % (clsname, clsname),
+                          DeprecationWarning, stacklevel=2)
+        super(Int, self).__init__(*args, **kw)
+
+class EnumeratedInt(ValueSet, Int):
+    """A field representing one of a selected set of Integers."""


=== Zope3/src/zope/schema/_field.py 1.7 => 1.8 ===
--- Zope3/src/zope/schema/_field.py:1.7	Thu Apr 10 05:34:30 2003
+++ Zope3/src/zope/schema/_field.py	Mon Apr 14 12:13:42 2003
@@ -16,6 +16,8 @@
 """
 __metaclass__ = type
 
+import warnings
+
 from zope.interface.implements import implements
 
 from zope.schema.interfaces import ValidationError
@@ -27,10 +29,13 @@
 from zope.schema.interfaces import IBool, IInt, IBytes, IBytesLine, IFloat
 from zope.schema.interfaces import IDatetime, ISequence, ITuple, IList, IDict
 from zope.schema.interfaces import IPassword
+from zope.schema.interfaces import IEnumeratedDatetime, IEnumeratedTextLine
+from zope.schema.interfaces import IEnumeratedInt, IEnumeratedFloat
 
 from zope.schema._bootstrapfields import Field, Container, Iterable, Orderable
 from zope.schema._bootstrapfields import MinMaxLen, ValueSet
 from zope.schema._bootstrapfields import Text, TextLine, Bool, Int, Password
+from zope.schema._bootstrapfields import EnumeratedTextLine, EnumeratedInt
 from zope.schema.fieldproperty import FieldProperty
 from datetime import datetime
 
@@ -42,21 +47,16 @@
 # Default is already taken care of
 implements(Field, IField)
 
-implements(Container, IContainer)
-implements(Iterable, IIterable)
-implements(Orderable, IOrderable)
-
 MinMaxLen.min_length = FieldProperty(IMinMaxLen['min_length'])
 MinMaxLen.max_length = FieldProperty(IMinMaxLen['max_length'])
-implements(MinMaxLen, IMinMaxLen)
-
-implements(ValueSet, IValueSet)
 
 implements(Text, IText)
 implements(TextLine, ITextLine)
 implements(Password, IPassword)
 implements(Bool, IBool)
 implements(Int, IInt)
+implements(EnumeratedInt, IEnumeratedInt)
+implements(EnumeratedTextLine, IEnumeratedTextLine)
 
 class SourceText(Text):
     __doc__ = ISourceText.__doc__
@@ -84,10 +84,36 @@
     __implements__ = IFloat
     _type = float
 
+    def __init__(self, *args, **kw):
+        if (  kw.get("allowed_values") is not None
+              and self.__class__ is Float):
+            clsname = self.__class__.__name__
+            warnings.warn("Support for allowed_values will be removed from %s;"
+                          " use Enumerated%s instead" % (clsname, clsname),
+                          DeprecationWarning, stacklevel=2)
+        super(Float, self).__init__(*args, **kw)
+
+class EnumeratedFloat(ValueSet, Float):
+    __doc__ = IEnumeratedFloat.__doc__
+    __implements__ = IEnumeratedFloat
+
 class Datetime(ValueSet, Orderable):
     __doc__ = IDatetime.__doc__
     __implements__ = IDatetime
     _type = datetime
+
+    def __init__(self, *args, **kw):
+        if (  kw.get("allowed_values") is not None
+              and self.__class__ is Datetime):
+            clsname = self.__class__.__name__
+            warnings.warn("Support for allowed_values will be removed from %s;"
+                          " use Enumerated%s instead" % (clsname, clsname),
+                          DeprecationWarning, stacklevel=2)
+        super(Datetime, self).__init__(*args, **kw)
+
+class EnumeratedDatetime(ValueSet, Datetime):
+    __doc__ = IEnumeratedDatetime.__doc__
+    __implements__ = IEnumeratedDatetime
 
 def _validate_sequence(value_types, value, errors=None):
     if errors is None:


=== Zope3/src/zope/schema/interfaces.py 1.7 => 1.8 ===
--- Zope3/src/zope/schema/interfaces.py:1.7	Mon Apr 14 04:21:16 2003
+++ Zope3/src/zope/schema/interfaces.py	Mon Apr 14 12:13:42 2003
@@ -263,16 +263,18 @@
     u"""a Boolean Field."""
 
 class IBytes(IMinMaxLen, IValueSet, IIterable):
+    # XXX IValueSet will be removed in the future.
     u"""a Field containing a byte string (like the python str).
 
-    The value might be contrained to be with length limits, or
-    be within a set of values.
+    The value might be contrained to be with length limits.
     """
 
 class IBytesLine(IBytes):
     u"""a Field containing a byte string without newlines."""
 
 class IText(IMinMaxLen, IValueSet, IIterable):
+    # XXX IValueSet doesn't make sense for multi-line strings, so will
+    # be removed in the future.
     u"""a Field containing a unicode string."""
 
 class ISourceText(IText):
@@ -281,18 +283,48 @@
 class ITextLine(IText):
     u"""a Field containing a unicode string without newlines."""
 
+class IEnumeratedTextLine(ITextLine, IValueSet):
+    u"""a Field containing a unicode string without newlines.
+
+    The value may be constrained to an element of a specified list.
+    """
+
 class IPassword(ITextLine):
     u"""a Field containing a unicode string without newlines that is a password."""
 
 class IInt(IMinMax, IValueSet):
+    # XXX IValueSet will be removed; use IEnumeratedInt instead if you
+    # need the IValueSet interface.
     u"""a Field containing an Integer Value."""
 
+class IEnumeratedInt(IInt, IValueSet):
+    u"""a Field containing an Integer Value.
+
+    The value may be constrained to an element of a specified list.
+    """
+
 class IFloat(IMinMax, IValueSet):
+    # XXX IValueSet will be removed; use IEnumeratedFloat instead if you
+    # need the IValueSet interface.
     u"""a Field containing a Float."""
 
+class IEnumeratedFloat(IFloat, IValueSet):
+    u"""a Field containing a Float.
+
+    The value may be constrained to an element of a specified list.
+    """
+
 class IDatetime(IMinMax, IValueSet):
+    # XXX IValueSet will be removed; use IEnumeratedDatetime instead
+    # if you need the IValueSet interface.
     u"""a Field containing a DateTime."""
 
+class IEnumeratedDatetime(IDatetime, IValueSet):
+    u"""a Field containing a DateTime.
+
+    The value may be constrained to an element of a specified list.
+    """
+
 def _fields(values):
     for value in values:
         if not IField.isImplementedBy(value):
@@ -349,4 +381,3 @@
         constraint=_fields,
         required=False,
         )
-