[Checkins] SVN: zope.generic/trunk/src/zope/generic/ refactored .type package:

Dominik Huber dominik.huber at perse.ch
Tue Apr 25 15:38:28 EDT 2006


Log message for revision 67606:
  refactored .type package:
  - move factory and initializer stuff into .factory
  - remove class attribute of type directive
  - replace initializer directive by factory subdirective
  - simplify the generic implementations (no __keyface__
    input parameter anymore)
  - handle all the initialization stuff by the new factory
    subdirective
  
  CHANGES: class attribute is not any more provided by
  the type directive. the initalizer subdirective is
  removed. use the factory subdirective instead
  
  <generic:type
      keyface=".IWebPlatform"
      label="Web-Platform" hint="n/a"
      >
    <factory
        class="zope.generic.type.api.Folder"
        />
  </generic:type>

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

-=-
Modified: zope.generic/trunk/src/zope/generic/configuration/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/base.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/configuration/base.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -81,7 +81,7 @@
         >>> config_data = ConfigurationData(IExampleConfiugrationSchema, {})
         Traceback (most recent call last):
         ...
-        AttributeError: 'IExampleConfiugrationSchema' object has no attribute 'foo'.
+        TypeError: __init__ requires 'foo' of 'IExampleConfiugrationSchema'.
 
     The schema should not contain methods:
 
@@ -122,7 +122,7 @@
                     missedArguments.append(name)
         
         if missedArguments:
-            raise AttributeError("'%s' object has no attribute '%s'." % (schema.__name__, ', '.join(missedArguments)))
+            raise TypeError("__init__ requires '%s' of '%s'." % (', '.join(missedArguments), schema.__name__))
     
         # essentials
         self.__dict__['_ConfigurationData__data'] = PersistentDict(data)

Modified: zope.generic/trunk/src/zope/generic/configuration/helper.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/helper.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/configuration/helper.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -124,7 +124,7 @@
         >>> argumentsToConfiguration(IAnyConfiguration)
         Traceback (most recent call last):
         ...
-        AttributeError: 'IAnyConfiguration' object has no attribute 'a, d'.
+        TypeError: __init__ requires 'a, d' of 'IAnyConfiguration'.
 
     B: Provide the required as positionals:
 

Modified: zope.generic/trunk/src/zope/generic/configuration/testing.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/testing.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/configuration/testing.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -98,13 +98,13 @@
         setUp(doctest)
 
     def tearDown(self, doctest=None):
-        super(PlacelessSetup, self).tearDown()
+        # internal teardown
+        tearDown(doctest)
         # external teardown
         zope.generic.configuration.testing.tearDown(doctest)
         zope.generic.keyface.testing.tearDown(doctest)
         zope.generic.directlyprovides.testing.tearDown(doctest)
         zope.generic.testing.testing.tearDown(doctest)
-        # internal teardown
-        tearDown(doctest)
+        super(PlacelessSetup, self).tearDown()
 
 placelesssetup = PlacelessSetup()

Added: zope.generic/trunk/src/zope/generic/factory/PUBLICATION.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/PUBLICATION.cfg	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/factory/PUBLICATION.cfg	2006-04-25 19:38:26 UTC (rev 67606)
@@ -0,0 +1,8 @@
+Metadata-Version: 1.0
+Name: zope.generic.informed
+Summary: Provide introspectable extendable factories
+Author: Dominik Huber, Perse Engineering GmbH, Switzerland
+Author-email: dominik.huber at perse.ch
+License: ZPL 2.1
+Description:
+      	n/a


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

Added: zope.generic/trunk/src/zope/generic/factory/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/README.txt	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/factory/README.txt	2006-04-25 19:38:26 UTC (rev 67606)
@@ -0,0 +1,167 @@
+===============
+Generic Factory
+===============
+
+Regular factories have two disadvantages:
+
+    1.    The initialization parameters cannot be introspected
+    2.    The factory id cannot be shared as easy as an interface
+
+This package try to avoid those points:
+
+    1.    You can declare the parameters parameters within input attribute
+          using a configuration key interface.
+    2.    The factory can be registered with and looked up by an key interface.
+
+For simple example see factory.py
+
+Complex sample
+--------------
+
+As usual first we have to declare an key interface for our implementation:
+
+    >>> from zope.interface import Interface
+
+    >>> class IMyInstance(Interface):
+    ...     pass
+
+    >>> registerDirective('''
+    ... <generic:keyface
+    ...     keyface="example.IMyInstance"
+    ...     />
+    ... ''') 
+
+Then we have to implement an example class with dedicated initalization
+parameters:
+
+    >>> from zope.generic.configuration import IAttributeConfigurable
+    >>> from zope.generic.keyface import IAttributeKeyfaced
+
+    >>> class Example(object):
+    ...    interface.implements(IAttributeKeyfaced, IAttributeConfigurable)
+    ...    def __init__(self, a, b, c):
+    ...        print '__init__:', 'a=',a ,', b=', b, ', c=', c
+
+Now we have to declare the signature for our key interface. We like to provide
+default arguments. Afterward we register the schema as IConfigurationType:
+
+    >>> from zope.schema import TextLine
+
+    >>> class IMyParameter(Interface):
+    ...    a = TextLine()
+    ...    b = TextLine(required=False)
+    ...    c = TextLine(required=False, default=u'c default')
+
+    >>> registerDirective('''
+    ... <generic:keyface
+    ...     keyface="example.IMyParameter"
+    ...     type="zope.generic.configuration.IConfigurationType"
+    ...     />
+    ... ''') 
+
+During the creation process we can invoke initializer operations. In our example
+we are defining a simple handler, but you could use object providing IOperation
+or interfaces providing IOperationType too:
+
+    >>> def init_handler(context, *pos, **kws):
+    ...    print 'initializing'
+
+This stuff can be registered within the factory directive.
+
+    >>> registerDirective('''
+    ... <generic:factory
+    ...     keyface="example.IMyInstance"
+    ...     class="example.Example"
+    ...     operations="example.init_handler"
+    ...     input="example.IMyParameter"
+    ...     providesKeyface="True"
+    ...     storeInput="True"
+    ...     notifyCreated="True"
+    ...     />
+    ... ''') 
+
+The keyface defines the key interface to lookup the factory. The class
+is the implementation. The operations attribute defines one operation or a
+pipe of operations (see zope.generic.operation). Input declares the input
+parameter. The attribute provideKeyface asserts that the key interface is
+provided. Four cases are checked: 
+
+1.  If the class does provide the keyface nothing happens. 
+
+2.  If the instance provides zope.generic.keyface.IProvidesAttributeKeyfaced
+    the __keyface__ attribute is set and the updateDirectlyProvided is called.
+
+3.  If zope.generic.keyface.IAttributeKeyfaced is provided the the __keyface__ 
+    attribute is set and the keyface is directly provided.
+
+4.  Else only the keyface is directly provided.
+
+The storeInput decides if the input configuration should be stored within the
+instance's configurations. The notifyCreated is notifying an object created event.
+
+After this registration we find the following stuff within the component
+registration:
+
+    >>> from zope.component import IFactory
+    >>> from zope.generic.keyface.api import toDottedName
+
+    >>> util = component.getUtility(IFactory, name=toDottedName(IMyInstance))
+    >>> util.keyface == IMyInstance
+    True
+
+    >>> util = component.getUtility(api.IFactoryInformation, name=toDottedName(IMyInstance))
+    >>> util.keyface == IMyInstance
+    True
+
+    >>> from zope.generic.configuration import IConfigurations
+    >>> from zope.generic.operation import IOperationConfiguration
+
+    >>> configs_of_factory_info = IConfigurations(util)
+    >>> create_config = IOperationConfiguration(configs_of_factory_info)
+    >>> create_config.input == IMyParameter
+    True
+    >>> create_config.operation('ignore')
+    initializing
+    >>> create_config.output == IMyInstance
+    True
+
+Fortunately there is a convenience api for the daily questions:
+
+Before you are going to invoke the factory you can look up the create parameters
+for a certain key interface:
+
+    >>> api.createParameter(IMyInstance) is IMyParameter
+    True
+
+You can create an instance, but don't forget to supply the input parameters:
+
+    >>> ex = api.createObject(IMyInstance)
+    Traceback (most recent call last):
+    ... 
+    TypeError: __init__ requires 'a' of 'IMyParameter'.
+
+    >>> ex = api.createObject(IMyInstance, u'a bla')
+    __init__: a= a bla , b= None , c= c default
+    initializing
+
+As you can see our intializer operation was invoked so as the regular intializer.
+
+We selected to store the input. Therefore you can lookup the corresponding
+configuration:
+
+    >>> from zope.generic.informationprovider.api import getInformation
+    >>> info = getInformation(ex, IMyParameter)
+    >>> info.a, info.b, info.c
+    (u'a bla', None, u'c default')
+
+We selected object created event notification too:
+
+    >>> from zope.app.event.tests.placelesssetup import getEvents, clearEvents
+    
+    >>> events = getEvents()
+    >>> len(events)
+    1
+    >>> events.pop().object is ex
+    True
+
+    >>> clearEvents()


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

