[Checkins] SVN: zope.generic/trunk/src/zope/generic/ move all information provider stuff from .face to .informationprovider

Dominik Huber dominik.huber at perse.ch
Wed May 3 05:57:06 EDT 2006


Log message for revision 67877:
  move all information provider stuff from .face to .informationprovider

Changed:
  U   zope.generic/trunk/src/zope/generic/content/helper.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/meta.zcml
  U   zope.generic/trunk/src/zope/generic/face/metaconfigure.py
  U   zope.generic/trunk/src/zope/generic/factory/metaconfigure.py
  U   zope.generic/trunk/src/zope/generic/informationprovider/README.txt
  U   zope.generic/trunk/src/zope/generic/informationprovider/api.py
  U   zope.generic/trunk/src/zope/generic/informationprovider/base.py
  U   zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py

-=-
Modified: zope.generic/trunk/src/zope/generic/content/helper.py
===================================================================
--- zope.generic/trunk/src/zope/generic/content/helper.py	2006-05-03 09:38:22 UTC (rev 67876)
+++ zope.generic/trunk/src/zope/generic/content/helper.py	2006-05-03 09:57:05 UTC (rev 67877)
@@ -19,7 +19,7 @@
 __docformat__ = 'restructuredtext'
 
 from zope.generic.face.api import getKeyface
-from zope.generic.face.api import getInformationProvider
+from zope.generic.informationprovider.api import getInformationProvider
 from zope.generic.informationprovider.api import queryInformation
 
 from zope.generic.face import IUndefinedContext

Modified: zope.generic/trunk/src/zope/generic/face/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/face/README.txt	2006-05-03 09:38:22 UTC (rev 67876)
+++ zope.generic/trunk/src/zope/generic/face/README.txt	2006-05-03 09:57:05 UTC (rev 67877)
@@ -10,8 +10,8 @@
 provider offers the possiblity to register information according to a pair of 
 key- and context interfaces.
 
