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

Dominik Huber dominik.huber at perse.ch
Fri May 5 11:37:12 EDT 2006


Log message for revision 67994:
  .configuration:
  - refactored ConfigurationDate (removed PersistentDict)
  - better validation of configuration
  - readonly field of configuration data can set once
  
  .operation and .factory:
  - few fixes and simplifications
  - Introduce INoParameter and IUndefinedParameter

Changed:
  U   zope.generic/trunk/src/zope/generic/configuration/api.py
  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/tests.py
  U   zope.generic/trunk/src/zope/generic/content/EXAMPLE.txt
  U   zope.generic/trunk/src/zope/generic/content/metaconfigure.py
  U   zope.generic/trunk/src/zope/generic/factory/factory.py
  U   zope.generic/trunk/src/zope/generic/factory/metaconfigure.py
  U   zope.generic/trunk/src/zope/generic/factory/metadirectives.py
  U   zope.generic/trunk/src/zope/generic/informationprovider/api.py
  A   zope.generic/trunk/src/zope/generic/informationprovider/helper.py
  U   zope.generic/trunk/src/zope/generic/informationprovider/meta.zcml
  U   zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py
  U   zope.generic/trunk/src/zope/generic/informationprovider/metadirectives.py
  U   zope.generic/trunk/src/zope/generic/informationprovider/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/metadirectives.py

-=-
Modified: zope.generic/trunk/src/zope/generic/configuration/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/api.py	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/configuration/api.py	2006-05-05 15:37:11 UTC (rev 67994)
@@ -22,9 +22,8 @@
 from zope.generic.configuration.adapter import AttributeConfigurations
 from zope.generic.configuration.base import ConfigurationData
 from zope.generic.configuration.helper import configuratonToDict
-from zope.generic.configuration.helper import getValue
+from zope.generic.configuration.helper import provideConfigurationType
 from zope.generic.configuration.helper import requiredInOrder
-from zope.generic.configuration.helper import toConfigFaceTriple
 
 
 

Modified: zope.generic/trunk/src/zope/generic/configuration/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/base.py	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/configuration/base.py	2006-05-05 15:37:11 UTC (rev 67994)
@@ -20,12 +20,12 @@
 
 from persistent import Persistent
 from persistent import IPersistent
-from persistent.dict import PersistentDict
 
 from zope.interface import directlyProvides
 from zope.interface import implements
+from zope.schema import ValidationError
+from zope.schema.interfaces import IField
 from zope.schema.interfaces import IObject
-from zope.schema.interfaces import IContainer
 
 from zope.generic.face import IAttributeFaced
 from zope.generic.face import IFace
@@ -35,7 +35,6 @@
 from zope.generic.configuration import IConfigurationData
 from zope.generic.configuration import IConfigurations
 from zope.generic.configuration import IConfigurationType
-from zope.generic.configuration.helper import getValue
 
 
 
@@ -124,12 +123,29 @@
         >>> config_data.bar
         Traceback (most recent call last):
         ...
-        AttributeError: bar
-        
+        AttributeError: 'IExampleConfiugrationSchema' configuration has no attribute 'bar'.
+ 
+    The implementation provide an adapter to IFace by its __conform__ method:
+
+        >>> adapted = IFace(config_data)
+        >>> IFace.providedBy(adapted)
+        True
+
+        >>> adapted.keyface is IExampleConfiugrationSchema
+        True
+
+    A configuration belong to the configuration context:
+
+        >>> adapted.conface is IUndefinedContext
+        True
+ 
+    Readonly attribute can be set once. Afterward an value error is raised:
+
         >>> config_data.fii = u'Bla bla'
+        >>> config_data.fii = u'Bla bla'
         Traceback (most recent call last):
         ...
-        ValueError: ('fii', 'Data is readonly.')
+        ValueError: 'IExampleConfiugrationSchema' configuration's attribute 'fii' is readonly.
 
     If a relevant key is missed within the data a key error is raised:
 
@@ -138,7 +154,7 @@
         ...
         TypeError: __init__ requires 'foo' of 'IExampleConfiugrationSchema'.
 
-    The schema should not contain methods:
+    The schema should never contain methods:
 
         >>> class IBarConfiguration(Interface):
         ...    bar = TextLine(title=u'Bar')
@@ -146,67 +162,85 @@
         ...        pass
 
         >>> config_data = ConfigurationData(IBarConfiguration, {'bar': u'Bar!', 'method': u'Method!'})
