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

Dominik Huber dominik.huber at perse.ch
Mon Apr 24 09:57:48 EDT 2006


Log message for revision 67567:
  refactored zope.generic.operation

Changed:
  U   zope.generic/trunk/src/zope/generic/configuration/adapter.py
  U   zope.generic/trunk/src/zope/generic/configuration/api.py
  U   zope.generic/trunk/src/zope/generic/configuration/helper.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/base.py
  D   zope.generic/trunk/src/zope/generic/operation/helper.py
  U   zope.generic/trunk/src/zope/generic/operation/interfaces.py
  U   zope.generic/trunk/src/zope/generic/operation/metaconfigure.py
  U   zope.generic/trunk/src/zope/generic/operation/metadirectives.py

-=-
Modified: zope.generic/trunk/src/zope/generic/configuration/adapter.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/adapter.py	2006-04-24 12:39:37 UTC (rev 67566)
+++ zope.generic/trunk/src/zope/generic/configuration/adapter.py	2006-04-24 13:57:46 UTC (rev 67567)
@@ -123,7 +123,7 @@
         except AttributeError:
             configurations = self.context.__configurations__ = OOBTree()
 
-        data = configuratonToDict(keyface, value, all=True)
+        data = configuratonToDict(value, all=True)
         configurations[toDottedName(keyface)] = value
         # notify setting
         parent = self.__parent__

Modified: zope.generic/trunk/src/zope/generic/configuration/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/api.py	2006-04-24 12:39:37 UTC (rev 67566)
+++ zope.generic/trunk/src/zope/generic/configuration/api.py	2006-04-24 13:57:46 UTC (rev 67567)
@@ -23,7 +23,9 @@
 from zope.generic.configuration.adapter import ConfigurationAdapterClass
 from zope.generic.configuration.adapter import ConfigurationAdapterProperty
 from zope.generic.configuration.base import ConfigurationData
+from zope.generic.configuration.helper import argumentsToConfiguration
 from zope.generic.configuration.helper import configuratonToDict
+from zope.generic.configuration.helper import requiredInOrder
 
 
 

Modified: zope.generic/trunk/src/zope/generic/configuration/helper.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/helper.py	2006-04-24 12:39:37 UTC (rev 67566)
+++ zope.generic/trunk/src/zope/generic/configuration/helper.py	2006-04-24 13:57:46 UTC (rev 67567)
@@ -19,9 +19,15 @@
 __docformat__ = 'restructuredtext'
 
 
+from zope.generic.keyface import IKeyface
+
+from zope.generic.configuration.base import ConfigurationData
+
+
+
 _marker = object()
 
-def configuratonToDict(interface, configuration, all=False):
+def configuratonToDict(configuration, all=False):
     """Extract values from configuration to a dictionary.
 
     First we have to specify a test configurtion interface:
@@ -29,27 +35,29 @@
         >>> from zope.interface import Interface
         >>> from zope.schema import TextLine
         
-        >>> class IFooConfiguration(Interface):
-        ...    fo = TextLine(title=u'Fo')
-        ...    foo = TextLine(title=u'Foo', required=False)
-        ...    fooo = TextLine(title=u'Fooo', required=False, readonly=True, default=u'fooo bla')
+        >>> class IAnyConfiguration(Interface):
+        ...    a = TextLine()
+        ...    b = TextLine(required=False)
+        ...    c = TextLine(required=False, readonly=True, default=u'c default')
 
     Minimal data without defaults:
 
         >>> from zope.generic.configuration.base import ConfigurationData
-        >>> configuration = ConfigurationData(IFooConfiguration, {'fo': 'fo bla'})
-        >>> configuratonToDict(IFooConfiguration, configuration)
-        {'fo': 'fo bla'}
+        >>> configuration = ConfigurationData(IAnyConfiguration, {'a': 'a bla'})
+        >>> configuratonToDict(configuration)
+        {'a': 'a bla'}
 
     Including defaults:
-        >>> configuratonToDict(IFooConfiguration, configuration, all=True)
-        {'fooo': u'fooo bla', 'foo': None, 'fo': 'fo bla'}
+        >>> configuratonToDict(configuration, all=True)
+        {'a': 'a bla', 'c': u'c default', 'b': None}
 
     """
     data = {}
