[Zope3-dev] ItemTypePreconditions and ContainerTypesContstraints

Dominik Huber dominik.huber at projekt01.ch
Wed Dec 8 15:01:53 EST 2004


I would like to extend/generalize the precondition and constraint 
mechanism.

At the moment only restrictions based on type informations are covered
in the container framework. IMO their are other interesting usecases
for those preconditions/constraints:

- affected types (existing implementation)
- banned types
- multiplicity of a type
- logical combinations of simple preconditions/constraints
- ...

I sketched possible implementation steps for an extension that
is backward compatible. If nobody complains explicitly 
I'm going to check in the first step(#1) anyway. That
would simply the extension in a third party package.

Thoughts are appreciated.

Regards,
Dominik

#1 As a first step I would introduced a base interface for 
precondition/constraint interfaces that can used for other 
implementations too:

    class IItemPrecondition(zope.interface.Interface):
        """Base interface for item preconditions.
    
        This interface should be used for specialized item
preconditions
        interfaces like IItemTypePrecondition for example.
        """
        ...
    
    # existing implementation
    class IItemTypePrecondition(IItemPrecondition):
        """Test whether items provides one of the given types."""
    
    class IContainerConstraint(zope.interface.Interface):
        """Base interface for container constraints.
    
        This interface should be used for specialized container
constraint
        interfaces like IContainerTypesConstraint for example.
        """
        ...
    
    # existing implementation
    class IContainerTypesConstraint(IContainerConstraint):
        """Test whether container provides one of the given types."""

#2 In a second step I would add a generic precondition/constraint 
implementations that looks up its precondition/constraint by an
adapter
registered to IItemPrecondition/IContainerConstraint for a derived
interface of IContainer. Example:

    class ItemPrecondition(object):
        """__setitem__ precondition that restricts items for
containers."""
    
        implements(IItemPrecondition)
    
        def __call__(self, container, name, object):
            precondition = IItemPrecondition(container, None)
            if precondition is None:
                return
    
            return precondition(container, name, object)
    
        def factory(self, container, name, factory):
            precondition = IItemPrecondition(container, None)
            if precondition is None:
                return
    
            return precondition.factory(container, name, factory)

Afterward their will be generic adapter factories for 
preconditions/constraints. For example:

    class ItemPreconditionAdapterFactory(object):
        """Item precondition adapter factory."""
    
        implements(ItemPreconditionAdapterFactory)
    
        title = u'ItemPreconditionAdapterFactory'
        description = u'A factory that builds singleton item
precondtion'
    
        def __init__(self, class_, *args, **kw):
            if not
implementedBy(class_).isOrExtends(IItemPrecondition):
                raise ValueError('Parameter class_: 
                    IItemPrecondition required.')
    
            self.precondition = class_(*args, **kw)
    
        def __call__(self, context):
            return self.precondition
    
        def getInterfaces(self):
            return providedBy(self.precondition)

If somebody uses those precondition in its interfaces. He has to 
declare the generic precondition/constraint and register
an corresponding adapter:

    class IMyContainer(IContainer):
    
        def __setitem__(name, object): 
            """Add object."""
    
        __setitem__.precondition = ItemPrecondition()
    
    # The adapter factory uses existing, specialized ItemPrecondion,
for example
    MyAdapter = ItemPreconditionAdapterFactory(ItemTypePrecondition,
IXY)
    
      <adapter
          for=".IMyContainer"
          provides=".ItemPrecondition"
          factory=".MyAdapter"
          trusted="True"
          />

Specialized interfaces could overwrite those precondition/constraint
with their own adapter registration:

    class IMyOtherContainer(IMyContainer):
        pass
    
    MyOtherAdapter =
ItemPreconditionAdapterFactory(ItemTypePrecondition, IBC)
    
      <adapter
          for=".IMyOtherContainer"
          provides=".ItemPrecondition"
          factory=".MyOtherAdapter
          trusted="True"
          />

#3 In a third step we could provide (different) simple directives for
those
registrations. Some drafts:

   <itemprecondition
      for=".IMyContainer"
      factory=".MyOtherAdapter" />

   <itemprecondition
      for=".IMyContainer"
      class="ItemTypePrecondition"
      types="IY IXY" />

  ...

#4 In a fourth step we could provide a complex directive for container
registration (or/and open the contains and containers declarations):

    <container
        for=".IMyContainer" >
        
        <contains ../>
        
        <containers ../>
        
        ....
        
    </container>



More information about the Zope3-dev mailing list