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

Dominik Huber dominik.huber at perse.ch
Thu Apr 13 18:55:12 EDT 2006


Log message for revision 66938:
  refactoring:
  merge .information and .configuration into .component
  rename information to information provider

Changed:
  A   zope.generic/trunk/src/zope/generic/component/DEPENDENCIES.cfg
  A   zope.generic/trunk/src/zope/generic/component/NEW_README.txt
  A   zope.generic/trunk/src/zope/generic/component/PUBLICATION.cfg
  U   zope.generic/trunk/src/zope/generic/component/README.txt
  A   zope.generic/trunk/src/zope/generic/component/README_2.txt
  A   zope.generic/trunk/src/zope/generic/component/adapter.py
  U   zope.generic/trunk/src/zope/generic/component/api.py
  U   zope.generic/trunk/src/zope/generic/component/base.py
  U   zope.generic/trunk/src/zope/generic/component/configure.zcml
  A   zope.generic/trunk/src/zope/generic/component/event.py
  U   zope.generic/trunk/src/zope/generic/component/helper.py
  U   zope.generic/trunk/src/zope/generic/component/interfaces.py
  A   zope.generic/trunk/src/zope/generic/component/meta.zcml
  A   zope.generic/trunk/src/zope/generic/component/metaconfigure.py
  A   zope.generic/trunk/src/zope/generic/component/metadirectives.py
  U   zope.generic/trunk/src/zope/generic/component/testing.py
  U   zope.generic/trunk/src/zope/generic/component/tests.py
  A   zope.generic/trunk/src/zope/generic/component/zope.generic.component-meta.zcml
  D   zope.generic/trunk/src/zope/generic/configuration/
  D   zope.generic/trunk/src/zope/generic/information/
  U   zope.generic/trunk/src/zope/generic/operation/README.txt
  U   zope.generic/trunk/src/zope/generic/operation/base.py
  U   zope.generic/trunk/src/zope/generic/operation/helper.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
  U   zope.generic/trunk/src/zope/generic/type/DEPENDENCIES.cfg
  U   zope.generic/trunk/src/zope/generic/type/EXAMPLE.txt
  U   zope.generic/trunk/src/zope/generic/type/README.txt
  U   zope.generic/trunk/src/zope/generic/type/adapter.py
  U   zope.generic/trunk/src/zope/generic/type/base.py
  U   zope.generic/trunk/src/zope/generic/type/configure.zcml
  U   zope.generic/trunk/src/zope/generic/type/helper.py
  U   zope.generic/trunk/src/zope/generic/type/interfaces.py
  U   zope.generic/trunk/src/zope/generic/type/meta.zcml
  U   zope.generic/trunk/src/zope/generic/type/metaconfigure.py
  U   zope.generic/trunk/src/zope/generic/type/metadirectives.py
  U   zope.generic/trunk/src/zope/generic/type/testing.py

-=-
Added: zope.generic/trunk/src/zope/generic/component/DEPENDENCIES.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/component/DEPENDENCIES.cfg	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/component/DEPENDENCIES.cfg	2006-04-13 22:55:09 UTC (rev 66938)
@@ -0,0 +1,9 @@
+zope.generic.component
+zope.generic.testing
+zope.app.annotation
+zope.app.component
+zope.component
+zope.configuration
+zope.interface
+zope.schema
+zope.testing


Property changes on: zope.generic/trunk/src/zope/generic/component/DEPENDENCIES.cfg
___________________________________________________________________
Name: svn:keywords
   + Id

Added: zope.generic/trunk/src/zope/generic/component/NEW_README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/component/NEW_README.txt	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/component/NEW_README.txt	2006-04-13 22:55:09 UTC (rev 66938)
@@ -0,0 +1,141 @@
+===================================
+How to use the information package?
+===================================
+
+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.
+
+In order to implement such an information registry we have to declare an
+*key-like* interface extending the IInformation interface:
+
+    >>> from zope.generic.component import IInformationProvider
+    
+    >>> class ILogSupplierInformation(IInformationProvider):
+    ...     """Store log supplier information."""
+
+    >>> class ILogUserInformation(IInformationProvider):
+    ...     """Store log user information."""
+
+This specialized information interface has to be registered later by 
+informationRegistry-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.
+
+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.
+
+    >>> 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')
+
+This configuration should be registered by using the configuration directive:
+
+    >>> registerDirective('''
+    ... <generic:configuration
+    ...     interface="example.ILogConfiguration"
+    ...     />
+    ... ''') 
+
+A user has to provide logger configuration. This configuration defines the
+selected logger and a user-specific source tag:
+
+    >>> from zope.configuration.fields import GlobalInterface
+
+    >>> class ILoggerConfiguration(Interface):
+    ...     """Define the log output."""
+    ...     logger = GlobalInterface(title=u'Logger')
+    ...     sourceTag = BytesLine(title=u'Source Tag', required=False, default='     ')   
+
+    >>> registerDirective('''
+    ... <generic:configuration
+    ...     interface="example.ILoggerConfiguration"
+    ...     />
+    ... ''') 
+
+TODO: Should be a dependency between informationRegistry and its configuration?
+
+    >>> registerDirective('''
+    ... <generic:informationRegistry
+    ...     interface='example.ILogSupplierInformation'
+    ...     />
+    ... ''')
+
+    >>> registerDirective('''
+    ... <generic:informationRegistry
+    ...     interface='example.ILogUserInformation'
+    ...     />
+    ... ''')
+
+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:
+
+    >>> class ILogger(Interface):
+    ...     """Log."""
+    ...     def log(message):
+    ...         """Log the message."""
+
+    >>> from zope.interface import implements
+    >>> from zope.component import adapts
+    >>> from zope.generic.component import IKeyInterface
+
+    >>> class Logger(object):
+    ...     """Generic logger adapter."""
+    ...     implements(ILogger)
+    ...     adapts(IKeyInterface)
+    ...     def __init__(self, context):
+    ...         self.context = context
+    ...     def log(self, message):
+    ...         id = IKeyInterface(self.context())
+    ...         info = queryInformationProvider(id.interface, ILogUserInformation)
+    >>> class Logger(object):
+    ...     """Generic logger adapter."""
+    ...     implements(ILogger)
+    ...     adapts(IKeyInterface)
+    ...     def __init__(self, context):
+    ...         self.context = context
+    ...     def log(self, message):
+    ...         id = IKeyInterface(self.context())
+    ...         info = queryInformationProvider(id.interface, ILogUserInformation)
+    >>> class Logger(object):
+    ...     """Generic logger adapter."""
+    ...     implements(ILogger)
+    ...     adapts(IKeyInterface)
+    ...     def __init__(self, context):
+    ...         self.context = context
+    ...     def log(self, message):
+    ...         id = IKeyInterface(self.context())
+    ...         info = queryInformationProvider(id.interface, ILogUserInformation)
+
+
+
+After the registration we can retrieve the registries using the
+queryInformationProvider function:
+
+    >>> from zope.generic.component.api import queryInformationProvider
+    
+    >>> supplier_registry =  queryInformationProvider(ILogSupplierInformation)
+    >>> supplier_registry.label
+    u'ILogSupplierInformation'
+    >>> supplier_registry.hint
+    u'Store log supplier information.'
+
+    >>> user_registry =  queryInformationProvider(ILogUserInformation)
+    >>> user_registry.label
+    u'ILogUserInformation'
+    >>> user_registry.hint
+    u'Store log user information.'
+


Property changes on: zope.generic/trunk/src/zope/generic/component/NEW_README.txt
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/component/PUBLICATION.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/component/PUBLICATION.cfg	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/component/PUBLICATION.cfg	2006-04-13 22:55:09 UTC (rev 66938)
@@ -0,0 +1,11 @@
+Metadata-Version: 1.0
+Name: zope.generic.component
+Summary: Information about interface based registrations
+Author: Dominik Huber, Perse Engineering GmbH, Switzerland
+Author-email: dominik.huber at perse.ch
+License: ZPL 2.1
+Description:
+        Provide facility for reusable information registry. The information
+        registries are implemented as utility providing IInformationRegistry.
+        The name of the registry is given by the dotted name of the interface
+        of the deciated information collected by the information registry.


Property changes on: zope.generic/trunk/src/zope/generic/component/PUBLICATION.cfg
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: zope.generic/trunk/src/zope/generic/component/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/component/README.txt	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/component/README.txt	2006-04-13 22:55:09 UTC (rev 66938)
@@ -1,9 +1,435 @@
-=========
-Component
-=========
+=================
+Generic Component
+=================
 