-    for name in interface:
+    keyface = IKeyface(configuration).keyface
+
+    for name in keyface:
         value = getattr(configuration, name, _marker)
-        field = interface[name]
+        field = keyface[name]
 
         if field.required is False:
             if value is not _marker and value != field.default:
@@ -70,3 +78,134 @@
             raise RuntimeError('Data is missing', name)
 
     return data
+
+
+
+def requiredInOrder(configuration):
+    """Evaluate the relevant order of positional arguments.
+
+    The relevant order of positional arguments is evaluated by a configuration
+    key interface.
+
+        >>> from zope.interface import Interface
+        >>> from zope.schema import TextLine
+        
+        >>> class IAnyConfiguration(Interface):
+        ...    a = TextLine()
+        ...    b = TextLine(required=False)
+        ...    c = TextLine(required=False, readonly=True, default=u'c bla')
+        ...    d = TextLine()
+
+        >>> requiredInOrder(IAnyConfiguration)
+        ['a', 'd']
+    
+    """
+    
+    return [name for name in configuration if configuration[name].required is True]
+
+
+
+def argumentsToConfiguration(__keyface__, *pos, **kws):
+    """Create configuration data
+
+    The generic signature *pos, **kws can will be resolved into a configuration.
+
+        >>> from zope.interface import Interface
+        >>> from zope.schema import TextLine
+        
+        >>> class IAnyConfiguration(Interface):
+        ...    a = TextLine()
+        ...    b = TextLine(required=False)
+        ...    c = TextLine(required=False, readonly=True, default=u'c default')
+        ...    d = TextLine()
+
+    A: No arguments does not satisfy the configuration:
+
+        >>> argumentsToConfiguration(IAnyConfiguration)
+        Traceback (most recent call last):
+        ...
+        AttributeError: 'IAnyConfiguration' object has no attribute 'a, d'.
+
+    B: Provide the required as positionals:
+
+        >>> config = argumentsToConfiguration(IAnyConfiguration, u'a bla', u'd bla')
+        >>> config.a, config.b, config.c, config.d
+        (u'a bla', None, u'c default', u'd bla')
+
+    C: Provide the required as positional and keyword:
+
+        >>> config = argumentsToConfiguration(IAnyConfiguration, u'a bla', d=u'd bla')
+        >>> config.a, config.b, config.c, config.d
+        (u'a bla', None, u'c default', u'd bla')
+
+    D: Provide all required as keyword:
+
+        >>> config = argumentsToConfiguration(IAnyConfiguration, d=u'd bla', c=u'c bla', a=u'a bla')
+        >>> config.a, config.b, config.c, config.d
+        (u'a bla', None, u'c bla', u'd bla')
+
+    E: You can also use an existing configuration as input:
+
+        >>> argumentsToConfiguration(IAnyConfiguration, config) == config
+        True
+
+
+    F: Provide the required as positional and keyword, do not messup the order otherwise
+    a duplacted arguments error could occur:
+
+        >>> config = argumentsToConfiguration(IAnyConfiguration, u'a bla', d=u'd bla', c=u'c bla')
+        >>> config.a, config.b, config.c, config.d
+        (u'a bla', None, u'c bla', u'd bla')
+
+        >>> argumentsToConfiguration(IAnyConfiguration, u'd bla', a=u'd bla', c=u'c bla')
+        Traceback (most recent call last):
+        ...
+        AttributeError: Duplicated arguments: a.
+
+    G: Sometimes no arguments are allowed. This use case is indicated by a None key interface:
+
+        >>> argumentsToConfiguration(None) is None
+        True
+
+        >>> argumentsToConfiguration(None, 'not allowed parameter')
+        Traceback (most recent call last):
+        ...
+        AttributeError: No arguments allowed.
+    """
+    # no arguments declared
+    if __keyface__ is None:
+        if pos or kws:
+            raise AttributeError('No arguments allowed.')
+
+        return None
+
+    # assume that kws are ok
+    if not pos:
+        try:
+            return ConfigurationData(__keyface__, kws)
+
+        except:
+            pass
+
+    # assume that first pos is already a configuration
+    if len(pos) == 1 and not kws and __keyface__.providedBy(pos[0]):
+        return pos[0]
+
+    # pos and kws mixture
+    attribution = requiredInOrder(__keyface__)
+    errors = []
+    for i in range(len(pos)):
+        key = attribution[i]
+        value = pos[i]
+        
+        
+        if key not in kws:
+            kws[key] = value
+        else:
+            errors.append(key)
+
+    if errors:
+        raise AttributeError('Duplicated arguments: %s.' % ', '.join(errors))
+
+    return ConfigurationData(__keyface__, kws)
+        
\ No newline at end of file

