[Checkins] SVN: zope.generic/trunk/src/zope/generic/ another refactoring :)

Dominik Huber dominik.huber at perse.ch
Tue May 2 18:48:29 EDT 2006


Log message for revision 67873:
  another refactoring :)
  
  

Changed:
  U   zope.generic/trunk/src/zope/generic/adapter/README.txt
  U   zope.generic/trunk/src/zope/generic/adapter/adapter.py
  U   zope.generic/trunk/src/zope/generic/adapter/metaconfigure.py
  U   zope.generic/trunk/src/zope/generic/adapter/property.py
  U   zope.generic/trunk/src/zope/generic/configuration/README.txt
  U   zope.generic/trunk/src/zope/generic/configuration/adapter.py
  U   zope.generic/trunk/src/zope/generic/configuration/base.py
  U   zope.generic/trunk/src/zope/generic/configuration/interfaces.py
  U   zope.generic/trunk/src/zope/generic/content/EXAMPLE.txt
  U   zope.generic/trunk/src/zope/generic/content/README.txt
  U   zope.generic/trunk/src/zope/generic/content/helper.py
  U   zope.generic/trunk/src/zope/generic/content/meta.zcml
  U   zope.generic/trunk/src/zope/generic/content/metaconfigure.py
  U   zope.generic/trunk/src/zope/generic/content/metadirectives.py
  U   zope.generic/trunk/src/zope/generic/face/README.txt
  U   zope.generic/trunk/src/zope/generic/face/api.py
  U   zope.generic/trunk/src/zope/generic/face/base.py
  U   zope.generic/trunk/src/zope/generic/face/configure.zcml
  U   zope.generic/trunk/src/zope/generic/face/interfaces.py
  D   zope.generic/trunk/src/zope/generic/face/metadirectives.py
  U   zope.generic/trunk/src/zope/generic/face/testing.py
  U   zope.generic/trunk/src/zope/generic/factory/README.txt
  U   zope.generic/trunk/src/zope/generic/factory/adapter.py
  U   zope.generic/trunk/src/zope/generic/factory/api.py
  U   zope.generic/trunk/src/zope/generic/factory/factory.py
  U   zope.generic/trunk/src/zope/generic/factory/interfaces.py
  U   zope.generic/trunk/src/zope/generic/factory/metaconfigure.py
  U   zope.generic/trunk/src/zope/generic/factory/metadirectives.py
  U   zope.generic/trunk/src/zope/generic/handler/README.txt
  U   zope.generic/trunk/src/zope/generic/handler/metaconfigure.py
  U   zope.generic/trunk/src/zope/generic/handler/metadirectives.py
  U   zope.generic/trunk/src/zope/generic/informationprovider/NEW_README.txt
  U   zope.generic/trunk/src/zope/generic/informationprovider/PUBLICATION.cfg
  U   zope.generic/trunk/src/zope/generic/informationprovider/README.txt
  U   zope.generic/trunk/src/zope/generic/informationprovider/api.py
  A   zope.generic/trunk/src/zope/generic/informationprovider/base.py
  U   zope.generic/trunk/src/zope/generic/informationprovider/configure.zcml
  U   zope.generic/trunk/src/zope/generic/informationprovider/interfaces.py
  U   zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py
  U   zope.generic/trunk/src/zope/generic/informationprovider/metadirectives.py
  U   zope.generic/trunk/src/zope/generic/informationprovider/testing.py
  U   zope.generic/trunk/src/zope/generic/informationprovider/tests.py
  U   zope.generic/trunk/src/zope/generic/operation/README.txt
  U   zope.generic/trunk/src/zope/generic/operation/api.py
  U   zope.generic/trunk/src/zope/generic/operation/base.py
  U   zope.generic/trunk/src/zope/generic/operation/interfaces.py
  U   zope.generic/trunk/src/zope/generic/operation/metaconfigure.py
  U   zope.generic/trunk/src/zope/generic/operation/metadirectives.py
  U   zope.generic/trunk/src/zope/generic/operation/testing.py

-=-
Modified: zope.generic/trunk/src/zope/generic/adapter/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/adapter/README.txt	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/adapter/README.txt	2006-05-02 22:48:25 UTC (rev 67873)
@@ -46,14 +46,14 @@
 We register the configuration schema using generic:face directive:
 
     >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IFooConfiguration"
-    ...     type="zope.generic.configuration.IConfiguration"
+    ... <generic:interface
+    ...     interface="example.IFooConfiguration"
+    ...     type="zope.generic.configuration.IConfigurationType"
     ...     />
     ... ''') 
 
-    >>> from zope.generic.configuration import IConfiguration
-    >>> IConfiguration.providedBy(IFooConfiguration)
+    >>> from zope.generic.configuration import IConfigurationType
+    >>> IConfigurationType.providedBy(IFooConfiguration)
     True
 
 We implement a class which is providing the configuration mechanism:
@@ -61,9 +61,9 @@
     >>> class IFoo(interface.Interface):
     ...    pass
 
-    >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IFoo"
+    ... <generic:interface
+    ...     interface="example.IFoo"
+    ...     type="zope.generic.face.IKeyfaceType"
     ...     />
     ... ''')
     

Modified: zope.generic/trunk/src/zope/generic/adapter/adapter.py
===================================================================
--- zope.generic/trunk/src/zope/generic/adapter/adapter.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/adapter/adapter.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -22,7 +22,7 @@
 from zope.interface import classImplements
 from zope.interface import implements
 
-from zope.generic.configuration import IConfiguration
+from zope.generic.configuration import IConfigurationType
 from zope.generic.configuration import IConfigurations
 
 from zope.generic.adapter.property import ConfigurationAdapterProperty
@@ -55,14 +55,14 @@
     We register the configuration schema using generic:face directive:
 
         >>> registerDirective('''
-        ... <generic:face
-        ...     keyface="example.IFooConfiguration"
-        ...     type="zope.generic.configuration.IConfiguration"
+        ... <generic:interface
+        ...     interface="example.IFooConfiguration"
+        ...     type="zope.generic.configuration.IConfigurationType"
         ...     />
         ... ''') 
 
-        >>> from zope.generic.configuration import IConfiguration
-        >>> IConfiguration.providedBy(IFooConfiguration)
+        >>> from zope.generic.configuration import IConfigurationType
+        >>> IConfigurationType.providedBy(IFooConfiguration)
         True
 
     We implement a class which is providing the configuration mechanism:
@@ -71,8 +71,9 @@
         ...    pass
 
         >>> registerDirective('''
-        ... <generic:face
-        ...     keyface="example.IFoo"
+        ... <generic:interface
+        ...     interface="example.IFoo"
+        ...     type="zope.generic.face.IKeyfaceType"
         ...     />
         ... ''')
 
@@ -119,8 +120,8 @@
     """
 
     # preconditions
-    if not IConfiguration.providedBy(keyface):
-        raise ValueError('Interface must provide %s.' % IConfiguration.__name__)
+    if not IConfigurationType.providedBy(keyface):
+        raise ValueError('Interface must provide %s.' % IConfigurationType.__name__)
 
     # essentails
     if not bases:

Modified: zope.generic/trunk/src/zope/generic/adapter/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/adapter/metaconfigure.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/adapter/metaconfigure.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -23,7 +23,7 @@
 from zope.configuration.exceptions import ConfigurationError
 from zope.location import ILocation
 
-from zope.generic.configuration import IConfiguration
+from zope.generic.configuration import IConfigurationType
 
 from zope.generic.adapter.adapter import ConfigurationAdapterClass
 
@@ -42,7 +42,7 @@
         raise ConfigurationError('Use class or key/ informationProividers attriubte.')
 
     # we will provide a generic adapter class
-    if class_ is None and IConfiguration.providedBy(provides):
+    if class_ is None and IConfigurationType.providedBy(provides):
         class_ = ConfigurationAdapterClass(provides, informationProviders)
 
     if class_ is None and key:

Modified: zope.generic/trunk/src/zope/generic/adapter/property.py
===================================================================
--- zope.generic/trunk/src/zope/generic/adapter/property.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/adapter/property.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -22,7 +22,7 @@
 from zope.generic.configuration.base import ConfigurationData
 from zope.generic.configuration.helper import configuratonToDict
 from zope.generic.informationprovider.api import getInformation
-from zope.generic.informationprovider.api import getNextInformationProvider
+from zope.generic.informationprovider.api import getInformationProvider
 
 
 
@@ -68,7 +68,7 @@
         if configuration is None and self._providers:
             for registry in self._providers:
                 try:
-                    provider = getNextInformationProvider(context, registry)
+                    provider = getInformationProvider(context, registry)
                     configuration = getInformation(provider, keyface)
                     break
                 except:
@@ -115,7 +115,7 @@
                 if configuration is None and self._providers:
                     for registry in self._providers:
                         try:
-                            provider = getNextInformationProvider(context, registry)
+                            provider = getInformationProvider(context, registry)
                             configuration = getInformation(provider, keyface)
                             break
                         except:

Modified: zope.generic/trunk/src/zope/generic/configuration/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/README.txt	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/configuration/README.txt	2006-05-02 22:48:25 UTC (rev 67873)
@@ -16,25 +16,32 @@
 ---------------
 
 Configurations is a container of configuration data. Configuration data are
-defined by an schema which is providing IConfiguration. The configuration
-data itself has to provide the schema that is used to reference it.
+defined by an schema which is typed as IConfigurationType. IConfigurationType
+is extending IKeyType because the configuration schemas are the key interface
+of a configuration object too. The configuration object itself has to provide 
+the schema too.
 
+    >>> from zope.interface import Interface
     >>> from zope.schema import TextLine
-        
-    >>> class IMyConfiguration(interface.Interface):
-    ...     my = TextLine(title=u'My')
+    
+    >>> class IFooConfiguration(Interface):
+    ...    foo = TextLine(title=u'Foo')
+    ...    optional = TextLine(title=u'Optional', required=False, default=u'Bla')
 
     >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IMyConfiguration"
-    ...     type="zope.generic.configuration.IConfiguration"
+    ... <generic:interface
+    ...     interface="example.IFooConfiguration"
+    ...     type="zope.generic.configuration.IConfigurationType"
     ...     />
     ... ''') 
 
-    >>> from zope.generic.configuration.api import IConfiguration
-    >>> IConfiguration.providedBy(IMyConfiguration)
+    >>> api.IConfigurationType.providedBy(IFooConfiguration)
     True
  
+    >>> from zope.generic.face import IKeyfaceType
+    >>> IKeyfaceType.providedBy(IFooConfiguration)
+    True
+
 Regularly local configurations are provided by objects marked with
 IAttributeConfigurations automatically:
 
@@ -61,26 +68,6 @@
     >>> configurations.__nonzero__()
     False
 
-Configuration data will be stored under an key interface within the
-configurations. Such a configuration schema defines its configuration
-data:
-
-    >>> from zope.interface import Interface
-    >>> from zope.schema import TextLine
-    
-    >>> class IFooConfiguration(Interface):
-    ...    foo = TextLine(title=u'Foo')
-    ...    optional = TextLine(title=u'Optional', required=False, default=u'Bla')
-
-The configuration schema is a regular schema, but it has to be typed
-by IConfiguration (Regularly done by the configuration directive):
-
-    >>> from zope.interface import directlyProvides
-
-    >>> directlyProvides(IFooConfiguration, IConfiguration)
-    >>> IConfiguration.providedBy(IFooConfiguration)
-    True
-
 The configurations provides a regular dictionary api by the UserDictMixin
 (like AttributeAnnotations). This mixin bases on the following methods:
 
@@ -106,7 +93,7 @@
     >>> configurations[IBarConfiguration] = object()
     Traceback (most recent call last):
     ...
-    KeyError: 'Interface key IBarConfiguration does not provide IConfiguration.'
+    KeyError: 'Interface key IBarConfiguration requires IConfigurationType.'
 
     >>> configurations[IFooConfiguration] = object()
     Traceback (most recent call last):

Modified: zope.generic/trunk/src/zope/generic/configuration/adapter.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/adapter.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/configuration/adapter.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -32,7 +32,7 @@
 from zope.generic.face.api import toInterface
 
 from zope.generic.configuration import IAttributeConfigurable
-from zope.generic.configuration import IConfiguration
+from zope.generic.configuration import IConfigurationType
 from zope.generic.configuration import IConfigurations
 from zope.generic.configuration.event import Configuration
 from zope.generic.configuration.event import ObjectConfiguredEvent
@@ -107,9 +107,9 @@
 
     def __setitem__(self, keyface, value):
         # preconditions
-        if not IConfiguration.providedBy(keyface):
-            raise KeyError('Interface key %s does not provide %s.' % 
-                (keyface.__name__, IConfiguration.__name__))
+        if not IConfigurationType.providedBy(keyface):
+            raise KeyError('Interface key %s requires %s.' % 
+                (keyface.__name__, IConfigurationType.__name__))
 
         if not keyface.providedBy(value):
             raise ValueError('Value does not provide %s.' % keyface.__name__)

Modified: zope.generic/trunk/src/zope/generic/configuration/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/base.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/configuration/base.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -29,9 +29,9 @@
 
 from zope.generic.face import IAttributeFaced
 from zope.generic.face import IFace
+from zope.generic.face import IUndefinedContext
 from zope.generic.face.api import FaceForAttributeFaced
 
-from zope.generic.configuration import IConfiguration
 from zope.generic.configuration import IConfigurationData
 from zope.generic.configuration import IConfigurations
 
@@ -110,7 +110,7 @@
 
     A configuration belong to the configuration context:
 
-        >>> adapted.conface is IConfiguration
+        >>> adapted.conface is IUndefinedContext
         True
 
     """
@@ -132,7 +132,7 @@
         # essentials
         self.__dict__['_ConfigurationData__data'] = PersistentDict(data)
         self.__dict__['__keyface__'] = __keyface__
-        self.__dict__['__conface__'] = IConfiguration
+        self.__dict__['__conface__'] = IUndefinedContext
         directlyProvides(self, __keyface__)
 
     def __conform__(self, interface):