-The generic package relies heavily on interfaces. Often we have relation between
-different interfaces. One component does provide serveral interfaces so 
-Informations provides dedicated data about an certain 
-marker interface. Informations are implemented as utility. The package provides
-some convenience functions and directives.
\ No newline at end of file
+The behavior of components within the ca-framework depends heavily on their
+provided interfaces. A component, except most of the adapters and utilities, 
+regularly provides more than one interface. The adaption and subscriber 
+mechanism of the ca-framework invokes the provided interfaces by a 
+lookup-algorithmus similar to the method resolution order by class inherintance.
+
+Most of the time this behavior satisfies our requirements. Additionally this 
+package offers a mechanism to declare a single key interface (IKeyInterface).
+This key interface can be used to lookup corresponding information providers
+more explicitly. 
+
+You can register different information providers to the same key interface. An
+information provider encapsulates a certain information aspect of the key 
+interface. The relation between information providers of a key interface to
+components providing the same key interface is similar to the object class 
+relation except that each informatio aspect follows its own information 
+acquisition.
+
+You can attache generic informations such as annotations or configurations
+to an certain information provider.
+
+The annotations mechanism is well-known and documented (zope.annotations).
+
+The configurations mechansim works similar to the annotations mechansim, but 
+references a single configuration (annotation) by its corresponding 
+configuration schema (regular interfac-based schema see zope.schema). 
+Such a configuration associates data and its corresponding schema. That means
+the configuration data provides the related schema and you can allways lookup
+dedicated configuration data by its configuration schema.
+
+Similar atomic informations defined by an annotation key or a 
+configuration schemas can be reused by different information providers. So
+the identical information types will receive a contextual meaning that is related
+to information provider type.
+
+Information Provider
+--------------------
+
+You can use the information provider directive to register an information 
+provider as utiliy with an interface extending IInformationProvider and a
+dotted name of an corresponding key interface as utility name:
+
+    >>> from zope.generic.component.api import IInformationProvider
+
+    >>> class ISpecialInformation(IInformationProvider):
+    ...    pass
+
+    >>> from zope.interface import Interface
+    >>> class IFooMarker(Interface):
+    ...    pass
+
+    >>> registerDirective('''
+    ... <generic:information
+    ...     interface="example.IFooMarker"
+    ...     registry="example.ISpecialInformation"
+    ...     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:
+    
+    >>> from zope.generic.component.api import getInformationProvidersFor
+
+    >>> listing = list(getInformationProvidersFor(ISpecialInformation))
+    >>> len(listing) is 1
+    True
+    >>> [(key.__name__, value) for key, value in listing]
+    [('IFooMarker', {})]
+
+A single information provider can be retrieved by the get- or 
+queryInformationProvider function:
+
+    >>> from zope.generic.component.api import getInformationProvider
+    >>> from zope.generic.component.api import queryInformationProvider
+
+    >>> info = getInformationProvider(IFooMarker, ISpecialInformation)
+    >>> info = queryInformationProvider(IFooMarker, ISpecialInformation)
+
+    >>> listing[0][1] == info
+    True
+    >>> listing[0][0] == IFooMarker
+    True
+
+    >>> info.key == IFooMarker
+    True
+    >>> ISpecialInformation.providedBy(info)
+    True
+    >>> info.label = u'Foo Specials'
+    >>> info.hint = u'Bla bla foo.'
+
+
+
+
+If no information provider is available for a certain interface the default
+value is returned. If no default is defined None is returned:
+
+    >>> class IBarMarker(Interface):
+    ...    pass
+
+    >>> default = object()
+    >>> info = queryInformationProvider(IBarMarker, ISpecialInformation, default)
+    >>> info is default
+    True
+
+    >>> info = queryInformationProvider(IBarMarker, ISpecialInformation)
+    >>> info is None
+    True
+
+Information providers are annotable
+-----------------------------------
+
+Information providers are annotable. The annotations mechanism is used to provide
+additional informations in a generic manner:
+
+    >>> from zope.app.annotation.interfaces import IAnnotations
+
+    >>> info = queryInformationProvider(IFooMarker, ISpecialInformation)
+
+    >>> annotations = IAnnotations(info)
+    >>> annotations.get('test.annotation')
+    >>> annotations['test.annotation']
+    Traceback (most recent call last):
+    ...
+    KeyError: 'test.annotation'
+    >>> list(annotations.keys())
+    []
+    >>> del annotations['test.annotation']
+    Traceback (most recent call last):
+    ...
+    KeyError: 'test.annotation'
+    >>> annotations['test.annotation'] = 'a'
+    >>> annotations.get('test.annotation')
+    'a'
+    >>> annotations['test.annotation']
+    'a'
+    >>> list(annotations.keys())
+    ['test.annotation']
+    >>> del annotations['test.annotation']
+
+
+Information providers are configurable
+--------------------------------------
+
+Information providers are configurable. The configurations mechanism is used 
+to provide additional configurations in a generic manner. A configuration
+is declared by a configuration schema providing IConfigurationType:
+
+    >>> from zope.schema import TextLine
+        
+    >>> class IMyConfiguration(interface.Interface):
+    ...     my = TextLine(title=u'My')
+
+    >>> registerDirective('''
+    ... <generic:configuration
+    ...     interface="example.IMyConfiguration"
+    ...     label='My' hint='My bla.'
+    ...     />
+    ... ''') 
+
+    >>> from zope.generic.component.api import IConfigurationType
+
+    >>> IConfigurationType.providedBy(IMyConfiguration)
+    True
+
+For the further exploration we query this information provider:
+
+    >>> from zope.generic.component.api import IConfigurationInformation
+
+    >>> my_config_ip = queryInformationProvider(IMyConfiguration, IConfigurationInformation)
+    >>> my_config_ip.key == IMyConfiguration
+    True
+    >>> IConfigurationInformation.providedBy(my_config_ip)
+    True
+
+We now can use this configuration to extend our information provider of the
+key interface IFooMarker. At the moment there are no configurations:
+
+    >>> from zope.generic.component.api import queryInformation
+
+    >>> queryInformation(info, IMyConfiguration) is None
+    True
+
+The configuration subdirective of the information provider directive provides a mechanism
+to register further configurations to an information provider:
+
+    >>> from zope.generic.component.api import ConfigurationData
+    >>> my_information_config = ConfigurationData(IMyConfiguration, {'my': u'My!'})
+
+    >>> registerDirective('''
+    ... <generic:information
+    ...     interface="example.IFooMarker"
+    ...     registry="example.ISpecialInformation"
+    ...     label='Foo Specials' hint='Bla bla foo.'
+    ...     >
+    ...        <configuration
+    ...            interface="example.IMyConfiguration"
+    ...            data="example.my_information_config"
+    ...            />
+    ...     </generic:information>
+    ... ''')
+
+    >>> from zope.generic.component.api import queryInformationProvider
+
+    >>> info = queryInformationProvider(IFooMarker, ISpecialInformation)
+    >>> queryInformation(info, IMyConfiguration) is my_information_config
+    True
+
+
+Global Configurations
+---------------------
+
+Configurations is a container of configuration data. Configuration data are
+defined by an schema which is providing IConfigurationType. The configuration
+data itself has to provide the schema that is used to reference it.
+
+    >>> from zope.schema import TextLine
+        
+    >>> class IMyConfiguration(interface.Interface):
+    ...     my = TextLine(title=u'My')
+
+    >>> registerDirective('''
+    ... <generic:configuration
+    ...     interface="example.IMyConfiguration"
+    ...     label='My' hint='My bla.'
+    ...     />
+    ... ''') 
+
+    >>> from zope.generic.component.api import IConfigurationType
+    >>> IConfigurationType.providedBy(IMyConfiguration)
+    True
+
+The registered configuration itself is an information provider which
+is registered as utility providing IConfigurationInformation and is named
+by the dotted configuration schema name (key interface). A configuration
+is an information which can be looked up later using the get- or 
+queryInformationProvider function too:
+
+    >>> from zope.generic.component.api import IConfigurationInformation
+    >>> from zope.generic.component.api import getInformationProvider
+
+    >>> config_info = getInformationProvider(IMyConfiguration, 
+    ...        IConfigurationInformation) 
+    >>> config_info.label == u'My'
+    True
+    >>> config_info.hint == u'My bla.'
+    True
+
+The modification of configuration might cause object configured event.
+Those event extend the regular object event. This event regularly implies
+a location of the referenced object. Therefore only locatable objects will get
+notified. In our example we registered a transient global information which does
+not satify the condition:
+
+    >>> from zope.app.event.tests.placelesssetup import getEvents, clearEvents
+    >>> from zope.generic.component.api import IObjectConfiguredEvent
+
+    >>> events = getEvents()
+    >>> len(events)
+    0 
+
+Local Configurations
+--------------------
+ 
+Regularly local configurations are provided by objects marked with
+IAttributeConfigurations automatically:
+
+    >>> from zope.interface import implements
+    >>> from zope.generic.component.api import IAttributeConfigurable
+
+    >>> class Foo(object):
+    ...    implements(IAttributeConfigurable)
+
+    >>> foo = Foo()
+    >>> IAttributeConfigurable.providedBy(foo)
+    True
+
+Now you can adapt you to IConfigurations:
+
+    >>> from zope.generic.component.api import IConfigurations
+
+    >>> configurations = IConfigurations(foo)
+    >>> IConfigurations.providedBy(configurations)
+    True
+
+At the beginning the IConfigurations storage does not exists:
+
+    >>> configurations.__nonzero__()
+    False
+
+Configuration data will be stored under an key interface within the
+configurations. Such a configuration schema defines its configuration
+data:
+
+    >>> from zope.interface import Interface
+    >>> from zope.schema import TextLine
+    
+    >>> class IFooConfiguration(Interface):
+    ...    foo = TextLine(title=u'Foo')
+    ...    optional = TextLine(title=u'Optional', required=False, default=u'Bla')
+
+The configuration schema is a regular schema, but it has to be typed
+by IConfigurationType (Regularly done by the configuration directive):
+
+    >>> from zope.interface import directlyProvides
+
+    >>> directlyProvides(IFooConfiguration, IConfigurationType)
+    >>> IConfigurationType.providedBy(IFooConfiguration)
+    True
+
+The configurations provides a regular dictionary api by the UserDictMixin
+(like AttributeAnnotations). This mixin bases on the following methods:
+
+    >>> configurations[IFooConfiguration]
+    Traceback (most recent call last):
+    ...
+    KeyError: <InterfaceClass example.IFooConfiguration>
+
+    >>> del configurations[IFooConfiguration]
+    Traceback (most recent call last):
+    ...
+    KeyError: <InterfaceClass example.IFooConfiguration>
+
+    >>> configurations.keys()
+    []
+
+... if a value might be set to the configurations it must provide the 
+configuration schema itself. This key interface must provide IConfigurationType:
+
+    >>> class IBarConfiguration(Interface):
+    ...    bar = TextLine(title=u'Bar')
+
+    >>> configurations[IBarConfiguration] = object()
+    Traceback (most recent call last):
+    ...
+    KeyError: 'Interface key IBarConfiguration does not provide IConfigurationType.'
+
+    >>> configurations[IFooConfiguration] = object()
+    Traceback (most recent call last):
+    ...
+    ValueError: Value does not provide IFooConfiguration.
+
+Furthermore there is an update method that can be used to update a specific
+configuration. This method can be only used if a configuration already exists:
+
+    >>> configurations.update(IFooConfiguration, {'foo': u'Foo!'})
+    Traceback (most recent call last):
+    ...
+    KeyError: <InterfaceClass example.IFooConfiguration>
+
+You can create valid configuration data using the generic ConfigurationData
+implementation and a configuration schema:
+
+    >>> from zope.generic.component.api import ConfigurationData
+
+    >>> data = ConfigurationData(IFooConfiguration, {'foo': u'Foo!'})
+
+    >>> configurations[IFooConfiguration] = data
+
+The setting of the configuration is notified by a object configured event if 
+the parent has a location an the parent's parent is not None:
+
+    >>> events = getEvents()
+    >>> len(events)
+    0
+
+    >>> from zope.app.location import Location
+    >>> parent = Location()
+    >>> configurations.__parent__ = parent
+    
+    >>> configurations[IFooConfiguration] = data
+    >>> events = getEvents()
+    >>> len(events)
+    0
+
+    >>> parent.__parent__ = Location()
+    >>> configurations[IFooConfiguration] = data
+    >>> events = getEvents()
+    >>> len(events)
+    1
+
+    >>> event = events.pop()
+    >>> IObjectConfiguredEvent.providedBy(event)
+    True
+    >>> [(key.__name__, value) for key, value in event.items()]
+    [('IFooConfiguration', {'foo': u'Foo!', 'optional': u'Bla'})]
+
+If the configuration data is set the first time an oobtree storage is set
+to the __configurations__ attribute of the context:
+
+    >>> configurations.__nonzero__()
+    True
+
+    >>> IFooConfiguration in configurations
+    True
+
+    >>> configurations[IFooConfiguration] == data
+    True
+
+    >>> [iface.__name__ for iface in configurations.keys()]
+    ['IFooConfiguration']
+
+You should update a configuration using the update method instead of setting
+new configuration data. If the change differs from the configuration an object
+configuration modified event is notify else not:
+
+    >>> clearEvents()
+    >>> configurations.update(IFooConfiguration, {'foo': u'Bar!'})
+    >>> events = getEvents()
+    >>> len(events)
+    1
+    >>> event = events.pop()
+    >>> [(key.__name__, value) for key, value in event.items()]
+    [('IFooConfiguration', {'foo': u'Bar!'})]
+
+Also the deletion is notified by an empty dict:
+
+    >>> clearEvents()
+
+    >>> del configurations[IFooConfiguration]
+    >>> IFooConfiguration in configurations
+    False
+
+    >>> events = getEvents()
+    >>> len(events)
+    1
+    >>> event = events.pop()
+    >>> [(key.__name__, value) for key, value in event.items()]
+    [('IFooConfiguration', {})]
+

Added: zope.generic/trunk/src/zope/generic/component/README_2.txt
===================================================================


Property changes on: zope.generic/trunk/src/zope/generic/component/README_2.txt
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/component/adapter.py
===================================================================
--- zope.generic/trunk/src/zope/generic/component/adapter.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/component/adapter.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -0,0 +1,174 @@
+##############################################################################
+#
+# 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 BTrees.OOBTree import OOBTree
+import transaction
+from UserDict import DictMixin
+
+from zope.app.location import Location
+from zope.app.location.interfaces import ILocation
+from zope.component import adapts
+from zope.event import notify
+from zope.interface import implements
+
+from zope.generic.component import IAttributeConfigurable
+from zope.generic.component import IConfigurationType
+from zope.generic.component import IConfigurations
+from zope.generic.component import IKeyInterface
+from zope.generic.component import IAttributeKeyInterface
+from zope.generic.component.event import Configuration
+from zope.generic.component.event import ObjectConfiguredEvent
+from zope.generic.component.helper import configuratonToDict
+from zope.generic.component.helper import toDottedName
+from zope.generic.component.helper import toKeyInterface
+
+
+class KeyInterface(object):
+    """Adapts IAttributeKeyInterface to IKeyInterface.
+
+    You can adapt IKeyInterface if you provide IAttributeKeyInterface:
+
+        >>> class AnyAttributeKeyInterface(KeyInterface):
+        ...    def __init__(self, key):
+        ...         self.__key_interface__ = key
+
+        >>> fake_key_interface = object()
+        >>> any = AnyAttributeKeyInterface(fake_key_interface)
+
+        >>> KeyInterface(any).key == fake_key_interface
+        True
+        >>> IKeyInterface.providedBy(KeyInterface(any))
+        True
+
+"""
+
+    implements(IKeyInterface)
+    adapts(IAttributeKeyInterface)
+
+    def __init__(self, context):
+        self.context = context
+
+    @property
+    def key(self):
+        return self.context.__key_interface__
+
+
+
+class AttributeConfigurations(DictMixin, Location):
+    """Store configurations on an object within the __configurations__ attribute.
+
+    """
+
+    implements(IConfigurations)
+
+    adapts(IAttributeConfigurable)
+
+    def __init__(self, context):
+        self.context = context
+
+    def __nonzero__(self):
+        return bool(getattr(self.context, '__configurations__', 0))
+
+    def __conform__(self, interface):
+        configurations = getattr(self.context, '__configurations__', None)
+        if configurations is None:
+            return None
+
+        else:
+            return configurations.get(toDottedName(interface), None)
+
+    def __getitem__(self, interface):
+        configurations = getattr(self.context, '__configurations__', None)
+        if configurations is None:
+            raise KeyError(interface)
+
+        return configurations[toDottedName(interface)]
+
+    def keys(self):
+        configurations = getattr(self.context, '__configurations__', None)
+        if configurations is None:
+            return []
+
+        return [toKeyInterface(iface) for iface in configurations.keys()]
+
+    def update(self, interface, data):
+        current_config = self[interface]
+
+        updated_data = {}
+        errors = []
+        
+        savepoint = transaction.savepoint()
+        try:
+            for name, value in data.items():
+                # raise attribute error
+                field = interface[name]
+                if field.readonly:
+                    raise ValueError(name, 'Data is readonly.')
+                else:
+                    if value != getattr(current_config, name, field.missing_value):
+                        setattr(current_config, name, value)
+                        updated_data[name] = value
+
+            # notify update
+            parent = self.__parent__
+            if updated_data and ILocation.providedBy(parent) and parent.__parent__ is not None:
+                notify(ObjectConfiguredEvent(parent, 
+                    Configuration(interface, updated_data)))
+
+        except:
+            savepoint.rollback()
+            raise
+
+    def __setitem__(self, interface, value):
+        # preconditions
+        if not IConfigurationType.providedBy(interface):
+            raise KeyError('Interface key %s does not provide %s.' % 
+                (interface.__name__, IConfigurationType.__name__))
+
+        if not interface.providedBy(value):
+            raise ValueError('Value does not provide %s.' % interface.__name__)
+
+        # essentials
+        try:
+            configurations = self.context.__configurations__
+        except AttributeError:
+            configurations = self.context.__configurations__ = OOBTree()
+
+        data = configuratonToDict(interface, value, all=True)
+        configurations[toDottedName(interface)] = value
+        # notify setting
+        parent = self.__parent__
+        if ILocation.providedBy(parent) and parent.__parent__ is not None:
+            notify(ObjectConfiguredEvent(parent, 
+                Configuration(interface, data)))
+
+    def __delitem__(self, interface):
+        try:
+            configurations = self.context.__configurations__
+        except AttributeError:
+            raise KeyError(interface)
+
+        del configurations[toDottedName(interface)]
+        # notify deletion
+        # notify setting
+        parent = self.__parent__
+        if ILocation.providedBy(parent) and parent.__parent__ is not None:
+            notify(ObjectConfiguredEvent(parent, 
+                Configuration(interface, {})))


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

Modified: zope.generic/trunk/src/zope/generic/component/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/component/api.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/component/api.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -18,8 +18,113 @@
 
 __docformat__ = 'restructuredtext'
 
+from zope.app.annotation import IAnnotations
+from zope.component import getUtilitiesFor
+from zope.component import getUtility
+from zope.interface.interfaces import IInterface
+
+from zope.generic.component import *
+from zope.generic.component.base import ConfigurationData
+from zope.generic.component.base import InformationProvider
+from zope.generic.component.base import KeyInterface
 from zope.generic.component.base import KeyInterfaceDescription
-from zope.generic.component.helper import getKey
-from zope.generic.component.helper import queryKey
-from zope.generic.component.helper import toComponent
+from zope.generic.component.helper import configuratonToDict
 from zope.generic.component.helper import toDottedName
+from zope.generic.component.helper import toKeyInterface
+
+
+
+def getKey(object):
+    """Evaluate the interface key from an object."""
+
+    if IInterface.providedBy(object):
+        interface = object
+
+    elif IKeyInterface.providedBy(object):
+        interface = object.interface
+
+    else:
+        interface = IKeyInterface(object).interface
+
+    return interface
+
+
+
+def queryKey(object, default=None):
+    """Evaluate the interface key from an object."""
+
+    try:
+        return getKey(object)
+
+    except:
+        return default
+
+
+
+def getInformationProvider(object, provider=IInformationProviderInformation):
+    """Evaluate an information provider for an object."""
+
+    return getUtility(provider, toDottedName(getKey(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 (toKeyInterface(name), information)
+
+
+
+def getInformation(context, key):
+    """Evaluate an information by a key (string or key interface)."""
+    if IConfigurationType.providedBy(key):
+        return key(IConfigurations(context))
+
+    else:
+        return IAnnotations(context)[key]
+
+
+
+def queryInformation(context, key, default=None):
+    """Evaluate an information by a key (string or key interface)."""
+    try:
+        return getInformation(context, key)
+
+    except:
+        return default
+
+
+
+def provideInformation(context, key, information):
+    """Set an information to a context using a key (string or key interface)."""
+
+    if IConfigurationType.providedBy(key):
+        if type(information) is dict:
+            information = ConfigurationData(key, information)
+    
+        IConfigurations(context)[key] = information
+
+    else:
+        IAnnotations(context)[key] = information
+
+
+
+def deleteInformation(context, key):
+    """Delete an information of a context using a key (string or key interface)."""
+
+    if IConfigurationType.providedBy(key):
+        del IConfigurations(context)[key]
+    
+    else:
+        del IAnnotations(context)[key]

Modified: zope.generic/trunk/src/zope/generic/component/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/component/base.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/component/base.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -18,27 +18,266 @@
 
 __docformat__ = 'restructuredtext'
 
+from persistent import Persistent
+from persistent.dict import PersistentDict
+
+from zope.app.annotation.interfaces import IAttributeAnnotatable
 from zope.app.i18n import ZopeMessageFactory as _
+from zope.interface import alsoProvides
+from zope.interface import directlyProvides
 from zope.interface import implements
+from zope.interface.interfaces import IMethod
+from zope.schema.interfaces import IField
 
+from zope.generic.component import IAttributeConfigurable
+from zope.generic.component import IConfigurationData
+from zope.generic.component import IConfigurations
+from zope.generic.component import IInformationProvider
+from zope.generic.component import IKeyInterface
+from zope.generic.component import IAttributeKeyInterface
 from zope.generic.component import IKeyInterfaceDescription
+from zope.generic.component import adapter
+from zope.generic.component.helper import toDottedName
 
 
 
-class KeyInterfaceDescription(object):
-    """Information description."""
+class KeyInterface(object):
+    """Key interface mixin for key interface attribute implementations.
+    
+    You can mixin this class if you like to provide IKeyInterface for
+    IAttributeKeyInterface implementations:
 
+        >>> class AnyAttributeKeyInterface(KeyInterface):
+        ...    def __init__(self, key):
+        ...         self.__key_interface__ = key
+
+        >>> fake_key_interface = object()
+        >>> any = AnyAttributeKeyInterface(fake_key_interface)
+        >>> any.__key_interface__ == fake_key_interface
+        True
+
+    You get only the following method decorator for free :):
+
+        >>> any.key == fake_key_interface
+        True
+            
+    """
+
+    implements(IKeyInterface)
+
+    @property
+    def key(self):
+        return self.__key_interface__
+
+
+
+class KeyInterfaceDescription(KeyInterface):
+    """Key interface description mixin."""
+
     implements(IKeyInterfaceDescription)
 
-    def __init__(self, interface, label=None, hint=None):
-        self.interface = interface
+    def __init__(self, key, label=None, hint=None):
+        self.__key_interface__ = key
 
         if label is None:
-            self.label = _(interface.__name__)
+            self.label = _(key.__name__)
         else:
             self.label = label
 
         if hint is None:
-            self.hint = _(interface.__doc__)
+            self.hint = _(key.__doc__)
         else:
             self.hint = hint
+
+
+
+_marker = object()
+
+class ConfigurationData(Persistent):
+    """Generic configuration data.
+    
+    The generic configuration data implementation can be used to create
+    instances providing a certain configuration schema on the fly. This is done
+    only by a __getattr__ and a __setattr__ method that asserts the configuration
+    schema constraint.
+
+    We first have to define an example configuration schema:
+
+        >>> from zope.interface import Interface
+        >>> from zope.schema import TextLine
+        
+        >>> class IExampleConfiugrationSchema(Interface):
+        ...    foo = TextLine(title=u'Foo')
+        ...    fuu = TextLine(title=u'Fuu', required=False)
+        ...    fii = TextLine(title=u'Fii', required=False, readonly=True)
+
+    Create a corresponding configuration data:
+
+        >>> config_data = ConfigurationData(IExampleConfiugrationSchema, {'foo': u'Foo!'})
+        >>> IExampleConfiugrationSchema.providedBy(config_data)
+        True
+        >>> config_data.foo
+        u'Foo!'
+        >>> config_data.fuu
+        
+        >>> config_data.bar
+        Traceback (most recent call last):
+        ...
+        AttributeError: bar
+        
+        >>> config_data.fii = u'Bla bla'
+        Traceback (most recent call last):
+        ...
+        ValueError: ('fii', 'Data is readonly.')
+
+    If a relevant key is missed within the data a key error is raised:
+
+        >>> config_data = ConfigurationData(IExampleConfiugrationSchema, {})
+        Traceback (most recent call last):
+        ...
+        AttributeError: 'IExampleConfiugrationSchema' object has no attribute 'foo'.
+
+    The schema should not contain methods:
+
+        >>> class IBarConfiguration(Interface):
+        ...    bar = TextLine(title=u'Bar')
+        ...    def method(self):
+        ...        pass
+
+        >>> config_data = ConfigurationData(IBarConfiguration, {'bar': u'Bar!', 'method': u'Method!'})
+        >>> config_data.bar
+        u'Bar!'
+        >>> config_data.method
+        Traceback (most recent call last):
+        ...
+        RuntimeError: ('Data value is not a schema field', 'method')
+
+    The implementation provide an adapter to IKeyInterface by its __conform__
+    method:
+
+        >>> adapted = IKeyInterface(config_data)
+        >>> IKeyInterface.providedBy(adapted)
+        True
+
+        >>> adapted.key is IBarConfiguration
+        True
+
+        
+    """
+
+    implements(IAttributeKeyInterface, IConfigurationData)
+
+    def __init__(self, schema, data):
+        # preconditions
+        missedArguments = []
+        for name in schema:
+            if name not in data:
+                field = schema[name]
+                if field.required is True:
+                    missedArguments.append(name)
+        
+        if missedArguments:
+            raise AttributeError("'%s' object has no attribute '%s'." % (schema.__name__, ', '.join(missedArguments)))
+    
+        # essentials
+        self.__dict__['_ConfigurationData__data'] = PersistentDict(data)
+        self.__dict__['__key_interface__'] = schema
+        directlyProvides(self, schema)
+
+    def __conform__(self, interface):
+        if interface is IKeyInterface:
+            return adapter.KeyInterface(self)
+
+    def __getattr__(self, name):
+        # assert IAttributeKeyInterface
+        if name == '__key_interface__':
+            return self.__dict__['__key_interface__']
+
+        schema = self.__dict__['__key_interface__']
+        data = self.__dict__['_ConfigurationData__data']
+        try:
+            field = schema[name]
+        except KeyError:
+            raise AttributeError(name)
+        else:
+            value = data.get(name, _marker)
+            if value is _marker:
+                value = getattr(field, 'default', _marker)
+                if value is _marker:
+                    raise RuntimeError('Data is missing', name)
+
+            if IMethod.providedBy(field):
+                if not IField.providedBy(field):
+                    raise RuntimeError('Data value is not a schema field', name)
+                v = lambda: value
+            else:
+                v = value
+            #setattr(self, name, v)
+            return v
+        raise AttributeError(name)
+
+    def __setattr__(self, name, value):
+        schema = self.__dict__['__key_interface__']
+        data = self.__dict__['_ConfigurationData__data']
+
+        if name != '__provides__':
+            try:
+                field = schema[name]
+            except KeyError:
+                raise AttributeError(name)
+            else:
+                if field.readonly is True:
+                    raise ValueError(name, 'Data is readonly.')
+            data[name] = value
+        else:
+            super(ConfigurationData, self).__setattr__(name, value)
+
+
+
+class InformationProvider(KeyInterfaceDescription, dict):
+    """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.key == 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, key, provides, label=None, hint=None):
+        super(InformationProvider, self).__init__(key, label, hint)
+        alsoProvides(self, provides)
\ No newline at end of file

Modified: zope.generic/trunk/src/zope/generic/component/configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/component/configure.zcml	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/component/configure.zcml	2006-04-13 22:55:09 UTC (rev 66938)
@@ -3,4 +3,38 @@
   xmlns:generic="http://namespaces.zope.org/generic"
   i18n_domain="zope">
 
+  <generic:information
+      interface=".IConfigurationInformation"
+      label="Configuration Information"
+      registry="zope.generic.component.IInformationProviderInformation"
+      />
+ 
+  <generic:information
+      interface=".IInformationProviderInformation"
+      label="Information Provider Information"
+      registry=".IInformationProviderInformation"
+      />
+ 
+   <!-- attribute configurations -->
+  <class class=".adapter.AttributeConfigurations">
+    <require
+        permission="zope.Public"
+        interface=".IReadConfigurations"
+        />
+    <require
+        permission="zope.ManageContent"
+        interface=".IUpdateConfigurations"
+        />
+    <require
+        permission="zope.ManageSite"
+        interface=".IWriteConfigurations"
+        />
+  </class>
+
+  <adapter 
+  	  factory=".adapter.AttributeConfigurations"
+  	  provides="zope.generic.component.IConfigurations"
+  	  trusted="True"
+  	  />
+
 </configure>

Added: zope.generic/trunk/src/zope/generic/component/event.py
===================================================================
--- zope.generic/trunk/src/zope/generic/component/event.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/component/event.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -0,0 +1,145 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.app.event.objectevent import ObjectEvent
+from zope.interface import implements
+
+from zope.generic.component import IObjectConfiguredEvent
+from zope.generic.component import IConfigurationModificationDescription
+
+
+
+class Configuration(object) :
+    """Describes a single modified configuration.
+
+    A possible configuration schema:
+
+        >>> from zope.interface import Interface
+        >>> from zope.schema import TextLine
+        
+        >>> class IMyConfiguration(Interface):
+        ...     my = TextLine(title=u'My')
+
+    Check interface implementation:
+        
+        >>> description = Configuration(IMyConfiguration, {'my': u'Bla'})
+
+        >>> IConfigurationModificationDescription.providedBy(description)
+        True
+
+        >>> description.interface == IMyConfiguration
+        True
+
+        >>> 'my' in description.data
+        True
+        >>> description.data.get('my')
+        u'Bla'
+
+    If no data argument is set, the data attribute will be set to an empty
+    dict, which implies that the configuration was deleted:
+
+        >>> description = Configuration(IMyConfiguration)
+        >>> description.interface == IMyConfiguration
+        True
+
+        >>> description.data
+        {}
+
+    """
+
+    implements(IConfigurationModificationDescription)
+
+    def __init__(self, interface, data=None) :
+        self.interface = interface
+        if data is not None:
+            self.data = data
+
+        else:
+            self.data = {}
+
+
+
+class ObjectConfiguredEvent(ObjectEvent):
+    """An object's configurations has been modified.
+        
+    A possible configuration schema:
+
+        >>> from zope.interface import Interface
+        >>> from zope.schema import TextLine
+                
+        >>> class IMyConfiguration(Interface):
+        ...     my = TextLine(title=u'My')
+        
+        >>> class IYourConfiguration(Interface):
+        ...     your = TextLine(title=u'Your')
+         
+        >>> class IRegularInterface(Interface):
+        ...    pass
+ 
+    A possible event:
+ 
+        >>> descriptions = []
+        >>> descriptions.append(Configuration(IMyConfiguration, {'my': u'Bla'}))
+        >>> descriptions.append(Configuration(IYourConfiguration))
+        >>> from zope.app.event.objectevent import Attributes
+        >>> descriptions.append(Attributes(IRegularInterface))
+        >>> context = object()
+        >>> event = ObjectConfiguredEvent(context, *descriptions)
+
+    There are two convenience function to introspect configuration modifications
+    specifically:
+
+        >>> len(event.descriptions) is 3
+        True
+
+        >>> items = event.items()
+        >>> len(items) is 2
+        True
+        >>> [(interface.__name__, data) for interface, data in items]
+        [('IMyConfiguration', {'my': u'Bla'}), ('IYourConfiguration', {})]
+
+        >>> event.get(IMyConfiguration)
+        {'my': u'Bla'}
+
+        >>> event.get(IYourConfiguration)
+        {}
+
+        >>> event.get(IRegularInterface, 'default')
+        'default'
+    """
+
+    implements(IObjectConfiguredEvent)
+
+    def __init__(self, object, *descriptions):
+        super(ObjectConfiguredEvent, self).__init__(object) 
+        self.descriptions = descriptions
+
+    def items(self):
+        return [(d.interface, d.data) for d in self.descriptions 
+                   if IConfigurationModificationDescription.providedBy(d)]
+
+    def get(self, interface, default=None):
+        result = [d.data for d in self.descriptions 
+                   if IConfigurationModificationDescription.providedBy(d) and d.interface is interface]
+        if result:
+            return result[0]
+
+        else:
+            return default


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

Modified: zope.generic/trunk/src/zope/generic/component/helper.py
===================================================================
--- zope.generic/trunk/src/zope/generic/component/helper.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/component/helper.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -19,12 +19,9 @@
 __docformat__ = 'restructuredtext'
 
 from zope.dottedname.resolve import resolve
-from zope.interface.interfaces import IInterface
 
-from zope.generic.component import IKeyInterface
 
 
-
 def toDottedName(component):
     if component is None:
         return 'None'
@@ -34,7 +31,7 @@
 # cache
 __name_to_component = {}
 
-def toComponent(name):
+def toKeyInterface(name):
     try:
         return __name_to_component[name]
     except KeyError:
@@ -42,27 +39,54 @@
 
 
 
-def getKey(component):
-    """Evaluate the interface key from a component."""
+_marker = object()
 
-    if IInterface.providedBy(component):
-        interface = component
+def configuratonToDict(interface, configuration, all=False):
+    """Extract values from configuration to a dictionary.
 
-    elif IKeyInterface.providedBy(component):
-        interface = component.interface
+    First we have to specify a test configurtion interface:
 
-    else:
-        interface = IKeyInterface(component).interface
+        >>> from zope.interface import Interface
+        >>> from zope.schema import TextLine
+        
+        >>> class IFooConfiguration(Interface):
+        ...    fo = TextLine(title=u'Fo')
+        ...    foo = TextLine(title=u'Foo', required=False)
+        ...    fooo = TextLine(title=u'Fooo', required=False, readonly=True, default=u'fooo bla')
 
-    return interface
+    Minimal data without defaults:
 
+        >>> from zope.generic.component.base import ConfigurationData
+        >>> configuration = ConfigurationData(IFooConfiguration, {'fo': 'fo bla'})
+        >>> configuratonToDict(IFooConfiguration, configuration)
+        {'fo': 'fo bla'}
 
+    Including defaults:
+        >>> configuratonToDict(IFooConfiguration, configuration, all=True)
+        {'fooo': u'fooo bla', 'foo': None, 'fo': 'fo bla'}
 
-def queryKey(component, default=None):
-    """Evaluate the interface key from a component."""
+    """
+    data = {}
+    for name in interface:
+        value = getattr(configuration, name, _marker)
+        field = interface[name]
 
-    try:
-        return getKey(component)
+        if field.required is False:
+            if value is not _marker and value != field.default:
+               data[name] = value
 
-    except:
-        return default
+            elif value == field.default:
+                if all:
+                    data[name] = value
+
+            else:
+                if all:
+                    data[name] = field.default
+        
+        elif value is not _marker:
+            data[name] = value
+
+        else:
+            raise RuntimeError('Data is missing', name)
+
+    return data

Modified: zope.generic/trunk/src/zope/generic/component/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/component/interfaces.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/component/interfaces.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -18,14 +18,27 @@
 
 __docformat__ = 'restructuredtext'
 
+from zope.app.event.interfaces import IModificationDescription
+from zope.app.event.interfaces import IObjectEvent
 from zope.app.i18n import ZopeMessageFactory as _
+from zope.app.location import ILocation
 from zope.interface import Interface
+from zope.interface import alsoProvides
+from zope.interface import Attribute
 from zope.interface.interfaces import IInterface
+from zope.schema import Bool
+from zope.schema import Dict
 from zope.schema import Object
 from zope.schema import Text
 from zope.schema import TextLine
+from zope.schema import Tuple
 
 
+###############################################################################
+#
+# Base key interface related interfaces  
+#
+###############################################################################
 
 class IKeyInterfaceProvider(Interface):
     """Assert that a key interface can be looked up.
@@ -34,11 +47,17 @@
 
 
 
-class IKeyInterfaceAttributeProvider(IKeyInterfaceProvider):
-    """Provide the key interface within an attribute.
+class IAttributeKeyInterface(IKeyInterfaceProvider):
+    """Provide the key interface within the __key_interface__ attribute."""
 
-    The key interface is stored within the __key_interface__ attribute.
-    """
+    __key_interface__ = Object(
+        title=_('Key interface'),
+        description=_('Key interface that allows to lookup ' +
+                      'key-interface-specific informations such as ' +
+                      'configurations providers.'),
+        required=True,
+        readonly=True,
+        schema=IInterface)
 
 
 
@@ -48,10 +67,9 @@
     You can use this key to lookup component-specific informations.
     """
 
-    interface = Object(
-        title=_('Interface'),
-        description=_('Interface marker that can be used as' +
-                      'interface-specific-key to lookup informations.'),
+    key = Object(
+        title=_('Key interface'),
+        description=_('Key interface of the adapted context.'),
         required=True,
         readonly=True,
         schema=IInterface)
@@ -59,14 +77,215 @@
 
 
 class IKeyInterfaceDescription(IKeyInterface):
-    """Describe the associated interface key."""
+    """User description about the associated key interface."""
 
     label = TextLine(title=_('Label'),
-        description=_('Label for associated interface marker.'),
+        description=_('Label for associated key interface.'),
         required=True
         )  
 
     hint = Text(title=_('Hint'),
-        description=_('Hint explaning the properties of the associated interface marker.'),
+        description=_('Hint explaning the properties of the associated key interface.'),
         required=True
         )
+
+
+###############################################################################
+#
+# base configurations related interfaces 
+#
+###############################################################################
+
+class IConfigurable(Interface):
+    """Provides an adapter to IConfigurations."""
+
+
+
+class IConfigurationType(IInterface):
+    """Mark a schema that is used for configuration."""
+
+
+
+class IConfigurationData(IKeyInterfaceProvider):
+    """Marker for configuration data implementations."""
+
+
+
+class IReadConfigurations(Interface):
+    """Read configuration data or looku for a certain configuration shema."""
+
+    def __conform__(key_interface):
+        """Invoke configuration data that are stored under the key interface.
+
+        Regularly the interface-key should provide configuration type.
+        If no value could be found None is returned.
+        """
+
+    def __nonzero__():
+        """Test whether there are any configurations at all."""
+
+    def __getitem__(key_interface):
+        """Return the configuration data stored under key interface.
+
+        Raises a KeyError if the key interface is not found.
+        """
+
+    def keys(self):
+        """Return stored key interfaces."""
+
+
+
+class IUpdateConfigurations(Interface):
+    """Update configuration data."""
+
+    def update(key_interface, data):
+        """Update the configuration data partially if nessecary.
+
+        data - dict providing keys and values corresponding to key interface.
+        
+        The data object itself will not be saved, only the values that
+        differs from the existing configuration data.
+        
+        A ValueError is raised if an read-only attribute/value should be set.
+
+        A AttributeError is raised if a not declared name should be set.
+
+        A KeyError is raise if there is no corresponding configuration available.
+        
+        A successfull update is notified by a ObjectConfiguredEvent if
+        any value of the configuration data got changed and the surrounding 
+        context (parent of the configurations) is providing ILocation.
+        """
+
+
+
+class IWriteConfigurations(Interface):
+    """Set or delete a configuration data."""
+
+    def __setitem__(key_interface, configuration_data):
+        """Store a certain configuration data under the interface-key.
+
+        The interface key should provide IConfigurationType.
+
+        The configuration data has to provide the declared key interface. 
+        
+        Configuration data will be invoked by the __conform__ mechanism if
+        somebody try to adapt the configurations to corresponding key interface.
+        
+        A successfull setting is notified by a ObjectConfiguredEvent if
+        any value of the configuration data got changed and the surrounding 
+        context (parent of the configurations) is providing ILocation.
+        """
+
+    def __delitem__(key_interface):
+        """Removes the configuration data stored under interface-key.
+
+        Raises a KeyError if the key interface is not found.
+
+        A successfull deletion is notified by a ObjectConfiguredEvent if
+        any value of the configuration data got changed and the surrounding 
+        context (parent of the configurations) is providing ILocation.
+        """
+
+
+
+class IConfigurations(IReadConfigurations, IUpdateConfigurations, 
+                      IWriteConfigurations, IConfigurable, ILocation):
+    """United configurations interfaces."""
+
+
+###############################################################################
+#
+# base configurations related interfaces 
+#
+###############################################################################
+
+
+
+class IInformationProviderType(IInterface):
+    """Mark information interface as information type."""
+
+
+
+class IInformationProvider(IKeyInterfaceDescription):
+    """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)
+
+
+
+###############################################################################
+#
+# Extended key interface related interfaces 
+#
+###############################################################################
+
+
+
+
+
+###############################################################################
+#
+# Extended configurations related interfaces 
+#
+###############################################################################
+
+class IAttributeConfigurable(IConfigurable):
+    """Marker indicating that configurations can be stored on an attribute.
+    
+    This is a marker interface giving permission for an `IConfigurations`
+    adapter to store data in an attribute named `__configurations__`.
+
+    """
+
+
+AnnotationKey = 'zope.generic.component.IConfigurations'
+
+class IAnnotationsConfigurable(IConfigurable):
+    """Marker indicating that configurations can be stored on annotations.
+
+    """
+
+
+class IConfigurationModificationDescription(IModificationDescription):
+    """Declares the modified configuration by its interface and
+    the corresponding data that got modified.
+
+    An empty data dictionary implies that the configuration was deleted."""
+
+    interface = Attribute("The involved configuratoin interface.")
+    data = Attribute("A dict of modified configuration data.")
+
+
+
+class IObjectConfiguredEvent(IObjectEvent):
+    """An object's configurations has been modified.
+    
+    The corresponding modifications will be attached on the description attribute
+    """
+
+    descriptions = Attribute("Sequence of modifiaction descriptions.")
+
+    def items():
+        """List affected configuration interfaces and corresponding data from the descriptions."""
+
+    def get(interface, default=None):
+        """Return affected configuration data from the description or default."""
+
+    
+
+class IConfigurationInformation(IInformationProvider):
+    """Information about a configuration."""

Added: zope.generic/trunk/src/zope/generic/component/meta.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/component/meta.zcml	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/component/meta.zcml	2006-04-13 22:55:09 UTC (rev 66938)
@@ -0,0 +1,41 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:meta="http://namespaces.zope.org/meta">
+
+  <meta:directives namespace="http://namespaces.zope.org/generic">
+
+    <meta:directive
+        name="configuration"
+        schema=".metadirectives.IConfigurationDirective"
+        handler=".metaconfigure.configurationDirective"
+        />
+
+    <meta:complexDirective
+        name="information"
+        schema=".metadirectives.IInformationDirective"
+        handler=".metaconfigure.InformationDirective"
+        >
+
+      <meta:subdirective
+          name="configuration"
+          schema=".metadirectives.IConfigurationSubdirective"
+          />
+
+    </meta:complexDirective>
+
+    <meta:complexDirective
+        name="informationRegistry"
+        schema=".metadirectives.IInformationRegistryDirective"
+        handler=".metaconfigure.InformationRegistryDirective"
+        >
+
+      <meta:subdirective
+          name="configuration"
+          schema=".metadirectives.IConfigurationSubdirective"
+          />
+
+    </meta:complexDirective>
+
+  </meta:directives>
+
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/component/meta.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/component/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/component/metaconfigure.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/component/metaconfigure.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -0,0 +1,170 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Projekt01 GmbH and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.app.component.interface import provideInterface
+from zope.component import provideUtility
+from zope.configuration.exceptions import ConfigurationError
+from zope.interface import alsoProvides
+
+from zope.generic.component import IConfigurationInformation
+from zope.generic.component import IConfigurationType
+from zope.generic.component import IConfigurations
+from zope.generic.component import IInformationProvider
+from zope.generic.component import IInformationProviderInformation
+from zope.generic.component import IInformationProviderType
+from zope.generic.component.api import queryInformationProvider
+from zope.generic.component.base import ConfigurationData
+from zope.generic.component.base import InformationProvider
+from zope.generic.component.helper import toDottedName
+
+
+def provideInformationProvider(interface, 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.component.helper import queryInformationProvider
+        >>> info = queryInformationProvider(IFooMarker, ISpecialInformation)
+        >>> info.interface == 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(interface, registry, label, hint)
+
+    if not registry.providedBy(component):
+        raise ValueError('Factory must implement %s.' % registry.__name__)
+    
+    provideUtility(component, provides=registry, name=toDottedName(interface))
+
+
+
+def provideConfiguration(interface, registry, configuration, data):
+    """Provide configuration for a certain type marker."""
+
+    info = queryInformationProvider(interface, registry)
+    
+    configurations = IConfigurations(info)
+    configurations[configuration] = data
+
+
+
+class InformationDirective(object):
+    """Provide a new information of a certain information registry."""
+    
+    _information_type = None
+
+    def __init__(self, _context, interface, registry, label=None, hint=None):
+        self._interface = interface
+        self._context = _context
+        self._registry = registry
+    
+        # assert type as soon as possible
+        if self._information_type is not None:
+            alsoProvides(interface, self._information_type)
+    
+        _context.action(
+            discriminator = ('provideInformationProvider', self._interface, self._registry),
+            callable = provideInformationProvider,
+            args = (self._interface, self._registry, label, hint),
+            )
+    
+        _context.action(
+            discriminator = None,
+            callable = provideInterface,
+            args = (None, self._interface),
+            )
+    
+        _context.action(
+            discriminator = None,
+            callable = provideInterface,
+            args = (None, self._registry),
+            )
+
+    def __call__(self):
+        "Handle empty/simple declaration."
+        return ()
+
+    def configuration(self, _context, interface, data):
+        # preconditions
+        if not interface.providedBy(data):
+            raise ConfigurationError('Data attribute must provide %s.' % interface.__name__)
+
+        _context.action(
+            discriminator = (
+            'InformationConfiguration', self._interface, self._registry, interface),
+            callable = provideConfiguration,
+            args = (self._interface, self._registry, interface, data),
+            )
+
+
+
+def configurationDirective(_context, interface, label=None, hint=None):
+    """Provide new configuration information."""
+
+    registry = IConfigurationInformation
+    iface_type = IConfigurationType
+
+    # assert type as soon as possible
+    if not iface_type.providedBy(interface):
+        alsoProvides(interface, iface_type)
+
+    _context.action(
+        discriminator = ('provideInformationProvider', interface, registry),
+        callable = provideInformationProvider,
+        args = (interface, registry, label, hint),
+        )
+
+    _context.action(
+        discriminator = None,
+        callable = provideInterface,
+        args = (None, interface, iface_type),
+        )
+
+
+
+class InformationRegistryDirective(InformationDirective):
+    """Provide a new information registry."""
+
+    _information_type = IInformationProviderType
+
+    def __init__(self, _context, interface, label=None, hint=None):
+        super(InformationRegistryDirective, self).__init__(_context, interface, IInformationProviderInformation, label, hint)


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

Added: zope.generic/trunk/src/zope/generic/component/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/component/metadirectives.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/component/metadirectives.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -0,0 +1,96 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.app.i18n import ZopeMessageFactory as _
+from zope.configuration.fields import GlobalInterface
+from zope.configuration.fields import GlobalObject
+from zope.configuration.fields import MessageID
+from zope.interface import Interface
+
+from zope.generic.component import IInformationProvider
+
+
+
+class IBaseInformationDirective(Interface):
+    """Base information attributes."""
+
+    interface = GlobalInterface(
+        title=_('Interface'),
+        description=_('Interface that represents an information.'),
+        required=True
+        )
+
+    label = MessageID(
+        title=_('Label'),
+        description=_('Label of the information.'),
+        required=False
+        )
+
+    hint = MessageID(
+        title=_('Hint'),
+        description=_('Hint of the informtion.'),
+        required=False
+        )
+
+
+
+class IConfigurationDirective(IBaseInformationDirective):
+    """Declare configuration schema.
+
+    Register configuration schema as interface utility typed by
+    IConfigurationType within the configuration registry utility.    
+    """
+
+
+
+class IInformationDirective(IBaseInformationDirective):
+    """Directive to register an information to corresponding information
+    registry."""
+
+    registry = GlobalInterface(
+        title=_('Information Registry Key'),
+        description=_('A registry key is a dedicated interface which should extend' +
+                      'IInformationProvider.'),
+        required=True,
+        constraint=lambda v: v.extends(IInformationProvider)
+        )
+
+
+
+class IInformationRegistryDirective(IBaseInformationDirective):
+    """Directive to register an information registry."""
+
+
+
+class IConfigurationSubdirective(Interface):
+    """Declare a certain configuration of a type."""
+
+    interface = GlobalInterface(
+        title=_('Interface'),
+        description=_('Interface referencing a configuraiton.'),
+        required=True
+        )
+
+    data = GlobalObject(
+        title=_('Data'),
+        description=_('Configuration data component providing the configuraiton interface.'),
+        required=True
+        )
+


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

Modified: zope.generic/trunk/src/zope/generic/component/testing.py
===================================================================
--- zope.generic/trunk/src/zope/generic/component/testing.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/component/testing.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -18,9 +18,13 @@
 
 __docformat__ = 'restructuredtext'
 
+import zope.app.testing.placelesssetup
+from zope.component import provideAdapter
 from zope.configuration.xmlconfig import XMLConfig
+from zope.interface import Interface
+from zope.schema import TextLine
 
-import zope.app.testing.placelesssetup
+import zope.generic.component.testing
 import zope.generic.directlyprovides.testing
 import zope.generic.testing.testing
 
@@ -30,20 +34,51 @@
 #
 ################################################################################
 
+class IMarker(Interface):
+    """Demo marker."""
 
 
+class IBarConfiguration(Interface):
+
+    bar = TextLine(title=u'Bar')
+
+
+class IInputConfiguration(Interface):
+
+    foo = TextLine(title=u'Foo')
+
+    bar = TextLine(title=u'Bar')
+
+
+class IFooConfiguration(Interface):
+
+    foo = TextLine(title=u'Foo')
+    
+    fo = TextLine(title=u'Fo', required=False, readonly=True, default=u'fo default')
+
+
+class TestKeyInterfaceAttriute(object):
+    __key__interface__ = IFooConfiguration
+
+
 ################################################################################
 #
 # Placeless setup
 #
 ################################################################################
 
-
-
 # specific tests
 def setUp(doctest=None):
-    pass 
+    # register attribute configurations adapter
+    import zope.generic.component.adapter
+    from zope.generic.component import IConfigurations
+    provideAdapter(zope.generic.component.adapter.AttributeConfigurations,
+        provides=IConfigurations)
 
+    # register the directive of this package
+    import zope.generic.component
+    XMLConfig('meta.zcml', zope.generic.component)()
+
 def tearDown(doctest=None):
     pass
 
@@ -56,14 +91,16 @@
         # external setup
         zope.generic.testing.testing.setUp(doctest)
         zope.generic.directlyprovides.testing.setUp(doctest)
+        zope.generic.component.testing.setUp(doctest)
         # internal setup
         setUp(doctest)
 
     def tearDown(self, doctest=None):
         super(PlacelessSetup, self).tearDown()
         # external teardown
+        zope.generic.component.testing.tearDown(doctest)
+        zope.generic.directlyprovides.testing.tearDown(doctest)
         zope.generic.testing.testing.tearDown(doctest)
-        zope.generic.directlyprovides.testing.tearDown(doctest)
         # internal teardown
         tearDown(doctest)
 

Modified: zope.generic/trunk/src/zope/generic/component/tests.py
===================================================================
--- zope.generic/trunk/src/zope/generic/component/tests.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/component/tests.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -22,23 +22,87 @@
 from zope import interface
 from zope.testing import doctest
 
-from zope.generic.configuration.testing import placelesssetup
+
+from zope.generic.testing.testing import InterfaceBaseTest
 from zope.generic.testing.testing import registerDirective
 
+from zope.generic.component import api
 from zope.generic.component import testing
 
 
+###############################################################################
+#
+# Unit tests  
+#
+###############################################################################
 
+class ConfigurationDataTest(InterfaceBaseTest):
+
+    _verify_class = False
+    _test_interface = testing.IFooConfiguration
+    _test_pos = (testing.IFooConfiguration, {'foo': u'Bla bla'})
+
+    @property
+    def _test_class(self):
+        from zope.generic.component.base import ConfigurationData
+        return  ConfigurationData
+
+    def test_readonly_attributes(self):
+        interface = self._test_interface
+        test_obj = self.makeTestObject()
+        for name in interface:
+            field = interface[name]
+            if field.readonly is True:
+                self.assertRaises(ValueError, setattr, test_obj, name, object())
+
+    def test_default_value(self):
+        interface = self._test_interface
+        test_obj = self.makeTestObject()
+        fo_field = interface['fo']
+        self.assertEqual(getattr(test_obj, 'fo'), fo_field.default)
+
+
+class KeyInterfaceAdapterTest(InterfaceBaseTest):
+
+    @property
+    def _test_interface(self):
+        from zope.generic.component import IKeyInterface
+        return  IKeyInterface
+
+    @property
+    def _test_class(self):
+        from zope.generic.component.adapter import KeyInterface
+        return KeyInterface
+
+    @property
+    def _test_pos(self):
+        return (testing.TestKeyInterfaceAttriute(),)
+
+
 def test_suite():
     return unittest.TestSuite((
+        unittest.makeSuite(ConfigurationDataTest),
+        #TODO: Why does it fail? unittest.makeSuite(KeyInterfaceAdapterTest),
+        doctest.DocTestSuite('zope.generic.component.helper'),
+        doctest.DocTestSuite('zope.generic.component.base'),
+        doctest.DocTestSuite('zope.generic.component.event'),
+        doctest.DocTestSuite('zope.generic.component.adapter'),
         doctest.DocFileSuite('README.txt',
-                             setUp=placelesssetup.setUp,
-                             tearDown=placelesssetup.tearDown,
+                             setUp=testing.placelesssetup.setUp,
+                             tearDown=testing.placelesssetup.tearDown,
                              globs={'component': component, 'interface': interface,
                              'registerDirective': registerDirective,
-                             'testing': testing},
+                             'testing': testing, 'api': api},
                              optionflags=doctest.NORMALIZE_WHITESPACE+
                                             doctest.ELLIPSIS),
+        doctest.DocFileSuite('NEW_README.txt',
+                             setUp=testing.placelesssetup.setUp,
+                             tearDown=testing.placelesssetup.tearDown,
+                             globs={'component': component, 'interface': interface,
+                             'registerDirective': registerDirective,
+                             'testing': testing, 'api': api},
+                             optionflags=doctest.NORMALIZE_WHITESPACE+
+                                            doctest.ELLIPSIS),
         ))
 
 if __name__ == '__main__': unittest.main()

Added: zope.generic/trunk/src/zope/generic/component/zope.generic.component-meta.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/component/zope.generic.component-meta.zcml	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/component/zope.generic.component-meta.zcml	2006-04-13 22:55:09 UTC (rev 66938)
@@ -0,0 +1,5 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <include package="zope.generic.component" file="meta.zcml" />
+
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/component/zope.generic.component-meta.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Modified: zope.generic/trunk/src/zope/generic/operation/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/README.txt	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/operation/README.txt	2006-04-13 22:55:09 UTC (rev 66938)
@@ -147,9 +147,9 @@
 For each operation directive we registered an operation information. This
 operation information can be retrieved:
 
-    >>> from zope.generic.information.api import registeredInformations
+    >>> from zope.generic.component.api import getInformationProvidersFor
 
-    >>> listing = list(registeredInformations(api.IOperationInformation))
+    >>> listing = list(getInformationProvidersFor(api.IOperationInformation))
     >>> len(listing)
     4
 

Modified: zope.generic/trunk/src/zope/generic/operation/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/base.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/operation/base.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -21,26 +21,29 @@
 from zope.interface import implements
 from zope.schema.fieldproperty import FieldProperty
 
+from zope.generic.component import IAttributeKeyInterface
+from zope.generic.component.api import KeyInterface
+
 from zope.generic.operation import IOperation
 from zope.generic.operation import IPrivateOperation
 
 
 
-class Operation(object):
+class Operation(KeyInterface):
     """Generic operation wrapper."""
 
     implements(IOperation)
 
-    interface = FieldProperty(IOperation['interface'])
+    interface = FieldProperty(IAttributeKeyInterface['__key_interface__'])
 
     def __init__(self, callable=None, interface=None):
         self.__callable = callable
 
         # otherwise use IPrivatConfigurationHandler
         if interface is not None:
-            self.interface = interface
+            self.__key_interface__ = interface
         else:
-            self.interface = IPrivateOperation
+            self.__key_interface__ = IPrivateOperation
 
     def __call__(self, context, *pos, **kws):
         self._proceed(context)

Modified: zope.generic/trunk/src/zope/generic/operation/helper.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/helper.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/operation/helper.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -18,8 +18,8 @@
 
 __docformat__ = 'restructuredtext'
 
-from zope.generic.information.api import getInformation
-from zope.generic.configuration.api import getConfigurationData
+from zope.generic.component.api import getInformationProvider
+from zope.generic.component.api import getInformation
 
 from zope.generic.operation import IOperationInformation
 from zope.generic.operation import IOperationConfiguration
@@ -28,7 +28,7 @@
 
 def getOperationInformation(object):
     """Evaluate an operation information from an object."""
-    return getInformation(object, IOperationInformation)
+    return getInformationProvider(object, IOperationInformation)
 
 
 
@@ -45,7 +45,7 @@
 def getOperationConfiguration(object):
     """Evaluate an operation configuration."""
     
-    return getConfigurationData(getOperationInformation(object), IOperationConfiguration)
+    return getInformation(getOperationInformation(object), IOperationConfiguration)
 
 
 

Modified: zope.generic/trunk/src/zope/generic/operation/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/interfaces.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/operation/interfaces.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -27,9 +27,10 @@
 from zope.schema import Tuple
 
 from zope.generic.component import IKeyInterface
-from zope.generic.configuration import IConfigurationType
-from zope.generic.information import IInformation
-from zope.generic.information import IInformationRegistryType
+from zope.generic.component import IConfigurationType
+from zope.generic.component import IInformationProvider
+from zope.generic.component import IInformationProviderType
+
 from zope.generic.type import ITypeType
 
 
@@ -65,10 +66,10 @@
 
 
 
-class IOperationInformation(IInformation):
+class IOperationInformation(IInformationProvider):
     """Registration about an global operation."""
 
-alsoProvides(IOperationInformation, IInformationRegistryType)
+alsoProvides(IOperationInformation, IInformationProviderType)
 
 
 

Modified: zope.generic/trunk/src/zope/generic/operation/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/metaconfigure.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/operation/metaconfigure.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -22,14 +22,14 @@
 from zope.configuration.exceptions import ConfigurationError
 from zope.interface import alsoProvides
 
-from zope.generic.information.api import queryInformation
-from zope.generic.information.metaconfigure import provideInformation
+from zope.generic.component.api import queryInformationProvider
+from zope.generic.component.metaconfigure import provideInformationProvider
 
-from zope.generic.configuration import IConfigurationType
-from zope.generic.configuration import IConfigurations
-from zope.generic.configuration.api import ConfigurationData
-from zope.generic.configuration.api import provideConfigurationData
-from zope.generic.configuration.api import queryConfigurationData
+from zope.generic.component import IConfigurationType
+from zope.generic.component import IConfigurations
+from zope.generic.component.api import ConfigurationData
+from zope.generic.component.api import provideInformation
+from zope.generic.component.api import queryInformation
 
 from zope.generic.operation import IOperation
 from zope.generic.operation import IOperationConfiguration
@@ -47,12 +47,12 @@
     
     if IOperationType.providedBy(handler):
         registry = IOperationInformation
-        info = queryInformation(handler, IOperationInformation)
+        info = queryInformationProvider(handler, IOperationInformation)
 
         if info is None:
             ConfigurationError('Operation %s does not exist.' % handler.__name__)
 
-        config = queryConfigurationData(info, IOperationConfiguration)
+        config = queryInformation(info, IOperationConfiguration)
 
         if config is None:
             ConfigurationError('OperationConfiguration for Operation %s does not exist.' % handler.__name__)
@@ -68,7 +68,7 @@
     """Provide the handler to an configuration information."""
     
     registry = IOperationInformation
-    info = queryInformation(interface, IOperationInformation)
+    info = queryInformationProvider(interface, IOperationInformation)
 
     # this should never happen...
     if info is None:
@@ -87,7 +87,7 @@
 
     configurations = IConfigurations(info)
     # create and set configuration data
-    provideConfigurationData(info, IOperationConfiguration, 
+    provideInformation(info, IOperationConfiguration, 
         {'operation': operation, 'input': tuple(input), 'output': tuple(output)})
 
 
@@ -102,8 +102,8 @@
     registry = IOperationInformation
 
     _context.action(
-        discriminator = ('provideInformation', interface, registry),
-        callable = provideInformation,
+        discriminator = ('provideInformationProvider', interface, registry),
+        callable = provideInformationProvider,
         args = (interface, registry, label, hint),
         )
 

Modified: zope.generic/trunk/src/zope/generic/operation/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/metadirectives.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/operation/metadirectives.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -23,8 +23,8 @@
 from zope.configuration.fields import GlobalObject
 from zope.configuration.fields import Tokens
 
-from zope.generic.configuration import IConfigurationType
-from zope.generic.information.metadirectives import IBaseInformationDirective
+from zope.generic.component import IConfigurationType
+from zope.generic.component.metadirectives import IBaseInformationDirective
 
 
 

Modified: zope.generic/trunk/src/zope/generic/operation/testing.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/testing.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/operation/testing.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -22,13 +22,13 @@
 
 import zope.app.testing.placelesssetup
 import zope.generic.component.testing
-import zope.generic.configuration.testing
+import zope.generic.component.testing
 import zope.generic.directlyprovides.testing
-import zope.generic.information.testing
+import zope.generic.component.testing
 import zope.generic.operation
 import zope.generic.testing.testing
 
-from zope.generic.information.api import provideInformation
+from zope.generic.component.metaconfigure import provideInformationProvider
 from zope.generic.operation import IOperationInformation
 
 
@@ -49,7 +49,7 @@
 # specific tests
 def setUp(doctest=None):
     # register operation information registry
-    provideInformation(IOperationInformation)
+    provideInformationProvider(IOperationInformation)
 
     # register the directive of this package
     XMLConfig('meta.zcml', zope.generic.operation)()
@@ -67,8 +67,8 @@
         zope.generic.testing.testing.setUp(doctest)
         zope.generic.directlyprovides.testing.setUp(doctest)
         zope.generic.component.testing.setUp(doctest)
-        zope.generic.information.testing.setUp(doctest)
-        zope.generic.configuration.testing.setUp(doctest)
+        zope.generic.component.testing.setUp(doctest)
+        zope.generic.component.testing.setUp(doctest)
         # internal setup
         setUp(doctest)
 
@@ -78,8 +78,8 @@
         zope.generic.testing.testing.tearDown(doctest)
         zope.generic.directlyprovides.testing.tearDown(doctest)
         zope.generic.component.testing.tearDown(doctest)
-        zope.generic.information.testing.tearDown(doctest)
-        zope.generic.configuration.testing.tearDown(doctest)
+        zope.generic.component.testing.tearDown(doctest)
+        zope.generic.component.testing.tearDown(doctest)
         # internal teardown
         tearDown(doctest)
 

Modified: zope.generic/trunk/src/zope/generic/type/DEPENDENCIES.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/type/DEPENDENCIES.cfg	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/type/DEPENDENCIES.cfg	2006-04-13 22:55:09 UTC (rev 66938)
@@ -1,7 +1,7 @@
 persistent
-zope.generic.configuration
+zope.generic.component
 zope.generic.directlyprovides
-zope.generic.information
+zope.generic.component
 zope.generic.testing
 zope.app.annotation
 zope.app.component

Modified: zope.generic/trunk/src/zope/generic/type/EXAMPLE.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/type/EXAMPLE.txt	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/type/EXAMPLE.txt	2006-04-13 22:55:09 UTC (rev 66938)
@@ -61,9 +61,9 @@
 Step 3: Implement Specific Handlers and the type-specific default data
 ----------------------------------------------------------------------
 
-    >>> from zope.generic.configuration.api import queryConfigurationData
-    >>> from zope.generic.configuration.api import provideConfigurationData
-    >>> from zope.generic.configuration.api import deleteConfigurationData
+    >>> from zope.generic.component.api import queryInformation
+    >>> from zope.generic.component.api import provideInformation
+    >>> from zope.generic.component.api import deleteInformation
     >>> from zope.generic.type.api import queryTypeConfiguration
 
 Let's implement the initializer of the article. Initializers are called from
@@ -77,7 +77,7 @@
     ...     - raises an exception if no configurationis defined
     ...     """
     ...     # looks up the allready configured data on the object
-    ...     article_config = queryConfigurationData(context, 
+    ...     article_config = queryInformation(context, 
     ...         IArticleInitializationConfiguration)
     ...     if article_config is None:
     ...         text_config = queryTypeConfiguration(context, ITextConfig)
@@ -86,11 +86,11 @@
     ...     else:
     ...         text, note = article_config.text, article_config.note
     ...
-    ...     provideConfigurationData(context, ITextConfig, {'body': text})
-    ...     provideConfigurationData(context, INoteConfig, {'body': note})
-    ...     deleteConfigurationData(context, IArticleInitializationConfiguration)
+    ...     provideInformation(context, ITextConfig, {'body': text})
+    ...     provideInformation(context, INoteConfig, {'body': note})
+    ...     deleteInformation(context, IArticleInitializationConfiguration)
  
-    >>> from zope.generic.configuration.api import ConfigurationData
+    >>> from zope.generic.component.api import ConfigurationData
     
     >>> textDefaults = ConfigurationData(ITextConfig, 
     ...     {'body': u"This is the default text."})
@@ -167,10 +167,10 @@
     >>> IArticle.providedBy(article)
     True
 
-    >>> queryConfigurationData(article, ITextConfig).body
+    >>> queryInformation(article, ITextConfig).body
     'First version of article.'
     
-    >>> queryConfigurationData(article, IArticleInitializationConfiguration).text
+    >>> queryInformation(article, IArticleInitializationConfiguration).text
     Traceback (most recent call last):
     ...
     AttributeError: 'NoneType' object has no attribute 'text'

Modified: zope.generic/trunk/src/zope/generic/type/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/type/README.txt	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/type/README.txt	2006-04-13 22:55:09 UTC (rev 66938)
@@ -18,7 +18,7 @@
 of instances marked by a certain type marker interface.
 
 The type directive does extend the information directive
-(see zope.generic.information).
+(see zope.generic.component).
 
 
 Base type directive
@@ -81,7 +81,7 @@
 
     >>> info = queryUtility(api.ITypeInformation, toDottedName(IFooMarker))
 
-    >>> info.interface == IFooMarker
+    >>> info.key == IFooMarker
     True
     >>> info.label
     u'Foo Type'
@@ -104,7 +104,7 @@
 
 There are serveral subdirectives like:
 
--	configurations (see zope.generic.information)
+-	configurations (see zope.generic.component)
 -	initializer
 
 You can extend type informations by the annotations and configurations mechanism
@@ -139,7 +139,7 @@
     ...     />
     ... ''') 
 