-        >>> config_data.bar
-        u'Bar!'
-        >>> config_data.method
         Traceback (most recent call last):
         ...
-        RuntimeError: ('Data value is not a schema field', 'method')
+        AttributeError: 'Method' object has no attribute 'readonly'
 
-    The implementation provide an adapter to IFace by its __conform__
-    method:
-
-        >>> adapted = IFace(config_data)
-        >>> IFace.providedBy(adapted)
-        True
-
-        >>> adapted.keyface is IBarConfiguration
-        True
-
-    A configuration belong to the configuration context:
-
-        >>> adapted.conface is IUndefinedContext
-        True
-
     """
 
     implements(IAttributeFaced, IConfigurationData)
 
     def __init__(self, __keyface__, data):
         # essentials
-        self.__dict__['_ConfigurationData__data'] = PersistentDict(prepareData(__keyface__, data))
         self.__dict__['__keyface__'] = __keyface__
         self.__dict__['__conface__'] = IUndefinedContext
         directlyProvides(self, __keyface__)
 
+        # set other data
+        for key, value in prepareData(__keyface__, data).items():
+            setattr(self, key, value)
+
     def __conform__(self, interface):
         if interface is IFace:
             return FaceForAttributeFaced(self)
 
     def __getattr__(self, name):
-        # assert IAttributeFaced
+        """Get value of a configuration."""
+
+        # assert acces attribute faced attributes
         if name in ['__keyface__', '__conface__']:
             return self.__dict__[name]
+        
+        # filter all names except keyface attributes  
+        else:
+            # short cut
+            data = self.__dict__
+            keyface = data['__keyface__']
 
-        keyface = self.__dict__['__keyface__']
-        data = self.__dict__['_ConfigurationData__data']
+            try:
+                field = keyface[name]
+    
+            except KeyError:
+                raise AttributeError("'%s' configuration has no attribute '%s'." % (keyface.__name__, name))
+    
+            else:
+                value = data.get(name, _marker)
+                if value is _marker:
+                    value = getattr(field, 'default', _marker)
+                    if value is _marker:
+                        # should not happen
+                        raise RuntimeError("'%s' configuration's value for '%s' is missing." % (keyface.__name__, name))
+        
+                return value
+        
+            raise AttributeError("'%s' configuration has no attribute '%s'." % (keyface.__name__, name))
 
-        return getValue(keyface, name, data)
 
-
     def __setattr__(self, name, value):
+        """Set value of a configuration."""
 
-        if not(name == '__provides__' or name in IPersistent):
-            keyface = self.__dict__['__keyface__']
-            data = self.__dict__['_ConfigurationData__data']
+        # assert setting of dedicated  faced attributes
+        if name == '__provides__' or name in IPersistent:
+            super(ConfigurationData, self).__setattr__(name, value)
+ 
+        else:
+            # short cut
+            data = self.__dict__
+            keyface = data['__keyface__']
 
             try:
                 field = keyface[name]
             except KeyError:
                 raise AttributeError(name)
             else:
-                if field.readonly is True:
-                    raise ValueError(name, 'Data is readonly.')
-            data[name] = value
-        else:
-            super(ConfigurationData, self).__setattr__(name, value)
+                if field.readonly and data.has_key(name):
+                    raise ValueError("'%s' configuration's attribute '%s' is readonly." % (keyface.__name__, name))
+
+                field = field.bind(self)
+                try:
+                    field.validate(value)
+                    
+                except ValidationError, e:
+                    raise e.__class__("'%s' configuration's attribute '%s' is not valid: %s." % (keyface.__name__, name, ', '.join([repr(a) for a in e.args])))
+
+                super(ConfigurationData, self).__setattr__(name, value)

Modified: zope.generic/trunk/src/zope/generic/configuration/helper.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/helper.py	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/configuration/helper.py	2006-05-05 15:37:11 UTC (rev 67994)
@@ -18,43 +18,22 @@
 
 __docformat__ = 'restructuredtext'
 
-from zope.interface.interfaces import IMethod
-from zope.schema.interfaces import IField
+from zope.interface import alsoProvides
 
 from zope.generic.face import IFace
-from zope.generic.face import IUndefinedContext
-from zope.generic.face import IUndefinedKeyface
-from zope.generic.face.api import toFaceTuple
-from zope.generic.face.api import toInterface
 
+from zope.generic.configuration import IConfigurationType
 
 
-_marker = object()
+def provideConfigurationType(interface):
+    """Mark an interface as IConfigurationType."""
 
-def getValue(keyface, name, data):
-    """Return a declared value."""
-    try:
-        field = keyface[name]
-    except KeyError:
-        raise AttributeError(name)
-    else:
-        value = data.get(name, _marker)
-        if value is _marker:
-            value = getattr(field, 'default', _marker)
-            if value is _marker:
-                raise RuntimeError('Data is missing', name)
+    alsoProvides(interface, IConfigurationType)
 
-        if IMethod.providedBy(field):
-            if not IField.providedBy(field):
-                raise RuntimeError('Data value is not a schema field', name)
-            v = lambda: value
-        else:
-            v = value
 
-        return v
-    raise AttributeError(name)
 
 
+_marker = object()
 
 def configuratonToDict(configuration, all=False):
     """Extract values from configuration to a dictionary.
