[Zope3-checkins] CVS: Zope3/src/zope/app/schema - interfaces.py:1.1 mutableschemafield.py:1.1 schema.py:1.1 wrapper.py:1.1 configure.zcml:1.6 fieldforms.zcml:1.4

Stephan Richter srichter at cosmos.phy.tufts.edu
Tue Mar 9 19:58:27 EST 2004


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

Modified Files:
	configure.zcml fieldforms.zcml 
Added Files:
	interfaces.py mutableschemafield.py schema.py wrapper.py 
Log Message:


Moved mutable schemas out of zope.app.utilities to zope.app.schema. Also,
seperated it from the mutable schema content definition/instance code, which
now lives in zope.app.schemacontent.




=== Added File Zope3/src/zope/app/schema/interfaces.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""TTW Schema Interfaces

$Id: interfaces.py,v 1.1 2004/03/10 00:57:56 srichter Exp $
"""
from zope.interface import Interface
from zope.interface.interfaces import IInterface
from zope.app.container.interfaces import IAdding
from zope.app.interfaces.component import IInterfaceField

class ISchemaUtility(Interface):
    pass

class ISchemaAdding(IAdding):
    pass

class IReadMutableSchema(IInterface):
    """This object represents an interface/schema that can be edited by
    managing the fields it contains."""

    def getName(name):
        """Get the name of the schema."""

class IWriteMutableSchema(Interface):
    """This object represents an interface/schema that can be edited by
    managing the fields it contains."""

    def setName(name):
        """Set the name of the schema."""

    def addField(name, field):
        """Add a field to schema."""

    def removeField(name):
        """Remove field by name from the schema.

        If the field does not exist, raise an error.
        """

    def renameField(orig_name, target_name):
        """Rename a field.

        If the target_name is already taken, raise an error.
        """

    def insertField(name, field, position):
        """Insert a field with a given name at the specified position.

        If the position does not make sense, i.e. a negative number of a
        number larger than len(self), then an error is raised.
        """

    def moveField(name, position):
        """Move a field (given by its name) to a particular position.

        If the position does not make sense, i.e. a negative number of a
        number larger than len(self), then an error is raised.
        """

    def moveField(name, position):
        """Move a field (given by its name) to a particular position.

        If the position does not make sense, i.e. a negative number of a
        number larger than len(self), then an error is raised.
        """

    def __setitem__(name, object):
        """Add the given object to the container under the given name.
        """

    def __delitem__(name):
        """Delete the nameed object from the container.

        Raises a KeyError if the object is not found.
        """

class IMutableSchema(IReadMutableSchema, IWriteMutableSchema):
    """This object represents an interface/schema that can be edited by
    managing the fields it contains."""

class IMutableSchemaField(IInterfaceField):
    """A type of Field that has an IMutableSchema as its value."""

class IMutableSchemasField(IInterfaceField):
    """A type of Field that has a tuple of IMutableSchemas as its value."""


=== Added File Zope3/src/zope/app/schema/mutableschemafield.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Defines fields that are used in mutable schemas.

$Id: mutableschemafield.py,v 1.1 2004/03/10 00:57:56 srichter Exp $
"""
from zope.interface import implements, providedBy
from zope.interface.interfaces import IInterface
from zope.schema.interfaces import ValidationError
from zope.app.component.interfacefield import InterfaceField, InterfacesField

from interfaces import IMutableSchemaField, IMutableSchemasField, IMutableSchema

class MutableSchemaField(InterfaceField):

    __doc__ = IMutableSchemaField.__doc__
    implements(IMutableSchemaField)
    basetype = None

    def __init__(self, basetype=IMutableSchema, *args, **kw):
        # XXX Workaround for None indicating a missing value
        if basetype is None:
            kw['required'] = False
        super(MutableSchemaField, self).__init__(basetype=basetype,
                                                 *args, **kw)

    def _validate(self, value):
        basetype = self.basetype

        if value is None and basetype is None:
            return

        if basetype is None:
            basetype = IMutableSchema

        if not IInterface.providedBy(value):
            raise ValidationError("Not an interface", value)

        if basetype in providedBy(value):
            return

        if not value.extends(basetype, 0):
            raise ValidationError("Does not extend", value, basetype)