Added: zope.generic/trunk/src/zope/generic/factory/SETUP.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/SETUP.cfg	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/factory/SETUP.cfg	2006-04-25 19:38:26 UTC (rev 67606)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+  zope.generic.factory-*.zcml
+</data-files>
\ No newline at end of file


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

Added: zope.generic/trunk/src/zope/generic/factory/__init__.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/__init__.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/factory/__init__.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -0,0 +1,19 @@
+##############################################################################
+#
+# 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$
+"""
+
+from zope.generic.factory.interfaces import *
\ No newline at end of file


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

Added: zope.generic/trunk/src/zope/generic/factory/adapter.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/adapter.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/factory/adapter.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -0,0 +1,45 @@
+##############################################################################
+#
+# 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.component import adapts
+from zope.interface import implements
+
+from zope.generic.informationprovider.api import queryInformation
+from zope.generic.informationprovider.api import getInformationProvider
+from zope.generic.keyface import IKeyfaced
+from zope.generic.operation import IOperationConfiguration
+
+from zope.generic.factory import IFactoryInformation
+from zope.generic.factory import IInitializer
+
+
+
+class Initializer(object):
+    """Initialize an object."""
+
+    implements(IInitializer)
+    
+    adapts(IKeyfaced)
+
+    def __init__(self, context):
+        self.context = context
+
+    def __call__(self, *pos, **kws):
+


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

Added: zope.generic/trunk/src/zope/generic/factory/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/api.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/factory/api.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -0,0 +1,47 @@
+##############################################################################
+#
+# 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 import component
+
+from zope.generic.informationprovider.api import getInformationProvider
+from zope.generic.informationprovider.api import queryInformation
+from zope.generic.keyface.api import toDottedName
+from zope.generic.operation import IOperationConfiguration
+
+from zope.generic.factory import *
+
+
+
+
+def createObject(keyface, *pos, **kws):
+    """Create an instance of a logical type using the type marker."""
+    return component.createObject(toDottedName(keyface), *pos, **kws)
+
+
+
+def createParameter(keyface):
+    """Evaluate initializer parameters."""
+    provider = getInformationProvider(keyface, IFactoryInformation)
+    config = queryInformation(provider, IOperationConfiguration)
+    if config:
+        return config.input
+    
+    else:
+        return None


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

Added: zope.generic/trunk/src/zope/generic/factory/configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/configure.zcml	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/factory/configure.zcml	2006-04-25 19:38:26 UTC (rev 67606)
@@ -0,0 +1,12 @@
+<configure
+  xmlns="http://namespaces.zope.org/zope"
+  xmlns:generic="http://namespaces.zope.org/generic"
+  i18n_domain="zope">
+ 
+  <generic:informationProvider
+      keyface="zope.generic.informationprovider.IInformationProviderInformation"
+      label="Factory Information"
+      registry=".IFactoryInformation"
+      />
+
+</configure>


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

Added: zope.generic/trunk/src/zope/generic/factory/factory.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/factory.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/factory/factory.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -0,0 +1,290 @@
+##############################################################################
+#
+# 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.component import factory
+from zope.event import notify
+from zope.app.event.objectevent import ObjectCreatedEvent
+from zope.interface import alsoProvides
+
+from zope.generic.configuration.api import argumentsToConfiguration
+from zope.generic.configuration.api import configuratonToDict
+from zope.generic.directlyprovides.api import updateDirectlyProvided
+from zope.generic.informationprovider.api import getInformationProvider
+from zope.generic.informationprovider.api import provideInformation
+from zope.generic.informationprovider.api import queryInformation
+from zope.generic.keyface import IAttributeKeyfaced
+from zope.generic.keyface import IProvidesAttributeKeyfaced
+from zope.generic.keyface.api import Keyface
+from zope.generic.operation import IOperationConfiguration
+
+from zope.generic.factory import IFactoryInformation
+        
+
+
+class Factory(factory.Factory, Keyface):
+    """Key-interface-based factory implementation.
+
+    First we declare an key interface:
+
+        >>> from zope.interface import Interface
+
+        >>> class IMyInstance(Interface):
+        ...     pass
+
+    Second we need an implementation class. There are different possible ways.
+    We try first the easiest one:
+
+        >>> class Simple(object):
+        ...    pass
+
+        >>> from zope.generic.factory.factory import Factory
+
+        >>> f = Factory(Simple, IMyInstance)
+        >>> f()
+        <example.Simple object at ...>
+        
+        >>> f.title
+        u''
+        >>> f.description
+        u''
+
+        >>> f('wrong')
+        Traceback (most recent call last):
+        ...
+        TypeError: default __new__ takes no parameters
+
+    We can provide the key interface during the creation:
+
+        >>> f = Factory(Simple, IMyInstance, providesKeyface=True)
+        >>> IMyInstance.providedBy(f())
+        True
+
+    If the class does implement IAttributeKeyfaced the __keyface__
+    attribute is set too:
+
+        >>> from zope.generic.keyface import IAttributeKeyfaced
+
+        >>> class SimpleKeyFaced(object):
+        ...    interface.implements(IAttributeKeyfaced)
+
+        >>> f = Factory(SimpleKeyFaced, IMyInstance, providesKeyface=True)
+        >>> IMyInstance.providedBy(f())
+        True
+        >>> f().__keyface__ is IMyInstance
+        True
+
+    We can notify an ObjectCreatedEvent for created instance:
+
+        >>> from zope.app.event.tests.placelesssetup import getEvents, clearEvents
+        >>> clearEvents()
+
+        >>> f = Factory(Simple, IMyInstance, notifyCreated=True)
+        >>> instance = f()
+        
+        >>> events = getEvents()
+        >>> len(events)
+        1
+        >>> events.pop().object is instance
+        True
+
+    There are further features but to use them we have to register an
+    an IFactoryInformation information provider including an
+    IOperationConfiguration:
+
+        >>> def init_handler(context, *pos, **kws):
+        ...    print 'initializing'
+
+        >>> from zope.generic.configuration.api import ConfigurationData
+        >>> from zope.generic.operation import IOperationConfiguration
+
+        >>> my_factory=ConfigurationData(IOperationConfiguration, {'operation': init_handler})
+
+        >>> registerDirective('''
+        ... <generic:informationProvider
+        ...     keyface="example.IMyInstance"
+        ...     registry="zope.generic.factory.IFactoryInformation"
+        ...     >
+        ...    <information
+        ...       keyface="zope.generic.operation.IOperationConfiguration"
+        ...       configuration="example.my_factory"
+        ...       />
+        ... </generic:informationProvider>
+        ... ''')
+
+        >>> f = Factory(Simple, IMyInstance, mode=2)
+        >>> f()
+        initializing
+        <example.Simple object at ...>
+        
+        >>> f('wrong')
+        Traceback (most recent call last):
+        ...
+        TypeError: default __new__ takes no parameters
+
+
+    If we like to provide parameter we have to declare them by an input
+    configuration:
+
+        >>> from zope.schema import TextLine
+
+        >>> class SimpleKeyFacedWithParameter(object):
+        ...    interface.implements(IAttributeKeyfaced)
+        ...    def __init__(self, a, b, c):
+        ...        print '__init__:', 'a=',a ,', b=', b, ', c=', c
+
+        >>> class IMyParameter(Interface):
+        ...    a = TextLine()
+        ...    b = TextLine(required=False)
+        ...    c = TextLine(required=False, default=u'c default')
+
+        >>> registerDirective('''
+        ... <generic:keyface
+        ...     keyface="example.IMyParameter"
+        ...     type="zope.generic.configuration.IConfigurationType"
+        ...     />
+        ... ''') 
+
+        >>> my_factory=ConfigurationData(IOperationConfiguration, 
+        ...                              {'operation': init_handler,
+        ...                               'input': IMyParameter})
+
+        >>> registerDirective('''
+        ... <generic:informationProvider
+        ...     keyface="example.IMyInstance"
+        ...     registry="zope.generic.factory.IFactoryInformation"
+        ...     >
+        ...    <information
+        ...       keyface="zope.generic.operation.IOperationConfiguration"
+        ...       configuration="example.my_factory"
+        ...       />
+        ... </generic:informationProvider>
+        ... ''')
+
+        >>> f = Factory(SimpleKeyFacedWithParameter, IMyInstance, mode=3)
+        >>> f(u'a bla bla')
+        __init__: a= a bla bla , b= None , c= c default
+        initializing
+        <example.SimpleKeyFacedWithParameter object at ...>
+
+    We can ignore the factory configuration fully by mode=0:
+
+        >>> f = Factory(SimpleKeyFacedWithParameter, IMyInstance, mode=0)
+        >>> f(u'a bla bla')
+        Traceback (most recent call last):
+         ...
+        TypeError: default __new__ takes no parameters
+
+    Last but not least we can store the arguments directly as configuration. 
+    Such an configuration can be retrieved later on using the queryInformation
+    function:
+
+        >>> from zope.generic.configuration import IAttributeConfigurable
+
+        >>> class SimpleConfigurable(object):
+        ...    interface.implements(IAttributeKeyfaced, IAttributeConfigurable)
+        ...    def __init__(self, a, b, c):
+        ...        print '__init__:', 'a=',a ,', b=', b, ', c=', c
+
+        >>> f = Factory(SimpleConfigurable, IMyInstance, storeInput=True, mode=3)
+        >>> instance = f(u'a bla')
+        __init__: a= a bla , b= None , c= c default
+        initializing
+        
+        >>> from zope.generic.informationprovider.api import queryInformation
+        
+        >>> config = queryInformation(instance, IMyParameter)
+        >>> config.a, config.b, config.c
+        (u'a bla', None, u'c default')
+
+    """
+
+    def __init__(self, callable, __keyface__, providesKeyface=False, 
+                 storeInput=False, notifyCreated=False, 
+                 title=u'', description=u'', mode=0):
+
+        super(Factory, self).__init__(callable, title, description, interfaces=(__keyface__,))
+
+        # essentials
+        self.__keyface__ = __keyface__
+        self.__provideKeyface = providesKeyface
+        self.__storeInput = storeInput
+        self.__notifyCreated = notifyCreated
+        self.__mode = mode
+        if mode == 0:
+            self.__dict__['_Factory__config'] = None
+
+    def __call__(self, *pos, **kws):
+        """Create instance."""
+        config = self.__config
+        mode = self.__mode
+        if config and config.input:
+            new_kws = configuratonToDict(argumentsToConfiguration(config.input, *pos, **kws), all=True)
+            instance = self._callable(**new_kws)
+        
+        elif not pos and not kws:
+            instance = self._callable()
+
+        else:
+            raise TypeError('default __new__ takes no parameters')
+            
+
+        # provide key interface
+        if self.__provideKeyface:
+            if not self.keyface.providedBy(instance):
+                if IProvidesAttributeKeyfaced.providedBy(instance):
+                    instance.__dict__['__keyface__'] = self.keyface
+                    updateDirectlyProvided(instance, self.keyface)
+
+                elif IAttributeKeyfaced.providedBy(instance):
+                    instance.__dict__['__keyface__'] = self.keyface
+                    alsoProvides(instance, self.keyface)
+
+                else:
+                    alsoProvides(instance, self.keyface)
+
+        # store input configuration
+        if self.__storeInput and config:
+            input = config.input
+            if input:
+                configuration = argumentsToConfiguration(input, *pos, **kws)
+                provideInformation(instance, input, configuration)
+
+        # invoke initializer operations
+        if mode > 1:
+            config.operation(instance, *pos, **kws)
+
+        # notify created object
+        if self.__notifyCreated:
+            notify(ObjectCreatedEvent(instance))
+
+        return instance
+
+    @property
+    def __config(self):
+        if '_Factory__config' not in self.__dict__:
+            try:
+                provider = getInformationProvider(self.keyface, IFactoryInformation)
+                self.__dict__['_Factory__config'] = queryInformation(provider, IOperationConfiguration)
+
+            except:
+                self.__dict__['_Factory__config'] = None
+
+
+        return self.__dict__['_Factory__config']


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

Added: zope.generic/trunk/src/zope/generic/factory/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/interfaces.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/factory/interfaces.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -0,0 +1,25 @@
+##############################################################################
+#
+# 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.generic.informationprovider import IInformationProvider
+
+
+class IFactoryInformation(IInformationProvider):
+    """Provide information for the factory referenced by the key interface."""


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

Added: zope.generic/trunk/src/zope/generic/factory/meta.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/meta.zcml	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/factory/meta.zcml	2006-04-25 19:38:26 UTC (rev 67606)
@@ -0,0 +1,15 @@
+<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="factory"
+        schema=".metadirectives.IFactoryDirective"
+        handler=".metaconfigure.factoryDirective"
+        />
+
+  </meta:directives>
+
+</configure>


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

Added: zope.generic/trunk/src/zope/generic/factory/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/metaconfigure.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/factory/metaconfigure.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -0,0 +1,104 @@
+##############################################################################
+#
+# 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 types import ModuleType
+
+from zope.app.component.metaconfigure import proxify
+from zope.component import provideUtility
+from zope.component import IFactory
+from zope.configuration.exceptions import ConfigurationError
+from zope.security.checker import CheckerPublic
+from zope.security.checker import InterfaceChecker
+
+from zope.generic.informationprovider.api import getInformationProvider
+from zope.generic.informationprovider.api import provideInformation
+from zope.generic.informationprovider.metaconfigure import InformationProviderDirective
+from zope.generic.informationprovider.metaconfigure import provideInformationProvider
+from zope.generic.keyface import IKeyfaceType
+from zope.generic.keyface.api import toDescription
+from zope.generic.keyface.api import toDottedName
+from zope.generic.keyface.metaconfigure import keyfaceDirective
+from zope.generic.operation.api import assertOperation
+from zope.generic.operation.api import provideOperationConfiguration
+
+from zope.generic.factory import IFactoryInformation
+from zope.generic.factory.factory import Factory
+
+
+
+def factoryDirective(_context, keyface, class_, type=None, operations=(), input=None,
+                     providesKeyface=False, notifyCreated=False, storeInput=False,
+                     label=None, hint=None):
+    """Register a public factory."""
+    # preconditions
+    if isinstance(class_, ModuleType):
+        raise ConfigurationError('Implementation attribute must be a class')
+
+    # assert keyface type
+    if not IKeyfaceType.providedBy(keyface):
+        keyfaceDirective(_context, keyface, type)
+
+    registry = IFactoryInformation
+    
+    # set label and hint
+    label, hint = toDescription(keyface, label, hint)
+
+    # how to invoke the factory
+    if operations and input:
+        mode = 3
+    
+    elif operations:
+        mode = 2
+    
+    elif input:
+        mode = 1
+    
+    else:
+        mode = 0
+
+    if mode and providesKeyface:
+        output = keyface
+
+    # create and proxy type factory
+    factory = Factory(class_, keyface, providesKeyface, storeInput, 
+                      notifyCreated, label, hint, mode) 
+    component = proxify(factory, InterfaceChecker(IFactory, CheckerPublic))
+    
+    _context.action(
+        discriminator = ('provideUtility', keyface),
+        callable = provideUtility,
+        args = (component, IFactory, toDottedName(keyface)),
+        )
+
+    if mode != 0:
+        # create operation wrapper
+        operation = assertOperation(operations, keyface, input, output)
+
+        _context.action(
+            discriminator = ('provideInformationProvider', keyface, registry),
+            callable = provideInformationProvider,
+            args = (keyface, registry, label, hint),
+            )
+    
+        _context.action(
+            discriminator = ('provideOperationConfiguration', keyface),
+            callable = provideOperationConfiguration,
+            args = (keyface, operation, registry, input, output),
+            )


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

Added: zope.generic/trunk/src/zope/generic/factory/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/metadirectives.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/factory/metadirectives.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -0,0 +1,71 @@
+##############################################################################
+#
+# 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 Bool
+from zope.configuration.fields import GlobalObject
+from zope.interface import Interface
+
+from zope.generic.informationprovider.metadirectives import IBaseInformationProviderDirective
+from zope.generic.operation.metadirectives import IBaseOperationDirective
+
+
+class IBaseFactoryDirective(Interface):
+    """Declare a factory."""
+
+    class_ = GlobalObject(
+        title=_('Class'),
+        description=_('Generic class implementation.'),
+        required=True
+        )
+
+    providesKeyface = Bool(
+        title=_('Provides Keyface'),
+        description=_('If the class does not implement the key interface ' +
+                      'directly provide it to the instances ' +
+                      'before initalization.'),
+        required=False,
+        default=False
+        )
+
+    storeInput = Bool(
+        title=_('Store Input'),
+        description=_('Store input configuration within the objects configurations.'),
+        required=False,
+        default=False
+        )
+
+    notifyCreated = Bool(
+        title=_('Notify created'),
+        description=_('Notify an object created event after the initialization is fullfilled.'),
+        required=False,
+        default=False
+        )
+
+
+class IFactoryDirective(IBaseInformationProviderDirective, IBaseFactoryDirective, IBaseOperationDirective):
+    """Register a public factory.
+
+    The factory will be registered as information provider utility providing
+    IFactoryInformation.
+    """
+
+
+


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

Added: zope.generic/trunk/src/zope/generic/factory/testing.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/testing.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/factory/testing.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -0,0 +1,83 @@
+##############################################################################
+#
+# 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'
+
+import zope.app.testing.placelesssetup
+from zope.configuration.xmlconfig import XMLConfig
+
+import zope.generic.configuration.testing
+import zope.generic.directlyprovides.testing
+import zope.generic.informationprovider.testing
+import zope.generic.keyface.testing
+import zope.generic.operation.testing
+import zope.generic.testing.testing
+
+################################################################################
+#
+# Public Test implementations
+#
+################################################################################
+
+
+
+################################################################################
+#
+# Placeless setup
+#
+################################################################################
+
+# specific tests
+def setUp(doctest=None):
+    # register the directive of this package
+    import zope.generic.factory
+    XMLConfig('meta.zcml', zope.generic.factory)()
+
+def tearDown(doctest=None):
+    pass
+
+
+
+class PlacelessSetup(zope.app.testing.placelesssetup.PlacelessSetup):
+
+    def setUp(self, doctest=None):
+        super(PlacelessSetup, self).setUp(doctest)
+        # external setup
+        zope.generic.testing.testing.setUp(doctest)
+        zope.generic.directlyprovides.testing.setUp(doctest)
+        zope.generic.keyface.testing.setUp(doctest)
+        zope.generic.configuration.testing.setUp(doctest)
+        zope.generic.informationprovider.testing.setUp(doctest)
+        zope.generic.operation.testing.setUp(doctest)
+        # internal setup
+        setUp(doctest)
+
+    def tearDown(self, doctest=None):
+        # internal teardown
+        tearDown(doctest)
+        # external teardown
+        zope.generic.operation.testing.tearDown(doctest)
+        zope.generic.informationprovider.testing.tearDown(doctest)
+        zope.generic.configuration.testing.tearDown(doctest)
+        zope.generic.keyface.testing.tearDown(doctest)
+        zope.generic.directlyprovides.testing.tearDown(doctest)
+        zope.generic.testing.testing.tearDown(doctest)
+        super(PlacelessSetup, self).tearDown()
+
+
+placelesssetup = PlacelessSetup()


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

Added: zope.generic/trunk/src/zope/generic/factory/tests.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/tests.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/factory/tests.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# 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$
+"""
+
+import unittest
+
+from zope import component
+from zope import interface
+from zope.testing import doctest
+
+
+from zope.generic.factory import api
+from zope.generic.factory import testing
+from zope.generic.testing.testing import registerDirective
+
+
+
+def test_suite():
+    return unittest.TestSuite((
+        doctest.DocTestSuite('zope.generic.factory.factory',
+                             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),
+        doctest.DocFileSuite('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()


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

Added: zope.generic/trunk/src/zope/generic/factory/zope.generic.factory-configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/zope.generic.factory-configure.zcml	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/factory/zope.generic.factory-configure.zcml	2006-04-25 19:38:26 UTC (rev 67606)
@@ -0,0 +1,5 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <include package="zope.generic.factory" />
+
+</configure>


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

Added: zope.generic/trunk/src/zope/generic/factory/zope.generic.factory-meta.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/zope.generic.factory-meta.zcml	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/factory/zope.generic.factory-meta.zcml	2006-04-25 19:38:26 UTC (rev 67606)
@@ -0,0 +1,5 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <include package="zope.generic.factory" file="meta.zcml" />
+
+</configure>


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

Modified: zope.generic/trunk/src/zope/generic/informationprovider/NEW_README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/NEW_README.txt	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/informationprovider/NEW_README.txt	2006-04-25 19:38:26 UTC (rev 67606)
@@ -129,13 +129,13 @@
     
     >>> supplier_registry =  api.queryInformationProvider(ILogSupplierInformation)
     >>> supplier_registry.label
-    u'ILogSupplierInformation'
+    u'Store log supplier information.'
     >>> supplier_registry.hint
-    u'Store log supplier information.'
+    u''
 
     >>> user_registry =  api.queryInformationProvider(ILogUserInformation)
     >>> user_registry.label
-    u'ILogUserInformation'
+    u'Store log user information.'
     >>> user_registry.hint
-    u'Store log user information.'
+    u''
 

Modified: zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -26,6 +26,7 @@
 
 from zope.generic.configuration import IConfigurations
 from zope.generic.configuration.api import ConfigurationData
+from zope.generic.keyface.api import toDescription
 from zope.generic.keyface.api import toDottedName
 
 from zope.generic.informationprovider.base import InformationProvider
@@ -107,6 +108,11 @@
         self._keyface = keyface
         self._context = _context
         self._registry = registry
+
+        # set label and hint
+        label, hint = toDescription(keyface, label, hint)
+        self._label = label
+        self._hint = hint
     
         # assert type as soon as possible
         if self._information_type is not None:

Modified: zope.generic/trunk/src/zope/generic/informationprovider/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/metadirectives.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/informationprovider/metadirectives.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -30,11 +30,11 @@
 
 
 class IBaseInformationProviderDirective(Interface):
-    """Base information attributes."""
+    """Base information provider attributes."""
 
     keyface = GlobalInterface(
-        title=_('Interface'),
-        description=_('Interface that represents an information.'),
+        title=_('Key Interface'),
+        description=_('Key interface that is refered by the information.'),
         required=True
         )
 

Modified: zope.generic/trunk/src/zope/generic/keyface/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/keyface/api.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/keyface/api.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -22,6 +22,7 @@
 from zope.generic.keyface.adapter import KeyfaceForAttributeKeyfaced
 from zope.generic.keyface.base import Keyface
 from zope.generic.keyface.base import KeyfaceDescription
+from zope.generic.keyface.helper import toDescription
 from zope.generic.keyface.helper import toDottedName
 from zope.generic.keyface.helper import toKeyface
 

Modified: zope.generic/trunk/src/zope/generic/keyface/helper.py
===================================================================
--- zope.generic/trunk/src/zope/generic/keyface/helper.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/keyface/helper.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -31,8 +31,102 @@
 # cache
 __name_to_component = {}
 
-def toKeyface(name):
+def toKeyface(dottedname):
     try:
-        return __name_to_component[name]
+        return __name_to_component[dottedname]
     except KeyError:
-        return __name_to_component.setdefault(name, resolve(name))
+        return __name_to_component.setdefault(dottedname, resolve(dottedname))
+
+
+def toDescription(component, label=None, hint=None):
+    """Use the __doc__ attribute for label and hint.
+
+    This function can be used to generate the label an hint of an description.
+
+    No doc string provided:
+
+        >>> class A:
+        ...     pass
+
+        >>> label, hint = toDescription(A)
+        >>> label
+        u''
+        >>> hint
+        u''
+
+    Single line:
+
+        >>> class B:
+        ...    '''Test label.   
+        ...    '''
+
+        >>> label, hint = toDescription(B)
+        >>> label
+        u'Test label.'
+        >>> hint
+        u''
+
+    Multi line:
+
+        >>> class C:
+        ...    '''Test label.   
+        ...
+        ...    Test hint, bla bla .  
+        ...    bla bla bla:  
+        ...         - bla, bla, bla.   '''
+
+        >>> label, hint = toDescription(C)
+        >>> label
+        u'Test label.'
+        >>> hint
+        u'Test hint, bla bla .\\\\nbla bla bla:\\\\n- bla, bla, bla.'
+
+    You can overwrite the underlying doc string providing your own
+    label or hint:
+
+        >>> label, hint = toDescription(C, label=u'My label')
+        >>> label
+        u'My label'
+        >>> hint
+        u'Test hint, bla bla .\\\\nbla bla bla:\\\\n- bla, bla, bla.'
+
+        >>> label, hint = toDescription(C, hint=u'My hint')
+        >>> label
+        u'Test label.'
+        >>> hint
+        u'My hint'
+
+    """
+    if label and hint:
+        return (label, hint)
+
+    elif label:
+        doc = getattr(component, '__doc__', None)
+        if doc:
+            lines = doc.splitlines()
+            if lines and lines > 2:
+                return (label, u'\\n'.join([line.strip() for line in lines[2:]]))
+
+        return (label, u'')
+
+    elif hint:
+        doc = getattr(component, '__doc__', None)
+        if doc:
+            lines = doc.splitlines()
+            if lines:
+                return (unicode(lines[0].strip()), hint)
+
+        return (u'')
+
+    else:
+        doc = getattr(component, '__doc__', None)
+        if doc:
+            lines = doc.splitlines()
+            if lines:
+                if lines > 2:
+                    return (unicode(lines[0].strip()), u'\\n'.join([line.strip() for line in lines[2:]]))
+
+                else:
+                    return (unicode(lines[0].strip()), u'')
+
+        return (u'', u'')   

Modified: zope.generic/trunk/src/zope/generic/keyface/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/keyface/interfaces.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/keyface/interfaces.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -25,7 +25,9 @@
 from zope.schema import Text
 from zope.schema import TextLine
 
+from zope.generic.directlyprovides import IProvides
 
+
 ###############################################################################
 #
 # Base key interface related interfaces  
@@ -40,7 +42,7 @@
 
 
 class IAttributeKeyfaced(IKeyfaced):
-    """Provide the key interface within the __keyface__ attribute."""
+    """Store the key interface within the __keyface__ attribute."""
 
     __keyface__ = Object(
         title=_('Key interface'),
@@ -53,6 +55,11 @@
 
 
 
+class IProvidesAttributeKeyfaced(IAttributeKeyfaced, IProvides):
+    """Directly provide the __keyface__ attribute."""
+
+
+
 class IKeyfaceType(IInterface):
     """Mark key interfaces.
 

Modified: zope.generic/trunk/src/zope/generic/keyface/tests.py
===================================================================
--- zope.generic/trunk/src/zope/generic/keyface/tests.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/keyface/tests.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -60,6 +60,7 @@
     return unittest.TestSuite((
         unittest.makeSuite(KeyfaceAdapterTest),
         doctest.DocTestSuite('zope.generic.keyface.adapter'),
+        doctest.DocTestSuite('zope.generic.keyface.helper'),
         doctest.DocFileSuite('README.txt',
                              setUp=testing.placelesssetup.setUp,
                              tearDown=testing.placelesssetup.tearDown,

Modified: zope.generic/trunk/src/zope/generic/operation/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/README.txt	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/operation/README.txt	2006-04-25 19:38:26 UTC (rev 67606)
@@ -87,7 +87,7 @@
     >>> operation('corresponding Context')
     Traceback (most recent call last):
     ...
-    AttributeError: 'IAnyInput' object has no attribute 'a'.
+    TypeError: __init__ requires 'a' of 'IAnyInput'.
 
     >>> output = operation('corresponding Context', u'a bla')
     Any input: a=a bla, b=None, c=c default.

Modified: zope.generic/trunk/src/zope/generic/operation/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/api.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/operation/api.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -21,6 +21,8 @@
 from zope.generic.informationprovider.api import getInformation
 
 from zope.generic.operation.interfaces import *
+from zope.generic.operation.metaconfigure import assertOperation
+from zope.generic.operation.metaconfigure import provideOperationConfiguration
 
 
 

Modified: zope.generic/trunk/src/zope/generic/operation/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/interfaces.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/operation/interfaces.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -22,7 +22,6 @@
 from zope.interface import alsoProvides
 from zope.interface import Interface
 from zope.interface.interfaces import IInterface
-from zope.schema import Bool
 from zope.schema import Object
 from zope.schema import Tuple
 

Modified: zope.generic/trunk/src/zope/generic/operation/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/metaconfigure.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/operation/metaconfigure.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -38,13 +38,36 @@
 from zope.generic.operation.base import OperationPipe
 
 
-def _assertOperation(handler, keyface=None, input=None, output=None):
+def assertOperation(handlers, keyface=None, input=None, output=None):
     """Assert that we get an operation."""
 
+    # handle operations tuple or lists
+    if type(handlers) == tuple or type(handlers) == list:
+        if len(handlers) > 1:
+            return OperationPipe([assertOperation(handler) 
+                                 for handler in handlers], 
+                                 keyface, input, output)
+
+        elif len(handlers) == 1:
+            handler = handlers[0]
+
+        else:
+            handler=None
+
+    # assume that handlers is a single handler
+    else:
+        handler = handlers
+
+    # nothing to do, this is already an information
     if IOperation.providedBy(handler):
         return handler
     
-    if IOperationType.providedBy(handler):
+    # sometimes we use an do nothing operation
+    elif handler is None:
+        return Operation(None, keyface, input, output)
+
+    # evaluate an operation from a operation key interface
+    elif IOperationType.providedBy(handler):
         registry = IOperationInformation
         info = queryInformationProvider(handler, IOperationInformation)
 
@@ -59,34 +82,30 @@
         return config.operation
 
     # asume callabe (context)
-    return Operation(handler, keyface, input, output)
+    else:
+        return Operation(handler, keyface, input, output)
 
 
 
-def provideOperationConfiguration(keyface, operations=(), input=None, output=None):
+def provideOperationConfiguration(keyface, operations=None, registry=None, input=None, output=None):
     """Provide the handler to an configuration information."""
-    
-    registry = IOperationInformation
-    info = queryInformationProvider(keyface, IOperationInformation)
 
+    # assume configuration within an IOperationInformation
+    if registry is None:
+        registry = IOperationInformation
+
+    provider = queryInformationProvider(keyface, registry)
+
     # this should never happen...
-    if info is None:
+    if provider is None:
         ConfigurationError('No operation information for %s' 
                            % keyface.__name__)
 
-    if len(operations) == 0:
-        # hidding overwrite -> pass handler
-        operation = _assertOperation(None, keyface, input, output)
-    
-    elif len(operations) == 1:
-        operation = _assertOperation(operations[0], keyface, input, output)
-    
-    else:
-        operation = OperationPipe([_assertOperation(handler) for handler in operations], keyface, input, output)
+    # create operation wrapper
+    operation = assertOperation(operations, keyface, input, output)
 
-    configurations = IConfigurations(info)
     # create and set configuration data
-    provideInformation(info, IOperationConfiguration, 
+    provideInformation(provider, IOperationConfiguration, 
         {'operation': operation, 'input': input, 'output': output})
 
 
@@ -109,5 +128,5 @@
     _context.action(
         discriminator = ('provideOperationConfiguration', keyface),
         callable = provideOperationConfiguration,
-        args = (keyface, operations, input, output),
+        args = (keyface, operations, registry, input, output),
         )

Modified: zope.generic/trunk/src/zope/generic/operation/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/metadirectives.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/operation/metadirectives.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -22,29 +22,40 @@
 from zope.configuration.fields import GlobalInterface
 from zope.configuration.fields import GlobalObject
 from zope.configuration.fields import Tokens
+from zope.interface import Interface
 
 from zope.generic.configuration import IConfigurationType
 from zope.generic.informationprovider.metadirectives import IBaseInformationProviderDirective
 
 
 
-class IOperationDirective(IBaseInformationProviderDirective):
-    """Register a public operation.
+class IBaseOperationDirective(Interface):
+    """Register an operation."""
 
-    The operation will be registered as interface utility typed by IOperationType.
-    """
-
     operations = Tokens(
-        title=_('Operation or IOperationType'),
-        description=_('Global operation or callable(context) or IOperationType keyface.'),
+        title=_('Callable, Operation or IOperationType'),
+        description=_('Callable(context, *pos, **kws), global operation ' +
+                      'or IOperationType key interface.'),
         required=False,
         value_type=GlobalObject()
         )
 
-    input = GlobalInterface(title=_('Input Configurations'),
-        description=_('Tuple of configuration schema that will be respected.'),
+    input = GlobalInterface(title=_('Input Declaration'),
+        description=_('Configuration schema describing the input arguments.'),
         required=False)
 
-    output = GlobalInterface(title=_('Output Configurations'),
-        description=_('Tuple of configuration schema that might be modified or created.'),
-        required=False)
+
+
+class IOperationDirective(IBaseInformationProviderDirective, IBaseOperationDirective):
+    """Register a public operation.
+
+    The operation will be registered as information provider utility providing
+    IOperationInformation.
+
+    The operation key interface will be registered as interface utility typed as
+    IOperationType too.
+    """
+
+    output = GlobalInterface(title=_('Output Declaration'),
+        description=_('Configuration schema or interface describing the input arguments.'),
+        required=False)
\ No newline at end of file

Modified: zope.generic/trunk/src/zope/generic/type/EXAMPLE.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/type/EXAMPLE.txt	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/type/EXAMPLE.txt	2006-04-25 19:38:26 UTC (rev 67606)
@@ -110,10 +110,10 @@
     >>> registerDirective('''
     ... <generic:type
     ...     keyface="example.IText"
-    ...     class='zope.generic.type.api.Object'
     ...     >
-    ...    <initializer
-    ...         keyface='example.ITextConfig'
+    ...    <factory
+    ...        class='zope.generic.type.api.Object'
+    ...        input='example.ITextConfig'
     ...    />
     ...    <information
     ...        keyface='example.ITextConfig'
@@ -125,10 +125,10 @@
     >>> registerDirective('''
     ... <generic:type
     ...     keyface="example.INote"
-    ...     class='zope.generic.type.api.Object'
     ...     >
-    ...    <initializer
-    ...         keyface='example.INoteConfig'
+    ...    <factory
+    ...        class='zope.generic.type.api.Object'
+    ...        input='example.INoteConfig'
     ...    />
     ...    <information
     ...        keyface='example.INoteConfig'
@@ -140,11 +140,11 @@
     >>> registerDirective('''
     ... <generic:type
     ...     keyface="example.IArticle"
-    ...     class='zope.generic.type.api.Object'
     ...     >
-    ...    <initializer
-    ...         keyface='example.IArticleInitializationConfiguration'
-    ...         handler="example.articleInitializer"
+    ...    <factory
+    ...        class='zope.generic.type.api.Object'
+    ...        input='example.IArticleInitializationConfiguration'
+    ...        operations='example.articleInitializer'
     ...    />
     ...    <information
     ...        keyface='example.ITextConfig'
@@ -165,13 +165,18 @@
 
     >>> from zope.generic.type.api import createObject
 
-    >>> article = createObject(IArticle, text="First version of article.")
+    >>> article = createObject(IArticle)
+    Traceback (most recent call last):
+    ...
+    TypeError: __init__ requires 'text' of 'IArticleInitializationConfiguration'.
+
+    >>> article = createObject(IArticle, u"First version of article.")
     
     >>> IArticle.providedBy(article)
     True
 
     >>> queryInformation(article, ITextConfig).body
-    'First version of article.'
+    u'First version of article.'
     
     >>> queryInformation(article, IArticleInitializationConfiguration).text
     Traceback (most recent call last):

Modified: zope.generic/trunk/src/zope/generic/type/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/type/README.txt	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/type/README.txt	2006-04-25 19:38:26 UTC (rev 67606)
@@ -42,15 +42,17 @@
 	>>> from zope.generic.type import api
 	>>> api.ITypeable.implementedBy(api.Object)
 	True
-	>>> api.IDirectlyTyped.implementedBy(api.Object)
+	>>> api.IGenericTyped.implementedBy(api.Object)
 	True
 
     >>> registerDirective('''
     ... <generic:type
     ...     keyface="example.IFooMarker"
     ...     label='Foo Type' hint='Bla bla bla.'
-    ...	    class='zope.generic.type.api.Object'
-    ...     />
+    ...     >
+    ...    <factory
+    ...        class='zope.generic.type.api.Object' />
+    ... </generic:type>
     ... ''')
 
 After the typed is registered the type marker will provide ITypeType:
@@ -156,12 +158,12 @@
     ... <generic:type
     ...     keyface="example.IBarMarker"
     ...     label='Bar Type' hint='Bla bla bla.'
-    ...	    class='zope.generic.type.api.Object'
     ...     >
-    ...    <initializer
-    ...			keyface='example.IOtherConfiguration'
-    ...			handler='example.barInitializer'
-    ...	   />
+    ...    <factory
+    ...        class='zope.generic.type.api.Object'
+    ...        input='example.IOtherConfiguration'
+    ...        operations='example.barInitializer'
+    ...    />
     ...	   <information
     ...	       keyface='example.IAnyConfiguration'
     ...        configuration='example.typedata'
@@ -182,7 +184,7 @@
 	>>> bar = api.createObject(IBarMarker)
 	Traceback (most recent call last):
 	...
-	AttributeError: 'IOtherConfiguration' object has no attribute 'other'.
+	TypeError: __init__ requires 'other' of 'IOtherConfiguration'.
 
 	>>> bar = api.createObject(IBarMarker, other=u'Specific initialization data.')
 	Initializing ...

Deleted: zope.generic/trunk/src/zope/generic/type/adapter.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/adapter.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/type/adapter.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -1,53 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-
-"""
-$Id$
-"""
-
-__docformat__ = 'restructuredtext'
-
-from zope.component import adapts
-from zope.interface import implements
-
-from zope.generic.informationprovider.api import provideInformation
-
-from zope.generic.type import IInitializer
-from zope.generic.type import IInitializerConfiguration
-from zope.generic.type import ITypeable
-from zope.generic.type.api import queryTypeConfiguration
-
-
-
-class Initializer(object):
-    """Initialize an object."""
-
-    implements(IInitializer)
-    
-    adapts(ITypeable)
-
-    def __init__(self, context):
-        self.context = context
-
-    def __call__(self, *pos, **kws):
-        config = queryTypeConfiguration(self.context, IInitializerConfiguration)
-        if config:
-            # store initialization data
-            if config.keyface:
-                provideInformation(self.context, config.keyface, kws)
-
-            # invoke initialization handler
-
-            if config.handler:
-                config.handler(self.context, *pos, **kws)

Modified: zope.generic/trunk/src/zope/generic/type/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/api.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/type/api.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -17,6 +17,8 @@
 """
 
 # usage see README.txt
+from zope.generic.factory.api import createObject
+from zope.generic.factory.api import createParameter
 from zope.generic.type.interfaces import *
 from zope.generic.type.base import Object
 from zope.generic.type.base import Contained
@@ -25,8 +27,6 @@
 from zope.generic.type.base import OrderedContainer
 
 from zope.generic.type.helper import acquireObjectConfiguration
-from zope.generic.type.helper import createObject
-from zope.generic.type.helper import createParameter
 from zope.generic.type.helper import queryObjectConfiguration
 from zope.generic.type.helper import queryTypeConfiguration
 from zope.generic.type.helper import queryTypeInformation

Modified: zope.generic/trunk/src/zope/generic/type/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/base.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/type/base.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -22,38 +22,30 @@
 
 from zope.interface import implements
 
-from zope.app.annotation.interfaces import IAttributeAnnotatable
 from zope.app.container import contained
 from zope.app.container import btree
 from zope.app.container import ordered
 from zope.app import folder
 
-from zope.generic.configuration.api import IAttributeConfigurable
 from zope.generic.directlyprovides.api import provides
 from zope.generic.directlyprovides.api import UpdateProvides
 from zope.generic.directlyprovides.api import updateDirectlyProvided
 
-from zope.generic.type import IDirectlyTyped
-from zope.generic.type import IInitializer
+from zope.generic.type import IGenericTyped
 
 
 
 class Object(object):
     """Default implementation for simple objects."""
 
-    implements(IDirectlyTyped, IAttributeConfigurable, IAttributeAnnotatable)
+    implements(IGenericTyped)
 
-    def __init__(self, __keyface__, *pos, **kws):
+    def __init__(self, *pos, **kws):
         super(Object, self).__init__()
-        self.__dict__['__keyface__'] = __keyface__
-        updateDirectlyProvided(self, __keyface__)
-        initializer = IInitializer(self, None)
-        if initializer:
-            initializer(*pos, **kws)
 
     provides('__keyface__')
 
-    __keyface__ = UpdateProvides(IDirectlyTyped['__keyface__'])
+    __keyface__ = UpdateProvides(IGenericTyped['__keyface__'])
     
     @property
     def keyface(self):
@@ -64,19 +56,14 @@
 class Contained(contained.Contained, Persistent):
     """Default implementation local, persistend and contained objects."""
 
-    implements(IDirectlyTyped, IAttributeConfigurable, IAttributeAnnotatable)
+    implements(IGenericTyped)
 
-    def __init__(self, __keyface__, *pos, **kws):
+    def __init__(self, *pos, **kws):
         super(Contained, self).__init__()
-        self.__dict__['__keyface__'] = __keyface__
-        updateDirectlyProvided(self, __keyface__)
-        initializer = IInitializer(self, None)
-        if initializer:
-            initializer(*pos, **kws)
 
     provides('__keyface__')
 
-    __keyface__ = UpdateProvides(IDirectlyTyped['__keyface__'])
+    __keyface__ = UpdateProvides(IGenericTyped['__keyface__'])
 
     @property
     def keyface(self):
@@ -86,19 +73,14 @@
 class Container(btree.BTreeContainer):
     """Default implementation local, persistend and containerish objects."""
 
-    implements(IDirectlyTyped, IAttributeConfigurable, IAttributeAnnotatable)
+    implements(IGenericTyped)
 
-    def __init__(self, __keyface__, *pos, **kws):
+    def __init__(self, *pos, **kws):
         super(Container, self).__init__()
-        self.__dict__['__keyface__'] = __keyface__
-        updateDirectlyProvided(self, __keyface__)
-        initializer = IInitializer(self, None)
-        if initializer:
-            initializer(*pos, **kws)
 
     provides('__keyface__')
 
-    __keyface__ = UpdateProvides(IDirectlyTyped['__keyface__'])
+    __keyface__ = UpdateProvides(IGenericTyped['__keyface__'])
 
     @property
     def keyface(self):
@@ -109,19 +91,14 @@
 class OrderedContainer(ordered.OrderedContainer):
     """Default implementation local, persistend and ordered-containerish objects."""
 
-    implements(IDirectlyTyped, IAttributeConfigurable, IAttributeAnnotatable)
+    implements(IGenericTyped)
 
-    def __init__(self, __keyface__, *pos, **kws):
+    def __init__(self, *pos, **kws):
         super(OrderedContainer, self).__init__()
-        self.__dict__['__keyface__'] = __keyface__
-        updateDirectlyProvided(self, __keyface__)
-        initializer = IInitializer(self, None)
-        if initializer:
-            initializer(*pos, **kws)
 
     provides('__keyface__')
 
-    __keyface__ = UpdateProvides(IDirectlyTyped['__keyface__'])
+    __keyface__ = UpdateProvides(IGenericTyped['__keyface__'])
 
     @property
     def keyface(self):
@@ -132,19 +109,14 @@
 class Folder(folder.Folder):
     """Default implementation local, persistend and containerish possible sites."""
 
-    implements(IDirectlyTyped, IAttributeConfigurable, IAttributeAnnotatable)
+    implements(IGenericTyped)
 
-    def __init__(self, __keyface__, *pos, **kws):
+    def __init__(self, *pos, **kws):
         super(Folder, self).__init__()
-        self.__dict__['__keyface__'] = __keyface__
-        updateDirectlyProvided(self, __keyface__)
-        initializer = IInitializer(self, None)
-        if initializer:
-            initializer(*pos, **kws)
 
     provides('__keyface__')
 
-    __keyface__ = UpdateProvides(IDirectlyTyped['__keyface__'])
+    __keyface__ = UpdateProvides(IGenericTyped['__keyface__'])
 
     @property
     def keyface(self):

Deleted: zope.generic/trunk/src/zope/generic/type/factory.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/factory.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/type/factory.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -1,121 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-
-"""
-$Id$
-"""
-
-__docformat__ = 'restructuredtext'
-
-from zope.interface import implements
-
-from zope.component.factory import Factory
-from zope.component.interfaces import IFactory
-
-from zope.generic.type import ITypeable
-from zope.generic.type import ITyped
-from zope.generic.type import IDirectlyTyped
-from zope.generic.type import ITypeType
-        
-
-
-class TypeFactory(Factory):
-    """Type factory implementation.
-
-    Preset the type keyface for generic directly typed implementation 
-    of its __init__ method.
-
-    The type factory constructs directly typed objects of a given generic 
-    implementation (class).
-
-    First we declare a type marker:
-
-        >>> from zope.interface import Interface
-
-        >>> class IMyMarker(Interface):
-        ...     pass
-
-        >>> from zope.app.component.interface import provideInterface
-        >>> provideInterface('', IMyMarker, ITypeType)
-
-    Afterward we build a generic implementation implementing ITyped or a
-    regular typeable class:
-
-        >>> from zope.generic.type import IDirectlyTyped
-        >>> from zope.generic.directlyprovides.api import provides
-        >>> from zope.generic.directlyprovides.api import UpdateProvides
-        >>> from zope.generic.directlyprovides.api import updateDirectlyProvided
-
-        >>> class Object(object):
-        ...     implements(IDirectlyTyped)
-        ...
-        ...     def __init__(self, __keyface__, **kws):
-        ...         super(Object, self).__init__()
-        ...         self.__dict__['__keyface__'] = __keyface__
-        ...         updateDirectlyProvided(self, __keyface__)
-        ...
-        ...     provides('__keyface__')
-        ...     __keyface__ = UpdateProvides(IDirectlyTyped['__keyface__'])
-        ...     keyface = __keyface__
-
-        >>> class Foo(object):
-        ...    implements(ITypeable)
-
-    Now we make a factory instance and check it:
-
-        >>> myFactory = TypeFactory(Object, IMyMarker)
-
-        >>> my = myFactory()
-        >>> isinstance(my, Object)
-        True
-        >>> IMyMarker.providedBy(my)
-        True
-
-        >>> ITyped in myFactory.getInterfaces().flattened()
-        False
-        >>> IMyMarker in myFactory.getInterfaces().flattened()
-        True
-
-        >>> myFactory
-        <TypeFactory for <class 'zope.generic.type.factory.Object'>>
-        
-    """
-
-    implements(IFactory)
-
-    def __init__(self, callable, __keyface__):
-        # preconditions
-        if not ITypeable.implementedBy(callable):
-            raise ValueError('Callable must implement %s.' % ITypeable.__name__)
-
-        if not ITypeType.providedBy(__keyface__):
-            raise ValueError('Interface must provide %s.' % ITypeType.__name__)
-
-        super(TypeFactory, self).__init__(callable, title='', description='', interfaces=(__keyface__,))
-
-        # essentials
-        self.__keyface__ = __keyface__
-
-    def __call__(self, *pos, **kws):
-        if IDirectlyTyped.implementedBy(self._callable):
-            instance = self._callable(self.__keyface__, *pos, **kws)
-        
-        else:
-            instance = self._callable(*pos, **kws)
-
-        # TODO: query type information look for InitConfiguration and invoke the
-        # handler if possible
-        
-        return instance
-

Modified: zope.generic/trunk/src/zope/generic/type/helper.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/helper.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/type/helper.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -18,35 +18,15 @@
 
 __docformat__ = 'restructuredtext'
 
-from zope import component
-
-from zope.generic.keyface.api import toDottedName
 from zope.generic.informationprovider.api import queryInformation
-from zope.generic.informationprovider.api import queryInformationProvider
+from zope.generic.informationprovider.api import getInformationProvider
 
-from zope.generic.type import IInitializerConfiguration
 from zope.generic.type import ITypeInformation
 from zope.generic.type import ITyped
 from zope.generic.type import ITypeType
 
 
 
-def createObject(keyface, *pos, **kws):
-    """Create an instance of a logical type using the type marker."""
-    return component.createObject(toDottedName(keyface), *pos, **kws)
-
-
-
-def createParameter(keyface):
-    config = queryTypeConfiguration(keyface, IInitializerConfiguration)
-    if config:
-        return config.keyface
-    
-    else:
-        return None
-
-
-
 def getType(object):
     """Evaluate relevant type marker keyface of an object."""
 
@@ -73,7 +53,7 @@
 
 
 def getTypeInformation(object):
-    return queryInformationProvider(getType(object), ITypeInformation)
+    return getInformationProvider(getType(object), ITypeInformation)
 
 
 

Modified: zope.generic/trunk/src/zope/generic/type/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/interfaces.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/type/interfaces.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -18,22 +18,20 @@
 
 __docformat__ = 'restructuredtext'
 
+from zope.app.annotation.interfaces import IAttributeAnnotatable
 from zope.app.i18n import ZopeMessageFactory as _
-from zope.interface import alsoProvides
 from zope.interface import Interface
-from zope.schema import Bool
 from zope.schema import Object
 
-from zope.generic.configuration import IConfigurationType
-from zope.generic.directlyprovides import IProvides
+from zope.generic.configuration.api import IAttributeConfigurable
 from zope.generic.informationprovider import IInformationProvider
 from zope.generic.keyface import IKeyface
 from zope.generic.keyface import IKeyfaceType
+from zope.generic.keyface import IProvidesAttributeKeyfaced
 
 
-__all__ = ['ITypeType', 'ITypeable', 'ITyped', 'IDirectlyTyped', 
-           'ITypeInformation', 'IInitializer', 'IInitializationHandler', 
-           'IInitializerConfiguration']
+__all__ = ['ITypeType', 'ITypeable', 'ITyped', 'IGenericTyped', 
+           'ITypeInformation']
 
 
 
@@ -52,7 +50,7 @@
 
 
 class ITyped(ITypeable, IKeyface):
-    """Provid an information within the."""
+    """Provide the key interface."""
 
     keyface = Object(
         title=_('Key interface'),
@@ -62,63 +60,11 @@
 
 
 
-class IDirectlyTyped(ITyped, IProvides, IKeyface):
-    """Directly provide the declared interface."""
+class IGenericTyped(ITyped, IProvidesAttributeKeyfaced, IAttributeConfigurable, IAttributeAnnotatable):
+    """Directly provide the declared key interface interface."""
 
-    def __init__(__keyface__, *pos, **kws):
-        """Directly provide the key interface during the __init__ call."""
 
-    __keyface__ = Object(
-        title=_('Key interface'),
-        description=_('The declared key interface must be directly provided too.'),
-        required=True,
-        readonly=True,
-        schema=ITypeType)
 
-
-
 class ITypeInformation(IInformationProvider):
     """Provide information for the declared type interface."""
 
-
-
-class IInitializer(Interface):
-    """Initialize an object."""
-
-    def __call__(*pos, **kws):
-        """Invoke initialization handler declared by the initializer configuration."""
-
-
-
-class IInitializationHandler(Interface):
-    """Initialize an object."""
-
-    def __call__(context, *pos, **kws):
-        """Initialize the object referenced by self."""
-
-
-
-class IInitializerConfiguration(Interface):
-    """Provide initialization handler.
-
-    At least a handler or an interface must be defined.
-
-    If the interface is defined, **kws are stored as configuration defined by
-    the interface.
-
-    If the **kws does not satify the interface a KeyError is raised.
-    """
-
-    keyface = Object(
-        title=_('Configuration interface'),
-        description=_('Configuration interface defining the signature.'),
-        required=False,
-        schema=IConfigurationType)
-
-    handler = Object(
-        title=_('Initialization Handler'),
-        description=_('Callable (context, *pos, **kws).'),
-        required=False,
-        schema=IInitializationHandler)
-
-alsoProvides(IInitializerConfiguration, IConfigurationType)

Modified: zope.generic/trunk/src/zope/generic/type/meta.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/type/meta.zcml	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/type/meta.zcml	2006-04-25 19:38:26 UTC (rev 67606)
@@ -16,8 +16,8 @@
           />
 
       <meta:subdirective
-          name="initializer"
-          schema="zope.generic.type.metadirectives.IInitializerSubdirective"
+          name="factory"
+          schema=".metadirectives.IFactorySubdirective"
           />
 
       <meta:subdirective

Modified: zope.generic/trunk/src/zope/generic/type/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/metaconfigure.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/type/metaconfigure.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -21,29 +21,16 @@
 from types import ModuleType
 
 from zope.app.component.contentdirective import ClassDirective
-from zope.app.component.metaconfigure import proxify
 from zope.app.component.metaconfigure import adapter
-from zope.component import provideAdapter
-from zope.component import provideUtility
-from zope.component.interfaces import IFactory
-from zope.configuration.exceptions import ConfigurationError
-from zope.interface import implements
-from zope.security.checker import CheckerPublic
-from zope.security.checker import InterfaceChecker
 
-from zope.generic.configuration.api import ConfigurationData
+from zope.generic.configuration.api import ConfigurationAdapterClass
+from zope.generic.configuration.api import ConfigurationAdapterProperty
+from zope.generic.factory.metaconfigure import factoryDirective
 from zope.generic.informationprovider.api import provideInformation
 from zope.generic.informationprovider.metaconfigure import InformationProviderDirective
-from zope.generic.keyface.api import toDottedName
 
-from zope.generic.type import IInitializationHandler
-from zope.generic.type import IInitializerConfiguration
 from zope.generic.type import ITypeInformation
 from zope.generic.type import ITypeType
-from zope.generic.type.adapter import Initializer
-from zope.generic.configuration.api import ConfigurationAdapterClass
-from zope.generic.configuration.api import ConfigurationAdapterProperty
-from zope.generic.type.factory import TypeFactory
 from zope.generic.type.helper import queryTypeConfiguration
 from zope.generic.type.helper import queryTypeInformation
 
@@ -86,31 +73,6 @@
 
 
 
-class InitializationHandler(object):
-    """Initialization handler.
-    
-    Wrap a callable:
-
-        >>> def callable(context, *pos, **kws):
-        ...     print context, pos, kws
-        
-        >>> init_handler = InitializationHandler(callable)
-        
-        >>> init_handler(1, 2, 3, x=4)
-        1 (2, 3) {'x': 4}
-    
-    """
-
-    implements(IInitializationHandler)
-
-    def __init__(self, callable):
-        self.__callable = callable
-
-    def __call__(self, context, *pos, **kws):
-        self.__callable(context, *pos, **kws)
-
-
-
 class TypeDirective(InformationProviderDirective):
     """Provide a new logical type."""
 
@@ -118,52 +80,19 @@
     _information_type = ITypeType
 
 
-    def __init__(self, _context, keyface, class_, label=None, hint=None):
-        # preconditions
-        if isinstance(class_, ModuleType):
-            raise ConfigurationError('Implementation attribute must be a class')
-        
+    def __init__(self, _context, keyface, label=None, hint=None):        
         # register types within the type information registry
         registry = ITypeInformation
         super(TypeDirective, self).__init__(_context, keyface, registry, label, hint)
 
-        # create and proxy type factory
-        factory = TypeFactory(class_, self._keyface) 
-        component = proxify(factory, InterfaceChecker(IFactory, CheckerPublic))
+    def factory(self, _context, class_, operations=(), input=None,
+                providesKeyface=True, notifyCreated=True, storeInput=True):
+        """Add factory."""
+        factoryDirective(_context, self._keyface, class_, None, operations, input,
+                     providesKeyface, notifyCreated, storeInput,
+                     self._label, self._hint)
 
-        _context.action(
-            discriminator = ('provideUtility', self._keyface),
-            callable = provideUtility,
-            args = (component, IFactory, toDottedName(self._keyface)),
-            )
 
-    def initializer(self, _context, keyface=None, handler=None):
-        """Add initializer."""
-        # preconditions
-        if keyface is None and handler is None:
-            raise ConfigurationError('Attribute keyface or handler must be defined')
-
-        data = {}
-        if handler is not None:
-            if not IInitializationHandler.providedBy(handler):
-                handler = InitializationHandler(handler)
-
-            data['handler'] = handler
-
-        if keyface is not None:
-            data['keyface'] = keyface
-
-        adapter(self._context, factory=[Initializer], provides=None, 
-                for_=[self._keyface], permission=None, name='', trusted=True, 
-                locate=False)
-
-        _context.action(
-            discriminator = (
-            'initializer', self._keyface),
-            callable = provideTypeConfiguration,
-            args = (self._keyface, IInitializerConfiguration, data),
-            )
-
     def configurationAdapter(self, _context, keyface, class_=None, writePermission=None, readPermission=None):
         """Provide a generic configuration adatper."""
 

Modified: zope.generic/trunk/src/zope/generic/type/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/metadirectives.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/type/metadirectives.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -25,7 +25,9 @@
 from zope.configuration.fields import GlobalObject
 from zope.interface import Interface
 
+from zope.generic.factory.metadirectives import IBaseFactoryDirective
 from zope.generic.informationprovider.metadirectives import IBaseInformationProviderDirective
+from zope.generic.operation.metadirectives import IBaseOperationDirective
 
     
 
@@ -35,31 +37,13 @@
     Register an type information and a type factory.
     """
 
-    class_ = GlobalObject(
-        title=_('Class'),
-        description=_('Generic class implementation.'),
-        required=True
-        )
 
 
+class IFactorySubdirective(IBaseFactoryDirective, IBaseOperationDirective):
+    """Provide an factory for the type."""
 
-class IInitializerSubdirective(Interface):
-    """Provide an initializer configuration for the type."""
 
-    keyface = GlobalInterface(
-        title=_('Configuration keyface'),
-        description=_('Configuration keyface defining the signature.'),
-        required=False
-        )
 
-    handler = GlobalObject(
-        title=_('Initializiation handler'),
-        description=_('Callable (context, *pos, **kws).'),
-        required=False
-        )
-
-
-
 class IConfigurationAdapterSubdirective(Interface):
     """Provide an adapter to a certain configuration."""
 

Modified: zope.generic/trunk/src/zope/generic/type/testing.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/testing.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/type/testing.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -21,9 +21,12 @@
 from zope.configuration.xmlconfig import XMLConfig
 
 import zope.app.testing.placelesssetup
+
+import zope.generic.configuration.testing
 import zope.generic.directlyprovides.testing
-import zope.generic.configuration.testing
+import zope.generic.factory.testing
 import zope.generic.keyface.testing
+import zope.generic.operation.testing
 import zope.generic.testing.testing
 
 ################################################################################
@@ -63,17 +66,21 @@
         zope.generic.directlyprovides.testing.setUp(doctest)
         zope.generic.keyface.testing.setUp(doctest)
         zope.generic.configuration.testing.setUp(doctest)
+        zope.generic.operation.testing.setUp(doctest)
+        zope.generic.factory.testing.setUp(doctest)
         # internal setup
         setUp(doctest)
 
     def tearDown(self, doctest=None):
-        super(PlacelessSetup, self).tearDown()
+        # internal teardown
+        tearDown(doctest)
         # external teardown
+        zope.generic.factory.testing.tearDown(doctest)
+        zope.generic.operation.testing.tearDown(doctest)
         zope.generic.configuration.testing.tearDown(doctest)
         zope.generic.keyface.testing.tearDown(doctest)
         zope.generic.directlyprovides.testing.tearDown(doctest)
         zope.generic.testing.testing.tearDown(doctest)
-        # internal teardown
-        tearDown(doctest)
+        super(PlacelessSetup, self).tearDown()
 
 placelesssetup = PlacelessSetup()

Modified: zope.generic/trunk/src/zope/generic/type/tests.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/tests.py	2006-04-25 19:33:52 UTC (rev 67605)
+++ zope.generic/trunk/src/zope/generic/type/tests.py	2006-04-25 19:38:26 UTC (rev 67606)
@@ -32,8 +32,6 @@
 
 def test_suite():
     return unittest.TestSuite((
-        doctest.DocTestSuite('zope.generic.type.factory'),
-        doctest.DocTestSuite('zope.generic.type.metaconfigure'),
         doctest.DocFileSuite('README.txt',
                              setUp=testing.placelesssetup.setUp,
                              tearDown=testing.placelesssetup.tearDown,



More information about the Checkins mailing list