Modified: zope.generic/trunk/src/zope/generic/configuration/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/interfaces.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/configuration/interfaces.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -26,8 +26,7 @@
 from zope.lifecycleevent.interfaces import IModificationDescription
 
 from zope.generic.face import IFaced
-from zope.generic.face import IConfaceType
-from zope.generic.face import IKeyfaceDescription
+from zope.generic.face import IKeyfaceType
 
 
 
@@ -36,14 +35,11 @@
 
 
 
-class IConfiguration(Interface):
-    """Mark a schema that is used for configuration."""
+class IConfigurationType(IKeyfaceType):
+    """Type a key schema that is used for configuration purposes."""
 
-alsoProvides(IConfiguration, IConfaceType)
 
 
-
-
 class IConfigurationData(IFaced):
     """Marker for configuration data implementations."""
 
@@ -103,7 +99,7 @@
     def __setitem__(keyface, configuration_data):
         """Store a certain configuration data under the interface-key.
 
-        The interface key should provide IConfiguration.
+        The interface key should provide IConfigurationType.
 
         The configuration data has to provide the declared key interface. 
         
@@ -141,14 +137,6 @@
     """
 
 
-AnnotationKey = 'zope.generic.configuration.IConfigurations'
-
-class IAnnotationsConfigurable(IConfigurable):
-    """Marker indicating that configurations can be stored on annotations.
-
-    """
-
-
 class IConfigurationModificationDescription(IModificationDescription):
     """Declares the modified configuration by its interface and
     the corresponding data that got modified.

Modified: zope.generic/trunk/src/zope/generic/content/EXAMPLE.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/content/EXAMPLE.txt	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/content/EXAMPLE.txt	2006-05-02 22:48:25 UTC (rev 67873)
@@ -41,23 +41,23 @@
     ...     note = schema.Text(title=u"Note body", required=False)
 
     >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.ITextConfig"
-    ...     type="zope.generic.configuration.IConfiguration"
+    ... <generic:interface
+    ...     interface="example.ITextConfig"
+    ...     type="zope.generic.configuration.IConfigurationType"
     ...     />
     ... ''') 
 
     >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.INoteConfig"
-    ...     type="zope.generic.configuration.IConfiguration"
+    ... <generic:interface
+    ...     interface="example.INoteConfig"
+    ...     type="zope.generic.configuration.IConfigurationType"
     ...     />
     ... ''')
 
     >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IArticleInitializationConfiguration"
-    ...     type="zope.generic.configuration.IConfiguration"
+    ... <generic:interface
+    ...     interface="example.IArticleInitializationConfiguration"
+    ...     type="zope.generic.configuration.IConfigurationType"
     ...     />
     ... ''')
 

Modified: zope.generic/trunk/src/zope/generic/content/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/content/README.txt	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/content/README.txt	2006-05-02 22:48:25 UTC (rev 67873)
@@ -47,7 +47,6 @@
     >>> registerDirective('''
     ... <generic:content
     ...     keyface="example.IFooMarker"
-    ...     label='Foo Type' hint='Bla bla bla.'
     ...     >
     ...    <factory class='zope.generic.content.api.Object'
     ...        />
@@ -85,12 +84,6 @@
     >>> info.keyface == IFooMarker
     True
 
-# TODO: Implement label and hint
-#    >>> info.label
-#    u'Foo Type'
-#    >>> info.hint
-#    u'Bla bla bla.'
-
 There is convenience function for the lookup of corresponding type information.
 You can lookup the type information by the type marker interface or an object
 providing ITypedContent by implementation or adaption:
@@ -130,16 +123,16 @@
     ...		optional = TextLine(title=u'Other', required=False, default=u'Default bla.')
 
     >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IAnyConfiguration"
-    ...     type="zope.generic.configuration.IConfiguration"
+    ... <generic:interface
+    ...     interface="example.IAnyConfiguration"
+    ...     type="zope.generic.configuration.IConfigurationType"
     ...     />
     ... ''') 
 
     >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IOtherConfiguration"
-    ...     type="zope.generic.configuration.IConfiguration"
+    ... <generic:interface
+    ...     interface="example.IOtherConfiguration"
+    ...     type="zope.generic.configuration.IConfigurationType"
     ...     />
     ... ''') 
 

Modified: zope.generic/trunk/src/zope/generic/content/helper.py
===================================================================
--- zope.generic/trunk/src/zope/generic/content/helper.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/content/helper.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -19,7 +19,7 @@
 __docformat__ = 'restructuredtext'
 
 from zope.generic.face.api import getKeyface
-from zope.generic.face.api import getNextInformationProvider
+from zope.generic.face.api import getInformationProvider
 from zope.generic.informationprovider.api import queryInformation
 
 from zope.generic.face import IUndefinedContext
@@ -28,7 +28,7 @@
 
 
 def getTypeInformation(object, conface=IUndefinedContext):
-    return getNextInformationProvider(getKeyface(object), conface)
+    return getInformationProvider(getKeyface(object), conface)
 
 
 

Modified: zope.generic/trunk/src/zope/generic/content/meta.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/content/meta.zcml	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/content/meta.zcml	2006-05-02 22:48:25 UTC (rev 67873)
@@ -6,8 +6,8 @@
 
     <meta:complexDirective
         name="content"
-        schema=".metadirectives.ITypeDirective"
-        handler=".metaconfigure.TypeDirective"
+        schema=".metadirectives.IContentDirective"
+        handler=".metaconfigure.ContentDirective"
         >
 
       <meta:subdirective

Modified: zope.generic/trunk/src/zope/generic/content/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/content/metaconfigure.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/content/metaconfigure.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -29,7 +29,7 @@
 
 
 
-class TypeDirective(InformationProviderDirective):
+class ContentDirective(InformationProviderDirective):
     """Provide a new logical type."""
 
     # mark types with a type marker type
@@ -39,14 +39,13 @@
     def __init__(self, _context, keyface, label=None, hint=None):        
         # register types within the type information registry
         conface = IUndefinedContext
-        super(TypeDirective, self).__init__(_context, keyface, conface, label, hint)
+        super(ContentDirective, self).__init__(_context, keyface, conface)
 
     def factory(self, _context, class_, operations=(), input=None,
                 providesFace=True, notifyCreated=False, storeInput=False):
         """Add factory."""
         factoryDirective(_context, self._keyface, class_, operations, input,
-                     providesFace, notifyCreated, storeInput,
-                     self._label, self._hint)
+                     providesFace, notifyCreated, storeInput)
 
 
     def adapter(self, _context, provides, class_=None, writePermission=None, 

Modified: zope.generic/trunk/src/zope/generic/content/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/content/metadirectives.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/content/metadirectives.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -23,13 +23,15 @@
 
 from zope.generic.adapter.metadirectives import IOthersAdapterDirective
 from zope.generic.factory.metadirectives import IBaseFactoryDirective
-from zope.generic.informationprovider.metadirectives import IBaseInformationProviderDirective
-from zope.generic.handler.metadirectives import IBaseHandlerDirective
-from zope.generic.operation.metadirectives import IBaseOperationDirective
+from zope.generic.informationprovider.metadirectives import IDescriptionDirective
+from zope.generic.informationprovider.metadirectives import IKeyfaceDirective
+from zope.generic.handler.metadirectives import IEventDirective
+from zope.generic.operation.metadirectives import IOperationsDirective
+from zope.generic.operation.metadirectives import IInputDirective
 
     
 
-class ITypeDirective(IBaseInformationProviderDirective):
+class IContentDirective(IKeyfaceDirective, IDescriptionDirective):
     """Declare attriubtes of the type directive.
 
     Register an type information and a type factory.
@@ -37,7 +39,7 @@
 
 
 
-class IFactorySubdirective(IBaseFactoryDirective, IBaseOperationDirective):
+class IFactorySubdirective(IBaseFactoryDirective, IOperationsDirective, IInputDirective):
     """Provide an factory for the type."""
 
     providesFace = Bool(
@@ -60,5 +62,5 @@
         default=False
         )
 
-class IHandlerSubdirective(IBaseHandlerDirective, IBaseOperationDirective):
+class IHandlerSubdirective(IEventDirective, IOperationsDirective, IInputDirective):
     """Provide object event handler for the keyface."""

Modified: zope.generic/trunk/src/zope/generic/face/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/face/README.txt	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/face/README.txt	2006-05-02 22:48:25 UTC (rev 67873)
@@ -2,83 +2,25 @@
 Generic Face
 ============
 
-This package provides a mechanism to define and access key interface marker 
-(IKeyfaceType) and a context interface marker (IConfaceType). Those interfaces
-can be used to provide dedicated information (IInformationProvider) such as 
-configurations and annotations contextually.
+This package provides interface types for key interfaces (IKeyfaceType) and 
+context interfaces (IConfaceType). 
 
-Within the system domain the key interface represents a permanent marker for an
-object. For example the marked object *is* a person. Regularly you will mark
-your content components with domain-specific key interface markers. Such a
-keyface (short for: key[ inter]face) has the same relation like classes
-to its instances.
+Typed interfaces can be used to register dedicated information providers 
+(IInformationProvider see zope.generic.informationprovider). An information 
+provider offers the possiblity to register information according to a pair of 
+key- and context interfaces.
 
-The context interface allows an more explicit comprehension and lookup of 
-information related to objects. Contexts of understanding are often changing
-within the same system domain. Regularly a certain information provider is 
-contextual. That means different information providers will provide the same
-type of information about one subject but the value of the provided information
-might differ contextually. For example your *name* within the system domain 
-*world* is changing: Within your childs context it will be 'Dad', within your 
-wife's context it will be 'Darling', within your friend's context it will be 
-'Dude' and within the official context will be 'Mr. Foo Bar'.
+Key interface
+-------------
 
-Both interface types provide the fundament to model more complex , contextual
-object-behavior and -properties. The package allows to define keys that allows 
-a dedicated, but generic invocation of information providers. This allows 
-dedicated facing or casing of objects.
+The key interface is the one piece to lookup information providers. 
 
-Context interface types
------------------------
+Within the system domain the key interface represents a permanent marker for an
+object. For example the marked object *is* a person. Regularly you will mark
+your content components with domain-specific key interfaces. Such a keyface 
+(short for: key[ inter]face) has a similar relation like classes and its 
+instances, therefore it can be used to type components.
 
-The context interface is one piece to lookup information providers contextually.
-You can provide a context interface simply by deriving from zope's Interface.
-
-    >>> class IMyContext(interface.Interface):
-    ...    pass
-
-The context interface should be registered by the conface directive. This
-asserts that the interface get marked as IKeyfaceType:
-
-    >>> api.IKeyfaceType.providedBy(IMyContext)
-    False
-
-    >>> registerDirective('''
-    ... <generic:face
-    ...     conface="example.IMyContext"
-    ...     />
-    ... ''') 
-
-    >>> api.IConfaceType.providedBy(IMyContext)
-    True
-
-As usual the typed interface is registered as utility too:
-
-    >>> component.getUtility(api.IConfaceType, 
-    ...     api.toDottedName(IMyContext)) == IMyContext
-    True
-
-As usual you can type context interfaces with other interface types:
-
-    >>> class IMyType(interface.interfaces.IInterface):
-    ...    pass
-
-    >>> registerDirective('''
-    ... <generic:face
-    ...     conface="example.IMyContext"
-    ...     type="example.IMyType"
-    ...     />
-    ... ''') 
-
-    >>> IMyType.providedBy(IMyContext)
-    True
-    >>> component.getUtility(IMyType, 
-    ...     api.toDottedName(IMyContext)) == IMyContext
-    True
-
-Key interface types
--------------------
-
 The behavior of components within the ca-framework depends heavily on their
 provided interfaces. A component, except most of the adapters and utilities, 
 regularly provides more than one interface. The adaption and subscriber 
@@ -86,98 +28,73 @@
 lookup-algorithmus similar to the method resolution order by class inherintance.
 
 Most of the time this behavior satisfies our requirements. Additionally this 
-package offers a mechanism to declare a single key interface (IFace).
-This key interface can be used to lookup corresponding information providers
-more explicitly.
+package offers a mechanism to declare a single key interface (IKeyface). This 
+key interface can be used to lookup corresponding information providers
+explicitly.
 
-First we use a key interface:
+Context Interface
+-----------------
 
-    >>> class IFoo(interface.Interface):
-    ...    pass
+The context interface is the other piece to lookup information providers. 
 
-The key interface should be registered by the keyface directive. This asserts
-that the interface get marked as IKeyfaceType:
+The context interface allows an more explicit comprehension and lookup of 
+information related to key interfaces. Contexts of understanding are often 
+changing within the same system domain. For example your *name* is changing 
+within the system domain *world*: Within your childs context it will be 'Dad', 
+within your wife's context it will be 'Darling', within your friend's context 
+it will be 'Dude' and within the official context will be 'Mr. Foo Bar'.
 
-    >>> api.IKeyfaceType.providedBy(IFoo)
-    False
+The key- and contes interfaces provide the fundament to model more complex, 
+contextual object-behavior and -properties. The package allows a dedicated, 
+but generic registration of information providers, which can be used for
+facing or casing your objects contextually.
 
-    >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IFoo"
-    ...     />
-    ... ''') 
+How to define a context interface
+---------------------------------
 
-    >>> api.IKeyfaceType.providedBy(IFoo)
-    True
+You can implement a context interface simply by deriving from zope's Interface
+and typing it by IConfaceType.
 
-As usual the typed interface is registered as utility too:
+    >>> class IMyContext(interface.Interface):
+    ...    pass
 
-    >>> component.getUtility(api.IKeyfaceType, 
-    ...     api.toDottedName(IFoo)) == IFoo
+    >>> interface.alsoProvides(IMyContext, api.IConfaceType)
+    >>> api.IConfaceType.providedBy(IMyContext)
     True
 
-As usual you can type context interfaces with other interface types:
+Context interfaces are pure marker interfaces. They can be used to register
+contextual information providers as utility providing the context interface.
 
-    >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IFoo"
-    ...     type="example.IMyType"
-    ...     />
-    ... ''') 
+Information providers that are not aware of a context should use 
+IUndefinedContext:
 