Modified: zope.generic/trunk/src/zope/generic/operation/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/README.txt	2006-04-24 12:39:37 UTC (rev 67566)
+++ zope.generic/trunk/src/zope/generic/operation/README.txt	2006-04-24 13:57:46 UTC (rev 67567)
@@ -7,81 +7,128 @@
 
 An operation is a reusable processing unit. The unit is also marked by a
 dedicated interface:
-    
-    >>> class IMakeSiteOperation(interface.Interface):
-    ...    """This operation makes a folderish context to a site."""
 
-    >>> class ISetupPAUOperation(interface.Interface):
-    ...    """Setup a PAU within the context."""
-
-    >>> class IConfigureAnythingOperation(interface.Interface):
+    >>> class IAnyOperation(interface.Interface):
     ...    """Write a configuration."""
 
+Such an operation consists of an input-declaration, an 
+output-declaration and a corresponding handler.
 
-If needed we have specify new or we can reuse existing input and output
-configuration schema.
-
     >>> from zope.schema import TextLine
 
-    >>> class IPAUConfig(interface.Interface):
-    ...    """Configuration information to setup a pau."""
-    ...    a = TextLine(required=False, default=u'Default pau config.')
-
-    >>> class IAnyInputConfig(interface.Interface):
-    ...    """Input configuration for the any application."""
+    >>> class IAnyInput(interface.Interface):
+    ...    """A possible input declaration for any operation."""
     ...    a = TextLine()
     ...    b = TextLine(required=False)
-    ...    c = TextLine(required=False)
+    ...    c = TextLine(required=False, default=u'c default')
 
-    >>> class IAConfig(interface.Interface):
-    ...    """Output a configuration."""
-    ...    a = TextLine()
-
-    >>> class IBConfig(interface.Interface):
-    ...    """Output b configuration."""
+    >>> class IAnyOutput(interface.Interface):
+    ...    """A possible output declaration for any operation."""
     ...    b = TextLine()
 
+    >>> from zope.generic.configuration.api import argumentsToConfiguration
+    >>> from zope.generic.configuration.api import ConfigurationData
 
-    >>> registerDirective('''
-    ... <generic:keyface
-    ...     keyface="example.IPAUConfig"
-    ...     type="zope.generic.configuration.IConfigurationType"
-    ...     />
-    ... ''') 
+    >>> def anyOperation(context, *pos, **kws):
+    ...     input = argumentsToConfiguration(IAnyInput, *pos, **kws)
+    ...     print 'Any input: a=%s, b=%s, c=%s.' % (input.a, input.b, input.c)
+    ...     print 'Operate on *%s*.' % context
+    ...     return ConfigurationData(IAnyOutput, {'b': u'b operated'})
 