@@ -72,13 +51,13 @@
     Minimal data without defaults:
 
         >>> from zope.generic.configuration.base import ConfigurationData
-        >>> configuration = ConfigurationData(IAnyConfiguration, {'a': 'a bla'})
+        >>> configuration = ConfigurationData(IAnyConfiguration, {'a': u'a bla'})
         >>> api.configuratonToDict(configuration)
-        {'a': 'a bla'}
+        {'a': u'a bla'}
 
     Including defaults:
         >>> api.configuratonToDict(configuration, all=True)
-        {'a': 'a bla', 'c': u'c default', 'b': None}
+        {'a': u'a bla', 'c': u'c default', 'b': None}
 
     """
     data = {}
@@ -131,30 +110,3 @@
     """
     
     return [name for name in configuration if configuration[name].required is True]
-
-
-
-def toConfigFaceTriple(identifier):
-    """Split configface:keyface at conface to (configface, keyface, conface).
-
-        >>> from zope.interface import Interface
-        
-        >>> class IA(Interface):
-        ...     pass
-
-        >>> from zope.generic.face.api import toDottedName
-
-        >>> api.toConfigFaceTriple(toDottedName(IA) + ':')
-        (<InterfaceClass example.IA>, <....IUndefinedKeyface>, <....IUndefinedContext>)
-    """
-
-    parts = identifier.split(':')
-
-    if len(parts) == 1:
-        return (toInterface(parts[0]), IUndefinedKeyface, IUndefinedContext)
-
-    else:
-        keyface, conface = toFaceTuple(parts[1])
-        return (toInterface(parts[0]), keyface, conface)
-            
-        

Modified: zope.generic/trunk/src/zope/generic/configuration/tests.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/tests.py	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/configuration/tests.py	2006-05-05 15:37:11 UTC (rev 67994)
@@ -49,10 +49,9 @@
     def test_readonly_attributes(self):
         interface = self._test_interface
         test_obj = self.makeTestObject()
-        for name in interface:
-            field = interface[name]
-            if field.readonly is True:
-                self.assertRaises(ValueError, setattr, test_obj, name, object())
+        # a read-only value can be set only once.
+        test_obj.fo = u'basdf'
+        self.assertRaises(ValueError, setattr, test_obj, 'fo', u'aasdf')
 
     def test_default_value(self):
         interface = self._test_interface

Modified: zope.generic/trunk/src/zope/generic/content/EXAMPLE.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/content/EXAMPLE.txt	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/content/EXAMPLE.txt	2006-05-05 15:37:11 UTC (rev 67994)
@@ -107,8 +107,10 @@
     ...         text, note = text_config.text, note_config.text
     ...     else:
     ...         text, note = article_config.text, article_config.note
-    ...
+    ... 
     ...     provideInformation(ITextConfig, {'body': text}, context)
+    ...     if note is None:
+    ...        note = u'Default Initializer Note.'
     ...     provideInformation(INoteConfig, {'body': note}, context)
     ...     deleteInformation(IArticleInitializationConfiguration, context)
  

Modified: zope.generic/trunk/src/zope/generic/content/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/content/metaconfigure.py	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/content/metaconfigure.py	2006-05-05 15:37:11 UTC (rev 67994)
@@ -28,6 +28,7 @@
 from zope.generic.factory.metaconfigure import factoryDirective
 from zope.generic.handler.metaconfigure import handlerDirective
 from zope.generic.informationprovider.metaconfigure import ensureInformationProvider