-Afterward the interface will be typed regularly:
-
-    >>> IMyType.providedBy(IFoo)
+    >>> api.IConfaceType.providedBy(api.IUndefinedContext)
     True
-    >>> component.getUtility(IMyType, 
-    ...     api.toDottedName(IFoo)) == IFoo
-    True
 
-An exception of the directive in relation to the regular interface directive is,
-that you can mark key interfaces by a context interface. This marking says there
-might be contextual information. The abscence of a context marker asserts that
-there are *no* contextual informations to an key interface:
+How to define a key interface
+-----------------------------
 
-    >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IFoo"
-    ...     type="example.IMyContext"
-    ...     />
-    ... ''') 
+You can implement a key interface simply by deriving from zope's Interface and 
+typing it by IKeyfaceType.
 
-    >>> IMyContext.providedBy(IFoo)
-    True
+    >>> class IFoo(interface.Interface):
+    ...    pass
 
-Attention: Those contextual types will be not available as interface utility.
-Instead there will be an information provider (see 
-zope.generic.informationprovider too):
-
-    >>> provider = component.getUtility(IMyContext, 
-    ...     api.toDottedName(IFoo)) 
-
-    >>> provider == IFoo
-    False
-
-    >>> IMyContext.providedBy(provider)
+    >>> interface.alsoProvides(IFoo, api.IKeyfaceType)
+    >>> api.IKeyfaceType.providedBy(IFoo)
     True
-    >>> provider.conface == IMyContext
-    True
 
-    >>> IFoo.providedBy(provider)
-    False
-    >>> provider.keyface == IFoo
-    True
+If no key interface is available regularly IUndefinedKeyface is provided:
 
-    >>> api.IInformationProvider.providedBy(provider)
+    >>> api.IKeyfaceType.providedBy(api.IUndefinedKeyface)
     True
 
+How to use the face mechanism
+-----------------------------
 
-How to provide the face mechanism
----------------------------------
-
 The IFaced interface promises access to keyface and/or conface of an object.
-The lookup of key and context interfaces is regularly done by providing 
-IAttributeFaced.
+The lookup of key and context interfaces is regularly done by component that
+are providing IAttributeFaced.
 
 Then we have to decorate a corresponding key-faced component:
 
@@ -206,29 +123,209 @@
     >>> fooface.conface == IMyContext
     True
 
+getKeyface
+----------
+
 The api provides convenience functions to get the key interfaces of components:
 
     >>> api.getKeyface(foofaced) == IFoo
     True
-    
     >>> api.getKeyface(fooface) == api.IUndefinedKeyface
     True
-
     >>> api.getKeyface(object()) == api.IUndefinedKeyface
     True
+    >>> api.getKeyface(object(), None) is None
+    True
 
+getConface
+----------
 
 The api provides convenience functions to get the context interfaces of components:
 
     >>> api.getConface(foofaced) == api.IUndefinedContext
     True
-    
     >>> api.getConface(fooface) == IMyContext
     True
-
     >>> api.getConface(object()) == api.IUndefinedContext
     True
+    >>> api.getConface(object(), None) is None
+    True
 
+InformationProvider Lookup
+--------------------------
 
+You can register information providers. This is done by the informationProvider
+directive (see zope.generic.informationprovider). This package defines the
+way those information providers can be looked up too.
 
+An information provider should provide the contex interface itself. Further more
+it is responsible to mark the key interface by the context interface:
 
+
+    >>> class DummyInformationProvider(object):
+    ...    def __init__(self, keyface, conface):
+    ...        self.keyface = keyface
+    ...        self.conface = conface
+    ...        interface.alsoProvides(self, conface)
+    ...        interface.alsoProvides(keyface, conface)
+    ...    def __repr__(self):
+    ...        return '<Information provider %s at %s>' % (self.keyface.__name__, self.conface.__name__)
+
+    >>> def ensureInformationProvider(keyface, conface):
+    ...    provider = DummyInformationProvider(keyface, conface)
+    ...    component.provideUtility(provider, conface, api.toDottedName(keyface))
+    ...    return provider
+
+    >>> provider_1 = ensureInformationProvider(IFoo, api.IUndefinedContext)
+
+    >>> api.IUndefinedContext.providedBy(IFoo)
+    True
+    >>> api.IUndefinedContext.providedBy(provider_1)
+    True
+
+Simple Lookup using queryInformationProvider and getInformationProvider
+------------------------------------------------------------------------
+
+    >>> api.getInformationProvider(IFoo)
+    <Information provider IFoo at IUndefinedContext>
+
+    >>> api.queryInformationProvider(IFoo)
+    <Information provider IFoo at IUndefinedContext>
+
+A key error is raised or the default is returned if no information provider 
+could be evalutated for a certain key interface, context interface pair:
+
+    >>> api.getInformationProvider(IFoo, IMyContext)
+    Traceback (most recent call last):
+    ...
+    KeyError: 'Missing information provider IFoo at IMyContext.'
+
+    >>> api.queryInformationProvider(IFoo, IMyContext, 'Missing information provider.')
+    'Missing information provider.'
+
+Attention information provider does not acquire from more specialized interface
+like the regular utility lookup does:
+
+    >>> class IYourContext(IMyContext):
+    ...    pass
+
+    >>> interface.alsoProvides(IYourContext, api.IConfaceType)
+
+    >>> provider_2 = ensureInformationProvider(IFoo, IYourContext)
+
+    >>> component.getUtility(IMyContext, api.toDottedName(IFoo))
+    <Information provider IFoo at IYourContext>
+
+    >>> api.getInformationProvider(IFoo, IMyContext)
+    Traceback (most recent call last):
+    ...
+    KeyError: 'Missing information provider IFoo at IMyContext.'
+
+Complex Lookup using acquireInformationProvider
+-----------------------------------------------
+
+You can use the acquireInformationProvider function to lookup more general
+information providers. The acquisition is based on the __iro__ of the key and
+context interface. You will start within the first context looking up all key
+interface in order of the __iro__. If no information provider could be found
+the context will be switch to the next more general context. There the same
+procedure will start until an information provider could be found. If no
+information could be found a key error is raised.
+
+In our example we cannot acquire anything therefore we still expect a key error.
+
+    >>> api.acquireInformationProvider(IFoo, IMyContext) 
+    Traceback (most recent call last):
+    ...
+    KeyError: 'Missing information provider IFoo at IMyContext.'
+
+We could derive a context from IUndefinedContext. That way we could acquire the
+first provider registered to IFoo and IUndefinedContext:
+
+    >>> class IOurContext(api.IUndefinedContext):
+    ...    pass
+
+    >>> interface.alsoProvides(IOurContext, api.IConfaceType)
+
+    >>> api.getInformationProvider(IFoo, IOurContext) 
+    Traceback (most recent call last):
+    ...
+    KeyError: 'Missing information provider IFoo at IOurContext.'
+
+    >>> api.acquireInformationProvider(IFoo, IOurContext)
+    <Information provider IFoo at IUndefinedContext>
+
+The other way round we can play with key interface inheritance:
+
+    >>> class IBar(interface.Interface):
+    ...    pass
+
+    >>> interface.alsoProvides(IBar, api.IKeyfaceType)
+
+    >>> api.acquireInformationProvider(IBar) 
+    Traceback (most recent call last):
+    ...
+    KeyError: 'Missing information provider IBar at IUndefinedContext.'
+
+    >>> class IFooBar(IFoo, IBar):
+    ...    pass
+
+    >>> api.acquireInformationProvider(IFooBar) 
+    <Information provider IFoo at IUndefinedContext>
+
+If we register a new information provider to IBar and IUndefinedContext, we can
+observe the following behavior:
+
+    >>> provider_3 = ensureInformationProvider(IBar, api.IUndefinedContext)
+
+    >>> api.acquireInformationProvider(IBar)
+    <Information provider IBar at IUndefinedContext>
+
+    >>> interface.alsoProvides(IFooBar, api.IKeyfaceType)
+
+    >>> api.acquireInformationProvider(IFooBar) 
+    <Information provider IFoo at IUndefinedContext>
+
+    >>> class IBarFoo(IBar, IFoo):
+    ...    pass
+
+    >>> interface.alsoProvides(IBarFoo, api.IKeyfaceType)
+
+    >>> api.acquireInformationProvider(IBarFoo) 
+    <Information provider IBar at IUndefinedContext>
+
+But we always get the most specialized one:
+
+    >>> api.acquireInformationProvider(IBarFoo, IOurContext) 
+    <Information provider IBar at IUndefinedContext> 
+
+    >>> provider_4 = ensureInformationProvider(IBarFoo, api.IUndefinedContext)
+    >>> api.acquireInformationProvider(IBarFoo, IOurContext) 
+    <Information provider IBarFoo at IUndefinedContext>
+
+    >>> provider_5 = ensureInformationProvider(IBar, IOurContext)
+    >>> api.acquireInformationProvider(IBarFoo, IOurContext) 
+    <Information provider IBar at IOurContext>
+
+    >>> provider_6 = ensureInformationProvider(IBarFoo, IOurContext)
+    >>> api.acquireInformationProvider(IBarFoo, IOurContext) 
+    <Information provider IBarFoo at IOurContext>
+
+Complex Lookup using getInformationProvidersFor
+-----------------------------------------------
+
+Last but not least you can lookup all information provider registered for a 
+certain key interface or context interface using getInformationProvidersFor
+function.
+
+If you lookup the providers for a context interface, you will get an iterator
+that returns (keyface, provider) pairs:
+
+    >>> [i.__name__ for i,p in api.getInformationProvidersFor(IOurContext)]
+    ['IBar', 'IBarFoo']
+
+If you lookup the providers for a key interface, you will get an iterator
+which returns (conface, provider) pairs:
+
+    >>> [i.__name__ for i,p in api.getInformationProvidersFor(IBarFoo)]
+    ['IOurContext', 'IUndefinedContext']

Modified: zope.generic/trunk/src/zope/generic/face/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/face/api.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/face/api.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -20,17 +20,14 @@
 
 from zope.component import getUtilitiesFor
 from zope.component import getUtility
+from zope.interface import directlyProvidedBy
 
 from zope.generic.face import *
 from zope.generic.face.adapter import FaceForAttributeFaced
 from zope.generic.face.base import Face
-from zope.generic.face.base import GlobalInformationProvider
-from zope.generic.face.base import KeyfaceDescription
-from zope.generic.face.base import LocalInformationProvider
 from zope.generic.face.helper import toDescription
 from zope.generic.face.helper import toDottedName
 from zope.generic.face.helper import toInterface
-from zope.generic.face.metaconfigure import ensureInformationProvider
 
 
 
@@ -79,43 +76,63 @@
 
 
 
-def getNextInformationProvider(object=None, conface=None):
+def getInformationProvider(object=None, conface=IUndefinedContext):
     """Evaluate the next information provider utility for an object or keyface."""
-    
-    if conface is None:
-        conface = getConface(object, IUndefinedContext)
-        
+
     keyface = getKeyface(object)
 
     try:
-        return getUtility(conface, toDottedName(keyface))
-
+        provider = getUtility(conface, toDottedName(keyface))
+        # return only provider that is or extends a certain context.
+        if provider.conface == conface:
+            return provider
     except:
-        # try to evaluate a matching super key interface
-        for more_general_keyface in keyface.__iro__:
-            if IKeyfaceType.providedBy(more_general_keyface):
-                try:
-                    return getUtility(conface, toDottedName(more_general_keyface))
+        pass
 
-                except:
-                    pass
-        else:
-            raise
+    raise KeyError('Missing information provider %s at %s.' % (keyface.__name__, conface.__name__))
 
 
 
-def queryNextInformationProvider(object=None, conface=None, default=None):
+def queryInformationProvider(object=None, conface=IUndefinedContext, default=None):
     """Evaluate the next information provider utility for an object or keyface."""
     try:
-        return getNextInformationProvider(object, conface)
+        return getInformationProvider(object, conface)
 
     except:
         return default
 
 
 
-def getNextInformationProvidersFor(provider, default=None):
+def acquireInformationProvider(object=None, conface=IUndefinedContext):
+    """Evaluate the next information provider utility for an object or keyface."""
+        
+    keyface = getKeyface(object)
+
+    for more_general_conface in conface.__iro__:
+        for more_general_keyface in keyface.__iro__:
+            if IConfaceType.providedBy(more_general_conface) and IKeyfaceType.providedBy(more_general_keyface):
+                #print '<Lookup %s at %s >' % (more_general_keyface.__name__, more_general_conface.__name__)
+                try:
+                    return getInformationProvider(more_general_keyface, more_general_conface)
+                
+                except:
+                    pass
+
+    raise KeyError('Missing information provider %s at %s.' % (keyface.__name__, conface.__name__))
+
+
+
+
+def getInformationProvidersFor(face):
     """Evaluate all information providers of a certain information aspect."""
 
-    for name, information in getUtilitiesFor(provider):
-        yield (toInterface(name), information)
\ No newline at end of file
+    if IConfaceType.providedBy(face):
+        for name, provider in getUtilitiesFor(face):
+            yield (toInterface(name), provider)
+    
+    elif IKeyfaceType.providedBy(face):
+        for conface in [conface for conface in directlyProvidedBy(face).flattened() if IConfaceType.providedBy(conface)]:
+            yield (conface, getInformationProvider(face, conface))
+
+    else:
+        raise TypeError('KeyfaceType or ConfaceType required.', face)

Modified: zope.generic/trunk/src/zope/generic/face/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/face/base.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/face/base.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -18,21 +18,9 @@
 
 __docformat__ = 'restructuredtext'
 
-from persistent import Persistent
-from zope.app.container.contained import Contained
-from zope.app.i18n import ZopeMessageFactory as _
 from zope.interface import implements
-from zope.schema.fieldproperty import FieldProperty
 
-from zope.generic.directlyprovides.api import provides
-from zope.generic.directlyprovides.api import updateDirectlyProvided
-from zope.generic.directlyprovides.api import UpdateProvides
-
-from zope.generic.face import IAttributeFaced
 from zope.generic.face import IFace
-from zope.generic.face import IGlobalInformationProvider
-from zope.generic.face import IKeyfaceDescription
-from zope.generic.face import ILocalInformationProvider
 from zope.generic.face import IUndefinedContext
 from zope.generic.face import IUndefinedKeyface
 
@@ -88,132 +76,3 @@
     @property
     def conface(self):
         return getattr(self, '__conface__', IUndefinedContext)
-
-
-
-class BaseInformationProvider(object):
-    """Information provider mixin.
-
-    Information provider provide contextual information for key interfaces
-    (keyface). The context is defined by a context interface (conface):
-
-        >>> from zope.interface import alsoProvides
-        >>> from zope.interface import Interface
-        >>> from zope.generic.face import IConfaceType
-
-        >>> class ISpecialContext(Interface):
-        ...    pass
-
-        >>> alsoProvides(ISpecialContext, IConfaceType)
-
-    The key interface is defined by a marker interface too.
-
-        >>> from zope.generic.face import IKeyfaceType
-
-        >>> class IFoo(Interface):
-        ...    pass
-
-        >>> alsoProvides(IFoo, IKeyfaceType)
-
-    During the registration of a information provider the key interface should
-    be marked by the context interface:
-
-        >>> alsoProvides(IFoo, ISpecialContext)
-
-    This typing asserts that there will be an information provider registered
-    as utility providing the context and named by the dotted name of the
-    key interface.
-
-        >>> provider = BaseInformationProvider(ISpecialContext, IFoo)
-
-    The information provider will provide the context interface:
-
-        >>> ISpecialContext.providedBy(provider)
-        True
-
-    The information provider is related to the key interface:
-
-        >>> provider.keyface == IFoo
-        True
-        >>> provider.conface == ISpecialContext
-        True
-
-    """
-
-    def __init__(self, __conface__=None, __keyface__=None):
-        if __keyface__:
-            self.__keyface__ = __keyface__
-        
-        if __conface__:
-            self.__conface__ = __conface__
-            updateDirectlyProvided(self, __conface__)
-
-    provides('__conface__')
-
-    __keyface__ = FieldProperty(IAttributeFaced['__keyface__'])
-    __conface__ = UpdateProvides(IAttributeFaced['__conface__'])
-    
-    @property
-    def keyface(self):
-        return self.__keyface__
-
-    @property
-    def conface(self):
-        return self.__conface__
-
-    def __conform__(self, interface):
-        raise NotImplementedErro('__conform__')
-
-
-_global_information_hook = {}
-
-class GlobalInformationProvider(BaseInformationProvider):
-    """Global information provider."""
-
-    implements(IGlobalInformationProvider)
-
-    provides('__conface__')
-
-    def __conform__(self, interface):
-        try:
-            return _global_information_hook[interface](self)
-
-        except:
-            return None
-
-
-_local_information_hook = {}
-
-class LocalInformationProvider(BaseInformationProvider, Contained, Persistent):
-    """Local information provider."""
-
-    implements(ILocalInformationProvider)
-
-    provides('__conface__')
-
-    def __conform__(self, interface):
-        try:
-            return _global_information_hook[interface](self)
-
-        except:
-            return None
-
-
-
-class KeyfaceDescription(Face):
-    """Key interface description mixin."""
-
-    implements(IKeyfaceDescription)
-
-    def __init__(self, keyface, label=None, hint=None):
-        self.__keyface__ = keyface
-
-        if label is None:
-            self.label = _(keyface.__name__)
-        else:
-            self.label = label
-
-        if hint is None:
-            self.hint = _(keyface.__doc__)
-        else:
-            self.hint = hint

Modified: zope.generic/trunk/src/zope/generic/face/configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/face/configure.zcml	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/face/configure.zcml	2006-05-02 22:48:25 UTC (rev 67873)
@@ -25,19 +25,5 @@
   	  provides=".IFace"
   	  trusted="True"
   	  />
-
-  <class class=".base.GlobalInformationProvider">
-    <require
-        permission="zope.Public"
-        interface=".IFace"
-        />
-  </class>
-
-  <class class=".base.LocalInformationProvider">
-    <require
-        permission="zope.Public"
-        interface=".IFace"
-        />
-  </class>
-
+ 
 </configure>

Modified: zope.generic/trunk/src/zope/generic/face/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/face/interfaces.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/face/interfaces.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -23,15 +23,13 @@
 from zope.interface import Interface
 from zope.interface.interfaces import IInterface
 from zope.schema import Object
-from zope.schema import Text
-from zope.schema import TextLine
 
 from zope.generic.directlyprovides import IProvides
 
 
 
 class IFaceType(IInterface):
-    """Mark key or context interfaces."""
+    """Abstract type interfaces."""
 
 
 
@@ -44,7 +42,7 @@
 
 
 class IUndefinedKeyface(Interface):
-    """A unspecified key interface."""
+    """An unspecified key interface."""
 
 alsoProvides(IUndefinedKeyface, IKeyfaceType)
 
@@ -63,7 +61,7 @@
 
 
 class IUndefinedContext(Interface):
-    """A unspecified context interface."""
+    """An unspecified context interface."""
 
 alsoProvides(IUndefinedContext, IConfaceType)
 
@@ -122,40 +120,3 @@
 
 class IProvidesAttributeFaced(IAttributeFaced, IProvides):
     """Directly provide the key and context interface."""
-
-
-class IKeyfaceDescription(Interface):
-    """Describe an key interface."""
-
-    label = TextLine(title=_('Lable'))
-
-    hint = Text(title=_('Hint'))
-
-
-
-class IInformationProvider(IProvidesAttributeFaced):
-    """Provide information to a dedicated context and key interface pair.
-
-    Information provider will be registered as utility providing the context 
-    interface and named by the dotted name of the key interface.
-
-    Information providers can be extended by generic information mechanism
-    such as zope.annotation.IAnnotations simply by adding a specific marker to
-    the information provider implementation. The marker should invoke the 
-    specific information mechanism:
-    
-        classProvides(api.InformationProvider, IAttributeAnnotatable)
-
-        <class class="zope.generic.api.InformationProvider" >
-            <implements="zope.annotation.IAttributeAnnotatable" />
-        </class>
-    """
-
-
-class IGlobalInformationProvider(IInformationProvider):
-    """Global information provider."""
-
-
-
-class ILocalInformationProvider(IInformationProvider):
-    """Local information provider."""

Deleted: zope.generic/trunk/src/zope/generic/face/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/face/metadirectives.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/face/metadirectives.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -1,56 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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.
-#
-##############################################################################
-
-"""
-$Id$
-"""
-
-__docformat__ = 'restructuredtext'
-
-from zope.app.i18n import ZopeMessageFactory as _
-from zope.configuration.fields import GlobalInterface
-from zope.interface import Interface
-
-
-class IKeyfaceDirective(Interface):
-    """Key interface registration directive."""
-
-    keyface = GlobalInterface(
-        title=_('Key Interface'),
-        description=_('Interface that represents an information key.'),
-        required=False
-        )
-
-
-
-class IConfaceDirective(Interface):
-    """Context interface registration directive."""
-
-    conface = GlobalInterface(
-        title=_('Context Interface'),
-        description=_('Interface that represents an information context.'),
-        required=False
-        )
-
-
-
-class IFaceDirective(IKeyfaceDirective, IConfaceDirective):
-    """Key or context interface registration directive."""
-
-    type = GlobalInterface(
-        title=_('Type'),
-        description=_('Type a key or contex interface by a regular type or type '
-                      'an key interface and interfac providing IConfaceType.'),
-        required=False
-        )

Modified: zope.generic/trunk/src/zope/generic/face/testing.py
===================================================================
--- zope.generic/trunk/src/zope/generic/face/testing.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/face/testing.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -33,7 +33,6 @@
 
 
 
-
 ################################################################################
 #
 # Public Test implementations
@@ -74,7 +73,6 @@
     provideAdapter(zope.generic.face.adapter.FaceForAttributeFaced ,
         provides=IFace)
 
-    # register the directive of this package
     import zope.generic.face
     XMLConfig('meta.zcml', zope.generic.face)()
 

Modified: zope.generic/trunk/src/zope/generic/factory/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/README.txt	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/factory/README.txt	2006-05-02 22:48:25 UTC (rev 67873)
@@ -25,12 +25,6 @@
     >>> class IMyInstance(Interface):
     ...     pass
 
-    >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IMyInstance"
-    ...     />
-    ... ''') 
-
 Then we have to implement an example class with dedicated initalization
 parameters:
 