-	>>> from zope.generic.configuration.api import ConfigurationData
+	>>> from zope.generic.component.api import ConfigurationData
 	>>> typedata = ConfigurationData(IAnyConfiguration, {'any': u'Guguseli from Type!'})
 	>>> IAnyConfiguration.providedBy(typedata)
 	True
@@ -212,7 +212,7 @@
 	>>> api.acquireObjectConfiguration(bar, IOtherConfiguration).other
 	u'Specific initialization data.'
 
-    >>> from zope.generic.configuration.api import IConfigurations
+    >>> from zope.generic.component.api import IConfigurations
 	>>> objectdata = ConfigurationData(IAnyConfiguration, {'any': u'Guguseli from Object!'})
 	>>> IConfigurations(bar)[IAnyConfiguration] = objectdata
 	

Modified: zope.generic/trunk/src/zope/generic/type/adapter.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/adapter.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/type/adapter.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -28,7 +28,7 @@
 from zope.event import notify
 from zope.interface import implements
 
-from zope.generic.configuration.api import provideConfigurationData
+from zope.generic.component.api import provideInformation
 
 from zope.generic.type import IInitializer
 from zope.generic.type import IInitializerConfiguration
@@ -52,7 +52,7 @@
         if config:
             # store initialization data
             if config.interface:
-                provideConfigurationData(self.context, config.interface, kws)
+                provideInformation(self.context, config.interface, kws)
 
             # invoke initialization handler
 

Modified: zope.generic/trunk/src/zope/generic/type/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/base.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/type/base.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -27,7 +27,7 @@
 from zope.app.container import btree
 from zope.app import folder
 
-from zope.generic.configuration.api import IAttributeConfigurable
+from zope.generic.component.api import IAttributeConfigurable
 from zope.generic.directlyprovides.api import provides
 from zope.generic.directlyprovides.api import UpdateProvides
 from zope.generic.directlyprovides.api import updateDirectlyProvided

Modified: zope.generic/trunk/src/zope/generic/type/configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/type/configure.zcml	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/type/configure.zcml	2006-04-13 22:55:09 UTC (rev 66938)
@@ -4,7 +4,7 @@
   i18n_domain="zope">
 
   <generic:information
-      interface="zope.generic.information.IInformationRegistryInformation"
+      interface="zope.generic.component.IInformationProviderInformation"
       label="Type Information Registry"
       registry=".ITypeInformation"
       />

Modified: zope.generic/trunk/src/zope/generic/type/helper.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/helper.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/type/helper.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -21,8 +21,8 @@
 from zope import component
 
 from zope.generic.component.api import toDottedName