+from zope.generic.operation import INoParameter
 
 from zope.generic.face import IUndefinedContext
 
@@ -62,7 +63,7 @@
         # ensure the corresponding information provider
         ensureInformationProvider(keyface, conface)
 
-    def factory(self, _context, class_, operations=(), input=None,
+    def factory(self, _context, class_, operations=(), input=INoParameter,
                 providesFace=True, notifyCreated=False, storeInput=False):
         """Add factory."""
         factoryDirective(_context, self._keyface, class_, operations, input,

Modified: zope.generic/trunk/src/zope/generic/factory/factory.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/factory.py	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/factory/factory.py	2006-05-05 15:37:11 UTC (rev 67994)
@@ -32,7 +32,9 @@
 from zope.generic.face import IAttributeFaced
 from zope.generic.face import IProvidesAttributeFaced
 from zope.generic.face.api import Face
+from zope.generic.operation import INoParameter
 from zope.generic.operation import IOperationConfiguration
+from zope.generic.operation import IUndefinedParameter
         
 
 
@@ -111,8 +113,9 @@
 
         >>> from zope.generic.configuration.api import ConfigurationData
         >>> from zope.generic.operation import IOperationConfiguration
+        >>> from zope.generic.operation.api import Operation
 
-        >>> my_factory=ConfigurationData(IOperationConfiguration, {'operation': init_handler})
+        >>> my_factory={'operation': Operation(init_handler)}
 
         >>> registerDirective('''
         ... <generic:informationProvider
@@ -125,7 +128,7 @@
         ... </generic:informationProvider>
         ... ''')
 
-        >>> f = Factory(Simple, IMyInstance, mode=2)
+        >>> f = Factory(Simple, IMyInstance, useConfig=True)
         >>> f()
         initializing
         <example.Simple object at ...>
@@ -133,7 +136,7 @@
         >>> f('wrong')
         Traceback (most recent call last):
         ...
-        TypeError: default __new__ takes no parameters
+        TypeError: This factory takes no parameters
 
 
     If we like to provide parameter we have to declare them by an input
@@ -158,9 +161,7 @@
         ...     />
         ... ''') 
 
-        >>> my_factory=ConfigurationData(IOperationConfiguration, 
-        ...                              {'operation': init_handler,
-        ...                               'input': IMyParameter})
+        >>> my_factory={'operation': Operation(init_handler), 'input': IMyParameter}
 
         >>> registerDirective('''
         ... <generic:informationProvider
@@ -173,7 +174,7 @@
         ... </generic:informationProvider>
         ... ''')
 
-        >>> f = Factory(SimpleKeyFacedWithParameter, IMyInstance, mode=3)
+        >>> f = Factory(SimpleKeyFacedWithParameter, IMyInstance, useConfig=True)
         >>> f(u'a bla bla')
         __init__: a= a bla bla , b= None , c= c default
         initializing
@@ -181,11 +182,11 @@
 
     We can ignore the factory configuration fully by mode=0:
 
-        >>> f = Factory(SimpleKeyFacedWithParameter, IMyInstance, mode=0)
+        >>> f = Factory(SimpleKeyFacedWithParameter, IMyInstance, useConfig=False)
         >>> f(u'a bla bla')
         Traceback (most recent call last):
          ...
-        TypeError: default __new__ takes no parameters
+        TypeError: __init__() takes exactly 4 arguments (2 given)
 
     Last but not least we can store the arguments directly as configuration. 
     Such an configuration can be retrieved later on using the queryInformation
@@ -198,7 +199,7 @@
         ...    def __init__(self, a, b, c):
         ...        print '__init__:', 'a=',a ,', b=', b, ', c=', c
 
-        >>> f = Factory(SimpleConfigurable, IMyInstance, storeInput=True, mode=3)
+        >>> f = Factory(SimpleConfigurable, IMyInstance, storeInput=True, useConfig=True)
         >>> instance = f(u'a bla')
         __init__: a= a bla , b= None , c= c default
         initializing
@@ -213,7 +214,7 @@
 
     def __init__(self, callable, __keyface__, providesFace=False, 
                  storeInput=False, notifyCreated=False, 
-                 title=u'', description=u'', mode=0):
+                 title=u'', description=u'', useConfig=False):
 
         super(Factory, self).__init__(callable, title, description, interfaces=(__keyface__,))
 
@@ -222,24 +223,31 @@
         self.__provideFace = providesFace
         self.__storeInput = storeInput
         self.__notifyCreated = notifyCreated
-        self.__mode = mode
-        if mode == 0:
+        # this assigns that there will be no configuration within an informatio provider
+        if useConfig is False:
             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(parameterToConfiguration(config.input, *pos, **kws), all=True)
-            instance = self._callable(**new_kws)
-        
-        elif not pos and not kws:
-            instance = self._callable()
+        # handle declared callables
+        new_kws = None
+        if config and config.input != IUndefinedParameter:
+            # callables with no parameter
+            if config.input == INoParameter:
+                if kws or pos:
+                    raise TypeError('This factory takes no parameters')
 
+                instance = self._callable()
+
+            # callables with defined parameters
+            else:
+                new_kws = configuratonToDict(parameterToConfiguration(config.input, *pos, **kws), all=True)
+                instance = self._callable(**new_kws)
+
+        # handle undeclared ones
         else:
-            raise TypeError('default __new__ takes no parameters')
-            
+            instance = self._callable(*pos, **kws)
 
         # provide key interface
         if self.__provideFace:
@@ -259,13 +267,23 @@
         if self.__storeInput and config:
             input = config.input
             if input:
-                configuration = parameterToConfiguration(input, *pos, **kws)
+                if new_kws:
+                    configuration = parameterToConfiguration(input, **new_kws)
+
+                else:
+                    configuration = parameterToConfiguration(input, *pos, **kws)
+
                 provideInformation(input, configuration, instance)
 
         # invoke initializer operations
-        if mode > 1:
-            config.operation(instance, *pos, **kws)
+        operation = getattr(config, 'operation', None)
+        if operation:
+            if new_kws:
+                config.operation(instance, **new_kws)
 
+            else:
+                config.operation(instance, *pos, **kws)
+
         # notify created object
         if self.__notifyCreated:
             notify(ObjectCreatedEvent(instance))

Modified: zope.generic/trunk/src/zope/generic/factory/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/metaconfigure.py	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/factory/metaconfigure.py	2006-05-05 15:37:11 UTC (rev 67994)
@@ -32,7 +32,9 @@
 from zope.generic.face.api import toDescription
 from zope.generic.face.api import toDottedName
 from zope.generic.informationprovider.metaconfigure import InformationProviderDirective
+from zope.generic.operation import INoParameter
 from zope.generic.operation import IOperationConfiguration
+from zope.generic.operation import IUndefinedParameter
 from zope.generic.operation.api import assertOperation
 
 from zope.generic.factory import IFactoryType
@@ -40,8 +42,8 @@
 
 
 
-def factoryDirective(_context, keyface, class_, operations=(), input=None,
-                     providesFace=False, notifyCreated=False, storeInput=False):
+def factoryDirective(_context, keyface, class_, operations=(), input=INoParameter,
+                     providesFace=False, notifyCreated=False, storeInput=False, useConfig=True):
     """Register a public factory."""
     # preconditions
     if isinstance(class_, ModuleType):
@@ -54,22 +56,9 @@
     # set label and hint
     label, hint = toDescription(keyface)
 
-    # how to invoke the factory
-    if operations and input:
-        mode = 3
-    
-    elif operations:
-        mode = 2
-    
-    elif input:
-        mode = 1
-    
-    else:
-        mode = 0
-
     # create and proxy type factory
     factory = Factory(class_, keyface, providesFace, storeInput, 
-                      notifyCreated, label, hint, mode) 
+                      notifyCreated, label, hint, useConfig) 
     proxied = proxify(factory, InterfaceChecker(IFactory, CheckerPublic))
     
     _context.action(
@@ -78,9 +67,9 @@
         args = (proxied, IFactory, toDottedName(keyface)),
         )
 
-    if mode != 0:
+    if useConfig:
         # does the output provide the keyface?
-        output = None
+        output = IUndefinedParameter
         if providesFace:
             output = keyface
 

Modified: zope.generic/trunk/src/zope/generic/factory/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/metadirectives.py	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/factory/metadirectives.py	2006-05-05 15:37:11 UTC (rev 67994)
@@ -60,6 +60,12 @@
         default=False
         )
 
+    useConfig = Bool(
+        title=_('Use configuration'),
+        description=_('Should the configuration be invoked during the initialization.'),
+        required=False,
+        default=True
+        )
 
 class IFactoryDirective(IKeyfaceDirective, IBaseFactoryDirective, IOperationsDirective, IInputDirective):
     """Register a public factory.

Modified: zope.generic/trunk/src/zope/generic/informationprovider/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/api.py	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/informationprovider/api.py	2006-05-05 15:37:11 UTC (rev 67994)
@@ -38,6 +38,7 @@
 from zope.generic.informationprovider.base import GlobalInformationProvider
 from zope.generic.informationprovider.base import LocalInformationProvider
 from zope.generic.informationprovider.base import UserDescription
+from zope.generic.informationprovider.helper import toConfigFaceTriple
 from zope.generic.informationprovider.metaconfigure import ensureInformationProvider
 from zope.generic.informationprovider.metaconfigure import getInformationProvider
 
@@ -76,7 +77,6 @@
 
 
 
-
 def getInformationProvidersFor(face):
     """Evaluate available information providers of a certain information aspect."""
 
@@ -93,7 +93,6 @@
 
 
 
-
 def getInformation(informationkey, keyface=IUndefinedKeyface, conface=IUndefinedContext):
     """Evaluate an information by a keyface (string or key keyface)."""
     
@@ -168,4 +167,3 @@
     
     else:
         del IAnnotations(context)[informationkey]
-

Added: zope.generic/trunk/src/zope/generic/informationprovider/helper.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/helper.py	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/informationprovider/helper.py	2006-05-05 15:37:11 UTC (rev 67994)
@@ -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$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.generic.face import IUndefinedContext
+from zope.generic.face import IUndefinedKeyface
+from zope.generic.face.api import toFaceTuple
+from zope.generic.face.api import toInterface
+
+
+
+
+def toConfigFaceTriple(identifier):
+    """Split configface:keyface at conface to (configface, keyface, conface).
+
+        >>> from zope.interface import Interface
+        
+        >>> class IA(Interface):
+        ...     pass
+
+        >>> from zope.generic.face.api import toDottedName
+
+        >>> api.toConfigFaceTriple(toDottedName(IA) + ':')
+        (<InterfaceClass example.IA>, <....IUndefinedKeyface>, <....IUndefinedContext>)
+    """
+
+    parts = identifier.split(':')
+
+    if len(parts) == 1:
+        return (toInterface(parts[0]), IUndefinedKeyface, IUndefinedContext)
+
+    else:
+        keyface, conface = toFaceTuple(parts[1])
+        return (toInterface(parts[0]), keyface, conface)
+            
+        


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

Modified: zope.generic/trunk/src/zope/generic/informationprovider/meta.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/meta.zcml	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/informationprovider/meta.zcml	2006-05-05 15:37:11 UTC (rev 67994)
@@ -19,8 +19,8 @@
 
     <meta:directive
         name="multiInformationProviders"
-        schema=".metadirectives.IMultiInformationProviderDirectives"
-        handler=".metaconfigure.multiInformationProviderDirectives"
+        schema=".metadirectives.IMultiInformationProvidersDirective"
+        handler=".metaconfigure.multiInformationProvidersDirective"
         />
 
   </meta:directives>

Modified: zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py	2006-05-05 15:37:11 UTC (rev 67994)
@@ -37,7 +37,6 @@
 from zope.generic.configuration import IConfigurations
 from zope.generic.configuration import IConfigurationType
 from zope.generic.configuration.api import ConfigurationData
-from zope.generic.configuration.api import toConfigFaceTriple
 from zope.generic.face import IConfaceType
 from zope.generic.face import IKeyfaceType
 from zope.generic.face import IUndefinedContext
@@ -49,6 +48,7 @@
 from zope.generic.face.api import toInterface
 
 from zope.generic.informationprovider.base import GlobalInformationProvider
+from zope.generic.informationprovider.helper import toConfigFaceTriple
 
 
 
@@ -323,7 +323,7 @@
 
 
 
-def multiInformationProviderDirectives(_context, iniFiles=()):
+def multiInformationProvidersDirective(_context, iniFiles=()):
     """Ini-file based configurations for multi information provider."""
         
     for path in iniFiles:

Modified: zope.generic/trunk/src/zope/generic/informationprovider/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/metadirectives.py	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/informationprovider/metadirectives.py	2006-05-05 15:37:11 UTC (rev 67994)
@@ -123,6 +123,6 @@
         )
 
 
-class IMultiInformationProviderDirectives(IIniFileDirective):
+class IMultiInformationProvidersDirective(IIniFileDirective):
     """Ini-file based configurations for multi information providers."""
 

Modified: zope.generic/trunk/src/zope/generic/informationprovider/tests.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/tests.py	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/informationprovider/tests.py	2006-05-05 15:37:11 UTC (rev 67994)
@@ -39,7 +39,15 @@
 
 def test_suite():
     return unittest.TestSuite((
-        doctest.DocTestSuite('zope.generic.face.base'),
+        doctest.DocTestSuite('zope.generic.informationprovider.base'),
+        doctest.DocTestSuite('zope.generic.informationprovider.helper',
+                             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,

Modified: zope.generic/trunk/src/zope/generic/operation/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/README.txt	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/operation/README.txt	2006-05-05 15:37:11 UTC (rev 67994)
@@ -218,7 +218,7 @@
 
     >>> operation = api.getOperation(IMakeSiteSetupPAUAndAnyOperation)
 
-    >>> operation(context, any='a any', pau=u'a pau')
+    >>> operation(context, any=u'a any', pau=u'a pau')
     Private operation: inputToConfigurations
     Public operation: makeSiteOperation
     Private operation: pauInitializer

Modified: zope.generic/trunk/src/zope/generic/operation/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/api.py	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/operation/api.py	2006-05-05 15:37:11 UTC (rev 67994)
@@ -22,6 +22,8 @@
 from zope.generic.informationprovider.api import getInformation
 
 from zope.generic.operation.interfaces import *
+from zope.generic.operation.base import Operation
+from zope.generic.operation.base import OperationPipe
 from zope.generic.operation.metaconfigure import assertOperation
 
 

Modified: zope.generic/trunk/src/zope/generic/operation/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/interfaces.py	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/operation/interfaces.py	2006-05-05 15:37:11 UTC (rev 67994)
@@ -26,6 +26,7 @@
 from zope.schema import Tuple
 
 from zope.generic.configuration import IConfigurationType
+from zope.generic.configuration.api import provideConfigurationType
 from zope.generic.face import IFace
 from zope.generic.face import IKeyfaceType
 
@@ -61,7 +62,20 @@
         """
 
 
+class IUndefinedParameter(Interface):
+    """Undefined input or output parameter."""
 
+provideConfigurationType(IUndefinedParameter)
+
+
+
+class INoParameter(Interface):
+    """No parameter."""
+
+provideConfigurationType(INoParameter)
+
+
+
 class IOperationType(IKeyfaceType):
     """Type an public operation key interface."""
 
@@ -82,17 +96,17 @@
         required=False,
         schema=IOperation)
 
-    input = Tuple(title=_('Input Declaration'),
+    input = Object(title=_('Input Declaration'),
         description=_('A configuration interface declaring the input parameters.'),
         required=False,
-        default=(),
-        value_type=Object(schema=IConfigurationType))
+        default=INoParameter,
+        schema=IConfigurationType)
 
-    output = Tuple(title=_('Output Declaration'),
+    output = Object(title=_('Output Declaration'),
         description=_('An interface interface declaring the output parameters.'),
         required=False,
-        default=(),
-        value_type=Object(schema=IInterface))
+        default=INoParameter,
+        schema=IInterface)
 
 
 

Modified: zope.generic/trunk/src/zope/generic/operation/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/operation/metadirectives.py	2006-05-05 14:14:59 UTC (rev 67993)
+++ zope.generic/trunk/src/zope/generic/operation/metadirectives.py	2006-05-05 15:37:11 UTC (rev 67994)
@@ -24,7 +24,9 @@
 from zope.configuration.fields import Tokens
 from zope.interface import Interface
 
+from zope.generic.configuration import IConfigurationType
 from zope.generic.informationprovider.metadirectives import IInformationProviderDirective
+from zope.generic.operation import INoParameter
 
 
 
@@ -46,7 +48,9 @@
 
     input = GlobalInterface(title=_('Input Declaration'),
         description=_('Configuration schema describing the input arguments.'),
-        required=False)
+        required=False,
+        default=INoParameter,
+        constraint=lambda v: IConfigurationType.providedBy(v))
 
 
 



More information about the Checkins mailing list