[Checkins] SVN: zope.generic/trunk/src/zope/generic/ update,
work in progress
Dominik Huber
dominik.huber at perse.ch
Mon May 1 11:50:24 EDT 2006
Log message for revision 67806:
update, work in progress
Changed:
U zope.generic/trunk/src/zope/generic/adapter/property.py
U zope.generic/trunk/src/zope/generic/configuration/base.py
U zope.generic/trunk/src/zope/generic/content/README.txt
U zope.generic/trunk/src/zope/generic/content/base.py
U zope.generic/trunk/src/zope/generic/content/configure.zcml
U zope.generic/trunk/src/zope/generic/content/helper.py
U zope.generic/trunk/src/zope/generic/content/interfaces.py
U zope.generic/trunk/src/zope/generic/content/metaconfigure.py
U zope.generic/trunk/src/zope/generic/face/README.txt
U zope.generic/trunk/src/zope/generic/face/adapter.py
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/interfaces.py
U zope.generic/trunk/src/zope/generic/face/metaconfigure.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/configure.zcml
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/informationprovider/NEW_README.txt
U zope.generic/trunk/src/zope/generic/informationprovider/README.txt
U zope.generic/trunk/src/zope/generic/informationprovider/api.py
D 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/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/property.py
===================================================================
--- zope.generic/trunk/src/zope/generic/adapter/property.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/adapter/property.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -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 getInformationProvider
+from zope.generic.informationprovider.api import getNextInformationProvider
@@ -68,7 +68,7 @@
if configuration is None and self._providers:
for registry in self._providers:
try:
- provider = getInformationProvider(context, registry)
+ provider = getNextInformationProvider(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 = getInformationProvider(context, registry)
+ provider = getNextInformationProvider(context, registry)
configuration = getInformation(provider, keyface)
break
except:
Modified: zope.generic/trunk/src/zope/generic/configuration/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/base.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/configuration/base.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -117,23 +117,23 @@
implements(IAttributeFaced, IConfigurationData)
- def __init__(self, schema, data):
+ def __init__(self, __keyface__, data):
# preconditions
missedArguments = []
- for name in schema:
+ for name in __keyface__:
if name not in data:
- field = schema[name]
+ field = __keyface__[name]
if field.required is True:
missedArguments.append(name)
if missedArguments:
- raise TypeError("__init__ requires '%s' of '%s'." % (', '.join(missedArguments), schema.__name__))
+ raise TypeError("__init__ requires '%s' of '%s'." % (', '.join(missedArguments), __keyface__.__name__))
# essentials
self.__dict__['_ConfigurationData__data'] = PersistentDict(data)
- self.__dict__['__keyface__'] = schema
+ self.__dict__['__keyface__'] = __keyface__
self.__dict__['__conface__'] = IConfiguration
- directlyProvides(self, schema)
+ directlyProvides(self, __keyface__)
def __conform__(self, interface):
if interface is IFace:
@@ -144,10 +144,10 @@
if name in ['__keyface__', '__conface__']:
return self.__dict__[name]
- schema = self.__dict__['__keyface__']
+ keyface = self.__dict__['__keyface__']
data = self.__dict__['_ConfigurationData__data']
try:
- field = schema[name]
+ field = keyface[name]
except KeyError:
raise AttributeError(name)
else:
@@ -170,11 +170,11 @@
def __setattr__(self, name, value):
if not(name == '__provides__' or name in IPersistent):
- schema = self.__dict__['__keyface__']
+ keyface = self.__dict__['__keyface__']
data = self.__dict__['_ConfigurationData__data']
try:
- field = schema[name]
+ field = keyface[name]
except KeyError:
raise AttributeError(name)
else:
Modified: zope.generic/trunk/src/zope/generic/content/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/content/README.txt 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/content/README.txt 2006-05-01 15:50:22 UTC (rev 67806)
@@ -7,7 +7,7 @@
provides by adaption or implementation access to a type marker. This type
marker can be used to lookup further information about the referenced type.
-For each interface typed by our type marker type (ITypeType) we provied a type
+For each interface typed by our type marker type (IUndefinedContext) we provied a type
factory that can create instaces of this certain *logical* type.
Furthermore a type information utility will be provided. This type information
@@ -35,15 +35,14 @@
Contained, Container and Folder (Site) that you might use as implementation of
your logical type. Certainly you can provide your own implementation. Such an
implementation should implement at least the marker ITypeable and a corresponding
-adapter to ITyped.
+adapter to ITypedContent.
In our example we will use a simple generic object:
>>> from zope.generic.content import api
- >>> api.ITypeable.implementedBy(api.Object)
+
+ >>> api.IDirectlyTypedContent.implementedBy(api.Object)
True
- >>> api.IGenericTyped.implementedBy(api.Object)
- True
>>> registerDirective('''
... <generic:content
@@ -55,17 +54,17 @@
... </generic:content>
... ''')
-After the typed is registered the type marker will provide ITypeType:
+After the typed is registered the type marker will provide IUndefinedContext:
- >>> from zope.generic.content import api
+ >>> from zope.generic.face import IUndefinedContext
- >>> api.ITypeType.providedBy(IFooMarker)
+ >>> IUndefinedContext.providedBy(IFooMarker)
True
You can create instances of the registered logical type:
>>> foo = api.createObject(IFooMarker)
- >>> typed = api.ITyped(foo)
+ >>> typed = api.ITypedContent(foo)
>>> typed.keyface == IFooMarker
True
@@ -81,18 +80,20 @@
>>> from zope.component import queryUtility
>>> from zope.generic.face.api import toDottedName
- >>> info = queryUtility(api.ITypeInformation, toDottedName(IFooMarker))
+ >>> info = queryUtility(IUndefinedContext, toDottedName(IFooMarker))
>>> info.keyface == IFooMarker
True
- >>> info.label
- u'Foo Type'
- >>> info.hint
- u'Bla bla bla.'
+# 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 ITyped by implementation or adaption:
+providing ITypedContent by implementation or adaption:
>>> api.queryTypeInformation(IFooMarker) == info
True
Modified: zope.generic/trunk/src/zope/generic/content/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/content/base.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/content/base.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -19,8 +19,8 @@
__docformat__ = 'restructuredtext'
from persistent import Persistent
-
from zope.interface import implements
+from zope.schema.fieldproperty import FieldProperty
from zope.app.container import contained
from zope.app.container import btree
@@ -29,22 +29,24 @@
from zope.generic.directlyprovides.api import provides
from zope.generic.directlyprovides.api import UpdateProvides
+from zope.generic.face.api import Face
-from zope.generic.content import IGenericTyped
+from zope.generic.content import IDirectlyTypedContent
-class Object(object):
+class Object(Face, Persistent):
"""Default implementation for simple objects."""
- implements(IGenericTyped)
+ implements(IDirectlyTypedContent)
def __init__(self, *pos, **kws):
super(Object, self).__init__()
provides('__keyface__')
- __keyface__ = UpdateProvides(IGenericTyped['__keyface__'])
+ __keyface__ = UpdateProvides(IDirectlyTypedContent['__keyface__'])
+ __conface__ = FieldProperty(IDirectlyTypedContent['__conface__'])
@property
def keyface(self):
@@ -52,34 +54,36 @@
-class Contained(contained.Contained, Persistent):
+class Contained(Face, contained.Contained, Persistent):
"""Default implementation local, persistend and contained objects."""
- implements(IGenericTyped)
+ implements(IDirectlyTypedContent)
def __init__(self, *pos, **kws):
super(Contained, self).__init__()
provides('__keyface__')
- __keyface__ = UpdateProvides(IGenericTyped['__keyface__'])
+ __keyface__ = UpdateProvides(IDirectlyTypedContent['__keyface__'])
+ __conface__ = FieldProperty(IDirectlyTypedContent['__conface__'])
@property
def keyface(self):
return self.__keyface__
-class Container(btree.BTreeContainer):
+class Container(Face, btree.BTreeContainer):
"""Default implementation local, persistend and containerish objects."""
- implements(IGenericTyped)
+ implements(IDirectlyTypedContent)
def __init__(self, *pos, **kws):
super(Container, self).__init__()
provides('__keyface__')
- __keyface__ = UpdateProvides(IGenericTyped['__keyface__'])
+ __keyface__ = UpdateProvides(IDirectlyTypedContent['__keyface__'])
+ __conface__ = FieldProperty(IDirectlyTypedContent['__conface__'])
@property
def keyface(self):
@@ -87,17 +91,18 @@
-class OrderedContainer(ordered.OrderedContainer):
+class OrderedContainer(Face, ordered.OrderedContainer):
"""Default implementation local, persistend and ordered-containerish objects."""
- implements(IGenericTyped)
+ implements(IDirectlyTypedContent)
def __init__(self, *pos, **kws):
super(OrderedContainer, self).__init__()
provides('__keyface__')
- __keyface__ = UpdateProvides(IGenericTyped['__keyface__'])
+ __keyface__ = UpdateProvides(IDirectlyTypedContent['__keyface__'])
+ __conface__ = FieldProperty(IDirectlyTypedContent['__conface__'])
@property
def keyface(self):
@@ -105,18 +110,15 @@
-class Folder(folder.Folder):
+class Folder(Face, folder.Folder):
"""Default implementation local, persistend and containerish possible sites."""
- implements(IGenericTyped)
+ implements(IDirectlyTypedContent)
def __init__(self, *pos, **kws):
super(Folder, self).__init__()
provides('__keyface__')
- __keyface__ = UpdateProvides(IGenericTyped['__keyface__'])
-
- @property
- def keyface(self):
- return self.__keyface__
+ __keyface__ = UpdateProvides(IDirectlyTypedContent['__keyface__'])
+ __conface__ = FieldProperty(IDirectlyTypedContent['__conface__'])
Modified: zope.generic/trunk/src/zope/generic/content/configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/content/configure.zcml 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/content/configure.zcml 2006-05-01 15:50:22 UTC (rev 67806)
@@ -19,17 +19,11 @@
parent="zope.generic"
/>
- <generic:informationProvider
- keyface="zope.generic.informationprovider.IInformationProviderInformation"
- label="Type Information Registry"
- registry=".ITypeInformation"
- />
-
<!-- transient generic object implementation -->
<class class=".base.Object">
<require
permission="zope.Public"
- interface="zope.generic.content.ITyped"
+ interface="zope.generic.content.ITypedContent"
/>
</class>
@@ -37,7 +31,7 @@
<class class=".base.Contained">
<require
permission="zope.Public"
- interface="zope.generic.content.ITyped"
+ interface="zope.generic.content.ITypedContent"
/>
</class>
@@ -45,7 +39,7 @@
<class class=".base.Container">
<require
permission="zope.Public"
- interface="zope.generic.content.ITyped"
+ interface="zope.generic.content.ITypedContent"
/>
<require
permission="zope.View"
@@ -61,7 +55,7 @@
<class class=".base.OrderedContainer">
<require
permission="zope.Public"
- interface="zope.generic.content.ITyped"
+ interface="zope.generic.content.ITypedContent"
/>
<require
permission="zope.View"
@@ -81,7 +75,7 @@
<class class=".base.Folder">
<require
permission="zope.Public"
- interface="zope.generic.content.ITyped"
+ interface="zope.generic.content.ITypedContent"
/>
<require
permission="zope.View"
Modified: zope.generic/trunk/src/zope/generic/content/helper.py
===================================================================
--- zope.generic/trunk/src/zope/generic/content/helper.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/content/helper.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -18,45 +18,20 @@
__docformat__ = 'restructuredtext'
+from zope.generic.face.api import getKeyface
+from zope.generic.face.api import getNextInformationProvider
from zope.generic.informationprovider.api import queryInformation
-from zope.generic.informationprovider.api import getInformationProvider
-from zope.generic.content import ITypeInformation
-from zope.generic.content import ITyped
-from zope.generic.content import ITypeType
+from zope.generic.face import IUndefinedContext
-def getType(object):
- """Evaluate relevant type marker keyface of an object."""
- if ITypeType.providedBy(object):
- keyface = object
+def getTypeInformation(object, conface=IUndefinedContext):
+ return getNextInformationProvider(getKeyface(object), conface)
- elif ITyped.providedBy(object):
- keyface = object.keyface
- else:
- keyface = ITyped(object).keyface
- return keyface
-
-
-
-def queryType(object, default=None):
- try:
- return getType(object)
-
- except:
- return default
-
-
-
-def getTypeInformation(object):
- return getInformationProvider(getType(object), ITypeInformation)
-
-
-
def queryTypeInformation(object, default=None):
"""Lookup an type information of any object."""
@@ -81,7 +56,7 @@
def acquireTypeConfiguration(object, configuration, default=None):
try:
- keyface = getType(object, default)
+ keyface = getKeyface(object, default)
except:
return default
Modified: zope.generic/trunk/src/zope/generic/content/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/content/interfaces.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/content/interfaces.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -19,52 +19,17 @@
__docformat__ = 'restructuredtext'
from zope.annotation.interfaces import IAttributeAnnotatable
-from zope.app.i18n import ZopeMessageFactory as _
-from zope.interface import Interface
-from zope.schema import Object
from zope.generic.configuration.api import IAttributeConfigurable
-from zope.generic.informationprovider import IInformationProvider
from zope.generic.face import IFace
-from zope.generic.face import IKeyfaceType
from zope.generic.face import IProvidesAttributeFaced
-__all__ = ['ITypeType', 'ITypeable', 'ITyped', 'IGenericTyped',
- 'ITypeInformation']
+class ITypedContent(IFace, IAttributeConfigurable, IAttributeAnnotatable):
+ """Content that provides the declared key interface."""
-class ITypeType(IKeyfaceType):
- """An abstract interface marker marker type.
- An interface marked by this marker type will provide an typed information
- within the corresponding ITypeInformation registry.
- """
-
-
-
-class ITypeable(Interface):
- """Assert ITyped by adaption or by implementation."""
-
-
-
-class ITyped(ITypeable, IFace):
- """Provide the key interface."""
-
- keyface = Object(
- title=_('Key interface'),
- description=_('Key interface that references corresponding type informations.'),
- required=True,
- schema=ITypeType)
-
-
-
-class IGenericTyped(ITyped, IProvidesAttributeFaced, IAttributeConfigurable, IAttributeAnnotatable):
- """Directly provide the declared key interface interface."""
-
-
-
-class ITypeInformation(IInformationProvider):
- """Provide information for the declared type interface."""
-
+class IDirectlyTypedContent(ITypedContent, IProvidesAttributeFaced):
+ """Content that directly provides the declared key interface."""
Modified: zope.generic/trunk/src/zope/generic/content/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/content/metaconfigure.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/content/metaconfigure.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -25,8 +25,7 @@
from zope.generic.informationprovider.metaconfigure import InformationProviderDirective
from zope.generic.handler.metaconfigure import handlerDirective
-from zope.generic.content import ITypeInformation
-from zope.generic.content import ITypeType
+from zope.generic.face import IUndefinedContext
@@ -34,18 +33,18 @@
"""Provide a new logical type."""
# mark types with a type marker type
- _information_type = ITypeType
+ _information_type = IUndefinedContext
def __init__(self, _context, keyface, label=None, hint=None):
# register types within the type information registry
- registry = ITypeInformation
- super(TypeDirective, self).__init__(_context, keyface, registry, label, hint)
+ conface = IUndefinedContext
+ super(TypeDirective, self).__init__(_context, keyface, conface, label, hint)
def factory(self, _context, class_, operations=(), input=None,
providesFace=True, notifyCreated=False, storeInput=False):
"""Add factory."""
- factoryDirective(_context, self._keyface, class_, None, operations, input,
+ factoryDirective(_context, self._keyface, class_, operations, input,
providesFace, notifyCreated, storeInput,
self._label, self._hint)
@@ -59,7 +58,7 @@
raise ConfigurationError('Use informationsProviders or acquire attriubte.')
if acquire:
- informationProviders = [ITypeInformation]
+ informationProviders = [IUndefinedContext]
adapterDirective(_context, provides, [self._keyface], class_,
writePermission, readPermission, attributes,
Modified: zope.generic/trunk/src/zope/generic/face/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/face/README.txt 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/face/README.txt 2006-05-01 15:50:22 UTC (rev 67806)
@@ -149,8 +149,8 @@
True
Attention: Those contextual types will be not available as interface utility.
-Instead there will be an information provider
-(see zope.generic.informationprovider too):
+Instead there will be an information provider (see
+zope.generic.informationprovider too):
>>> provider = component.getUtility(IMyContext,
... api.toDottedName(IFoo))
@@ -160,8 +160,12 @@
>>> IMyContext.providedBy(provider)
True
+ >>> provider.conface == IMyContext
+ True
>>> IFoo.providedBy(provider)
+ False
+ >>> provider.keyface == IFoo
True
>>> api.IInformationProvider.providedBy(provider)
@@ -188,7 +192,7 @@
>>> adapted = api.IFace(foofaced)
>>> adapted.keyface == IFoo
True
- >>> adapted.conface == api.INoConface
+ >>> adapted.conface == api.IUndefinedContext
True
Furthermore there is simple Face mixin for AttributeFaced objects:
@@ -197,7 +201,7 @@
... __conface__ = IMyContext
>>> fooface = FooFace()
- >>> fooface.keyface == api.INoKeyface
+ >>> fooface.keyface == api.IUndefinedKeyface
True
>>> fooface.conface == IMyContext
True
@@ -207,45 +211,24 @@
>>> api.getKeyface(foofaced) == IFoo
True
- >>> api.getKeyface(fooface) == api.INoKeyface
+ >>> api.getKeyface(fooface) == api.IUndefinedKeyface
True
- >>> api.getKeyface(object())
- Traceback (most recent call last):
- ...
- TypeError: ('Could not adapt', ...)
-
- >>> api.queryKeyface(foofaced) == IFoo
+ >>> api.getKeyface(object()) == api.IUndefinedKeyface
True
-
- >>> api.queryKeyface(fooface) == api.INoKeyface
- True
- >>> api.queryKeyface(object()) == None
- True
-
The api provides convenience functions to get the context interfaces of components:
- >>> api.getConface(foofaced) == api.INoConface
+ >>> api.getConface(foofaced) == api.IUndefinedContext
True
>>> api.getConface(fooface) == IMyContext
True
- >>> api.getConface(object())
- Traceback (most recent call last):
- ...
- TypeError: ('Could not adapt', ...)
-
- >>> api.queryConface(foofaced) == api.INoConface
+ >>> api.getConface(object()) == api.IUndefinedContext
True
-
- >>> api.queryConface(fooface) == IMyContext
- True
- >>> api.queryConface(object()) == None
- True
Modified: zope.generic/trunk/src/zope/generic/face/adapter.py
===================================================================
--- zope.generic/trunk/src/zope/generic/face/adapter.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/face/adapter.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -24,8 +24,8 @@
from zope.generic.face import IAttributeFaced
from zope.generic.face import IFace
-from zope.generic.face import INoConface
-from zope.generic.face import INoKeyface
+from zope.generic.face import IUndefinedContext
+from zope.generic.face import IUndefinedKeyface
@@ -53,9 +53,9 @@
>>> faced = NoAttributeFaced()
>>> face = FaceForAttributeFaced(faced)
- >>> face.keyface is INoKeyface
+ >>> face.keyface is IUndefinedKeyface
True
- >>> face.conface is INoConface
+ >>> face.conface is IUndefinedContext
True
"""
@@ -67,8 +67,8 @@
@property
def keyface(self):
- return getattr(self.context, '__keyface__', INoKeyface)
+ return getattr(self.context, '__keyface__', IUndefinedKeyface)
@property
def conface(self):
- return getattr(self.context, '__conface__', INoConface)
+ return getattr(self.context, '__conface__', IUndefinedContext)
Modified: zope.generic/trunk/src/zope/generic/face/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/face/api.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/face/api.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -18,10 +18,15 @@
__docformat__ = 'restructuredtext'
+from zope.component import getUtilitiesFor
+from zope.component import getUtility
+
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
@@ -29,9 +34,12 @@
-def getKeyface(object):
+def getKeyface(object, default=IUndefinedKeyface):
"""Return the key interface from an object."""
+ if object is None:
+ return default
+
# todo replace IInterface by IKeyfaceType
if IInterface.providedBy(object):
if not IKeyfaceType.providedBy(object):
@@ -41,41 +49,73 @@
return object
if IAttributeFaced.providedBy(object):
- return getattr(object, '__keyface__', INoKeyface)
+ return getattr(object, '__keyface__', IUndefinedKeyface)
- return IFace(object).keyface
-
-
-
-def queryKeyface(object, default=None):
- """Return the key interface from an object or default."""
-
try:
- return getKeyface(object)
+ return IFace(object).keyface
- except:
+ except TypeError:
return default
-def getConface(object):
+def getConface(object, default=IUndefinedContext):
"""Return the context interface from an object."""
+
+ if object is None:
+ return default
if IConfaceType.providedBy(object):
return object
if IAttributeFaced.providedBy(object):
- return getattr(object, '__conface__', INoConface)
+ return getattr(object, '__conface__', IUndefinedContext)
- return IFace(object).conface
+ try:
+ return IFace(object).conface
+ except TypeError:
+ return default
-def queryConface(object, default=None):
- """Return the context interface from an object or default."""
+def getNextInformationProvider(object=None, conface=None):
+ """Evaluate the next information provider utility for an object or keyface."""
+
+ if conface is None:
+ conface = getConface(object, IUndefinedContext)
+
+ keyface = getKeyface(object)
+
try:
- return getConface(object)
+ return getUtility(conface, toDottedName(keyface))
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))
+
+ except:
+ pass
+ else:
+ raise
+
+
+
+def queryNextInformationProvider(object=None, conface=None, default=None):
+ """Evaluate the next information provider utility for an object or keyface."""
+ try:
+ return getNextInformationProvider(object, conface)
+
+ except:
return default
+
+
+
+def getNextInformationProvidersFor(provider, default=None):
+ """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
Modified: zope.generic/trunk/src/zope/generic/face/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/face/base.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/face/base.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -22,6 +22,7 @@
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
@@ -32,8 +33,8 @@
from zope.generic.face import IGlobalInformationProvider
from zope.generic.face import IKeyfaceDescription
from zope.generic.face import ILocalInformationProvider
-from zope.generic.face import INoConface
-from zope.generic.face import INoKeyface
+from zope.generic.face import IUndefinedContext
+from zope.generic.face import IUndefinedKeyface
@@ -64,17 +65,17 @@
... pass
>>> face = NoAttributeFaced()
- >>> face.__keyface__ is INoKeyface
+ >>> face.__keyface__ is IUndefinedKeyface
Traceback (most recent call last):
...
AttributeError: 'NoAttributeFaced' object has no attribute '__keyface__'
- >>> face.__conface__ is INoConface
+ >>> face.__conface__ is IUndefinedContext
Traceback (most recent call last):
...
AttributeError: 'NoAttributeFaced' object has no attribute '__conface__'
- >>> face.keyface is INoKeyface
+ >>> face.keyface is IUndefinedKeyface
True
- >>> face.conface is INoConface
+ >>> face.conface is IUndefinedContext
True
"""
@@ -82,35 +83,74 @@
@property
def keyface(self):
- return getattr(self, '__keyface__', INoKeyface)
+ return getattr(self, '__keyface__', IUndefinedKeyface)
@property
def conface(self):
- return getattr(self, '__conface__', INoConface)
+ return getattr(self, '__conface__', IUndefinedContext)
-class GlobalInformationProvider(object):
- """Global information provider."""
+class BaseInformationProvider(object):
+ """Information provider mixin.
- implements(IGlobalInformationProvider)
+ 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):
- directlyprovided = []
if __keyface__:
self.__keyface__ = __keyface__
- directlyprovided.append(__keyface__)
if __conface__:
self.__conface__ = __conface__
- directlyprovided.append(__conface__)
+ updateDirectlyProvided(self, __conface__)
- if directlyprovided:
- updateDirectlyProvided(self, directlyprovided)
+ provides('__conface__')
- provides('__keyface__', '__conface__')
-
- __keyface__ = UpdateProvides(IAttributeFaced['__keyface__'])
+ __keyface__ = FieldProperty(IAttributeFaced['__keyface__'])
__conface__ = UpdateProvides(IAttributeFaced['__conface__'])
@property
@@ -121,41 +161,45 @@
def conface(self):
return self.__conface__
+ def __conform__(self, interface):
+ raise NotImplementedErro('__conform__')
-class LocalInformationProvider(Contained, Persistent):
+_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)
- def __init__(self, __conface__=None, __keyface__=None):
- directlyprovided = []
- if __keyface__:
- self.__keyface__ = __keyface__
- directlyprovided.append(__keyface__)
-
- if __conface__:
- self.__conface__ = __conface__
- directlyprovided.append(__conface__)
+ provides('__conface__')
- if directlyprovided:
- updateDirectlyProvided(self, directlyprovided)
+ def __conform__(self, interface):
+ try:
+ return _global_information_hook[interface](self)
- provides('__keyface__', '__conface__')
+ except:
+ return None
- __keyface__ = UpdateProvides(IAttributeFaced['__keyface__'])
- __conface__ = UpdateProvides(IAttributeFaced['__conface__'])
-
- @property
- def keyface(self):
- return self.__keyface__
- @property
- def conface(self):
- return self.__conface__
-
-
class KeyfaceDescription(Face):
"""Key interface description mixin."""
Modified: zope.generic/trunk/src/zope/generic/face/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/face/interfaces.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/face/interfaces.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -29,7 +29,13 @@
from zope.generic.directlyprovides import IProvides
-class IKeyfaceType(IInterface):
+
+class IFaceType(IInterface):
+ """Mark key or context interfaces."""
+
+
+
+class IKeyfaceType(IFaceType):
"""Mark key interfaces.
The key interface is the most relevant interface of the object in relation
@@ -37,25 +43,29 @@
-class INoKeyface(Interface):
+class IUndefinedKeyface(Interface):
"""A unspecified key interface."""
-alsoProvides(INoKeyface, IKeyfaceType)
+alsoProvides(IUndefinedKeyface, IKeyfaceType)
-class IConfaceType(IInterface):
+class IConfaceType(IFaceType):
"""Mark context interfaces.
- The context interface declares the context wherein infomration about an
- object should be catched."""
+ The context interface declares the context wherein information about an
+ object should be catched.
+ Context interfaces are *allways* pure marker interfaces. Utilities and
+ adapters providing this marker. Should provide IInformationProvider by
+ adaption or implementation."""
-class INoConface(Interface):
+
+class IUndefinedContext(Interface):
"""A unspecified context interface."""
-alsoProvides(INoConface, IConfaceType)
+alsoProvides(IUndefinedContext, IConfaceType)
@@ -73,14 +83,14 @@
title=_('Key interface'),
description=_('Key interface of the underlying object.'),
readonly=True,
- default=INoKeyface,
+ default=IUndefinedKeyface,
schema=IKeyfaceType)
conface = Object(
title=_('Context interface'),
description=_('Context interface of the underlying object.'),
readonly=True,
- default=INoConface,
+ default=IUndefinedContext,
schema=IConfaceType)
@@ -91,21 +101,21 @@
The context interface is provided by the attribute __conface__.
The key interface is provided by the attribute __keyface__.
- If no attribute is defined INoConface or INoKeyface will be returned.
+ If no attribute is defined IUndefinedContext or IUndefinedKeyface will be returned.
"""
__keyface__ = Object(
title=_('Key interface'),
description=_('Key interface of the assoziated object.'),
readonly=True,
- default=INoKeyface,
+ default=IUndefinedKeyface,
schema=IKeyfaceType)
__conface__ = Object(
title=_('Context interface'),
description=_('Context interface of the assoziated object.'),
readonly=True,
- default=INoConface,
+ default=IUndefinedContext,
schema=IConfaceType)
@@ -146,8 +156,6 @@
"""Global information provider."""
+
class ILocalInformationProvider(IInformationProvider):
"""Local information provider."""
-
-
-
Modified: zope.generic/trunk/src/zope/generic/face/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/face/metaconfigure.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/face/metaconfigure.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -26,7 +26,7 @@
from zope.generic.face import IConfaceType
from zope.generic.face import IKeyfaceType
-from zope.generic.face import INoKeyface
+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
@@ -47,7 +47,7 @@
provider = queryUtility(conface, name, context=context)
- if not provider:
+ if not (provider and provider.conface == conface):
if context is None:
provider = GlobalInformationProvider(conface, keyface)
@@ -62,14 +62,18 @@
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
- provideInterface(None, keyface, IKeyfaceType)
+ if not IKeyfaceType.providedBy(keyface):
+ provideInterface(None, keyface, IKeyfaceType)
- if type:
+ if type and not type.providedBy(keyface):
# provide additional interface utility
if not IConfaceType.providedBy(type):
provideInterface(None, keyface, type)
@@ -89,10 +93,11 @@
raise ConfigurationError('Context interface %s can not be registered as key interface too.' % conface.__name__)
# provide type as soon as possilbe
- provideInterface(None, conface, IConfaceType)
+ if not IConfaceType.providedBy(conface):
+ provideInterface(None, conface, IConfaceType)
# provide additional interface utility
- if type:
+ if type and not type.providedBy(conface):
provideInterface(None, conface, type)
Modified: zope.generic/trunk/src/zope/generic/factory/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/README.txt 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/factory/README.txt 2006-05-01 15:50:22 UTC (rev 67806)
@@ -61,7 +61,7 @@
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 IOperationType too:
+or interfaces providing IOperationContext too:
>>> def init_handler(context, *pos, **kws):
... print 'initializing'
@@ -106,17 +106,16 @@
>>> events = getEvents()
>>> len(events)
- 4
+ 5
>>> clearEvents()
- >>> from zope.component import IFactory
>>> from zope.generic.face.api import toDottedName
- >>> util = component.getUtility(IFactory, name=toDottedName(IMyInstance))
+ >>> util = component.getUtility(component.IFactory, name=toDottedName(IMyInstance))
>>> util.keyface == IMyInstance
True
- >>> util = component.getUtility(api.IFactoryInformation, name=toDottedName(IMyInstance))
+ >>> util = component.getUtility(api.IFactory, 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-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/factory/adapter.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -22,7 +22,7 @@
from zope.interface import implements
from zope.generic.informationprovider.api import queryInformation
-from zope.generic.informationprovider.api import getInformationProvider
+from zope.generic.informationprovider.api import getNextInformationProvider
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-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/factory/api.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -20,7 +20,7 @@
from zope import component
-from zope.generic.informationprovider.api import getInformationProvider
+from zope.generic.informationprovider.api import getNextInformationProvider
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 = getInformationProvider(keyface, IFactoryInformation)
+ provider = getNextInformationProvider(keyface, IFactory)
config = queryInformation(provider, IOperationConfiguration)
if config:
return config.input
Modified: zope.generic/trunk/src/zope/generic/factory/configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/configure.zcml 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/factory/configure.zcml 2006-05-01 15:50:22 UTC (rev 67806)
@@ -11,11 +11,5 @@
doc_path="README.txt"
parent="zope.generic"
/>
-
- <generic:informationProvider
- keyface="zope.generic.informationprovider.IInformationProviderInformation"
- label="Factory Information"
- registry=".IFactoryInformation"
- />
</configure>
Modified: zope.generic/trunk/src/zope/generic/factory/factory.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/factory.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/factory/factory.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -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 getInformationProvider
+from zope.generic.informationprovider.api import getNextInformationProvider
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 IFactoryInformation
+from zope.generic.factory import IFactory
@@ -105,7 +105,7 @@
True
There are further features but to use them we have to register an
- an IFactoryInformation information provider including an
+ an IFactory information provider including an
IOperationConfiguration:
>>> def init_handler(context, *pos, **kws):
@@ -119,7 +119,7 @@
>>> registerDirective('''
... <generic:informationProvider
... keyface="example.IMyInstance"
- ... registry="zope.generic.factory.IFactoryInformation"
+ ... conface="zope.generic.factory.IFactory"
... >
... <information
... keyface="zope.generic.operation.IOperationConfiguration"
@@ -168,7 +168,7 @@
>>> registerDirective('''
... <generic:informationProvider
... keyface="example.IMyInstance"
- ... registry="zope.generic.factory.IFactoryInformation"
+ ... conface="zope.generic.factory.IFactory"
... >
... <information
... keyface="zope.generic.operation.IOperationConfiguration"
@@ -280,7 +280,7 @@
def __config(self):
if '_Factory__config' not in self.__dict__:
try:
- provider = getInformationProvider(self.keyface, IFactoryInformation)
+ provider = getNextInformationProvider(self.keyface, IFactory)
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-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/factory/interfaces.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -18,8 +18,14 @@
__docformat__ = 'restructuredtext'
-from zope.generic.informationprovider import IInformationProvider
+from zope.interface import alsoProvides
+from zope.interface import Interface
+from zope.generic.face import IConfaceType
-class IFactoryInformation(IInformationProvider):
- """Provide information for the factory referenced by the key interface."""
+
+
+class IFactory(Interface):
+ """Factory context."""
+
+alsoProvides(IFactory, IConfaceType)
Modified: zope.generic/trunk/src/zope/generic/factory/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/metaconfigure.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/factory/metaconfigure.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -21,29 +21,27 @@
from types import ModuleType
from zope.app.component.metaconfigure import proxify
-from zope.component import provideUtility
-from zope.component import IFactory
+from zope import component
from zope.configuration.exceptions import ConfigurationError
from zope.security.checker import CheckerPublic
from zope.security.checker import InterfaceChecker
-from zope.generic.informationprovider.api import getInformationProvider
-from zope.generic.informationprovider.api import provideInformation
-from zope.generic.informationprovider.metaconfigure import InformationProviderDirective
-from zope.generic.informationprovider.metaconfigure import provideInformationProvider
from zope.generic.face import IKeyfaceType
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.informationprovider.api import provideInformation
+from zope.generic.informationprovider.metaconfigure import InformationProviderDirective
from zope.generic.operation.api import assertOperation
from zope.generic.operation.api import provideOperationConfiguration
-from zope.generic.factory import IFactoryInformation
+from zope.generic.factory import IFactory
from zope.generic.factory.factory import Factory
-def factoryDirective(_context, keyface, class_, type=None, operations=(), input=None,
+def factoryDirective(_context, keyface, class_, operations=(), input=None,
providesFace=False, notifyCreated=False, storeInput=False,
label=None, hint=None):
"""Register a public factory."""
@@ -51,12 +49,11 @@
if isinstance(class_, ModuleType):
raise ConfigurationError('Implementation attribute must be a class')
+ type = IFactory
# assert keyface type
- if not IKeyfaceType.providedBy(keyface):
- keyfaceDirective(_context, keyface, type)
+ keyfaceDirective(_context, keyface, type)
- registry = IFactoryInformation
-
+
# set label and hint
label, hint = toDescription(keyface, label, hint)
@@ -79,26 +76,22 @@
# create and proxy type factory
factory = Factory(class_, keyface, providesFace, storeInput,
notifyCreated, label, hint, mode)
- component = proxify(factory, InterfaceChecker(IFactory, CheckerPublic))
+ proxied = proxify(factory, InterfaceChecker(component.IFactory, CheckerPublic))
_context.action(
discriminator = ('provideUtility', keyface),
- callable = provideUtility,
- args = (component, IFactory, toDottedName(keyface)),
+ callable = component.provideUtility,
+ args = (proxied, component.IFactory, toDottedName(keyface)),
)
if mode != 0:
# create operation wrapper
operation = assertOperation(operations, keyface, input, output)
+ keyfaceDirective(_context, keyface, type)
+
_context.action(
- discriminator = ('provideInformationProvider', keyface, registry),
- callable = provideInformationProvider,
- args = (keyface, registry, label, hint),
- )
-
- _context.action(
discriminator = ('provideOperationConfiguration', keyface),
callable = provideOperationConfiguration,
- args = (keyface, operation, registry, input, output),
+ args = (keyface, operation, type, input, output),
)
Modified: zope.generic/trunk/src/zope/generic/factory/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/metadirectives.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/factory/metadirectives.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -63,9 +63,6 @@
class IFactoryDirective(IBaseInformationProviderDirective, IBaseFactoryDirective, IBaseOperationDirective):
"""Register a public factory.
- The factory will be registered as information provider utility providing
- IFactoryInformation.
+ The factory will be registered as information provider utility within
+ the IFactory context.
"""
-
-
-
Modified: zope.generic/trunk/src/zope/generic/handler/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/handler/README.txt 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/handler/README.txt 2006-05-01 15:50:22 UTC (rev 67806)
@@ -22,7 +22,7 @@
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 IOperationType too:
+or interfaces providing IOperationContext too:
>>> def simplehandler(context, event):
... print 'Guguseli!'
Modified: zope.generic/trunk/src/zope/generic/informationprovider/NEW_README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/NEW_README.txt 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/informationprovider/NEW_README.txt 2006-05-01 15:50:22 UTC (rev 67806)
@@ -2,140 +2,297 @@
How to use the information package?
===================================
+Part one: Provide a framework based on information providers
+------------------------------------------------------------
+
We are developing a logger framework that can be used by user-application
domains and supplier-application domains.
-Therefore we provide two public information registries for the members of our
-orthagonal application domain such as suppliers. The log-supplier-information
-registry is holding supplier-specific informations. The log-user-information
-registry is holding user-specific informations.
+Therefore we provide two public information contexts for the members of our
+orthagonal application domains. The supplier-context information provider
+should hold supplier-specific informations. The user-context information
+provider should hold user-specific informations.
-In order to implement such an information registry we have to declare an
-*key-like* interface extending the IInformation interface:
+In order to implement those information contexts we have to declare two context
+interfaces (short: conface con[text inter]face):
- >>> class ILogSupplierInformation(api.IInformationProvider):
+ >>> class ISupplierContext(interface.Interface):
... """Store log supplier information."""
- >>> class ILogUserInformation(api.IInformationProvider):
+ >>> class IUserContext(interface.Interface):
... """Store log user information."""
This specialized information interface has to be registered later by
-informationRegistry-directive.
+face-directive:
-Such an extended information is logical container for configurations and
-annotations. In our framework example we have now to specify concrete
-configuration that are registered to the two registries by the corresponding
-member group.
+ >>> registerDirective('''
+ ... <generic:face
+ ... conface="example.ISupplierContext"
+ ... />
+ ... ''')
-A supplier has to provide global log instance (dotted name) and an optional
-time formatter. We capture this configuration information within a configuration
-that can be attached to a dedicated supplier information.
+ >>> 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:
+
>>> from zope.interface import Interface
>>> from zope.configuration.fields import GlobalObject
>>> from zope.schema import BytesLine
>>> class ILogConfiguration(Interface):
... """Define the log output."""
- ... log = GlobalObject(title=u'Log')
... timeFormat = BytesLine(title=u'Time Format', required=False, default='%d.%m.%y')
+ ... header = BytesLine(title=u'Header', required=False, default='General')
-This configuration should be registered by using the configuration directive:
+We like to use the configuration mechansim of zope.generic.configuration. Within
+this configuration facility we have to type the configuration interface by
+the zope.generic.configuration.IConfiguration context interface. This should
+be done the following way:
>>> registerDirective('''
... <generic:face
... keyface="example.ILogConfiguration"
... type="zope.generic.configuration.IConfiguration"
... />
- ... ''')
+ ... ''')
-A user has to provide logger configuration. This configuration defines the
-selected logger and a user-specific source tag:
+ >>> from zope.generic.face import IKeyfaceType
+ >>> from zope.generic.configuration import IConfiguration
- >>> from zope.configuration.fields import GlobalInterface
+ >>> IKeyfaceType.providedBy(ILogConfiguration)
+ True
+ >>> IConfiguration.providedBy(ILogConfiguration)
+ True
- >>> class ILoggerConfiguration(Interface):
- ... """Define the log output."""
- ... logger = GlobalInterface(title=u'Logger')
- ... sourceTag = BytesLine(title=u'Source Tag', required=False, default=' ')
+Components that are using our log framework can provide their own log
+configuration by adding a log configuration to the corresponding information
+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.
- >>> registerDirective('''
- ... <generic:face
- ... keyface="example.ILoggerConfiguration"
- ... type="zope.generic.configuration.IConfiguration"
- ... />
- ... ''')
+You can provide all configuration value, but at least you have to provide
+the required ones.
-TODO: Should be a dependency between informationRegistry and its configuration?
+ >>> from zope.generic.configuration.api import ConfigurationData
+ >>> supplier_default = ConfigurationData(ILogConfiguration, {'header': 'Supplier', 'timeFormat': '%y.%m.%d'})
+
>>> registerDirective('''
... <generic:informationProvider
- ... keyface='example.ILogSupplierInformation'
- ... registry='zope.generic.informationprovider.IInformationProviderInformation'
- ... />
+ ... keyface="zope.generic.face.IUndefinedKeyface"
+ ... conface="example.ISupplierContext"
+ ... >
+ ... <information
+ ... keyface="example.ILogConfiguration"
+ ... configuration="example.supplier_default"
+ ... />
+ ... </generic:informationProvider>
... ''')
+Not provided optional data are taken from the default field values:
+
+ >>> user_default = ConfigurationData(ILogConfiguration, {})
+
>>> registerDirective('''
... <generic:informationProvider
- ... keyface='example.ILogUserInformation'
- ... registry='zope.generic.informationprovider.IInformationProviderInformation'
- ... />
+ ... keyface="zope.generic.face.IUndefinedKeyface"
+ ... conface="example.IUserContext"
+ ... >
+ ... <information
+ ... keyface="example.ILogConfiguration"
+ ... configuration="example.user_default"
+ ... />
+ ... </generic:informationProvider>
... ''')
-The third part of our framework is the logger itself. The logger will be
-implmented as an adapter. We have to declare the logger interface:
+You can retrieve this configurations the following way:
- >>> class ILogger(Interface):
+ >>> 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_usercontext = api.queryNextInformationProvider(conface=IUserContext)
+ >>> api.getInformation(provider_for_nokeyface_at_usercontext, ILogConfiguration) is user_default
+ True
+
+Last we have to define our application - the log itself.
+
+ >>> class ILog(Interface):
... """Log."""
- ... def log(message):
+ ... def __call__(message):
... """Log the message."""
- >>> from zope.interface import implements
- >>> from zope.component import adapts
- >>> from zope.generic.face import IFace
+ >>> import time
+ >>> from zope.generic.face import IAttributeFaced
+ >>> from zope.generic.face import IUndefinedKeyface, IUndefinedContext
- >>> class Logger(object):
- ... """Generic logger adapter."""
- ... implements(ILogger)
- ... adapts(IFace)
+ >>> class Log(object):
+ ... """Generic log adapter."""
+ ... __keyface__ = IUndefinedKeyface
+ ... __conface__ = IUndefinedContext
+ ...
+ ... interface.implements(ILog, IAttributeFaced)
+ ... component.adapts(None)
+ ...
... def __init__(self, context):
... self.context = context
- ... def log(self, message):
- ... id = IFace(self.context())
- ... info = queryInformationProvider(id.keyface, ILogUserInformation)
- >>> class Logger(object):
- ... """Generic logger adapter."""
- ... implements(ILogger)
- ... adapts(IFace)
- ... def __init__(self, context):
- ... self.context = context
- ... def log(self, message):
- ... id = IFace(self.context())
- ... info = queryInformationProvider(id.keyface, ILogUserInformation)
- >>> class Logger(object):
- ... """Generic logger adapter."""
- ... implements(ILogger)
- ... adapts(IFace)
- ... def __init__(self, context):
- ... self.context = context
- ... def log(self, message):
- ... id = IFace(self.context())
- ... info = queryInformationProvider(id.keyface, ILogUserInformation)
+ ... def __call__(self, message):
+ ... keyface = api.getKeyface(self.context)
+ ... conface = api.getConface(self)
+ ... provider = api.getNextInformationProvider(keyface, conface)
+ ... logconfig = api.getInformation(provider, ILogConfiguration)
+ ... return '%s: %s, %s' % (logconfig.header, message,
+ ... time.strftime(logconfig.timeFormat))
+We have to provide two contextual adapters. Preferably they will be implemented
+as named adapter:
+ >>> class SupplierLog(Log):
+ ... __conface__ = ISupplierContext
-After the registration we can retrieve the registries using the
-queryInformationProvider function:
+ >>> class UserLog(Log):
+ ... __conface__ = IUserContext
+
+ >>> component.provideAdapter(SupplierLog, provides=ILog,
+ ... name=api.toDottedName(ISupplierContext))
+
+ >>> component.provideAdapter(UserLog, provides=ILog,
+ ... name=api.toDottedName(IUserContext))
+
+
+We are done. Our log framework implementation is finished. This work is done only
+once a time. Now other developer can use this framework.
+
+
+Part two: Use a framework based on information providers
+--------------------------------------------------------
+
+You can use the logger framework *as it is* without any further registrations or
+configuration:
+
+ >>> my = object()
- >>> supplier_registry = api.queryInformationProvider(ILogSupplierInformation)
- >>> supplier_registry.label
- u'Store log supplier information.'
- >>> supplier_registry.hint
- u''
+ >>> supplier_log = component.getAdapter(my, ILog, api.toDottedName(ISupplierContext))
+ >>> entry = supplier_log('Guguseli'); entry
+ 'Supplier: Guguseli, ...'
- >>> user_registry = api.queryInformationProvider(ILogUserInformation)
- >>> user_registry.label
- u'Store log user information.'
- >>> user_registry.hint
- u''
+ >>> entry == 'Supplier: Guguseli, %s' % time.strftime('%y.%m.%d')
+ True
+ >>> user_log = component.getAdapter(my, ILog, api.toDottedName(IUserContext))
+ >>> entry = user_log('Guguseli'); entry
+ 'General: Guguseli, ...'
+
+ >>> entry == 'General: Guguseli, %s' % time.strftime('%d.%m.%y')
+ True
+
+Often you like to configure the framework for dedicated components. You have
+to define an own key interface that allows you to provide specific configuration:
+
+ >>> class IMy(interface.Interface):
+ ... """My own key interface."""
+
+ >>> my_supplier = ConfigurationData(ILogConfiguration, {'header': 'My Supplier'})
+
+ >>> registerDirective('''
+ ... <generic:informationProvider
+ ... keyface="example.IMy"
+ ... conface="example.ISupplierContext"
+ ... >
+ ... <information
+ ... keyface="example.ILogConfiguration"
+ ... configuration="example.my_supplier"
+ ... />
+ ... </generic:informationProvider>
+ ... ''')
+
+
+ >>> from zope.generic.face.base import Face
+
+ >>> class My(Face):
+ ... __keyface__ = IMy
+
+ >>> my = My()
+
+We configured a log configuration within the supplier context, but none within
+the user context:
+
+ >>> supplier_log = component.getAdapter(my, ILog, api.toDottedName(ISupplierContext))
+ >>> entry = supplier_log('Guguseli'); entry
+ 'My Supplier: Guguseli, ...'
+
+ >>> user_log = component.getAdapter(my, ILog, api.toDottedName(IUserContext))
+ >>> entry = user_log('Guguseli'); entry
+ Traceback (most recent call last):
+ ...
+ ComponentLookupError: (<InterfaceClass example.IUserContext>, 'example.IMy')
+
+If we like to acquire from the default user context configuration, we have
+to derive our marker from IUndefinedKeyface.
+
+ >>> class IMy(IUndefinedKeyface):
+ ... """My own key interface."""
+
+ >>> my_supplier = ConfigurationData(ILogConfiguration, {'header': 'My Supplier'})
+
+ >>> registerDirective('''
+ ... <generic:informationProvider
+ ... keyface="example.IMy"
+ ... conface="example.ISupplierContext"
+ ... >
+ ... <information
+ ... keyface="example.ILogConfiguration"
+ ... configuration="example.my_supplier"
+ ... />
+ ... </generic:informationProvider>
+ ... ''')
+
+
+ >>> from zope.generic.face.base import Face
+
+ >>> class My(Face):
+ ... __keyface__ = IMy
+
+ >>> my = My()
+
+ >>> supplier_log = component.getAdapter(my, ILog, api.toDottedName(ISupplierContext))
+ >>> entry = supplier_log('Guguseli'); entry
+ 'My Supplier: Guguseli, ...'
+
+ >>> user_log = component.getAdapter(my, ILog, api.toDottedName(IUserContext))
+ >>> entry = user_log('Guguseli'); entry
+ 'General: Guguseli, ...'
+
+As soon as we configure the user context information provider we ca overwrite
+the default settings, too:
+
+ >>> my_user = ConfigurationData(ILogConfiguration, {'header': 'My User'})
+
+ >>> registerDirective('''
+ ... <generic:informationProvider
+ ... keyface="example.IMy"
+ ... conface="example.IUserContext"
+ ... >
+ ... <information
+ ... keyface="example.ILogConfiguration"
+ ... configuration="example.my_user"
+ ... />
+ ... </generic:informationProvider>
+ ... ''')
+
+ >>> user_log = component.getAdapter(my, ILog, api.toDottedName(IUserContext))
+ >>> entry = user_log('Guguseli'); entry
+ 'My User: Guguseli, ...'
Modified: zope.generic/trunk/src/zope/generic/informationprovider/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/README.txt 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/informationprovider/README.txt 2006-05-01 15:50:22 UTC (rev 67806)
@@ -37,43 +37,53 @@
provider as utiliy with an interface extending IInformationProvider and a
dotted name of an corresponding key interface as utility name:
- >>> from zope.generic.informationprovider.api import IInformationProvider
-
- >>> class ISpecialInformation(IInformationProvider):
+ >>> class ISpecialContext(interface.Interface):
... pass
+ >>> registerDirective('''
+ ... <generic:face
+ ... conface="example.ISpecialContext"
+ ... />
+ ... ''')
+
>>> from zope.interface import Interface
>>> class IFooMarker(Interface):
... pass
>>> registerDirective('''
+ ... <generic:face
+ ... keyface="example.IFooMarker"
+ ... />
+ ... ''')
+
+ >>> registerDirective('''
... <generic:informationProvider
... keyface="example.IFooMarker"
- ... registry="example.ISpecialInformation"
+ ... 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
-getInformationProvidersFor function:
+getNextInformationProvidersFor function:
>>> from zope.component.eventtesting import getEvents, clearEvents
>>> len(getEvents())
- 2
+ 6
>>> clearEvents()
- >>> listing = list(api.getInformationProvidersFor(ISpecialInformation))
+ >>> listing = list(api.getNextInformationProvidersFor(ISpecialContext))
>>> len(listing) is 1
True
>>> [(key.__name__, value) for key, value in listing]
- [('IFooMarker', <zope.generic.informationprovider.base.InformationProvider ...>)]
+ [('IFooMarker', <zope.generic.face.base.GlobalInformationProvider ...>)]
A single information provider can be retrieved by the get- or
-queryInformationProvider function:
+queryNextInformationProvider function:
- >>> info = api.getInformationProvider(IFooMarker, ISpecialInformation)
- >>> info = api.queryInformationProvider(IFooMarker, ISpecialInformation)
+ >>> info = api.getNextInformationProvider(IFooMarker, ISpecialContext)
+ >>> info = api.queryNextInformationProvider(IFooMarker, ISpecialContext)
>>> listing[0][1] == info
True
@@ -82,7 +92,7 @@
>>> info.keyface == IFooMarker
True
- >>> ISpecialInformation.providedBy(info)
+ >>> ISpecialContext.providedBy(info)
True
>>> info.label = u'Foo Specials'
>>> info.hint = u'Bla bla foo.'
@@ -94,11 +104,11 @@
... pass
>>> default = object()
- >>> info = api.queryInformationProvider(IBarMarker, ISpecialInformation, default)
+ >>> info = api.queryNextInformationProvider(IBarMarker, ISpecialContext, default)
>>> info is default
True
- >>> info = api.queryInformationProvider(IBarMarker, ISpecialInformation)
+ >>> info = api.queryNextInformationProvider(IBarMarker, ISpecialContext)
>>> info is None
True
@@ -156,7 +166,7 @@
>>> registerDirective('''
... <generic:informationProvider
... keyface="example.IFooMarker"
- ... registry="example.ISpecialInformation"
+ ... conface="example.ISpecialContext"
... label='Foo Specials' hint='Bla bla foo.'
... >
... <information
@@ -171,14 +181,14 @@
... ''')
>>> len(getEvents())
- 3
+ 2
>>> clearEvents()
- >>> info = api.queryInformationProvider(IFooMarker, ISpecialInformation)
+ >>> info = api.queryNextInformationProvider(IFooMarker, ISpecialContext)
>>> api.queryInformation(info, 'example.my_annotation') is my_annotation
True
- >>> info = api.queryInformationProvider(IFooMarker, ISpecialInformation)
+ >>> info = api.queryNextInformationProvider(IFooMarker, ISpecialContext)
>>> api.queryInformation(info, IMyConfiguration) is my_configuration
True
Modified: zope.generic/trunk/src/zope/generic/informationprovider/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/api.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/informationprovider/api.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -19,10 +19,11 @@
__docformat__ = 'restructuredtext'
from zope.annotation import IAnnotations
-from zope.component import getUtilitiesFor
-from zope.component import getUtility
+from zope.generic.face.api import getConface
from zope.generic.face.api import getKeyface
-from zope.generic.face.api import queryKeyface
+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 toDottedName
from zope.generic.face.api import toInterface
@@ -31,74 +32,48 @@
from zope.generic.configuration.api import ConfigurationData
from zope.generic.informationprovider import *
-from zope.generic.informationprovider.base import InformationProvider
-def getInformationProvider(object, provider=IInformationProviderInformation):
- """Evaluate an information provider for an object."""
-
- return getUtility(provider, toDottedName(getKeyface(object)))
-
-
-
-def queryInformationProvider(object, provider=IInformationProviderInformation, default=None):
- """Evalute an information provider or return default."""
- try:
- return getInformationProvider(object, provider)
-
- except:
- return default
-
-
-
-def getInformationProvidersFor(provider, default=None):
- """Evaluate all information providers of a certain information aspect."""
-
- for name, information in getUtilitiesFor(provider):
- yield (toInterface(name), information)
-
-
-
-def getInformation(context, keyface):
+def getInformation(context, informationkey):
"""Evaluate an information by a keyface (string or key keyface)."""
- if IConfiguration.providedBy(keyface):
- return keyface(IConfigurations(context))
+ if IConfiguration.providedBy(informationkey):
+ return informationkey(IConfigurations(context))
else:
- return IAnnotations(context)[keyface]
+ return IAnnotations(context)[informationkey]
-def queryInformation(context, keyface, default=None):
+def queryInformation(context, informationkey, default=None):
"""Evaluate an information by a keyface (string or key interface)."""
try:
- return getInformation(context, keyface)
+ return getInformation(context, informationkey)
except:
return default
-def provideInformation(context, keyface, information):
+def provideInformation(context, informationkey, information):
"""Set an information to a context using a keyface (string or key interface)."""
- if IConfiguration.providedBy(keyface):
+ if IConfiguration.providedBy(informationkey):
if type(information) is dict:
- information = ConfigurationData(keyface, information)
+ information = ConfigurationData(informationkey, information)
- IConfigurations(context)[keyface] = information
+ IConfigurations(context)[informationkey] = information
else:
- IAnnotations(context)[keyface] = information
+ IAnnotations(context)[informationkey] = information
-def deleteInformation(context, keyface):
+def deleteInformation(context, informationkey):
"""Delete an information of a context using a keyface (string or key interface)."""
- if IConfiguration.providedBy(keyface):
- del IConfigurations(context)[keyface]
+ if IConfiguration.providedBy(informationkey):
+ del IConfigurations(context)[informationkey]
else:
- del IAnnotations(context)[keyface]
+ del IAnnotations(context)[informationkey]
Deleted: zope.generic/trunk/src/zope/generic/informationprovider/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/base.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/informationprovider/base.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -1,89 +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.annotation import IAnnotations
-from zope.annotation import IAttributeAnnotatable
-from zope.annotation.attribute import AttributeAnnotations
-from zope.interface import alsoProvides
-from zope.interface import implements
-
-from zope.generic.configuration import IAttributeConfigurable
-from zope.generic.configuration import IConfigurations
-from zope.generic.configuration.api import AttributeConfigurations
-from zope.generic.face.api import KeyfaceDescription
-
-from zope.generic.informationprovider import IInformationProvider
-
-
-
-class InformationProvider(KeyfaceDescription):
- """Generic information provider.
-
- Information do relate a dedicated type of information marked as an interface
- extending IInformationProvider and another marker interface:
-
- >>> class ISpecialInformation(IInformationProvider):
- ... pass
-
- >>> from zope.interface import Interface
- >>> class IFooMarker(Interface):
- ... '''Foo is member of the example domain.'''
-
- >>> info = InformationProvider(IFooMarker, ISpecialInformation)
-
- The information will provide the interface of the dedicated information:
-
- >>> ISpecialInformation.providedBy(info)
- True
-
- The information is related to the interface declared by the interface
- attribute:
-
- >>> info.keyface == IFooMarker
- True
- >>> info.label
- u'IFooMarker'
-
- >>> info.hint
- u'Foo is member of the example domain.'
-
-
- Often you will provide a specific label and hint for the end-user:
-
- >>> info = InformationProvider(IFooMarker, ISpecialInformation, u'Foo', u'Bla bla.')
- >>> info.label
- u'Foo'
-
- >>> info.hint
- u'Bla bla.'
- """
-
- implements(IInformationProvider, IAttributeConfigurable, IAttributeAnnotatable)
-
- def __init__(self, keyface, provides, label=None, hint=None):
- super(InformationProvider, self).__init__(keyface, label, hint)
- alsoProvides(self, provides)
-
- def __conform__(self, interface):
- if interface is IConfigurations:
- return AttributeConfigurations(self)
-
- elif interface is IAnnotations:
- return AttributeAnnotations(self)
\ No newline at end of file
Modified: zope.generic/trunk/src/zope/generic/informationprovider/configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/configure.zcml 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/informationprovider/configure.zcml 2006-05-01 15:50:22 UTC (rev 67806)
@@ -11,11 +11,25 @@
doc_path="README.txt"
parent="zope.generic"
/>
-
- <generic:informationProvider
- keyface=".IInformationProviderInformation"
- label="Information Provider Information"
- registry=".IInformationProviderInformation"
- />
+ <!-- add configuration and annotation mechanism to generic information providers. -->
+
+ <class class="zope.generic.face.api.GlobalInformationProvider">
+ <implements
+ interface="zope.generic.configuration.IAttributeConfigurable"
+ />
+ <implements
+ interface="zope.annotation.IAttributeAnnotable"
+ />
+ </class>
+
+ <class class="zope.generic.face.api.LocalInformationProvider">
+ <implements
+ interface="zope.generic.configuration.IAttributeConfigurable"
+ />
+ <implements
+ interface="zope.annotation.IAttributeAnnotable"
+ />
+ </class>
+
</configure>
Modified: zope.generic/trunk/src/zope/generic/informationprovider/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/interfaces.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/informationprovider/interfaces.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -17,42 +17,3 @@
"""
__docformat__ = 'restructuredtext'
-
-from zope.interface import alsoProvides
-from zope.interface import Interface
-
-from zope.generic.face import IKeyfaceType
-from zope.generic.face import IKeyfaceDescription
-
-
-
-###############################################################################
-#
-# base configurations related interfaces
-#
-###############################################################################
-
-
-class IInformationProviderType(IKeyfaceType):
- """Mark information interface as information type."""
-
-
-
-class IInformationProvider(Interface):
- """Provide information about a dedicated key interfaces.
-
- A configuration related to the key interface can be stored within the
- provider's configurations.
-
- Dedicated information providers has to extend this interface.
- """
-
-
-
-class IInformationProviderInformation(IInformationProvider):
- """Provide information about information providers."""
-
-
-
-alsoProvides(IInformationProviderInformation, IInformationProviderType)
-
Modified: zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -19,79 +19,46 @@
__docformat__ = 'restructuredtext'
from zope.annotation import IAnnotations
+from zope.annotation.attribute import AttributeAnnotations
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.face import IConfaceType
+from zope.generic.face.api import ensureInformationProvider
+from zope.generic.face.api import getNextInformationProvider
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 InformationProvider
-from zope.generic.informationprovider import IInformationProvider
-from zope.generic.informationprovider import IInformationProviderInformation
-from zope.generic.informationprovider import IInformationProviderType
-from zope.generic.informationprovider.api import queryInformationProvider
+# 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 provideInformationProvider(keyface, registry=IInformationProviderInformation, label=None, hint=None, factory=None):
- """Provide new information for the given registry-interface.
- Register an information as utiliy under registry-interface using
- the dotted name of the interface as utility name:
-
- >>> class ISpecialInformation(IInformationProvider):
- ... pass
-
- >>> from zope.interface import Interface
- >>> class IFooMarker(Interface):
- ... pass
-
- >>> provideInformationProvider(IFooMarker, ISpecialInformation)
-
- The information can be queried using the following method:
-
- >>> from zope.generic.configuration.helper import queryInformationProvider
- >>> info = queryInformationProvider(IFooMarker, ISpecialInformation)
- >>> info.keyface == IFooMarker
- True
- >>> ISpecialInformation.providedBy(info)
- True
-
- """
-
- # precondition
- if not registry.extends(IInformationProvider):
- raise ValueError('Registry must extend %s.' % IInformationProvider.__name__)
-
- if factory is None:
- factory = InformationProvider
-
- component = factory(keyface, registry, label, hint)
-
- if not registry.providedBy(component):
- raise ValueError('Factory must implement %s.' % registry.__name__)
-
- provideUtility(component, provides=registry, name=toDottedName(keyface))
-
-
-
-def provideConfiguration(keyface, registry, configuration_keyface, configuration):
+def provideConfiguration(keyface, conface, configuration_keyface, configuration):
"""Provide a configuration for a certain type marker."""
- info = queryInformationProvider(keyface, registry)
+ info = getNextInformationProvider(keyface, conface)
configurations = IConfigurations(info)
configurations[configuration_keyface] = configuration
-def provideAnnotation(keyface, registry, annotation_key, annotation):
+def provideAnnotation(keyface, conface, annotation_key, annotation):
"""Provide an annotation for a certain type marker."""
- info = queryInformationProvider(keyface, registry)
+ info = getNextInformationProvider(keyface, conface)
annotations = IAnnotations(info)
annotations[annotation_key] = annotation
@@ -100,13 +67,11 @@
class InformationProviderDirective(object):
"""Provide a new information of a certain information registry."""
-
- _information_type = None
- def __init__(self, _context, keyface, registry, label=None, hint=None):
+ def __init__(self, _context, keyface, conface, label=None, hint=None):
self._keyface = keyface
self._context = _context
- self._registry = registry
+ self._conface = conface
# set label and hint
label, hint = toDescription(keyface, label, hint)
@@ -114,16 +79,9 @@
self._hint = hint
# assert type as soon as possible
- if self._information_type is not None:
- alsoProvides(keyface, self._information_type)
-
+ faceDirective(_context, keyface=keyface, conface=None, type=conface)
+
_context.action(
- discriminator = ('provideInformationProvider', self._keyface, self._registry),
- callable = provideInformationProvider,
- args = (self._keyface, self._registry, label, hint),
- )
-
- _context.action(
discriminator = None,
callable = provideInterface,
args = (None, self._keyface),
@@ -132,7 +90,7 @@
_context.action(
discriminator = None,
callable = provideInterface,
- args = (None, self._registry),
+ args = (None, self._conface),
)
def __call__(self):
@@ -149,9 +107,9 @@
_context.action(
discriminator = (
- 'informationprovider.configuration', self._keyface, self._registry, keyface),
+ 'informationprovider.configuration', self._keyface, self._conface, keyface),
callable = provideConfiguration,
- args = (self._keyface, self._registry, keyface, configuration),
+ args = (self._keyface, self._conface, keyface, configuration),
)
# handle annotation
@@ -159,9 +117,9 @@
_context.action(
discriminator = (
- 'informationprovider.annotation', self._keyface, self._registry, key),
+ 'informationprovider.annotation', self._keyface, self._conface, key),
callable = provideAnnotation,
- args = (self._keyface, self._registry, key, annotation),
+ args = (self._keyface, self._conface, key, annotation),
)
# handle wrong usage
Modified: zope.generic/trunk/src/zope/generic/informationprovider/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/metadirectives.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/informationprovider/metadirectives.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -25,7 +25,7 @@
from zope.interface import Interface
from zope.schema import DottedName
-from zope.generic.informationprovider import IInformationProvider
+from zope.generic.face import IConfaceType
from zope.generic.face.metadirectives import IKeyfaceDirective
@@ -48,15 +48,13 @@
class IInformationProviderDirective(IBaseInformationProviderDirective):
- """Directive to register an information to corresponding information
- registry."""
+ """Directive to register an information to information provider."""
- registry = GlobalInterface(
- title=_('Information Registry Key'),
- description=_('A registry key is a dedicated interface which should extend' +
- 'IInformationProvider.'),
+ conface = GlobalInterface(
+ title=_('Context Interface'),
+ description=_('The context interface provided by the information provider.'),
required=True,
- constraint=lambda v: v.extends(IInformationProvider)
+ constraint=lambda v: IConfaceType.providedBy(v)
)
Modified: zope.generic/trunk/src/zope/generic/informationprovider/testing.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/testing.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/informationprovider/testing.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -24,6 +24,7 @@
import zope.generic.face.testing
import zope.generic.testing.testing
+from zope.interface import classImplements
from zope.configuration.xmlconfig import XMLConfig
@@ -50,6 +51,15 @@
import zope.generic.informationprovider
XMLConfig('meta.zcml', zope.generic.informationprovider)()
+
+ 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
+
+ classImplements(GlobalInformationProvider, IAttributeConfigurable, IAttributeAnnotatable)
+ classImplements(LocalInformationProvider, IAttributeConfigurable, IAttributeAnnotatable)
+
def tearDown(doctest=None):
pass
Modified: zope.generic/trunk/src/zope/generic/informationprovider/tests.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/tests.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/informationprovider/tests.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -39,7 +39,6 @@
def test_suite():
return unittest.TestSuite((
- doctest.DocTestSuite('zope.generic.informationprovider.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-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/operation/README.txt 2006-05-01 15:50:22 UTC (rev 67806)
@@ -64,9 +64,9 @@
using itself or its keyface. For each operation directive an operation
information will be registered:
- >>> from zope.generic.informationprovider.api import getInformationProvidersFor
+ >>> from zope.generic.informationprovider.api import getNextInformationProvidersFor
- >>> listing = list(getInformationProvidersFor(api.IOperationInformation))
+ >>> listing = list(getNextInformationProvidersFor(api.IOperationContext))
>>> len(listing)
1
Modified: zope.generic/trunk/src/zope/generic/operation/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/api.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/operation/api.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -17,7 +17,7 @@
"""
# usage see README.txt
-from zope.generic.informationprovider.api import getInformationProvider
+from zope.generic.informationprovider.api import getNextInformationProvider
from zope.generic.informationprovider.api import getInformation
from zope.generic.operation.interfaces import *
@@ -28,7 +28,7 @@
def getOperationInformation(object):
"""Evaluate an operation information from an object."""
- return getInformationProvider(object, IOperationInformation)
+ return getNextInformationProvider(object, IOperationContext)
Modified: zope.generic/trunk/src/zope/generic/operation/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/interfaces.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/operation/interfaces.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -26,8 +26,7 @@
from zope.schema import Tuple
from zope.generic.configuration import IConfiguration
-from zope.generic.informationprovider import IInformationProvider
-from zope.generic.informationprovider import IInformationProviderType
+from zope.generic.face import IConfaceType
from zope.generic.face import IFace
from zope.generic.face import IKeyfaceType
@@ -64,22 +63,17 @@
-class IOperationInformation(IInformationProvider):
+class IOperationContext(Interface):
"""Registration about an global operation."""
-alsoProvides(IOperationInformation, IInformationProviderType)
+alsoProvides(IOperationContext, IConfaceType)
-class IOperationType(IKeyfaceType):
- """Mark operation marker interface."""
-
-
-
class IPrivateOperation(Interface):
- """Mark private callables."""
+ """Marker private, undefined callables."""
-alsoProvides(IPrivateOperation, IOperationType)
+alsoProvides(IPrivateOperation, IKeyfaceType)
Modified: zope.generic/trunk/src/zope/generic/operation/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/metaconfigure.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/operation/metaconfigure.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -25,15 +25,14 @@
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.informationprovider.api import queryInformation
-from zope.generic.informationprovider.api import queryInformationProvider
-from zope.generic.informationprovider.metaconfigure import provideInformationProvider
+from zope.generic.informationprovider.api import queryNextInformationProvider
from zope.generic.operation import IOperation
from zope.generic.operation import IOperationConfiguration
-from zope.generic.operation import IOperationInformation
-from zope.generic.operation import IOperationType
+from zope.generic.operation import IOperationContext
from zope.generic.operation.base import Operation
from zope.generic.operation.base import OperationPipe
@@ -67,9 +66,9 @@
return Operation(None, keyface, input, output)
# evaluate an operation from a operation key interface
- elif IOperationType.providedBy(handler):
- registry = IOperationInformation
- info = queryInformationProvider(handler, IOperationInformation)
+ elif IOperationContext.providedBy(handler):
+ registry = IOperationContext
+ info = queryNextInformationProvider(handler, IOperationContext)
if info is None:
ConfigurationError('Operation %s does not exist.' % handler.__name__)
@@ -90,11 +89,11 @@
def provideOperationConfiguration(keyface, operations=None, registry=None, input=None, output=None):
"""Provide the handler to an configuration information."""
- # assume configuration within an IOperationInformation
+ # assume configuration within an IOperationContext
if registry is None:
- registry = IOperationInformation
+ registry = IOperationContext
- provider = queryInformationProvider(keyface, registry)
+ provider = queryNextInformationProvider(keyface, registry)
# this should never happen...
if provider is None:
@@ -113,20 +112,13 @@
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
- if not IOperationType.providedBy(keyface):
- alsoProvides(keyface, IOperationType)
+ keyfaceDirective(_context, keyface, type)
- registry = IOperationInformation
-
_context.action(
- discriminator = ('provideInformationProvider', keyface, registry),
- callable = provideInformationProvider,
- args = (keyface, registry, label, hint),
- )
-
- _context.action(
discriminator = ('provideOperationConfiguration', keyface),
callable = provideOperationConfiguration,
- args = (keyface, operations, registry, input, output),
+ 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-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/operation/metadirectives.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -33,9 +33,9 @@
"""Register an operation."""
operations = Tokens(
- title=_('Callable, Operation or IOperationType'),
+ title=_('Callable, Operation or IOperationContext'),
description=_('Callable(context, *pos, **kws), global operation ' +
- 'or IOperationType key interface.'),
+ 'or IOperationContext key interface.'),
required=False,
value_type=GlobalObject()
)
@@ -50,10 +50,10 @@
"""Register a public operation.
The operation will be registered as information provider utility providing
- IOperationInformation.
+ IOperationContext.
The operation key interface will be registered as interface utility typed as
- IOperationType too.
+ IOperationContext too.
"""
output = GlobalInterface(title=_('Output Declaration'),
Modified: zope.generic/trunk/src/zope/generic/operation/testing.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/testing.py 2006-05-01 15:44:10 UTC (rev 67805)
+++ zope.generic/trunk/src/zope/generic/operation/testing.py 2006-05-01 15:50:22 UTC (rev 67806)
@@ -28,8 +28,7 @@
import zope.generic.operation
import zope.generic.testing.testing
-from zope.generic.informationprovider.metaconfigure import provideInformationProvider
-from zope.generic.operation import IOperationInformation
+from zope.generic.operation import IOperationContext
@@ -48,9 +47,6 @@
# specific tests
def setUp(doctest=None):
- # register operation information registry
- provideInformationProvider(IOperationInformation)
-
# register the directive of this package
XMLConfig('meta.zcml', zope.generic.operation)()
More information about the Checkins
mailing list