+We have to register those parts:
+
     >>> registerDirective('''
     ... <generic:keyface
-    ...     keyface="example.IAnyInputConfig"
+    ...     keyface="example.IAnyInput"
     ...     type="zope.generic.configuration.IConfigurationType"
     ...     />
     ... ''') 
 
     >>> registerDirective('''
     ... <generic:keyface
-    ...     keyface="example.IAConfig"
+    ...     keyface="example.IAnyOutput"
     ...     type="zope.generic.configuration.IConfigurationType"
     ...     />
     ... ''') 
 
     >>> registerDirective('''
-    ... <generic:keyface
-    ...     keyface="example.IBConfig"
-    ...     type="zope.generic.configuration.IConfigurationType"
+    ... <generic:operation
+    ...     keyface="example.IAnyOperation"
+    ...     operations="example.anyOperation"
+    ...     input="example.IAnyInput"
+    ...     output="example.IAnyOutput"
     ...     />
-    ... ''') 
+    ... ''')
 
-The operation can be implemented in different ways:
+We can retrieve and introspect any registered operation by the following ways
+using itself or its keyface. For each operation directive an operation 
+information will be registered:
 
+    >>> from zope.generic.informationprovider.api import getInformationProvidersFor
+
+    >>> listing = list(getInformationProvidersFor(api.IOperationInformation))
+    >>> len(listing)
+    1
+
+    >>> operation = api.getOperation(IAnyOperation)
+
+    >>> api.inputParameter(operation) is IAnyInput
+    True
+    >>> api.inputParameter(IAnyOperation) is IAnyInput
+    True
+
+    >>> api.outputParameter(operation) is IAnyOutput
+    True
+    >>> api.outputParameter(IAnyOperation) is IAnyOutput
+    True
+
+You can call an operation on a context:
+
+    >>> operation('corresponding Context')
+    Traceback (most recent call last):
+    ...
+    AttributeError: 'IAnyInput' object has no attribute 'a'.
+
+    >>> output = operation('corresponding Context', u'a bla')
+    Any input: a=a bla, b=None, c=c default.
+    Operate on *corresponding Context*.
+
+    >>> api.outputParameter(operation).providedBy(output)
+    True
+    >>> output.b
+    u'b operated'
+
+
+Step 2: Build a complex operation reusing the base operations
+-------------------------------------------------------------
+
+For this example we provide a few other example operations:
+
+    >>> class IMakeSiteOperation(interface.Interface):
+    ...    """This operation makes a folderish context to a site."""
+
+    >>> class ISetupPAUOperation(interface.Interface):
+    ...    """Setup a PAU within the context."""
+
+    >>> class IPAUConfig(interface.Interface):
+    ...    """Configuration information to setup a pau."""
+    ...    a = TextLine(required=False, default=u'Default pau config.')
+
     >>> def makeSiteOperation(context, *pos, **kws):
-    ...     print 'makeSiteOperation'
+    ...     print 'Public operation: makeSiteOperation'
 
     >>> def setupPAUOperation(context, *pos, **kws):
-    ...     print 'setupPAUOperation'
+    ...     print 'Public operation: setupPAUOperation'
+    ...     input = argumentsToConfiguration(IPAUConfig, *pos, **kws)
+    ...     print 'Pau input: a=%s.' % (input.a)
 
-    >>> def configureAnythingOperation(context, *pos, **kws):
-    ...     print 'configureAnythingOperation'
+    >>> registerDirective('''
+    ... <generic:keyface
+    ...     keyface="example.IPAUConfig"
+    ...     type="zope.generic.configuration.IConfigurationType"
+    ...     />
+    ... ''')
 
-
     >>> registerDirective('''
     ... <generic:operation
     ...     keyface="example.IMakeSiteOperation"
