[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