class MutableSchemasField(InterfacesField):

    __doc__ = IMutableSchemasField.__doc__
    implements(IMutableSchemasField)
    basetype = None

    def __init__(self, basetype=IMutableSchema, default=(), *args, **kw):
        # XXX Workaround for None indicating a missing value
        if basetype is None:
            kw['required'] = False
        super(MutableSchemasField, self).__init__(basetype=basetype,
                                                  default=default, *args, **kw)

    def _validate(self, value):
        basetype = self.basetype

        if value is () and basetype is None:
            return

        if basetype is None:
            basetype = IMutableSchema

        for v in value:
            if not IInterface.providedBy(v):
                raise ValidationError("Not an interface", v)

        for v in value:
            if basetype in providedBy(v):
                return

        for v in value:
            if not v.extends(basetype, 0):
                raise ValidationError("Does not extend", v, basetype)


=== Added File Zope3/src/zope/app/schema/schema.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""TTW Schema (as Utility)

$Id: schema.py,v 1.1 2004/03/10 00:57:56 srichter Exp $
"""
from types import FunctionType

from persistent import Persistent
from persistent.dict import PersistentDict
from zope.interface import Interface, implements

from zope.security.proxy import trustedRemoveSecurityProxy
from zope.proxy import removeAllProxies
from zope.app import zapi
from zope.app.browser.container.adding import Adding
from zope.app.services.interface import PersistentInterfaceClass
from zope.app.services.utility import UtilityRegistration
from zope.app.container.contained import Contained, setitem, uncontained

from zope.interface.interface import Attribute, Method, fromFunction
from zope.interface.interface import InterfaceClass
from zope.interface.exceptions import InvalidInterface
from zope.schema import getFieldsInOrder, getFieldNamesInOrder

from wrapper import Struct
from interfaces import ISchemaAdding, IMutableSchema, ISchemaUtility

class BaseSchemaUtility(InterfaceClass):

    implements(IMutableSchema, ISchemaUtility)

    def __init__(self, name='', bases=(), attrs=None,
                 __doc__=None, __module__=None):
        if not bases:
            bases = (Interface,)
        super(BaseSchemaUtility, self).__init__(name, bases,
                                            attrs, __doc__, __module__)
        self._clear()

    def _clear(self):
        self.schemaPermissions = {}
        self._attrs = {}

    def setName(self, name):
        """See zope.app.interfaces.utilities.IMutableSchema"""
        self.__name__ = name

    def addField(self, name, field):
        """See zope.app.interfaces.utilities.IMutableSchema"""
        fields = getFieldsInOrder(self)
        field_names = [n for n, f in fields]
        fields = [f for n, f in fields]
        if name in field_names:
            raise KeyError, "Field %s already exists." % name
        if fields:
            field.order = fields[-1].order + 1
        self[name] = field

    def removeField(self, name):
        """See zope.app.interfaces.utilities.IMutableSchema"""
        fields = getFieldNamesInOrder(self)
        if name not in fields:
            raise KeyError, "Field %s does not exists." % name
        del self[name]

    def renameField(self, orig_name, target_name):
        """See zope.app.interfaces.utilities.IMutableSchema"""
        fields = getFieldNamesInOrder(self)
        if orig_name not in fields:
            raise KeyError, "Field %s does not exists." % orig_name
        if target_name in fields:
            raise KeyError, "Field %s already exists." % target_name
        field = self[orig_name]
        del self[orig_name]
        field.__name__ = None
        self[target_name] = field

    def insertField(self, name, field, position):
        """See zope.app.interfaces.utilities.IMutableSchema"""
        fields = getFieldsInOrder(self)
        field_names = [n for n, f in fields]
        fields = [f for n, f in fields]
        if name in field_names:
            raise KeyError, "Field %s already exists." % name
        if not 0 <= position <= len(field_names):
            raise IndexError, "Position %s out of range." % position
        fields.insert(position, field)
        for p, f in enumerate(fields):
            if not f.order == p:
                f.order = p
        self[name] = field

    def moveField(self, name, position):
        """See zope.app.interfaces.utilities.IMutableSchema"""
        fields = getFieldsInOrder(self)
        field_names = [n for n, f in fields]
        fields = [f for n, f in fields]
        if name not in field_names:
            raise KeyError, "Field %s does not exist." % name
        if not 0 <= position <= len(field_names):
            raise IndexError, "Position %s out of range." % position
        index = field_names.index(name)
        if index == position: return
        field = fields[index]
        del fields[index]
        fields.insert(position, field)
        for p, f in enumerate(fields):
            if not f.order == p:
                f.order = p

    def __delitem__(self, name):
        uncontained(self._attrs[name], self, name)
        del self._attrs[name]

    def __setitem__(self, name, value):
        value = removeAllProxies(value)
        if isinstance(value, Attribute):
            value.interface = name
            if not value.__name__:
                value.__name__ = name
            elif isinstance(value, FunctionType):
                attrs[name] = fromFunction(value, name, name=name)
            else:
                raise InvalidInterface("Concrete attribute, %s" % name)

        setitem(self, self._attrs.__setitem__, name, value)

    # Methods copied from zope.interface.interface.InterfaceClass,
    # to avoid having to work around name mangling, which happens to be
    # ugly and undesirable.
    # Copied some methods, but not all. Only the ones that used __attrs
    # and __bases__. Changed __attrs to _attrs, which is a PersistentDict,
    # and __bases__ to getBases(), whic filters instances of InterfaceClass
    def getBases(self):
        return [b for b in self.__bases__ if isinstance(b, self.__class__)]

    def extends(self, interface, strict=True):
        """Does an interface extend another?"""
        return ((interface in self._implied)
                and
                ((not strict) or (self != interface))
                )

    def names(self, all=False):
        """Return the attribute names defined by the interface."""
        if not all:
            return self._attrs.keys()

        r = {}
        for name in self._attrs.keys():
            r[name] = 1
        for base in self.getBases():
            for name in base.names(all):
                r[name] = 1
        return r.keys()

    def namesAndDescriptions(self, all=False):
        """Return attribute names and descriptions defined by interface."""
        if not all:
            return self._attrs.items()

        r = {}
        for name, d in self._attrs.items():
            r[name] = d

        for base in self.getBases():
            for name, d in base.namesAndDescriptions(all):
                if name not in r:
                    r[name] = d

        return r.items()

    def getDescriptionFor(self, name):
        """Return the attribute description for the given name."""
        r = self.queryDescriptionFor(name)
        if r is not None:
            return r

        raise KeyError, name

    __getitem__ = getDescriptionFor

    def queryDescriptionFor(self, name, default=None):
        """Return the attribute description for the given name."""
        r = self._attrs.get(name, self)
        if r is not self:
            return r
        for base in self.getBases():
            r = base.queryDescriptionFor(name, self)
            if r is not self:
                return r

        return default

    get = queryDescriptionFor

    def deferred(self):
        """Return a defered class corresponding to the interface."""
        if hasattr(self, "_deferred"): return self._deferred

        klass={}
        exec "class %s: pass" % self.__name__ in klass
        klass=klass[self.__name__]

        self.__d(klass.__dict__)

        self._deferred=klass

        return klass

    def __d(self, dict):

        for k, v in self._attrs.items():
            if isinstance(v, Method) and not (k in dict):
                dict[k]=v

        for b in self.getBases(): b.__d(dict)


class StructPersistentDict(PersistentDict):

    def __setitem__(self, name, value):
        if not isinstance(value, Persistent):
            value = Struct(value)
        return super(StructPersistentDict, self).__setitem__(name, value)


class SchemaUtility(BaseSchemaUtility, PersistentInterfaceClass, Contained):

    def __init__(self, name='', bases=(), attrs=None,
                 __doc__=None, __module__=None):
        if not bases:
            bases = (Interface,)
        PersistentInterfaceClass.__init__(self, name, bases,
                                          attrs, __doc__, __module__)
        self._clear()

    def _clear(self):
        self.schemaPermissions = PersistentDict()
        self._attrs = StructPersistentDict()


class SchemaAdding(Adding):

    implements(ISchemaAdding)

    menu_id = "add_schema_field"

    def add(self, content):
        name = self.contentName
        container = IMutableSchema(self.context)
        container.addField(name, content)
        return content

    def nextURL(self):
        """See zope.app.container.interfaces.IAdding"""
        return (str(zapi.getView(self.context, "absolute_url", self.request))
                + '/@@editschema.html')


class SchemaRegistration(UtilityRegistration):
    """Schema Registration

    We have a custom registration here, since we want active registrations to
    set the name of the schema.
    """

    def activated(self):
        schema = self.getComponent()
        schema.setName(self.name)

    def deactivated(self):
        schema = self.getComponent()
        schema.setName('<schema not activated>')


=== Added File Zope3/src/zope/app/schema/wrapper.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Provide persistent wrappers for objects that cannot derive from
persistence for some reason."""