@@ -97,30 +144,21 @@
     ...     />
     ... ''')
 
-    >>> registerDirective('''
-    ... <generic:operation
-    ...     keyface="example.IConfigureAnythingOperation"
-    ...     operations="example.configureAnythingOperation"
-    ...     input="example.IPAUConfig"
-    ...     />
-    ... ''')
+All of this registrations and the corresponding code might be provided by a
+third party.
 
-Step 2: Build a complex operation reusing the base operations
--------------------------------------------------------------
+We will build a new pipped operation. Therefore we declare a new key
+interface for the combined operations:
 
-There is a new interface marking the combined operation:
+    >>> class IMakeSiteSetupPAUAndAnyOperation(interface.Interface):
+    ...    """Invoke the other three operation."""
 
-    >>> class IMakeSiteSetupPAUConfigureAnythingOperation(interface.Interface):
-    ...    """Use the other three operation as nested information."""
+Regularly you will have to provide a new input configuration:
 
-Maybe you need an extra configuration:
-
     >>> class IComplexConfig(interface.Interface):
     ...    """Output complex configuration."""
     ...    pau = TextLine()
-    ...    any_a = TextLine()
-    ...    any_b = TextLine()
-    ...    any_c = TextLine()
+    ...    any = TextLine()
 
     >>> registerDirective('''
     ... <generic:keyface
@@ -129,49 +167,69 @@
     ...     />
     ... ''') 
 
-Sometimes you like to extend the base operation. Therefore you can include a simple
+Often you have to extend the base operations. Therefore you can include a simple
 function. It's not necessary to register such a private function as a public
-function using the operation directive:
+function using the operation directive. In our example we do need four private 
+operations, one is setting the IAnyConfiguration and IPauConfiguration to the 
+context and providing the pau configuration, the secound and third will provide
+the input parameter for the pau- and the any-operation, and the fourth should
+avoid the return value of the any-operation:
 
-    >>> def privateOperation(context, *pos, **kws):
-    ...    print 'privateOperation'
+    >>> from zope.generic.configuration.api import ConfigurationData
+    >>> from zope.generic.informationprovider.api import getInformation
+    >>> from zope.generic.informationprovider.api import provideInformation
 
+    >>> def inputToConfigurations(context, *pos, **kws):
+    ...    print 'Private operation: inputToConfigurations'
+    ...    input = argumentsToConfiguration(IComplexConfig, *pos, **kws)
+    ...    provideInformation(context, IAnyInput, {'a': input.any})
+    ...    provideInformation(context, IPAUConfig, {'a': input.pau})
+
+    >>> def pauInitializer(context, *pos, **kws):
+    ...    print 'Private operation: pauInitializer'
+    ...    return getInformation(context, IPAUConfig)
+
+    >>> def anyOperationInitializer(context, *pos, **kws):
+    ...    print 'Private operation: anyOperationInitializer'
+    ...    return getInformation(context, IAnyInput)
+
+    >>> def void(context, *pos, **kws):
+    ...    print 'Private operation: void'
+
 At least we register the complex operation using the operation marker interfaces
-and the private operation:
+and the private operations:
 
     >>> registerDirective('''
     ... <generic:operation
-    ...     keyface="example.IMakeSiteSetupPAUConfigureAnythingOperation"
-    ...     operations="example.IMakeSiteOperation example.setupPAUOperation
-    ...         example.configureAnythingOperation example.privateOperation"
+    ...     keyface="example.IMakeSiteSetupPAUAndAnyOperation"
+    ...     operations="example.inputToConfigurations example.IMakeSiteOperation 
+    ...         example.pauInitializer example.setupPAUOperation
+    ...         example.anyOperationInitializer example.anyOperation
+    ...         example.void"
     ...     input="example.IComplexConfig"