-from zope.generic.configuration.api import queryConfigurationData
-from zope.generic.information.api import queryInformation
+from zope.generic.component.api import queryInformation
+from zope.generic.component.api import queryInformationProvider
 
 from zope.generic.type import IInitializerConfiguration
 from zope.generic.type import ITypeInformation
@@ -72,7 +72,7 @@
 
 
 def getTypeInformation(object):
-    return queryInformation(getType(object), ITypeInformation)
+    return queryInformationProvider(getType(object), ITypeInformation)
 
 
 
@@ -88,13 +88,13 @@
 
 
 def queryObjectConfiguration(object, configuration, default=None):   
-    return queryConfigurationData(object, configuration, default)
+    return queryInformation(object, configuration, default)
 
 
 
 def queryTypeConfiguration(object, configuration, default=None):
     info = queryTypeInformation(object)
-    return queryConfigurationData(info, configuration, default)
+    return queryInformation(info, configuration, default)
 
 
 

Modified: zope.generic/trunk/src/zope/generic/type/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/interfaces.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/type/interfaces.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -26,9 +26,9 @@
 from zope.schema import Object
 
 from zope.generic.component import IKeyInterface
-from zope.generic.configuration import IConfigurationType
+from zope.generic.component import IConfigurationType
 from zope.generic.directlyprovides import IProvides