@@ -53,15 +47,15 @@
     ...    c = TextLine(required=False, default=u'c default')
 
     >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IMyParameter"
-    ...     type="zope.generic.configuration.IConfiguration"
+    ... <generic:interface
+    ...     interface="example.IMyParameter"
+    ...     type="zope.generic.configuration.IConfigurationType"
     ...     />
     ... ''') 
 
 During the creation process we can invoke initializer operations. In our example
 we are defining a simple handler, but you could use object providing IOperation
-or interfaces providing IOperationContext too:
+or interfaces providing IOperationType too:
 
     >>> def init_handler(context, *pos, **kws):
     ...    print 'initializing'
@@ -103,10 +97,7 @@
 registration:
 
     >>> from zope.component.eventtesting import getEvents, clearEvents
-    
-    >>> events = getEvents()
-    >>> len(events)
-    5
+
     >>> clearEvents()
 
     >>> from zope.generic.face.api import toDottedName
@@ -115,7 +106,9 @@
     >>> util.keyface == IMyInstance
     True
 
-    >>> util = component.getUtility(api.IFactory, name=toDottedName(IMyInstance))
+    >>> from zope.generic.face import IUndefinedContext
+
+    >>> util = component.getUtility(IUndefinedContext, name=toDottedName(IMyInstance))
     >>> util.keyface == IMyInstance
     True
 

Modified: zope.generic/trunk/src/zope/generic/factory/adapter.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/adapter.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/factory/adapter.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -22,7 +22,7 @@
 from zope.interface import implements
 
 from zope.generic.informationprovider.api import queryInformation
-from zope.generic.informationprovider.api import getNextInformationProvider
+from zope.generic.informationprovider.api import getInformationProvider
 from zope.generic.face import IFaced
 from zope.generic.operation import IOperationConfiguration
 

Modified: zope.generic/trunk/src/zope/generic/factory/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/api.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/factory/api.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -20,7 +20,7 @@
 
 from zope import component
 
-from zope.generic.informationprovider.api import getNextInformationProvider
+from zope.generic.informationprovider.api import getInformationProvider
 from zope.generic.informationprovider.api import queryInformation
 from zope.generic.face.api import toDottedName
 from zope.generic.operation import IOperationConfiguration
@@ -38,7 +38,7 @@
 
 def createParameter(keyface):
     """Evaluate initializer parameters."""
-    provider = getNextInformationProvider(keyface, IFactory)
+    provider = getInformationProvider(keyface)
     config = queryInformation(provider, IOperationConfiguration)
     if config:
         return config.input

Modified: zope.generic/trunk/src/zope/generic/factory/factory.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/factory.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/factory/factory.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -26,7 +26,7 @@
 from zope.generic.configuration.api import parameterToConfiguration
 from zope.generic.configuration.api import configuratonToDict
 from zope.generic.directlyprovides.api import updateDirectlyProvided
-from zope.generic.informationprovider.api import getNextInformationProvider
+from zope.generic.informationprovider.api import getInformationProvider
 from zope.generic.informationprovider.api import provideInformation
 from zope.generic.informationprovider.api import queryInformation
 from zope.generic.face import IAttributeFaced
@@ -34,7 +34,7 @@
 from zope.generic.face.api import Face
 from zope.generic.operation import IOperationConfiguration
 
-from zope.generic.factory import IFactory
+from zope.generic.factory import IFactoryType
         
 
 
@@ -119,7 +119,6 @@
         >>> registerDirective('''
         ... <generic:informationProvider
         ...     keyface="example.IMyInstance"
-        ...     conface="zope.generic.factory.IFactory"
         ...     >
         ...    <information
         ...       keyface="zope.generic.operation.IOperationConfiguration"
@@ -155,9 +154,9 @@
         ...    c = TextLine(required=False, default=u'c default')
 
         >>> registerDirective('''
-        ... <generic:face
-        ...     keyface="example.IMyParameter"
-        ...     type="zope.generic.configuration.IConfiguration"
+        ... <generic:interface
+        ...     interface="example.IMyParameter"
+        ...     type="zope.generic.configuration.IConfigurationType"
         ...     />
         ... ''') 
 