from persistent import Persistent, GHOST
from zope.interface import implementedBy
from zope.security.checker import selectChecker

class SecurityDescriptor:
    """ SecurityDescriptor is used by Struct to return the
    checker for the proxied object when its an instance,
    and return the checker for the Struct class, when its a class
    """

    def __get__(self, inst, cls=None):
        if inst is None:
            return selectChecker(cls)
        else:
            # XXX This is *VERY* tricky. There is a possibility that
            # the object was loaded, but not active by the time
            # __proxied__ needs to be accessed, which results
            # in an AttributeError here, which is swallowed
            # somewere inside the security machinery,
            # and then the object ends up using _defaultChecker
            #
            # Added the same code below, in ClassDescriptor,
            # though I'm not sure it is really needed there.
            if inst._p_state == GHOST:
                inst._p_activate()
            return selectChecker(inst.__proxied__)

class ClassDescriptor:
    """ ClassDescriptor is used by Struct to return the
    real class for Struct when a class is being used, and return
    the proxied object's class when its an instance.
    """

    def __get__(self, inst, cls=None):
        if inst is None:
            return cls
        else:
            if inst._p_state == GHOST:
                inst._p_activate()
            return inst.__proxied__.__class__


# Put those attributes in a list so its easier to add/remove
# when needed.
struct_attrs = ['__proxied__',
                '__dict__',
                '__reduce_ex__',
                '__reduce__',
                '__getstate__',
                '__setstate__',
                '__Security_checker__']