-from zope.generic.information import IInformation
+from zope.generic.component import IInformationProvider
 
 
 __all__ = ['ITypeType', 'ITypeable', 'ITyped', 'IDirectlyTyped', 
@@ -77,7 +77,7 @@
 
 
 
-class ITypeInformation(IInformation):
+class ITypeInformation(IInformationProvider):
     """Provide information for the declared type interface."""
 
 

Modified: zope.generic/trunk/src/zope/generic/type/meta.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/type/meta.zcml	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/type/meta.zcml	2006-04-13 22:55:09 UTC (rev 66938)
@@ -12,7 +12,7 @@
 
       <meta:subdirective
           name="configuration"
-          schema="zope.generic.information.metadirectives.IConfigurationSubdirective"
+          schema="zope.generic.component.metadirectives.IConfigurationSubdirective"
           />
 
       <meta:subdirective

Modified: zope.generic/trunk/src/zope/generic/type/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/metaconfigure.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/type/metaconfigure.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -31,9 +31,9 @@
 from zope.security.checker import InterfaceChecker
 
 from zope.generic.component.api import toDottedName
-from zope.generic.configuration.api import ConfigurationData
-from zope.generic.configuration.api import provideConfigurationData
-from zope.generic.information.metaconfigure import InformationDirective
+from zope.generic.component.api import ConfigurationData
+from zope.generic.component.api import provideInformation
+from zope.generic.component.metaconfigure import InformationDirective
 
 from zope.generic.type import IInitializationHandler
 from zope.generic.type import IInitializerConfiguration
@@ -49,7 +49,7 @@
     """Set configuration data into the context."""
 
     info = queryTypeInformation(interface)
-    provideConfigurationData(info, configuration, data)
+    provideInformation(info, configuration, data)
 
 
 

Modified: zope.generic/trunk/src/zope/generic/type/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/metadirectives.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/type/metadirectives.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -24,7 +24,7 @@
 from zope.configuration.fields import GlobalObject
 from zope.interface import Interface
 
-from zope.generic.information.metadirectives import IBaseInformationDirective
+from zope.generic.component.metadirectives import IBaseInformationDirective
 
     
 

Modified: zope.generic/trunk/src/zope/generic/type/testing.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/testing.py	2006-04-13 17:52:04 UTC (rev 66937)
+++ zope.generic/trunk/src/zope/generic/type/testing.py	2006-04-13 22:55:09 UTC (rev 66938)
@@ -22,9 +22,9 @@
 
 import zope.app.testing.placelesssetup
 import zope.generic.component.testing
-import zope.generic.configuration.testing
+import zope.generic.component.testing
 import zope.generic.directlyprovides.testing
-import zope.generic.information.testing
+import zope.generic.component.testing
 import zope.generic.testing.testing
 
 ################################################################################
@@ -63,8 +63,8 @@
         zope.generic.testing.testing.setUp(doctest)
         zope.generic.directlyprovides.testing.setUp(doctest)
         zope.generic.component.testing.setUp(doctest)
-        zope.generic.information.testing.setUp(doctest)
-        zope.generic.configuration.testing.setUp(doctest)
+        zope.generic.component.testing.setUp(doctest)
+        zope.generic.component.testing.setUp(doctest)
         # internal setup
         setUp(doctest)
 
@@ -74,8 +74,8 @@
         zope.generic.testing.testing.tearDown(doctest)
         zope.generic.directlyprovides.testing.tearDown(doctest)
         zope.generic.component.testing.tearDown(doctest)
-        zope.generic.information.testing.tearDown(doctest)
-        zope.generic.configuration.testing.tearDown(doctest)
+        zope.generic.component.testing.tearDown(doctest)
+        zope.generic.component.testing.tearDown(doctest)
         # internal teardown
         tearDown(doctest)
 



More information about the Checkins mailing list