@@ -168,7 +167,6 @@
         >>> registerDirective('''
         ... <generic:informationProvider
         ...     keyface="example.IMyInstance"
-        ...     conface="zope.generic.factory.IFactory"
         ...     >
         ...    <information
         ...       keyface="zope.generic.operation.IOperationConfiguration"
@@ -280,7 +278,7 @@
     def __config(self):
         if '_Factory__config' not in self.__dict__:
             try:
-                provider = getNextInformationProvider(self.keyface, IFactory)
+                provider = getInformationProvider(self.keyface)
                 self.__dict__['_Factory__config'] = queryInformation(provider, IOperationConfiguration)
 
             except:

Modified: zope.generic/trunk/src/zope/generic/factory/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/interfaces.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/factory/interfaces.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -18,14 +18,9 @@
 
 __docformat__ = 'restructuredtext'
 
-from zope.interface import alsoProvides
-from zope.interface import Interface
+from zope.generic.face import IKeyfaceType
 
-from zope.generic.face import IConfaceType
 
 
-
-class IFactory(Interface):
-    """Factory context."""
-
-alsoProvides(IFactory, IConfaceType)
+class IFactoryType(IKeyfaceType):
+    """Type key interfaces that provide a factory for its creation."""

Modified: zope.generic/trunk/src/zope/generic/factory/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/metaconfigure.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/factory/metaconfigure.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -21,41 +21,41 @@
 from types import ModuleType
 
 from zope.app.component.metaconfigure import proxify
-from zope import component
+from zope.component import IFactory
+from zope.component import provideUtility
+from zope.component.interface import provideInterface
 from zope.configuration.exceptions import ConfigurationError
 from zope.security.checker import CheckerPublic
 from zope.security.checker import InterfaceChecker
 
 from zope.generic.face import IKeyfaceType
+from zope.generic.face import IUndefinedContext
 from zope.generic.face.api import toDescription
 from zope.generic.face.api import toDottedName
-from zope.generic.face.api import getNextInformationProvider
-from zope.generic.face.metaconfigure import keyfaceDirective
+from zope.generic.face.api import getInformationProvider
 from zope.generic.informationprovider.api import provideInformation
 from zope.generic.informationprovider.metaconfigure import InformationProviderDirective
+from zope.generic.operation import IOperationConfiguration
 from zope.generic.operation.api import assertOperation
-from zope.generic.operation.api import provideOperationConfiguration
 
-from zope.generic.factory import IFactory
+from zope.generic.factory import IFactoryType
 from zope.generic.factory.factory import Factory
 
 
 
 def factoryDirective(_context, keyface, class_, operations=(), input=None,
-                     providesFace=False, notifyCreated=False, storeInput=False,
-                     label=None, hint=None):
+                     providesFace=False, notifyCreated=False, storeInput=False):
     """Register a public factory."""
     # preconditions
     if isinstance(class_, ModuleType):
         raise ConfigurationError('Implementation attribute must be a class')
 
-    type = IFactory
-    # assert keyface type
-    keyfaceDirective(_context, keyface, type)
+    # provide type as soon as possilbe
+    if not IFactoryType.providedBy(keyface):
+        provideInterface(None, keyface, IFactoryType) 
 
-
     # set label and hint
-    label, hint = toDescription(keyface, label, hint)
+    label, hint = toDescription(keyface)
 
     # how to invoke the factory
     if operations and input:
@@ -70,28 +70,31 @@
     else:
         mode = 0
 
-    if mode and providesFace:
-        output = keyface
-
     # create and proxy type factory
     factory = Factory(class_, keyface, providesFace, storeInput, 
                       notifyCreated, label, hint, mode) 
-    proxied = proxify(factory, InterfaceChecker(component.IFactory, CheckerPublic))
+    proxied = proxify(factory, InterfaceChecker(IFactory, CheckerPublic))
     
     _context.action(
         discriminator = ('provideUtility', keyface),
-        callable = component.provideUtility,
-        args = (proxied, component.IFactory, toDottedName(keyface)),
+        callable = provideUtility,
+        args = (proxied, IFactory, toDottedName(keyface)),
         )
 
     if mode != 0:
+        # does the output provide the keyface?
+        output = None
+        if providesFace:
+            output = keyface
+
+        # register for undefined context
+        conface = IUndefinedContext
+
+        # register the operatio using the information provider directive
+        directive = InformationProviderDirective(_context, keyface, conface)
+    
         # create operation wrapper
         operation = assertOperation(operations, keyface, input, output)
-
-        keyfaceDirective(_context, keyface, type)
-
-        _context.action(
-            discriminator = ('provideOperationConfiguration', keyface),
-            callable = provideOperationConfiguration,
-            args = (keyface, operation, type, input, output),
-            )
+        
+        directive.information(_context, keyface=IOperationConfiguration, 
+            configuration={'operation': operation, 'input': input, 'output': output})

Modified: zope.generic/trunk/src/zope/generic/factory/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/metadirectives.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/factory/metadirectives.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -23,8 +23,9 @@
 from zope.configuration.fields import GlobalObject
 from zope.interface import Interface
 
-from zope.generic.informationprovider.metadirectives import IBaseInformationProviderDirective
-from zope.generic.operation.metadirectives import IBaseOperationDirective
+from zope.generic.informationprovider.metadirectives import IKeyfaceDirective
+from zope.generic.operation.metadirectives import IInputDirective
+from zope.generic.operation.metadirectives import IOperationsDirective
 
 
 class IBaseFactoryDirective(Interface):
@@ -60,7 +61,7 @@
         )
 
 
-class IFactoryDirective(IBaseInformationProviderDirective, IBaseFactoryDirective, IBaseOperationDirective):
+class IFactoryDirective(IKeyfaceDirective, IBaseFactoryDirective, IOperationsDirective, IInputDirective):
     """Register a public factory.
 
     The factory will be registered as information provider utility within

Modified: zope.generic/trunk/src/zope/generic/handler/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/handler/README.txt	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/handler/README.txt	2006-05-02 22:48:25 UTC (rev 67873)
@@ -14,15 +14,15 @@
     >>> class IFoo(interface.Interface):
     ...    """The key interface."""
 
-    >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IFoo"
+    ... <generic:interface
+    ...     interface="example.IFoo"
+    ...     type="zope.generic.face.IKeyfaceType"
     ...     />
     ... ''')
 
 During the notification process we invoke the declared operations. In our example
 we are defining a simple handler, but you could use object providing IOperation
-or interfaces providing IOperationContext too:
+or interfaces providing IOperationType too:
 
     >>> def simplehandler(context, event):
     ...    print 'Guguseli!'

Modified: zope.generic/trunk/src/zope/generic/handler/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/handler/metaconfigure.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/handler/metaconfigure.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -20,7 +20,6 @@
 
 from zope.component.zcml import subscriber
 
-from zope.generic.face import IKeyfaceType
 from zope.generic.operation.api import assertOperation
 
 
@@ -32,7 +31,7 @@
         raise NotImplementedError('Missing feature: You cannot use the input attribute yet.')
 
     # evaluate the operation
-    operation = assertOperation(operations, keyface, input, None)
+    operation = assertOperation(operations, None, input, None)
 
     def handler(component, event):
         operation(component, event)

Modified: zope.generic/trunk/src/zope/generic/handler/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/handler/metadirectives.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/handler/metadirectives.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -22,13 +22,14 @@
 from zope.configuration.fields import GlobalInterface
 from zope.interface import Interface
 
-from zope.generic.face.metadirectives import IKeyfaceDirective
-from zope.generic.operation.metadirectives import IBaseOperationDirective
+from zope.generic.informationprovider.metadirectives import IKeyfaceDirective
+from zope.generic.operation.metadirectives import IOperationsDirective
+from zope.generic.operation.metadirectives import IInputDirective
 
 
 
-class IBaseHandlerDirective(Interface):
-    """Base handler directive."""
+class IEventDirective(Interface):
+    """Event directive."""
 
     event = GlobalInterface(
         title=_('Event'),
@@ -37,5 +38,5 @@
         )
 
 
-class IHandlerDirective(IKeyfaceDirective, IBaseHandlerDirective, IBaseOperationDirective):
+class IHandlerDirective(IKeyfaceDirective, IOperationsDirective, IInputDirective, IEventDirective):
     """Provide trusted locatable handler that invoke operations."""

Modified: zope.generic/trunk/src/zope/generic/informationprovider/NEW_README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/NEW_README.txt	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/informationprovider/NEW_README.txt	2006-05-02 22:48:25 UTC (rev 67873)
@@ -22,28 +22,6 @@
     >>> class IUserContext(interface.Interface):
     ...     """Store log user information."""
 
-This specialized information interface has to be registered later by 
-face-directive:
-
-    >>> registerDirective('''
-    ... <generic:face
-    ...     conface="example.ISupplierContext"
-    ...     />
-    ... ''') 
-
-    >>> registerDirective('''
-    ... <generic:face
-    ...     conface="example.IUserContext"
-    ...     />
-    ... ''') 
-
-    >>> from zope.generic.face import IConfaceType
-
-    >>> IConfaceType.providedBy(ISupplierContext)
-    True
-    >>> IConfaceType.providedBy(IUserContext)
-    True
-
 Within those contexts we like to provide log configuration information. In our
 example logger frame work  we need to configure a specific log:
 
@@ -62,18 +40,18 @@
 be done the following way:
 
     >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.ILogConfiguration"
-    ...     type="zope.generic.configuration.IConfiguration"
+    ... <generic:interface
+    ...     interface="example.ILogConfiguration"
+    ...     type="zope.generic.configuration.IConfigurationType"
     ...     />
     ... ''')
 
     >>> from zope.generic.face import IKeyfaceType
-    >>> from zope.generic.configuration import IConfiguration
+    >>> from zope.generic.configuration import IConfigurationType
 
     >>> IKeyfaceType.providedBy(ILogConfiguration)
     True
-    >>> IConfiguration.providedBy(ILogConfiguration)
+    >>> IConfigurationType.providedBy(ILogConfiguration)
     True
 
 Components that are using our log framework can provide their own log 
@@ -81,18 +59,19 @@
 provider. That has to be done by information that is set for an key interface
 within a dedicated context (ISupplierContext and IUserContext in our example).
 For all components that will not provide their own log configuration information
-we should provide default configuration within both contexts.
+we should provide default configuration within both contexts. This can be done
+by ommiting the keyface attribute of information provider directive. This
+assigns an information provider to IUndefinedKeyface
 
 You can provide all configuration value, but at least you have to provide
 the required ones.
 
     >>> from zope.generic.configuration.api import ConfigurationData
 
-    >>> supplier_default = ConfigurationData(ILogConfiguration, {'header': 'Supplier', 'timeFormat': '%y.%m.%d'})
+    >>> supplier_default = {'header': 'Supplier', 'timeFormat': '%y.%m.%d'}
 
     >>> registerDirective('''
     ... <generic:informationProvider
-    ...     keyface="zope.generic.face.IUndefinedKeyface"
     ...     conface="example.ISupplierContext"
     ...     >
     ...   <information
@@ -104,11 +83,10 @@
 
 Not provided optional data are taken from the default field values:
 
-    >>> user_default = ConfigurationData(ILogConfiguration, {})
+    >>> user_default = {}
 
     >>> registerDirective('''
     ... <generic:informationProvider
-    ...     keyface="zope.generic.face.IUndefinedKeyface"
     ...     conface="example.IUserContext"
     ...     >
     ...   <information
@@ -120,13 +98,15 @@
 
 You can retrieve this configurations the following way:
 
-    >>> provider_for_nokeyface_at_suppliercontext = api.queryNextInformationProvider(conface=ISupplierContext)
-    >>> api.getInformation(provider_for_nokeyface_at_suppliercontext, ILogConfiguration) is supplier_default
-    True
+    >>> provider_for_nokeyface_at_suppliercontext = api.getInformationProvider(conface=ISupplierContext)
+    >>> data = api.getInformation(provider_for_nokeyface_at_suppliercontext, ILogConfiguration)
+    >>> data.header, data.timeFormat
+    ('Supplier', '%y.%m.%d')
 
-    >>> provider_for_nokeyface_at_usercontext = api.queryNextInformationProvider(conface=IUserContext)
-    >>> api.getInformation(provider_for_nokeyface_at_usercontext, ILogConfiguration) is user_default
-    True
+    >>> provider_for_nokeyface_at_usercontext = api.getInformationProvider(conface=IUserContext)
+    >>> data = api.getInformation(provider_for_nokeyface_at_usercontext, ILogConfiguration)
+    >>> data.header, data.timeFormat
+    ('General', '%d.%m.%y')
 
 Last we have to define our application - the log itself.
 
@@ -152,7 +132,7 @@
     ...     def __call__(self, message):
     ...         keyface = api.getKeyface(self.context)
     ...         conface = api.getConface(self)
-    ...         provider = api.getNextInformationProvider(keyface, conface)
+    ...         provider = api.acquireInformationProvider(keyface, conface)
     ...         logconfig = api.getInformation(provider, ILogConfiguration)
     ...         return '%s: %s, %s' % (logconfig.header, message, 
     ...                               time.strftime(logconfig.timeFormat))
@@ -238,7 +218,7 @@
     >>> entry = user_log('Guguseli'); entry
     Traceback (most recent call last):
     ...
-    ComponentLookupError: (<InterfaceClass example.IUserContext>, 'example.IMy')
+    KeyError: 'Missing information provider IMy at IUserContext.'
 
 If we like to acquire from the default user context configuration, we have
 to derive our marker from IUndefinedKeyface.

Modified: zope.generic/trunk/src/zope/generic/informationprovider/PUBLICATION.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/PUBLICATION.cfg	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/informationprovider/PUBLICATION.cfg	2006-05-02 22:48:25 UTC (rev 67873)
@@ -7,5 +7,4 @@
 Description:
         You can register information providers to dedicated key interfaces.
         Afterwards you can extend those information provider by informations
-        such as annotation or configurations. There are an api to handle
-        those informations uniquely. 
+        such as annotation or configurations. 

Modified: zope.generic/trunk/src/zope/generic/informationprovider/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/README.txt	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/informationprovider/README.txt	2006-05-02 22:48:25 UTC (rev 67873)
@@ -1,17 +1,17 @@
-=================
-Generic Component
-=================
+============================
+Generic Information Provider
+============================
 
 The key interface (see zope.generic.face) can be used to lookup corresponding
-information providers. This package offers a way to implement information
-providers generically.
+information providers. This package offers a way to register information
+providers and theirs information by a zcml directive.
 
-You can register different information providers to the same key interface. An
-information provider encapsulates a certain information aspect of the key 
-interface. The relation between information providers of a key interface to
-components providing the same key interface is similar to the object class 
-relation except that each informatio aspect follows its own information 
-acquisition.
+You can register different contextual information providers for the same 
+key interface. An information provider encapsulates a certain contextual 
+information aspect of the key interface. The relation between information 
+providers of a key interface to components providing the same key interface is
+similar to the object class relation except that we have a contextual separation
+of the information.
 
 You can attache generic informations such as annotations or configurations
 to an certain information provider.
@@ -27,89 +27,68 @@
 
 Similar atomic informations defined by an annotation key or a 
 configuration schemas can be reused by different information providers. So
-the identical information types will receive a contextual meaning that is related
-to information provider type.
+the identical information types receive theirs contextual meaning within a
+information provider.
 
 Information Provider
 --------------------
 
 You can use the information provider directive to register an information 
-provider as utiliy with an interface extending IInformationProvider and a
-dotted name of an corresponding key interface as utility name:
+provider. For that purpose we need a key and a context interface:
 
     >>> class ISpecialContext(interface.Interface):
     ...    pass
 
-    >>> registerDirective('''
-    ... <generic:face
-    ...     conface="example.ISpecialContext"
-    ...     />
-    ... ''') 
-
     >>> from zope.interface import Interface
-    >>> class IFooMarker(Interface):
+    >>> class IMyFoo(Interface):
     ...    pass
 
     >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IFooMarker"
-    ...     />
-    ... ''') 
-
-    >>> registerDirective('''
     ... <generic:informationProvider
-    ...     keyface="example.IFooMarker"
+    ...     keyface="example.IMyFoo"
     ...     conface="example.ISpecialContext"
-    ...     label='Foo Specials' hint='Bla bla foo.'
     ...     />
     ... ''')
 
 After a registration the information provider can be looked up.