class Struct(Persistent):
  """Wraps a non-persistent object, assuming that *all* changes are
  made through external attribute assignments.
  """

  # XXX to do this right and expose both IPersistent and the
  # underlying object's interfaces, we'd need to use a specialized
  # descriptor.  This would create to great a dependency on
  # zope.interface.

  __class__ = ClassDescriptor()
  __Security_checker__ = SecurityDescriptor()


  def __init__(self, o):
      self.__proxied__ = o

  def __getattribute__(self, name):
      if name.startswith('_p_') or name in struct_attrs:
          v = Persistent.__getattribute__(self, name)
          # Handle descriptors here, eg: __Security_checker__
          # is a descriptor for Struct objects.
          if hasattr(v, '__get__'):
              return v.__get__(self, type(self))
          return v
      # XXX This is butt ugly. See the comment on SecurityDescriptor.
      if self._p_state == GHOST:
          self._p_activate()
      proxied = self.__proxied__
      v = getattr(proxied, name)
      # And also handle descriptors for the proxied object,
      # but using the proxied object on __get__ calls.
      if hasattr(v, '__get__'):
          # We should call it only if it came from the class,
          # otherwise its a descriptor being used as an instance
          # attribute, so just return it.
          if (hasattr(proxied, '__class__') and
              getattr(proxied.__class__, name) is v):
              return v.__get__(proxied, type(proxied))
      return v

  def __setattr__(self, name, v):
      if name.startswith('_p_') or name in struct_attrs:
          return Persistent.__setattr__(self, name, v)
      # Set _p_changed before calling the mutator on the
      # proxied object, so we have the object marked
      # as dirty even if an exception takes place later.
      self._p_changed = 1
      setattr(self.__proxied__, name, v)

  def __delattr__(self, name):
      if name.startswith('_p_') or name in struct_attrs:
          return Persistent.__delattr__(self, name)
      # Set _p_changed before deleting the attribute. See
      # comment above, on __setattr__
      self._p_changed = 1
      delattr(self.__proxied__, name, v)



=== Zope3/src/zope/app/schema/configure.zcml 1.5 => 1.6 ===
--- Zope3/src/zope/app/schema/configure.zcml:1.5	Wed Mar  3 17:54:27 2004
+++ Zope3/src/zope/app/schema/configure.zcml	Tue Mar  9 19:57:56 2004
@@ -1,5 +1,38 @@
 <configure xmlns="http://namespaces.zope.org/zope">
 
+  <content class=".schema.SchemaUtility">
+
+    <factory
+        title="Mutable Schema"
+        description="A Persistent Schema that can be edited through the web"/>
+
+    <implements
+        interface="zope.app.interfaces.services.utility.ILocalUtility" />
+
+    <implements
+        interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />
+
+    <require
+        permission="zope.ManageServices"
+        interface=".interfaces.IMutableSchema" />
+
+    <require
+        permission="zope.ManageServices"
+        interface=".interfaces.ISchemaUtility"
+        set_schema=".interfaces.ISchemaUtility" />
+
+  </content>
+
+  <content class=".schema.SchemaRegistration">
+    <require
+      permission="zope.ManageServices"
+      interface="zope.app.interfaces.services.utility.IUtilityRegistration
+                 zope.app.container.interfaces.IAddNotifiable
+                 zope.app.container.interfaces.IRemoveNotifiable"
+      set_schema="zope.app.interfaces.services.utility.IUtilityRegistration" />
+  </content>
+
   <include file="fields.zcml" />
+  <include package=".browser" />
 
 </configure>