-Key interface
--------------
+Key interface (Keyface: short for [key[ inter]face)
+---------------------------------------------------
 
 The key interface is the one piece to lookup information providers. 
 
@@ -32,8 +32,8 @@
 key interface can be used to lookup corresponding information providers
 explicitly.
 
-Context Interface
------------------
+Context Interface (Conface: short for [con[text inter]face)
+-----------------------------------------------------------
 
 The context interface is the other piece to lookup information providers. 
 
@@ -150,182 +150,3 @@
     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-03 09:38:22 UTC (rev 67876)
+++ zope.generic/trunk/src/zope/generic/face/api.py	2006-05-03 09:57:05 UTC (rev 67877)
@@ -18,10 +18,6 @@
 
 __docformat__ = 'restructuredtext'
 
-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
@@ -73,66 +69,3 @@
 
     except TypeError:
         return default
-
-
-
-def getInformationProvider(object=None, conface=IUndefinedContext):
-    """Evaluate the next information provider utility for an object or keyface."""
-
-    keyface = getKeyface(object)
-
-    try:
-        provider = getUtility(conface, toDottedName(keyface))
-        # return only provider that is or extends a certain context.
-        if provider.conface == conface:
-            return provider
-    except:
-        pass
-
-    raise KeyError('Missing information provider %s at %s.' % (keyface.__name__, conface.__name__))
-
-
-
-def queryInformationProvider(object=None, conface=IUndefinedContext, default=None):
-    """Evaluate the next information provider utility for an object or keyface."""
-    try:
-        return getInformationProvider(object, conface)
-
-    except:
-        return default
-
-
-
-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."""
-
-    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/meta.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/face/meta.zcml	2006-05-03 09:38:22 UTC (rev 67876)
+++ zope.generic/trunk/src/zope/generic/face/meta.zcml	2006-05-03 09:57:05 UTC (rev 67877)
@@ -5,9 +5,9 @@
   <meta:directives namespace="http://namespaces.zope.org/generic">
 
     <meta:directive
-        name="face"
-        schema=".metadirectives.IFaceDirective"
-        handler=".metaconfigure.faceDirective"
+        name="interface"
+        schema="zope.component.zcml.IInterfaceDirective"
+        handler=".metaconfigure.interfaceDirective"
         />
 
   </meta:directives>

Modified: zope.generic/trunk/src/zope/generic/face/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/face/metaconfigure.py	2006-05-03 09:38:22 UTC (rev 67876)
+++ zope.generic/trunk/src/zope/generic/face/metaconfigure.py	2006-05-03 09:57:05 UTC (rev 67877)
@@ -1,6 +1,6 @@
 ##############################################################################
 #
-# Copyright (c) 2005, 2006 Projekt01 GmbH and Contributors.
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
 # All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
@@ -18,100 +18,10 @@
 
 __docformat__ = 'restructuredtext'
 
-from zope.component import provideUtility
-from zope.component import queryUtility
 from zope.component.interface import provideInterface
-from zope.configuration.exceptions import ConfigurationError
-from zope.interface import alsoProvides
 
-from zope.generic.face import IConfaceType
-from zope.generic.face import IKeyfaceType
-from zope.generic.face import IUndefinedContext
-from zope.generic.face.base import GlobalInformationProvider
-from zope.generic.face.base import LocalInformationProvider
-from zope.generic.face.helper import toDottedName
 
-
-def ensureInformationProvider(conface, keyface, context=None):
-    """Provide an information provider."""
-
-    # preconditions
-    if not IConfaceType.providedBy(conface):
-        raise TypeError('Conface requires %.' % IConfaceType.__name__)
-
-    if not IKeyfaceType.providedBy(keyface):
-        raise TypeError('Keyface requires %.' % IKeyfaceType.__name__)
-
-    # essentials
-    name = toDottedName(keyface)
-
-    provider = queryUtility(conface, name, context=context)
-
-    if not (provider and provider.conface == conface):
-        
-        if context is None:
-            provider = GlobalInformationProvider(conface, keyface)
-            provideUtility(provider, conface, name=name)
-        
-        else:
-            provider = LocalInformationProvider(conface, keyface)
-            context.registerUtility(provider, conface, name=name)
-
-
-
-def keyfaceDirective(_context, keyface, type=None):
-    """Type and register an new key interface."""
-
-    if type is None:
-        type = IUndefinedContext
-
-    # context can never be key interface and key can never be context interface
-    if keyface and IConfaceType.providedBy(keyface):
-        raise ConfigurationError('Key interface %s can not be registered as context interface too.' % keyface.__name__)
-
-    # provide type as soon as possilbe
-    if not IKeyfaceType.providedBy(keyface):
-        provideInterface(None, keyface, IKeyfaceType)
-
-    if type and not type.providedBy(keyface):
-        # provide additional interface utility
-        if not IConfaceType.providedBy(type):
-            provideInterface(None, keyface, type)
-
-        # provide global information provider
-        else:
-            alsoProvides(keyface, type)
-            ensureInformationProvider(type, keyface)
-
-
-
-def confaceDirective(_context, conface, type=None):
-    """Type and register an new context interface."""
-
-    # context can never be key interface and key can never be context interface
-    if conface and IKeyfaceType.providedBy(conface):
-        raise ConfigurationError('Context interface %s can not be registered as key interface too.' % conface.__name__)
-
-    # provide type as soon as possilbe
-    if not IConfaceType.providedBy(conface):
-        provideInterface(None, conface, IConfaceType)
-
-    # provide additional interface utility
-    if type and not type.providedBy(conface):
-        provideInterface(None, conface, type)
-
-
-
-def faceDirective(_context, keyface=None, conface=None, type=None):
-    """Type and register an new key or context interface."""
-
-    # preconditions
-    # register only key or context interface
-    if keyface and conface:
-        raise ConfigurationError('Cannot register a key or a context interface at the same time.')
+def interfaceDirective(_context, interface, type=None, name=''):
     
-    if keyface:
-        keyfaceDirective(_context, keyface, type)
-
-    else:
-        confaceDirective(_context, conface, type)
+    if not type.providedBy(interface):
+        provideInterface(name, interface, type)

Modified: zope.generic/trunk/src/zope/generic/factory/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/metaconfigure.py	2006-05-03 09:38:22 UTC (rev 67876)
+++ zope.generic/trunk/src/zope/generic/factory/metaconfigure.py	2006-05-03 09:57:05 UTC (rev 67877)
@@ -32,7 +32,7 @@
 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 getInformationProvider
+from zope.generic.informationprovider.api import getInformationProvider
 from zope.generic.informationprovider.api import provideInformation
 from zope.generic.informationprovider.metaconfigure import InformationProviderDirective
 from zope.generic.operation import IOperationConfiguration

Modified: zope.generic/trunk/src/zope/generic/informationprovider/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/README.txt	2006-05-03 09:38:22 UTC (rev 67876)
+++ zope.generic/trunk/src/zope/generic/informationprovider/README.txt	2006-05-03 09:57:05 UTC (rev 67877)
@@ -58,7 +58,7 @@
     >>> len(listing) is 1
     True
     >>> [(key.__name__, value) for key, value in listing]
-    [('IMyFoo', <zope.generic.informationprovider.base.GlobalInformationProvider ...>)]
+    [('IMyFoo', <GlobalInformationProvider IMyFoo at ISpecialContext>)]
 
 A single information provider can be retrieved by the get- or 
 queryInformationProvider function:
@@ -166,7 +166,226 @@
     >>> api.queryInformation(provider, IMyConfiguration) is my_configuration
     True
 
-Complex information provider lookup using acquireInformationProvider
---------------------------------------------------------------------
+Further information provider exploration
+----------------------------------------
 
-see zope.generic.face README.txt
\ No newline at end of file
+The following example should provide a further exploration about information
+provider an theirs behavior:
+
+    >>> class IMyContext(interface.Interface):
+    ...    pass
+
+    >>> class IFoo(interface.Interface):
+    ...    pass
+
+    >>> registerDirective('''
+    ... <generic:informationProvider
+    ...     keyface="example.IFoo" />
+    ... ''')
+
+An information provider should provide the contex interface itself. Further more
+it is responsible to mark the key interface by the context interface:
+
+    >>> api.IUndefinedContext.providedBy(IFoo)
+    True
+    >>> api.IUndefinedContext.providedBy(api.getInformationProvider(IFoo))
+    True
+
+Simple Lookup using queryInformationProvider and getInformationProvider
+------------------------------------------------------------------------
+
+    >>> api.getInformationProvider(IFoo)
+    <GlobalInformationProvider IFoo at IUndefinedContext>
+
+    >>> api.queryInformationProvider(IFoo)
+    <GlobalInformationProvider 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
+
+    >>> registerDirective('''
+    ... <generic:informationProvider
+    ...     keyface="example.IFoo"
+    ...     conface="example.IYourContext" />
+    ... ''')
+
+    >>> component.getUtility(IMyContext, api.toDottedName(IFoo))
+    <GlobalInformationProvider 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
+
+    >>> api.getInformationProvider(IFoo, IOurContext) 
+    Traceback (most recent call last):
+    ...
+    KeyError: 'Missing information provider IFoo at IOurContext.'
+
+    >>> api.acquireInformationProvider(IFoo, IOurContext)
+    <GlobalInformationProvider IFoo at IUndefinedContext>
+
+The other way round we can play with key interface inheritance:
+
+    >>> class IBar(interface.Interface):
+    ...    pass
+
+    >>> api.acquireInformationProvider(IBar) 
+    Traceback (most recent call last):
+    ...
+    KeyError: 'Missing information provider IBar at IUndefinedContext.'
+
+    >>> class IFooBar(IFoo, IBar):
+    ...    pass
+
+    >>> api.acquireInformationProvider(IFooBar) 
+    <GlobalInformationProvider IFoo at IUndefinedContext>
+
+If we register a new information provider to IBar and IUndefinedContext, we can
+observe the following behavior:
+
+    >>> registerDirective('''
+    ... <generic:informationProvider
+    ...     keyface="example.IBar" />
+    ... ''')
+
+    >>> api.acquireInformationProvider(IBar)
+    <GlobalInformationProvider IBar at IUndefinedContext>
+
+    >>> api.acquireInformationProvider(IFooBar) 
+    <GlobalInformationProvider IFoo at IUndefinedContext>
+
+    >>> class IBarFoo(IBar, IFoo):
+    ...    pass
+
+    >>> api.acquireInformationProvider(IBarFoo) 
+    <GlobalInformationProvider IBar at IUndefinedContext>
+
+But we always get the most specialized one:
+
+    >>> api.acquireInformationProvider(IBarFoo, IOurContext) 
+    <GlobalInformationProvider IBar at IUndefinedContext> 
+
+    >>> registerDirective('''
+    ... <generic:informationProvider
+    ...     keyface="example.IBarFoo" />
+    ... ''')
+
+    >>> api.acquireInformationProvider(IBarFoo, IOurContext) 
+    <GlobalInformationProvider IBarFoo at IUndefinedContext>
+
+    >>> registerDirective('''
+    ... <generic:informationProvider
+    ...     keyface="example.IBar"
+    ...     conface="example.IOurContext" />
+    ... ''')
+
+    >>> api.acquireInformationProvider(IBarFoo, IOurContext) 
+    <GlobalInformationProvider IBar at IOurContext>
+
+    >>> registerDirective('''
+    ... <generic:informationProvider
+    ...     keyface="example.IBarFoo"
+    ...     conface="example.IOurContext" />
+    ... ''')
+
+    >>> api.acquireInformationProvider(IBarFoo, IOurContext) 
+    <GlobalInformationProvider 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']
+
+Components can suggest key and context interfaces
+-------------------------------------------------
+
+You can use the IFace interface to provide key interface and context interface
+by a component itself. Therefore the conface parameter has to be None:
+
+    >>> from zope.generic.face.api import Face
+
+    >>> class Foo(Face):
+    ...    __keyface__ = IFoo
+    ...    __conface__ = IOurContext
+
+    >>> foo = Foo()
+    >>> foo.keyface == IFoo
+    True
+    >>> foo.conface == IOurContext
+    True
+
+    >>> api.acquireInformationProvider(foo, None) 
+    <GlobalInformationProvider IFoo at IUndefinedContext>
+
+    >>> api.acquireInformationProvider(foo) 
+    <GlobalInformationProvider IFoo at IUndefinedContext>
+
+
+    >>> class Bar(Face):
+    ...    __keyface__ = IBar
+    ...    __conface__ = IOurContext
+
+    >>> bar = Bar()
+    >>> bar.keyface == IBar
+    True
+    >>> bar.conface == IOurContext
+    True
+
+    >>> api.acquireInformationProvider(bar, None) 
+    <GlobalInformationProvider IBar at IOurContext>
+
+    >>> api.acquireInformationProvider(bar) 
+    <GlobalInformationProvider IBar at IUndefinedContext>

Modified: zope.generic/trunk/src/zope/generic/informationprovider/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/api.py	2006-05-03 09:38:22 UTC (rev 67876)
+++ zope.generic/trunk/src/zope/generic/informationprovider/api.py	2006-05-03 09:57:05 UTC (rev 67877)
@@ -19,27 +19,79 @@
 __docformat__ = 'restructuredtext'
 
 from zope.annotation import IAnnotations
-from zope.generic.face.api import acquireInformationProvider
+from zope.component import getUtilitiesFor
+from zope.interface import directlyProvidedBy
+
+from zope.generic.configuration import IConfigurationType
+from zope.generic.configuration import IConfigurations
+from zope.generic.configuration.api import ConfigurationData
+from zope.generic.face import IConfaceType
+from zope.generic.face import IKeyfaceType
+from zope.generic.face import IUndefinedContext
+from zope.generic.face import IUndefinedKeyface
 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 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 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
+from zope.generic.informationprovider.metaconfigure import getInformationProvider
 
 
 
+def queryInformationProvider(object=None, conface=IUndefinedContext, default=None):
+    """Evaluate the next information provider utility for an object or keyface."""
+    try:
+        return getInformationProvider(object, conface)
+
+    except:
+        return default
+
+
+
+def acquireInformationProvider(object=None, conface=IUndefinedContext):
+    """Evaluate the next information provider utility for an object or keyface."""
+        
+    keyface = getKeyface(object)
+    if conface is None:
+        conface = getConface(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."""
+
+    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)
+
+
+
+
 def getInformation(context, informationkey):
     """Evaluate an information by a keyface (string or key keyface)."""
     if IConfigurationType.providedBy(informationkey):

Modified: zope.generic/trunk/src/zope/generic/informationprovider/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/base.py	2006-05-03 09:38:22 UTC (rev 67876)
+++ zope.generic/trunk/src/zope/generic/informationprovider/base.py	2006-05-03 09:57:05 UTC (rev 67877)
@@ -122,10 +122,12 @@
 
         elif interface == IAnnotations:
             return AttributeAnnotations(self)
-            
 
+    def __repr__(self):
+        return '<%s %s at %s>' % (self.__class__.__name__, self.keyface.__name__, self.conface.__name__)
 
 
+
 class GlobalInformationProvider(BaseInformationProvider):
     """Global information provider."""
 

Modified: zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py	2006-05-03 09:38:22 UTC (rev 67876)
+++ zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py	2006-05-03 09:57:05 UTC (rev 67877)
@@ -20,6 +20,7 @@
 
 from zope.annotation import IAnnotations
 from zope.component import provideUtility
+from zope.component import getUtility
 from zope.component import queryUtility
 from zope.component.interface import provideInterface
 from zope.configuration.exceptions import ConfigurationError
@@ -31,7 +32,8 @@
 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 getConface
+from zope.generic.face.api import getKeyface
 from zope.generic.face.api import toDescription
 from zope.generic.face.api import toDottedName
 
@@ -39,6 +41,25 @@
 
 
 
+def getInformationProvider(object=None, conface=IUndefinedContext):
+    """Evaluate the next information provider utility for an object or keyface."""
+
+    keyface = getKeyface(object)
+    if conface is None:
+        conface = getConface(object)
+
+    try:
+        provider = getUtility(conface, toDottedName(keyface))
+        # return only provider that is or extends a certain context.
+        if provider.conface == conface:
+            return provider
+    except:
+        pass
+
+    raise KeyError('Missing information provider %s at %s.' % (keyface.__name__, conface.__name__))
+
+
+
 def ensureInformationProvider(keyface, conface):
     """Provide an information provider."""
 



More information about the Checkins mailing list