-All information provider with the same interface can be gotten by the 
-getNextInformationProvidersFor function:
+All information provider with the same context interface can be looked up by the 
+getInformationProvidersFor function:
 
-    >>> from zope.component.eventtesting import getEvents, clearEvents
-    >>> len(getEvents())
-    6
-    >>> clearEvents()
-
-    >>> listing = list(api.getNextInformationProvidersFor(ISpecialContext))
+    >>> listing = list(api.getInformationProvidersFor(ISpecialContext))
     >>> len(listing) is 1
     True
     >>> [(key.__name__, value) for key, value in listing]
-    [('IFooMarker', <zope.generic.face.base.GlobalInformationProvider ...>)]
+    [('IMyFoo', <zope.generic.informationprovider.base.GlobalInformationProvider ...>)]
 
 A single information provider can be retrieved by the get- or 
-queryNextInformationProvider function:
+queryInformationProvider function:
 
-    >>> info = api.getNextInformationProvider(IFooMarker, ISpecialContext)
-    >>> info = api.queryNextInformationProvider(IFooMarker, ISpecialContext)
+    >>> provider = api.getInformationProvider(IMyFoo, ISpecialContext)
+    >>> provider = api.queryInformationProvider(IMyFoo, ISpecialContext)
 
-    >>> listing[0][1] == info
+    >>> listing[0][1] is provider
     True
-    >>> listing[0][0] == IFooMarker
+    >>> listing[0][0] is IMyFoo
     True
 
-    >>> info.keyface == IFooMarker
+    >>> provider.keyface == IMyFoo
     True
-    >>> ISpecialContext.providedBy(info)
+    >>> ISpecialContext.providedBy(provider)
     True
-    >>> info.label = u'Foo Specials'
-    >>> info.hint = u'Bla bla foo.'
 
 If no information provider is available for a certain interface the default
 value is returned. If no default is defined None is returned:
 
-    >>> class IBarMarker(Interface):
+    >>> class IMyBar(Interface):
     ...    pass
 
     >>> default = object()
-    >>> info = api.queryNextInformationProvider(IBarMarker, ISpecialContext, default)
-    >>> info is default
+    >>> provider = api.queryInformationProvider(IMyBar, ISpecialContext, default)
+    >>> provider is default
     True
 
-    >>> info = api.queryNextInformationProvider(IBarMarker, ISpecialContext)
-    >>> info is None
+    >>> provider = api.queryInformationProvider(IMyBar, ISpecialContext)
+    >>> provider is None
     True
 
 Information providers are extentable by informations
@@ -122,7 +101,7 @@
 additional informations in a well-known manner. At the moment there are no 
 configurations:
 
-    >>> api.queryInformation(info, 'example.my_annotation') is None
+    >>> api.queryInformation(provider, 'example.my_annotation') is None
     True
 
 Information providers are configurable. The configurations mechanism is used 
@@ -135,24 +114,24 @@
     ...     my = TextLine(title=u'My')
 
     >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IMyConfiguration"
-    ...     type="zope.generic.configuration.IConfiguration"
+    ... <generic:interface
+    ...     interface="example.IMyConfiguration"
+    ...     type="zope.generic.configuration.IConfigurationType"
     ...     />
     ... ''') 
 
-    >>> from zope.generic.configuration.api import IConfiguration
+    >>> from zope.generic.configuration.api import IConfigurationType
 
-    >>> IConfiguration.providedBy(IMyConfiguration)
+    >>> IConfigurationType.providedBy(IMyConfiguration)
     True
 
 At the moment there are no configurations:
 
-    >>> api.queryInformation(info, IMyConfiguration) is None
+    >>> api.queryInformation(provider, IMyConfiguration) is None
     True
 
 We now can use an annotation and a configuration to extend our information
-provider of the key interface IFooMarker.
+provider of the key interface IMyFoo.
 
 The annotation and configuration subdirective of the information provider
 directive provides a mechanism to register further informations to an 
@@ -165,9 +144,8 @@
 
     >>> registerDirective('''
     ... <generic:informationProvider
-    ...     keyface="example.IFooMarker"
+    ...     keyface="example.IMyFoo"
     ...     conface="example.ISpecialContext"
-    ...     label='Foo Specials' hint='Bla bla foo.'
     ...     >
     ...        <information
     ...            key="example.my_annotation"
@@ -180,211 +158,15 @@
     ...     </generic:informationProvider>
     ... ''')
 
-    >>> len(getEvents())
-    2
-    >>> clearEvents()
-
-    >>> info = api.queryNextInformationProvider(IFooMarker, ISpecialContext)
-    >>> api.queryInformation(info, 'example.my_annotation') is my_annotation
+    >>> provider = api.queryInformationProvider(IMyFoo, ISpecialContext)
+    >>> api.queryInformation(provider, 'example.my_annotation') is my_annotation
     True
 
-    >>> info = api.queryNextInformationProvider(IFooMarker, ISpecialContext)
-    >>> api.queryInformation(info, IMyConfiguration) is my_configuration
+    >>> provider = api.queryInformationProvider(IMyFoo, ISpecialContext)
+    >>> api.queryInformation(provider, IMyConfiguration) is my_configuration
     True
 
+Complex information provider lookup using acquireInformationProvider
+--------------------------------------------------------------------
 
-Configurations
----------------
-
-Configurations is a container of configuration data. Configuration data are
-defined by an schema which is providing IConfiguration. The configuration
-data itself has to provide the schema that is used to reference it.
-
-    >>> from zope.schema import TextLine
-        
-    >>> class IMyConfiguration(interface.Interface):
-    ...     my = TextLine(title=u'My')
-
-    >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IMyConfiguration"
-    ...     type="zope.generic.configuration.IConfiguration"
-    ...     />
-    ... ''') 
-
-    >>> len(getEvents())
-    1
-    >>> clearEvents()
-
-    >>> from zope.generic.configuration.api import IConfiguration
-    >>> IConfiguration.providedBy(IMyConfiguration)
-    True
- 
-Regularly local configurations are provided by objects marked with
-IAttributeConfigurations automatically:
-
-    >>> from zope.interface import implements
-    >>> from zope.generic.configuration.api import IAttributeConfigurable
-
-    >>> class Foo(object):
-    ...    implements(IAttributeConfigurable)
-
-    >>> foo = Foo()
-    >>> IAttributeConfigurable.providedBy(foo)
-    True
-
-Now you can adapt you to IConfigurations:
-
-    >>> from zope.generic.configuration.api import IConfigurations
-
-    >>> configurations = IConfigurations(foo)
-    >>> IConfigurations.providedBy(configurations)
-    True
-
-At the beginning the IConfigurations storage does not exists:
-
-    >>> configurations.__nonzero__()
-    False
-
-Configuration data will be stored under an key interface within the
-configurations. Such a configuration schema defines its configuration
-data:
-
-    >>> from zope.interface import Interface
-    >>> from zope.schema import TextLine
-    
-    >>> class IFooConfiguration(Interface):
-    ...    foo = TextLine(title=u'Foo')
-    ...    optional = TextLine(title=u'Optional', required=False, default=u'Bla')
-
-The configuration schema is a regular schema, but it has to be typed
-by IConfiguration (Regularly done by the configuration directive):
-
-    >>> from zope.interface import directlyProvides
-
-    >>> directlyProvides(IFooConfiguration, IConfiguration)
-    >>> IConfiguration.providedBy(IFooConfiguration)
-    True
-
-The configurations provides a regular dictionary api by the UserDictMixin
-(like AttributeAnnotations). This mixin bases on the following methods:
-
-    >>> configurations[IFooConfiguration]
-    Traceback (most recent call last):
-    ...
-    KeyError: <InterfaceClass example.IFooConfiguration>
-
-    >>> del configurations[IFooConfiguration]
-    Traceback (most recent call last):
-    ...
-    KeyError: <InterfaceClass example.IFooConfiguration>
-
-    >>> configurations.keys()
-    []
-
-... if a value might be set to the configurations it must provide the 
-configuration schema itself. This key interface must provide IConfiguration:
-
-    >>> class IBarConfiguration(Interface):
-    ...    bar = TextLine(title=u'Bar')
-
-    >>> configurations[IBarConfiguration] = object()
-    Traceback (most recent call last):
-    ...
-    KeyError: 'Interface key IBarConfiguration does not provide IConfiguration.'
-
-    >>> configurations[IFooConfiguration] = object()
-    Traceback (most recent call last):
-    ...
-    ValueError: Value does not provide IFooConfiguration.
-
-Furthermore there is an update method that can be used to update a specific
-configuration. This method can be only used if a configuration already exists:
-
-    >>> configurations.update(IFooConfiguration, {'foo': u'Foo!'})
-    Traceback (most recent call last):
-    ...
-    KeyError: <InterfaceClass example.IFooConfiguration>
-
-You can create valid configuration data using the generic ConfigurationData
-implementation and a configuration schema:
-
-    >>> from zope.generic.configuration.api import ConfigurationData
-
-    >>> data = ConfigurationData(IFooConfiguration, {'foo': u'Foo!'})
-
-    >>> configurations[IFooConfiguration] = data
-
-The setting of the configuration is notified by a object configured event if 
-the parent has a location an the parent's parent is not None:
-
-    >>> from zope.generic.configuration.api import IObjectConfiguredEvent
-
-    >>> events = getEvents()
-    >>> len(events)
-    0
-
-    >>> from zope.location import Location
-    >>> parent = Location()
-    >>> configurations.__parent__ = parent
-    
-    >>> configurations[IFooConfiguration] = data
-    >>> events = getEvents()
-    >>> len(events)
-    0
-
-    >>> parent.__parent__ = Location()
-    >>> configurations[IFooConfiguration] = data
-    >>> events = getEvents()
-    >>> len(events)
-    1
-
-    >>> event = events.pop()
-    >>> IObjectConfiguredEvent.providedBy(event)
-    True
-    >>> [(key.__name__, value) for key, value in event.items()]
-    [('IFooConfiguration', {'foo': u'Foo!', 'optional': u'Bla'})]
-
-If the configuration data is set the first time an oobtree storage is set
-to the __configurations__ attribute of the context:
-
-    >>> configurations.__nonzero__()
-    True
-
-    >>> IFooConfiguration in configurations
-    True
-
-    >>> configurations[IFooConfiguration] == data
-    True
-
-    >>> [iface.__name__ for iface in configurations.keys()]
-    ['IFooConfiguration']
-
-You should update a configuration using the update method instead of setting
-new configuration data. If the change differs from the configuration an object
-configuration modified event is notify else not:
-
-    >>> clearEvents()
-    >>> configurations.update(IFooConfiguration, {'foo': u'Bar!'})
-    >>> events = getEvents()
-    >>> len(events)
-    1
-    >>> event = events.pop()
-    >>> [(key.__name__, value) for key, value in event.items()]
-    [('IFooConfiguration', {'foo': u'Bar!'})]
-
-Also the deletion is notified by an empty dict:
-
-    >>> clearEvents()
-
-    >>> del configurations[IFooConfiguration]
-    >>> IFooConfiguration in configurations
-    False
-
-    >>> events = getEvents()
-    >>> len(events)
-    1
-    >>> event = events.pop()
-    >>> [(key.__name__, value) for key, value in event.items()]
-    [('IFooConfiguration', {})]
-
+see zope.generic.face README.txt
\ No newline at end of file

Modified: zope.generic/trunk/src/zope/generic/informationprovider/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/api.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/informationprovider/api.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -19,25 +19,30 @@
 __docformat__ = 'restructuredtext'
 
 from zope.annotation import IAnnotations
+from zope.generic.face.api import acquireInformationProvider
 from zope.generic.face.api import getConface
+from zope.generic.face.api import getInformationProvider
+from zope.generic.face.api import getInformationProvidersFor
 from zope.generic.face.api import getKeyface
-from zope.generic.face.api import getNextInformationProvider
-from zope.generic.face.api import getNextInformationProvidersFor
-from zope.generic.face.api import queryNextInformationProvider
+from zope.generic.face.api import queryInformationProvider
 from zope.generic.face.api import toDottedName
 from zope.generic.face.api import toInterface
 
 from zope.generic.configuration import IConfigurations
-from zope.generic.configuration import IConfiguration
+from zope.generic.configuration import IConfigurationType
 from zope.generic.configuration.api import ConfigurationData
 
 from zope.generic.informationprovider import *
+from zope.generic.informationprovider.base import GlobalInformationProvider
+from zope.generic.informationprovider.base import LocalInformationProvider
+from zope.generic.informationprovider.base import UserDescription
+from zope.generic.informationprovider.metaconfigure import ensureInformationProvider
 
 
 
 def getInformation(context, informationkey):
     """Evaluate an information by a keyface (string or key keyface)."""