-    ...     output=""
     ...     />
     ... ''')
 
-For each operation directive we registered an operation information. This
-operation information can be retrieved:
+Now we will check the behavior of the example on a dedicated context:
 
-    >>> from zope.generic.informationprovider.api import getInformationProvidersFor
+    >>> from zope.generic.configuration import IAttributeConfigurable
 
-    >>> listing = list(getInformationProvidersFor(api.IOperationInformation))
-    >>> len(listing)
-    4
+    >>> class DummyContext(object):
+    ...     interface.implements(IAttributeConfigurable)
+    ...     def __repr__(self):
+    ...         return 'DummyContext'
 
-We can retrieve any registered operation by the following function:
+    >>> context = DummyContext()
 
-    >>> operation = api.queryOperation(IMakeSiteSetupPAUConfigureAnythingOperation)
+    >>> operation = api.getOperation(IMakeSiteSetupPAUAndAnyOperation)
 
-    >>> operation(None)
-    makeSiteOperation
-    setupPAUOperation
-    configureAnythingOperation
-    privateOperation
-
-    >>> [c.__name__ for c in api.queryOperationInput(IMakeSiteSetupPAUConfigureAnythingOperation)]
-    ['IComplexConfig']
-
-    >>> [c.__name__ for c in api.queryOperationOutput(IMakeSiteSetupPAUConfigureAnythingOperation)]
-    []
-
-
+    >>> operation(context, any='a any', pau=u'a pau')
+    Private operation: inputToConfigurations
+    Public operation: makeSiteOperation
+    Private operation: pauInitializer
+    Public operation: setupPAUOperation
+    Pau input: a=a pau.
+    Private operation: anyOperationInitializer
+    Any input: a=a any, b=None, c=c default.
+    Operate on *DummyContext*.
+    Private operation: void

Modified: zope.generic/trunk/src/zope/generic/operation/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/api.py	2006-04-24 12:39:37 UTC (rev 67566)
+++ zope.generic/trunk/src/zope/generic/operation/api.py	2006-04-24 13:57:46 UTC (rev 67567)
@@ -17,12 +17,63 @@
 """
 
 # usage see README.txt
+from zope.generic.informationprovider.api import getInformationProvider
+from zope.generic.informationprovider.api import getInformation
+
 from zope.generic.operation.interfaces import *
 
-from zope.generic.operation.helper import getOperationInformation
-from zope.generic.operation.helper import getOperationConfiguration
-from zope.generic.operation.helper import queryOperationInformation
-from zope.generic.operation.helper import queryOperationConfiguration
-from zope.generic.operation.helper import queryOperation
-from zope.generic.operation.helper import queryOperationInput
-from zope.generic.operation.helper import queryOperationOutput
+
+
+def getOperationInformation(object):
+    """Evaluate an operation information from an object."""
+    return getInformationProvider(object, IOperationInformation)
+
+
+
+def queryOperationInformation(object, default=None):
+    """Evaluate an operation information from an object or return default."""
+    try:
+        return getOperationInformation(object)
+
+    except:
+        return default
+
+
+
+def getOperationConfiguration(object):
+    """Evaluate an operation configuration."""
+    
+    return getInformation(getOperationInformation(object), IOperationConfiguration)
+
+
+
+def queryOperationConfiguration(object, default=None):
+    """Evaluate an operation configuration or default."""
+    try:
+        return getOperationConfiguration(object)
+
+    except:
+        return default
+
+
+
+def getOperation(keyface, default=None):
+    """Return the operation of operation marker."""
+
+    return getOperationConfiguration(keyface).operation
+
+
+
+
+def inputParameter(object, default=None):
+    """Return the input paramters of an operation as tuple of configuration keyfaces."""
+
+    return getOperationConfiguration(object).input
+
+
+
+
+def outputParameter(object, default=None):
+    """Return the ouput paramters of an operation as tuple of configuration keyfaces."""
+
+    return getOperationConfiguration(object).output

Modified: zope.generic/trunk/src/zope/generic/operation/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/base.py	2006-04-24 12:39:37 UTC (rev 67566)
+++ zope.generic/trunk/src/zope/generic/operation/base.py	2006-04-24 13:57:46 UTC (rev 67567)
@@ -23,6 +23,7 @@
 
 from zope.generic.keyface import IAttributeKeyfaced
 from zope.generic.keyface.api import Keyface
+from zope.generic.configuration.api import argumentsToConfiguration
 
 from zope.generic.operation import IOperation
 from zope.generic.operation import IPrivateOperation
@@ -34,10 +35,12 @@
 
     implements(IOperation)
 
-    keyface = FieldProperty(IAttributeKeyfaced['__keyface__'])
+    __keyface__ = FieldProperty(IAttributeKeyfaced['__keyface__'])
 
-    def __init__(self, callable=None, keyface=None):
-        self.__callable = callable
+    def __init__(self, callable=None, keyface=None, input=None, output=None):
+        self._callable = callable
+        self._input = input
+        self._output = output
 
         # otherwise use IPrivatConfigurationHandler
         if keyface is not None:
@@ -46,22 +49,30 @@
             self.__keyface__ = IPrivateOperation
 
     def __call__(self, context, *pos, **kws):
-        self._proceed(context)
+        return self._proceed(context, *pos, **kws)
 
     def _proceed(self, context, *pos, **kws):
         # this method can be overwritten by subclasses
-        if self.__callable is not None:
-            self.__callable(context, *pos, **kws)
+        if self._callable is not None:
+            return self._callable(context, *pos, **kws)
 
 
 
-class OperationChain(Operation):
+class OperationPipe(Operation):
     """Generic operation chain wrapper."""
 
-    def __init__(self, operations, keyface=None):
-        super(OperationChain, self).__init__(None, keyface)
-        self.__operations = operations
+    def __init__(self, operations, keyface=None, input=None, output=None):
+        super(OperationPipe, self).__init__(None, keyface, input, output)
+        self._operations = operations
 
     def _proceed(self, context, *pos, **kws):
         """Invoke operation in the listed order."""
-        [operation(context) for operation in self.__operations]
+        last_output = argumentsToConfiguration(self._input, *pos, **kws)
+        for operation in self._operations:
+            if last_output is not None:
+                last_output = operation(context, last_output)
+
+            else:
+                last_output = operation(context)
+
+        return last_output

Deleted: zope.generic/trunk/src/zope/generic/operation/helper.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/helper.py	2006-04-24 12:39:37 UTC (rev 67566)
+++ zope.generic/trunk/src/zope/generic/operation/helper.py	2006-04-24 13:57:46 UTC (rev 67567)
@@ -1,91 +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.generic.informationprovider.api import getInformationProvider
-from zope.generic.informationprovider.api import getInformation
-
-from zope.generic.operation import IOperationInformation
-from zope.generic.operation import IOperationConfiguration
-
-
-
-def getOperationInformation(object):
-    """Evaluate an operation information from an object."""
-    return getInformationProvider(object, IOperationInformation)
-
-
-
-def queryOperationInformation(object, default=None):
-    """Evaluate an operation information from an object or return default."""
-    try:
-        return getOperationInformation(object)
-
-    except:
-        return default
-
-
-
-def getOperationConfiguration(object):
-    """Evaluate an operation configuration."""
-    
-    return getInformation(getOperationInformation(object), IOperationConfiguration)
-
-
-
-def queryOperationConfiguration(object, default=None):
-    """Evaluate an operation configuration or default."""
-    try:
-        return getOperationConfiguration(object)
-
-    except:
-        return default
-
-
-
-def queryOperation(keyface, default=None):
-    """Return the operation of operation marker."""
-
-    try:
-        return getOperationConfiguration(keyface).operation
-
-    except:
-        return default
-
-
-
-def queryOperationInput(keyface, default=None):
-    """Return the input paramters of an operation as tuple of configuration keyfaces."""
-
-    try:
-        return getOperationConfiguration(keyface).input
-
-    except:
-        return default
-
-
-
-def queryOperationOutput(keyface, default=None):
-    """Return the ouput paramters of an operation as tuple of configuration keyfaces."""
-
-    try:
-        return getOperationConfiguration(keyface).output
-
-    except:
-        return default

Modified: zope.generic/trunk/src/zope/generic/operation/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/interfaces.py	2006-04-24 12:39:37 UTC (rev 67566)
+++ zope.generic/trunk/src/zope/generic/operation/interfaces.py	2006-04-24 13:57:46 UTC (rev 67567)
@@ -21,6 +21,7 @@
 from zope.app.i18n import ZopeMessageFactory as _
 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
@@ -91,17 +92,17 @@
         required=False,
         schema=IOperation)
 
-    input = Tuple(title=_('Input Configurations'),
-        description=_('Tuple of configuration schema that will be respected.'),
+    input = Tuple(title=_('Input Declaration'),
+        description=_('A configuration interface declaring the input parameters.'),
         required=False,
         default=(),
         value_type=Object(schema=IConfigurationType))
 
-    output = Tuple(title=_('Output Configurations'),
-        description=_('Tuple of configuration schema that might be modified or created.'),
+    output = Tuple(title=_('Output Declaration'),
+        description=_('An interface interface declaring the output parameters.'),
         required=False,
         default=(),
-        value_type=Object(schema=IConfigurationType))
+        value_type=Object(schema=IInterface))
 
 
 

Modified: zope.generic/trunk/src/zope/generic/operation/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/metaconfigure.py	2006-04-24 12:39:37 UTC (rev 67566)
+++ zope.generic/trunk/src/zope/generic/operation/metaconfigure.py	2006-04-24 13:57:46 UTC (rev 67567)
@@ -35,10 +35,10 @@
 from zope.generic.operation import IOperationInformation
 from zope.generic.operation import IOperationType
 from zope.generic.operation.base import Operation
-from zope.generic.operation.base import OperationChain
+from zope.generic.operation.base import OperationPipe
 
 
-def _assertOperation(handler, keyface=None):
+def _assertOperation(handler, keyface=None, input=None, output=None):
     """Assert that we get an operation."""
 
     if IOperation.providedBy(handler):
@@ -59,11 +59,11 @@
         return config.operation
 
     # asume callabe (context)
-    return Operation(handler, keyface)
+    return Operation(handler, keyface, input, output)
 
 
 
-def provideOperationConfiguration(keyface, operations=(), input=(), output=()):
+def provideOperationConfiguration(keyface, operations=(), input=None, output=None):
     """Provide the handler to an configuration information."""
     
     registry = IOperationInformation
@@ -76,22 +76,22 @@
 
     if len(operations) == 0:
         # hidding overwrite -> pass handler
-        operation = _assertOperation(None, keyface)
+        operation = _assertOperation(None, keyface, input, output)
     
     elif len(operations) == 1:
-        operation = _assertOperation(operations[0], keyface)
+        operation = _assertOperation(operations[0], keyface, input, output)
     
     else:
-        operation = OperationChain([_assertOperation(handler) for handler in operations], keyface)
+        operation = OperationPipe([_assertOperation(handler) for handler in operations], keyface, input, output)
 
     configurations = IConfigurations(info)
     # create and set configuration data
     provideInformation(info, IOperationConfiguration, 
-        {'operation': operation, 'input': tuple(input), 'output': tuple(output)})
+        {'operation': operation, 'input': input, 'output': output})
 
 
 
-def operationDirective(_context, keyface, operations=(), input=(), output=(), label=None, hint=None):
+def operationDirective(_context, keyface, operations=(), input=None, output=None, label=None, hint=None):
     """Register a public operation."""
 
     # assert type as soon as possible

Modified: zope.generic/trunk/src/zope/generic/operation/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/metadirectives.py	2006-04-24 12:39:37 UTC (rev 67566)
+++ zope.generic/trunk/src/zope/generic/operation/metadirectives.py	2006-04-24 13:57:46 UTC (rev 67567)
@@ -41,13 +41,10 @@
         value_type=GlobalObject()
         )
 
-    input = Tokens(title=_('Input Configurations'),
+    input = GlobalInterface(title=_('Input Configurations'),
         description=_('Tuple of configuration schema that will be respected.'),
-        required=False,
-        value_type=GlobalInterface())
+        required=False)
 
-    output = Tokens(title=_('Output Configurations'),
+    output = GlobalInterface(title=_('Output Configurations'),
         description=_('Tuple of configuration schema that might be modified or created.'),
-        required=False,
-        value_type=GlobalInterface())
-        
\ No newline at end of file
+        required=False)



More information about the Checkins mailing list