=== Zope3/src/zope/app/schema/fieldforms.zcml 1.3 => 1.4 ===
--- Zope3/src/zope/app/schema/fieldforms.zcml:1.3	Fri Jan 16 08:38:19 2004
+++ Zope3/src/zope/app/schema/fieldforms.zcml	Tue Mar  9 19:57:56 2004
@@ -11,7 +11,7 @@
       title="Text Field"
       description="A Text Field"
       content_factory="zope.schema.Text"
-      for="zope.app.interfaces.utilities.schema.ISchemaAdding"
+      for=".interfaces.ISchemaAdding"
       schema="zope.schema.interfaces.IText"
       permission="zope.ManageContent"
       fields="title description required readonly
@@ -37,7 +37,7 @@
       title="TextLine Field"
       description="A TextLine Field"
       content_factory="zope.schema.TextLine"
-      for="zope.app.interfaces.utilities.schema.ISchemaAdding"
+      for=".interfaces.ISchemaAdding"
       schema="zope.schema.interfaces.ITextLine"
       permission="zope.ManageContent"
       fields="title description required readonly
@@ -63,7 +63,7 @@
       title="Boolean Field"
       description="A Boolean Field"
       content_factory="zope.schema.Bool"
-      for="zope.app.interfaces.utilities.schema.ISchemaAdding"
+      for=".interfaces.ISchemaAdding"
       schema="zope.schema.interfaces.IBool"
       permission="zope.ManageContent"
       fields="title description required readonly
@@ -89,7 +89,7 @@
       title="Integer Field"
       description="An Integer Field"
       content_factory="zope.schema.Int"
-      for="zope.app.interfaces.utilities.schema.ISchemaAdding"
+      for=".interfaces.ISchemaAdding"
       schema="zope.schema.interfaces.IInt"
       permission="zope.ManageContent"
       fields="title description required readonly
@@ -115,7 +115,7 @@
       title="Float Field"
       description="A Float Field"
       content_factory="zope.schema.Float"
-      for="zope.app.interfaces.utilities.schema.ISchemaAdding"
+      for=".interfaces.ISchemaAdding"
       schema="zope.schema.interfaces.IFloat"
       permission="zope.ManageContent"
       fields="title description required readonly
@@ -141,7 +141,7 @@
       title="Datetime Field"
       description="A Datetime Field"
       content_factory="zope.schema.Datetime"
-      for="zope.app.interfaces.utilities.schema.ISchemaAdding"
+      for=".interfaces.ISchemaAdding"
       schema="zope.schema.interfaces.IDatetime"
       permission="zope.ManageContent"
       fields="title description required readonly
@@ -170,7 +170,7 @@
       title="Enumerated TextLine Field"
       description="An Enumerated TextLine Field"
       content_factory="zope.schema.EnumeratedTextLine"
-      for="zope.app.interfaces.utilities.schema.ISchemaAdding"
+      for=".interfaces.ISchemaAdding"
       schema="zope.schema.interfaces.IEnumeratedTextLine"
       permission="zope.ManageContent"
       fields="title description required readonly
@@ -197,7 +197,7 @@
       title="Enumerated Integer Field"
       description="An Enumerated Integer Field"
       content_factory="zope.schema.EnumeratedInt"
-      for="zope.app.interfaces.utilities.schema.ISchemaAdding"
+      for=".interfaces.ISchemaAdding"
       schema="zope.schema.interfaces.IEnumeratedInt"
       permission="zope.ManageContent"
       fields="title description required readonly
@@ -224,7 +224,7 @@
       title="Enumerated Float Field"
       description="An Enumerated Float Field"
       content_factory="zope.schema.EnumeratedFloat"
-      for="zope.app.interfaces.utilities.schema.ISchemaAdding"
+      for=".interfaces.ISchemaAdding"
       schema="zope.schema.interfaces.IEnumeratedFloat"
       permission="zope.ManageContent"
       fields="title description required readonly
@@ -251,7 +251,7 @@
       title="Enumerated Datetime Field"
       description="An Enumerated Datetime Field"
       content_factory="zope.schema.EnumeratedDatetime"
-      for="zope.app.interfaces.utilities.schema.ISchemaAdding"
+      for=".interfaces.ISchemaAdding"
       schema="zope.schema.interfaces.IEnumeratedDatetime"
       permission="zope.ManageContent"
       fields="title description required readonly
@@ -278,7 +278,7 @@
       title="Enumerated Date Field"
       description="An Enumerated Date Field"
       content_factory="zope.schema.EnumeratedDate"
-      for="zope.app.interfaces.utilities.schema.ISchemaAdding"
+      for=".interfaces.ISchemaAdding"
       schema="zope.schema.interfaces.IEnumeratedDate"
       permission="zope.ManageContent"
       fields="title description required readonly




More information about the Zope3-Checkins mailing list