-    if IConfiguration.providedBy(informationkey):
+    if IConfigurationType.providedBy(informationkey):
         return informationkey(IConfigurations(context))
 
     else:
@@ -58,7 +63,7 @@
 def provideInformation(context, informationkey, information):
     """Set an information to a context using a keyface (string or key interface)."""
 
-    if IConfiguration.providedBy(informationkey):
+    if IConfigurationType.providedBy(informationkey):
         if type(information) is dict:
             information = ConfigurationData(informationkey, information)
     
@@ -72,7 +77,7 @@
 def deleteInformation(context, informationkey):
     """Delete an information of a context using a keyface (string or key interface)."""
 
-    if IConfiguration.providedBy(informationkey):
+    if IConfigurationType.providedBy(informationkey):
         del IConfigurations(context)[informationkey]
     
     else:

Added: zope.generic/trunk/src/zope/generic/informationprovider/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/base.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/informationprovider/base.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -0,0 +1,163 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from persistent import Persistent
+from zope.annotation import IAnnotations
+from zope.annotation.attribute import AttributeAnnotations
+from zope.app.container.contained import Contained
+from zope.app.i18n import ZopeMessageFactory as _
+from zope.interface import alsoProvides
+from zope.interface import implements
+from zope.schema.fieldproperty import FieldProperty
+
+from zope.generic.configuration import IConfigurations
+from zope.generic.configuration.api import AttributeConfigurations
+from zope.generic.directlyprovides.api import provides
+from zope.generic.directlyprovides.api import updateDirectlyProvided
+from zope.generic.directlyprovides.api import UpdateProvides
+
+from zope.generic.informationprovider import IInformationProvider
+from zope.generic.informationprovider import IGlobalInformationProvider
+from zope.generic.informationprovider import IUserDescription
+from zope.generic.informationprovider import ILocalInformationProvider
+
+
+
+class BaseInformationProvider(object):
+    """Information provider mixin.
+
+    Information provider provide contextual information for key interfaces
+    (keyface). The context is defined by a context interface (conface):
+
+        >>> from zope.interface import alsoProvides
+        >>> from zope.interface import Interface
+        >>> from zope.generic.face import IConfaceType
+
+        >>> class ISpecialContext(Interface):
+        ...    pass
+
+        >>> alsoProvides(ISpecialContext, IConfaceType)
+
+    The key interface is defined by a marker interface too.
+
+        >>> from zope.generic.face import IKeyfaceType
+
+        >>> class IFoo(Interface):
+        ...    pass
+
+        >>> alsoProvides(IFoo, IKeyfaceType)
+
+    During the registration of a information provider the key interface should
+    be marked by the context interface:
+
+        >>> alsoProvides(IFoo, ISpecialContext)
+
+    This typing asserts that there will be an information provider registered
+    as utility providing the context and named by the dotted name of the
+    key interface.
+
+        >>> provider = BaseInformationProvider(ISpecialContext, IFoo)
+
+    The information provider will provide the context interface:
+
+        >>> ISpecialContext.providedBy(provider)
+        True
+
+    The information provider is related to the key interface:
+
+        >>> provider.keyface == IFoo
+        True
+        >>> provider.conface == ISpecialContext
+        True
+
+    """
+
+    implements(IInformationProvider)
+
+    def __init__(self, __conface__=None, __keyface__=None):
+        if __keyface__:
+            self.__keyface__ = __keyface__
+        
+        if __conface__:
+            self.__conface__ = __conface__
+            updateDirectlyProvided(self, __conface__)
+        
+        # mark the key interface by the context
+        alsoProvides(self.__keyface__, self.__conface__)
+
+    provides('__conface__')
+
+    __keyface__ = FieldProperty(IInformationProvider['__keyface__'])
+    __conface__ = UpdateProvides(IInformationProvider['__conface__'])
+    
+    @property
+    def keyface(self):
+        return self.__keyface__
+
+    @property
+    def conface(self):
+        return self.__conface__
+
+    def __conform__(self, interface):
+
+        if interface == IConfigurations:
+            return AttributeConfigurations(self)
+
+        elif interface == IAnnotations:
+            return AttributeAnnotations(self)
+            
+
+
+
+class GlobalInformationProvider(BaseInformationProvider):
+    """Global information provider."""
+
+    implements(IGlobalInformationProvider)
+
+    provides('__conface__')
+
+
+
+class LocalInformationProvider(BaseInformationProvider, Contained, Persistent):
+    """Local information provider."""
+
+    implements(ILocalInformationProvider)
+
+    provides('__conface__')
+
+
+
+class UserDescription(object):
+    """Key interface description mixin."""
+
+    implements(IUserDescription)
+
+    def __init__(self, keyface, label=None, hint=None):
+        self.__keyface__ = keyface
+
+        if label is None:
+            self.label = _(keyface.__name__)
+        else:
+            self.label = label
+
+        if hint is None:
+            self.hint = _(keyface.__doc__)
+        else:
+            self.hint = hint


Property changes on: zope.generic/trunk/src/zope/generic/informationprovider/base.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Modified: zope.generic/trunk/src/zope/generic/informationprovider/configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/configure.zcml	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/informationprovider/configure.zcml	2006-05-02 22:48:25 UTC (rev 67873)
@@ -12,24 +12,32 @@
       parent="zope.generic"
       />
 
-  <!-- add configuration and annotation mechanism to generic information providers. -->
+  <!-- information providers. -->
 
-  <class class="zope.generic.face.api.GlobalInformationProvider">
+  <class class="zope.generic.informationprovider.api.GlobalInformationProvider">
     <implements
         interface="zope.generic.configuration.IAttributeConfigurable"
         />
     <implements
         interface="zope.annotation.IAttributeAnnotatable"
         />
+    <require
+        permission="zope.Public"
+        interface="zope.generic.face.IFace"
+        />
   </class>
 
-  <class class="zope.generic.face.api.LocalInformationProvider">
+  <class class="zope.generic.informationprovider.api.LocalInformationProvider">
     <implements
         interface="zope.generic.configuration.IAttributeConfigurable"
         />
     <implements
         interface="zope.annotation.IAttributeAnnotatable"
         />
+    <require
+        permission="zope.Public"
+        interface="zope.generic.face.IFace"
+        />
   </class>
 
 </configure>

Modified: zope.generic/trunk/src/zope/generic/informationprovider/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/interfaces.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/informationprovider/interfaces.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -17,3 +17,48 @@
 """
 
 __docformat__ = 'restructuredtext'
+
+from zope.app.i18n import ZopeMessageFactory as _
+from zope.interface import Interface
+from zope.schema import Text
+from zope.schema import TextLine
+
+from zope.generic.face import IProvidesAttributeFaced
+
+
+
+class IInformationProvider(IProvidesAttributeFaced):
+    """Provide information to a dedicated context and key interface pair.
+
+    Information provider will be registered as utility providing the context 
+    interface and named by the dotted name of the key interface.
+
+    Information providers can be extended by generic information mechanism
+    such as zope.annotation.IAnnotations simply by adding a specific marker to
+    the information provider implementation. The marker should invoke the 
+    specific information mechanism:
+    
+        classProvides(api.InformationProvider, IAttributeAnnotatable)
+
+        <class class="zope.generic.api.InformationProvider" >
+            <implements="zope.annotation.IAttributeAnnotatable" />
+        </class>
+    """
+
+
+class IGlobalInformationProvider(IInformationProvider):
+    """Global information provider."""
+
+
+
+class ILocalInformationProvider(IInformationProvider):
+    """Local information provider."""
+
+
+
+class IUserDescription(Interface):
+    """Description for an user."""
+
+    label = TextLine(title=_('Lable'))
+
+    hint = Text(title=_('Hint'))

Modified: zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -19,36 +19,62 @@
 __docformat__ = 'restructuredtext'
 
 from zope.annotation import IAnnotations
-from zope.annotation.attribute import AttributeAnnotations
+from zope.component import provideUtility
+from zope.component import queryUtility
 from zope.component.interface import provideInterface
-from zope.component import provideUtility
 from zope.configuration.exceptions import ConfigurationError
 from zope.interface import alsoProvides
 
 from zope.generic.configuration import IConfigurations
-from zope.generic.configuration.api import AttributeConfigurations
+from zope.generic.configuration.api import ConfigurationData
 from zope.generic.face import IConfaceType
-from zope.generic.face.api import ensureInformationProvider
-from zope.generic.face.api import getNextInformationProvider
+from zope.generic.face import IKeyfaceType
+from zope.generic.face import IUndefinedContext
+from zope.generic.face import IUndefinedKeyface
+from zope.generic.face.api import getInformationProvider
 from zope.generic.face.api import toDescription
 from zope.generic.face.api import toDottedName
-from zope.generic.face.base import _global_information_hook
-from zope.generic.face.base import _local_information_hook
-from zope.generic.face.metaconfigure import faceDirective
 
+from zope.generic.informationprovider.base import GlobalInformationProvider
 
-# provide adapter via __conform__ mechanism
-_global_information_hook[IAnnotations] = AttributeAnnotations
-_global_information_hook[IConfigurations] = AttributeConfigurations
-_local_information_hook[IAnnotations] = AttributeAnnotations
-_local_information_hook[IConfigurations] = AttributeConfigurations
 
 
+def ensureInformationProvider(keyface, conface):
+    """Provide an information provider."""
 
+    # preconditions
+    if not IConfaceType.providedBy(conface):
+        raise TypeError('Conface requires %s.' % IConfaceType.__name__)
+
+    if not IKeyfaceType.providedBy(keyface):
+        raise TypeError('Keyface requires %s.' % IKeyfaceType.__name__)
+
+    # essentials
+    name = toDottedName(keyface)
+
+    provider = queryUtility(conface, name)
+
+    # register
+    if not (provider and provider.conface == conface):
+
+        # type key face by its context interface
+        alsoProvides(keyface, conface)
+
+        # provide information provider utility
+        provider = GlobalInformationProvider(conface, keyface)
+        provideUtility(provider, conface, name=name)
+
+    return provider
+
+
+
 def provideConfiguration(keyface, conface, configuration_keyface, configuration):
     """Provide a configuration for a certain type marker."""
 
-    info = getNextInformationProvider(keyface, conface)
+    if type(configuration) is dict:
+        configuration = ConfigurationData(configuration_keyface, configuration)
+
+    info = getInformationProvider(keyface, conface)
     
     configurations = IConfigurations(info)
     configurations[configuration_keyface] = configuration
@@ -58,7 +84,7 @@
 def provideAnnotation(keyface, conface, annotation_key, annotation):
     """Provide an annotation for a certain type marker."""
 
-    info = getNextInformationProvider(keyface, conface)
+    info = getInformationProvider(keyface, conface)
     
     annotations = IAnnotations(info)
     annotations[annotation_key] = annotation
@@ -68,31 +94,33 @@
 class InformationProviderDirective(object):
     """Provide a new information of a certain information registry."""
 
-    def __init__(self, _context, keyface, conface, label=None, hint=None):
+    def __init__(self, _context, keyface=IUndefinedKeyface, conface=IUndefinedContext):
+        # preconditions
+        if IConfaceType.providedBy(keyface):
+            raise ConfigurationError('Key interface %s can not be registered '
+                                     'as context interface too.' % 
+                                     keyface.__name__)
+    
+        if conface and IKeyfaceType.providedBy(conface):
+            raise ConfigurationError('Context interface %s can not be '
+                                     'registered as key interface too.' % 
+                                     conface.__name__)
+
+        # assign variables for the subdirecitives
         self._keyface = keyface
         self._context = _context
         self._conface = conface
 
-        # set label and hint
-        label, hint = toDescription(keyface, label, hint)
-        self._label = label
-        self._hint = hint
-    
-        # assert type as soon as possible
-        faceDirective(_context, keyface=keyface, conface=None, type=conface)
+        # provide type as soon as possilbe
+        if not IKeyfaceType.providedBy(keyface):
+            provideInterface(None, keyface, IKeyfaceType)
 
-        _context.action(
-            discriminator = None,
-            callable = provideInterface,
-            args = (None, self._keyface),
-            )
-    
-        _context.action(
-            discriminator = None,
-            callable = provideInterface,
-            args = (None, self._conface),
-            )
+        if not IConfaceType.providedBy(conface):
+            provideInterface(None, conface, IConfaceType)
 
+        # ensure the corresponding information provider
+        ensureInformationProvider(keyface, conface)
+
     def __call__(self):
         "Handle empty/simple declaration."
         return ()
@@ -100,9 +128,9 @@
     def information(self, _context, keyface=None, configuration=None, key=None, annotation=None):
         """Add a configuration to the information provider."""
         # handle configuration
-        if keyface and configuration:
+        if keyface and configuration is not None:
             # preconditions
-            if not keyface.providedBy(configuration):
+            if not (keyface.providedBy(configuration) or type(configuration) is dict):
                 raise ConfigurationError('Data attribute must provide %s.' % keyface.__name__)
     
             _context.action(

Modified: zope.generic/trunk/src/zope/generic/informationprovider/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/metadirectives.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/informationprovider/metadirectives.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -26,11 +26,34 @@
 from zope.schema import DottedName
 
 from zope.generic.face import IConfaceType
-from zope.generic.face.metadirectives import IKeyfaceDirective
+from zope.generic.face import IKeyfaceType
 
 
+class IKeyfaceDirective(Interface):
+    """Key interface registration directive."""
 
-class IBaseInformationProviderDirective(IKeyfaceDirective):
+    keyface = GlobalInterface(
+        title=_('Key Interface'),
+        description=_('Interface that represents an information key.'),
+        required=False,
+        constraint=lambda v: not IConfaceType.providedBy(v)
+        )
+
+
+
+class IConfaceDirective(Interface):
+    """Context interface registration directive."""
+
+    conface = GlobalInterface(
+        title=_('Context Interface'),
+        description=_('Interface that represents an information context.'),
+        required=False,
+        constraint=lambda v: not IKeyfaceType.providedBy(v)
+        )
+
+
+
+class IDescriptionDirective(IKeyfaceDirective):
     """Base information provider attributes."""
 
     label = MessageID(
@@ -47,18 +70,11 @@
 
 
 
-class IInformationProviderDirective(IBaseInformationProviderDirective):
-    """Directive to register an information to information provider."""
+class IInformationProviderDirective(IKeyfaceDirective, IConfaceDirective):
+    """Directive to register information and information providers."""
 
-    conface = GlobalInterface(
-        title=_('Context Interface'),
-        description=_('The context interface provided by the information provider.'),
-        required=True,
-        constraint=lambda v: IConfaceType.providedBy(v)
-        )
 
 
-
 class IInformationSubdirective(Interface):
     """Declare a certain information of an information provider."""
 
@@ -70,7 +86,8 @@
 
     configuration = GlobalObject(
         title=_('Configuration'),
-        description=_('Configuration component providing the key interface.'),
+        description=_('Configuration component providing the key interface or '
+                      'a dictionary satisfying the key interface.'),
         required=False
         )
 

Modified: zope.generic/trunk/src/zope/generic/informationprovider/testing.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/testing.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/informationprovider/testing.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -54,8 +54,8 @@
 
     from zope.annotation import IAttributeAnnotatable
     from zope.generic.configuration import IAttributeConfigurable
-    from zope.generic.face.api import GlobalInformationProvider
-    from zope.generic.face.api import LocalInformationProvider
+    from zope.generic.informationprovider.api import GlobalInformationProvider
+    from zope.generic.informationprovider.api import LocalInformationProvider
 
     classImplements(GlobalInformationProvider, IAttributeConfigurable, IAttributeAnnotatable)
     classImplements(LocalInformationProvider, IAttributeConfigurable, IAttributeAnnotatable)

Modified: zope.generic/trunk/src/zope/generic/informationprovider/tests.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/tests.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/informationprovider/tests.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -39,6 +39,7 @@
 
 def test_suite():
     return unittest.TestSuite((
+        doctest.DocTestSuite('zope.generic.face.base'),
         doctest.DocFileSuite('README.txt',
                              setUp=testing.placelesssetup.setUp,
                              tearDown=testing.placelesssetup.tearDown,

Modified: zope.generic/trunk/src/zope/generic/operation/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/README.txt	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/operation/README.txt	2006-05-02 22:48:25 UTC (rev 67873)
@@ -38,16 +38,16 @@
 We have to register those parts:
 
     >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IAnyInput"
-    ...     type="zope.generic.configuration.IConfiguration"
+    ... <generic:interface
+    ...     interface="example.IAnyInput"
+    ...     type="zope.generic.configuration.IConfigurationType"
     ...     />
     ... ''') 
 
     >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IAnyOutput"
-    ...     type="zope.generic.configuration.IConfiguration"
+    ... <generic:interface
+    ...     interface="example.IAnyOutput"
+    ...     type="zope.generic.configuration.IConfigurationType"
     ...     />
     ... ''') 
 
@@ -64,12 +64,6 @@
 using itself or its keyface. For each operation directive an operation 
 information will be registered:
 
-    >>> from zope.generic.informationprovider.api import getNextInformationProvidersFor
-
-    >>> listing = list(getNextInformationProvidersFor(api.IOperationContext))
-    >>> len(listing)
-    1
-
     >>> operation = api.getOperation(IAnyOperation)
 
     >>> api.inputParameter(operation) is IAnyInput
@@ -123,9 +117,9 @@
     ...     print 'Pau input: a=%s.' % (input.a)
 
     >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IPAUConfig"
-    ...     type="zope.generic.configuration.IConfiguration"
+    ... <generic:interface
+    ...     interface="example.IPAUConfig"
+    ...     type="zope.generic.configuration.IConfigurationType"
     ...     />
     ... ''')
 
@@ -161,9 +155,9 @@
     ...    any = TextLine()
 
     >>> registerDirective('''
-    ... <generic:face
-    ...     keyface="example.IComplexConfig"
-    ...     type="zope.generic.configuration.IConfiguration"
+    ... <generic:interface
+    ...     interface="example.IComplexConfig"
+    ...     type="zope.generic.configuration.IConfigurationType"
     ...     />
     ... ''') 
 

Modified: zope.generic/trunk/src/zope/generic/operation/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/api.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/operation/api.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -17,65 +17,39 @@
 """
 
 # usage see README.txt
-from zope.generic.informationprovider.api import getNextInformationProvider
+from zope.generic.face import IUndefinedContext
+from zope.generic.informationprovider.api import getInformationProvider
 from zope.generic.informationprovider.api import getInformation
 
 from zope.generic.operation.interfaces import *
 from zope.generic.operation.metaconfigure import assertOperation
-from zope.generic.operation.metaconfigure import provideOperationConfiguration
 
 
 
-def getOperationInformation(object):
-    """Evaluate an operation information from an object."""
-    return getNextInformationProvider(object, IOperationContext)
-
-
-
-def queryOperationInformation(object, default=None):
-    """Evaluate an operation information from an object or return default."""
-    try:
-        return getOperationInformation(object)
-
-    except:
-        return default
-
-
-
-def getOperationConfiguration(object):
+def getOperationConfiguration(object, conface=IUndefinedContext):
     """Evaluate an operation configuration."""
     
-    return getInformation(getOperationInformation(object), IOperationConfiguration)
+    return getInformation(getInformationProvider(object, conface), IOperationConfiguration)
 
 
 
-def queryOperationConfiguration(object, default=None):
-    """Evaluate an operation configuration or default."""
-    try:
-        return getOperationConfiguration(object)
-
-    except:
-        return default
-
-
-
-def getOperation(keyface, default=None):
+def getOperation(keyface, conface=IUndefinedContext):
     """Return the operation of operation marker."""
 
-    return getOperationConfiguration(keyface).operation
+    return getOperationConfiguration(keyface, conface).operation
 
 
 
 
-def inputParameter(object, default=None):
+def inputParameter(object, conface=IUndefinedContext):
     """Return the input paramters of an operation as tuple of configuration keyfaces."""
 
-    return getOperationConfiguration(object).input
+    return getOperationConfiguration(object, conface).input
 
 
 
 
-def outputParameter(object, default=None):
+def outputParameter(object, conface=IUndefinedContext):
     """Return the ouput paramters of an operation as tuple of configuration keyfaces."""
 
-    return getOperationConfiguration(object).output
+    return getOperationConfiguration(object, conface).output

Modified: zope.generic/trunk/src/zope/generic/operation/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/base.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/operation/base.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -22,6 +22,7 @@
 from zope.schema.fieldproperty import FieldProperty
 
 from zope.generic.face import IAttributeFaced
+from zope.generic.face import IUndefinedKeyface
 from zope.generic.face.api import Face
 from zope.generic.configuration.api import parameterToConfiguration
 

Modified: zope.generic/trunk/src/zope/generic/operation/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/interfaces.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/operation/interfaces.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -25,8 +25,7 @@
 from zope.schema import Object
 from zope.schema import Tuple
 
-from zope.generic.configuration import IConfiguration
-from zope.generic.face import IConfaceType
+from zope.generic.configuration import IConfigurationType
 from zope.generic.face import IFace
 from zope.generic.face import IKeyfaceType
 
@@ -63,13 +62,11 @@
 
 
 
-class IOperationContext(Interface):
-    """Registration about an global operation."""
+class IOperationType(IKeyfaceType):
+    """Type an public operation key interface."""
 
-alsoProvides(IOperationContext, IConfaceType)
 
 
-
 class IPrivateOperation(Interface):
     """Marker private, undefined callables."""
 
@@ -89,7 +86,7 @@
         description=_('A configuration interface declaring the input parameters.'),
         required=False,
         default=(),
-        value_type=Object(schema=IConfiguration))
+        value_type=Object(schema=IConfigurationType))
 
     output = Tuple(title=_('Output Declaration'),
         description=_('An interface interface declaring the output parameters.'),
@@ -99,4 +96,4 @@
 
 
 
-alsoProvides(IOperationConfiguration, IConfiguration)
+alsoProvides(IOperationConfiguration, IConfigurationType)

Modified: zope.generic/trunk/src/zope/generic/operation/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/metaconfigure.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/operation/metaconfigure.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -20,23 +20,22 @@
 
 from zope.component.interface import provideInterface
 from zope.configuration.exceptions import ConfigurationError
-from zope.interface import alsoProvides
 
-from zope.generic.configuration import IConfiguration
 from zope.generic.configuration import IConfigurations
-from zope.generic.configuration.api import ConfigurationData
-from zope.generic.face.metaconfigure import keyfaceDirective
-from zope.generic.informationprovider.api import provideInformation
+from zope.generic.face import IUndefinedContext
+from zope.generic.face import IUndefinedKeyface
 from zope.generic.informationprovider.api import queryInformation
-from zope.generic.informationprovider.api import queryNextInformationProvider
+from zope.generic.informationprovider.api import queryInformationProvider
+from zope.generic.informationprovider.metaconfigure import InformationProviderDirective
 
 from zope.generic.operation import IOperation
 from zope.generic.operation import IOperationConfiguration
-from zope.generic.operation import IOperationContext
+from zope.generic.operation import IOperationType
 from zope.generic.operation.base import Operation
 from zope.generic.operation.base import OperationPipe
 
 
+
 def assertOperation(handlers, keyface=None, input=None, output=None):
     """Assert that we get an operation."""
 
@@ -66,9 +65,8 @@
         return Operation(None, keyface, input, output)
 
     # evaluate an operation from a operation key interface
-    elif IOperationContext.providedBy(handler):
-        registry = IOperationContext
-        info = queryNextInformationProvider(handler, IOperationContext)
+    elif IOperationType.providedBy(handler):
+        info = queryInformationProvider(handler)
 
         if info is None:
             ConfigurationError('Operation %s does not exist.' % handler.__name__)
@@ -86,39 +84,22 @@
 
 
 
-def provideOperationConfiguration(keyface, operations=None, registry=None, input=None, output=None):
-    """Provide the handler to an configuration information."""
+def operationDirective(_context, keyface, conface=None, operations=(), input=None, output=None, label=None, hint=None):
+    """Register a public operation."""
 
-    # assume configuration within an IOperationContext
-    if registry is None:
-        registry = IOperationContext
+    if conface is None:
+        conface = IUndefinedContext
 
-    provider = queryNextInformationProvider(keyface, registry)
+    # provide type as soon as possilbe
+    if not IOperationType.providedBy(keyface):
+        provideInterface(None, keyface, IOperationType)      
 
-    # this should never happen...
-    if provider is None:
-        ConfigurationError('No operation information for %s' 
-                           % keyface.__name__)
+    # register the operatio using the information provider directive
+    directive = InformationProviderDirective(_context, keyface, conface)
 
     # create operation wrapper
     operation = assertOperation(operations, keyface, input, output)
-
-    # create and set configuration data
-    provideInformation(provider, IOperationConfiguration, 
-        {'operation': operation, 'input': input, 'output': output})
-
-
-
-def operationDirective(_context, keyface, operations=(), input=None, output=None, label=None, hint=None):
-    """Register a public operation."""
-
-    type = IOperationContext
     
-    # assert type as soon as possible
-    keyfaceDirective(_context, keyface, type)
+    directive.information(_context, keyface=IOperationConfiguration, 
+        configuration={'operation': operation, 'input': input, 'output': output})
 
-    _context.action(
-        discriminator = ('provideOperationConfiguration', keyface),
-        callable = provideOperationConfiguration,
-        args = (keyface, operations, type, input, output),
-        )

Modified: zope.generic/trunk/src/zope/generic/operation/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/metadirectives.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/operation/metadirectives.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -24,13 +24,12 @@
 from zope.configuration.fields import Tokens
 from zope.interface import Interface
 
-from zope.generic.configuration import IConfiguration
-from zope.generic.informationprovider.metadirectives import IBaseInformationProviderDirective
+from zope.generic.informationprovider.metadirectives import IInformationProviderDirective
 
 
 
-class IBaseOperationDirective(Interface):
-    """Register an operation."""
+class IOperationsDirective(Interface):
+    """Register operations."""
 
     operations = Tokens(
         title=_('Callable, Operation or IOperationContext'),
@@ -40,13 +39,27 @@
         value_type=GlobalObject()
         )
 
+
+
+class IInputDirective(Interface):
+    """Register input schema of the operations."""
+
     input = GlobalInterface(title=_('Input Declaration'),
         description=_('Configuration schema describing the input arguments.'),
         required=False)
 
 
 
-class IOperationDirective(IBaseInformationProviderDirective, IBaseOperationDirective):
+class IOutputDirective(Interface):
+    """Register output schema of the operations."""
+
+    output = GlobalInterface(title=_('Output Declaration'),
+        description=_('Configuration schema or interface describing the input arguments.'),
+        required=False)
+
+
+
+class IOperationDirective(IInformationProviderDirective, IOperationsDirective, IInputDirective, IOutputDirective):
     """Register a public operation.
 
     The operation will be registered as information provider utility providing
@@ -56,6 +69,3 @@
     IOperationContext too.
     """
 
-    output = GlobalInterface(title=_('Output Declaration'),
-        description=_('Configuration schema or interface describing the input arguments.'),
-        required=False)
\ No newline at end of file

Modified: zope.generic/trunk/src/zope/generic/operation/testing.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/testing.py	2006-05-02 21:20:12 UTC (rev 67872)
+++ zope.generic/trunk/src/zope/generic/operation/testing.py	2006-05-02 22:48:25 UTC (rev 67873)
@@ -28,7 +28,7 @@
 import zope.generic.operation
 import zope.generic.testing.testing
 
-from zope.generic.operation import IOperationContext
+from zope.generic.operation import IOperationType
 
 
 



More information about the Checkins mailing list