[Checkins] SVN: zope.generic/trunk/src/zope/generic/ add new informations subdirecitve for information provider which is providing configuration from a ini-File

Dominik Huber dominik.huber at perse.ch
Thu May 4 08:35:12 EDT 2006


Log message for revision 67961:
  add new informations subdirecitve for information provider which is providing configuration from a ini-File

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/factory/DEPENDENCIES.cfg
  D   zope.generic/trunk/src/zope/generic/factory/adapter.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/informationprovider/README.txt
  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/testing.py

-=-
Modified: zope.generic/trunk/src/zope/generic/configuration/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/api.py	2006-05-04 08:00:22 UTC (rev 67960)
+++ zope.generic/trunk/src/zope/generic/configuration/api.py	2006-05-04 12:35:11 UTC (rev 67961)
@@ -21,8 +21,8 @@
 from zope.generic.configuration import *
 from zope.generic.configuration.adapter import AttributeConfigurations
 from zope.generic.configuration.base import ConfigurationData
-from zope.generic.configuration.helper import parameterToConfiguration
 from zope.generic.configuration.helper import configuratonToDict
+from zope.generic.configuration.helper import getValue
 from zope.generic.configuration.helper import requiredInOrder
 
 
@@ -40,3 +40,108 @@
     
     except:
         return default
+
+
+
+def parameterToConfiguration(__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:
+
+        >>> parameterToConfiguration(IAnyConfiguration)
+        Traceback (most recent call last):
+        ...
+        TypeError: __init__ requires 'a, d' of 'IAnyConfiguration'.
+
+    B: Provide the required as positionals:
+
+        >>> config = parameterToConfiguration(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 = parameterToConfiguration(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 = parameterToConfiguration(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:
+
+        >>> parameterToConfiguration(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 = parameterToConfiguration(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')
+
+        >>> parameterToConfiguration(IAnyConfiguration, u'd bla', a=u'd bla', c=u'c bla')
+        Traceback (most recent call last):
+        ...
+        AttributeError: Duplicated arguments: a.
+
+    G: Sometimes any parameters are allowed. This use case is indicated by a None key interface:
+
+        >>> parameterToConfiguration(None) is None
+        True
+
+        >>> parameterToConfiguration(None, 'not allowed parameter')
+
+    """
+    # 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/configuration/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/base.py	2006-05-04 08:00:22 UTC (rev 67960)
+++ zope.generic/trunk/src/zope/generic/configuration/base.py	2006-05-04 12:35:11 UTC (rev 67961)
@@ -24,8 +24,6 @@
 
 from zope.interface import directlyProvides
 from zope.interface import implements
-from zope.interface.interfaces import IMethod
-from zope.schema.interfaces import IField
 
 from zope.generic.face import IAttributeFaced
 from zope.generic.face import IFace
@@ -34,6 +32,7 @@
 
 from zope.generic.configuration import IConfigurationData
 from zope.generic.configuration import IConfigurations
+from zope.generic.configuration.helper import getValue
 
 
 
@@ -146,27 +145,10 @@
 
         keyface = self.__dict__['__keyface__']
         data = self.__dict__['_ConfigurationData__data']
-        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)
 
-            if IMethod.providedBy(field):
-                if not IField.providedBy(field):
-                    raise RuntimeError('Data value is not a schema field', name)
-                v = lambda: value
-            else:
-                v = value
-            #setattr(self, name, v)
-            return v
-        raise AttributeError(name)
+        return getValue(keyface, name, data)
 
+
     def __setattr__(self, name, value):
 
         if not(name == '__provides__' or name in IPersistent):

Modified: zope.generic/trunk/src/zope/generic/configuration/helper.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/helper.py	2006-05-04 08:00:22 UTC (rev 67960)
+++ zope.generic/trunk/src/zope/generic/configuration/helper.py	2006-05-04 12:35:11 UTC (rev 67961)
@@ -18,15 +18,40 @@
 
 __docformat__ = 'restructuredtext'
 
+from zope.interface.interfaces import IMethod
+from zope.schema.interfaces import IField
 
 from zope.generic.face import IFace
 
-from zope.generic.configuration.base import ConfigurationData
 
 
-
 _marker = object()
 
+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)
+
+        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)
+
+
+
 def configuratonToDict(configuration, all=False):
     """Extract values from configuration to a dictionary.
 
@@ -102,108 +127,3 @@
     """
     
     return [name for name in configuration if configuration[name].required is True]
-
-
-
-def parameterToConfiguration(__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:
-
-        >>> parameterToConfiguration(IAnyConfiguration)
-        Traceback (most recent call last):
-        ...
-        TypeError: __init__ requires 'a, d' of 'IAnyConfiguration'.
-
-    B: Provide the required as positionals:
-
-        >>> config = parameterToConfiguration(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 = parameterToConfiguration(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 = parameterToConfiguration(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:
-
-        >>> parameterToConfiguration(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 = parameterToConfiguration(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')
-
-        >>> parameterToConfiguration(IAnyConfiguration, u'd bla', a=u'd bla', c=u'c bla')
-        Traceback (most recent call last):
-        ...
-        AttributeError: Duplicated arguments: a.
-
-    G: Sometimes any parameters are allowed. This use case is indicated by a None key interface:
-
-        >>> parameterToConfiguration(None) is None
-        True
-
-        >>> parameterToConfiguration(None, 'not allowed parameter')
-
-    """
-    # 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/configuration/tests.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/tests.py	2006-05-04 08:00:22 UTC (rev 67960)
+++ zope.generic/trunk/src/zope/generic/configuration/tests.py	2006-05-04 12:35:11 UTC (rev 67961)
@@ -22,7 +22,6 @@
 from zope import interface
 from zope.testing import doctest
 
-
 from zope.generic.testing.testing import InterfaceBaseTest
 from zope.generic.testing.testing import registerDirective
 

Modified: zope.generic/trunk/src/zope/generic/factory/DEPENDENCIES.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/DEPENDENCIES.cfg	2006-05-04 08:00:22 UTC (rev 67960)
+++ zope.generic/trunk/src/zope/generic/factory/DEPENDENCIES.cfg	2006-05-04 12:35:11 UTC (rev 67961)
@@ -13,4 +13,4 @@
 zope.interface
 zope.lifecycleevent
 zope.security
-zope.testing
\ No newline at end of file
+zope.testing

Deleted: zope.generic/trunk/src/zope/generic/factory/adapter.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/adapter.py	2006-05-04 08:00:22 UTC (rev 67960)
+++ zope.generic/trunk/src/zope/generic/factory/adapter.py	2006-05-04 12:35:11 UTC (rev 67961)
@@ -1,45 +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 queryInformation
-from zope.generic.informationprovider.api import getInformationProvider
-from zope.generic.face import IFaced
-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(IFaced)
-
-    def __init__(self, context):
-        self.context = context
-
-    def __call__(self, *pos, **kws):
-

Modified: zope.generic/trunk/src/zope/generic/factory/factory.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/factory.py	2006-05-04 08:00:22 UTC (rev 67960)
+++ zope.generic/trunk/src/zope/generic/factory/factory.py	2006-05-04 12:35:11 UTC (rev 67961)
@@ -33,8 +33,6 @@
 from zope.generic.face import IProvidesAttributeFaced
 from zope.generic.face.api import Face
 from zope.generic.operation import IOperationConfiguration
-
-from zope.generic.factory import IFactoryType
         
 
 

Modified: zope.generic/trunk/src/zope/generic/factory/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/metaconfigure.py	2006-05-04 08:00:22 UTC (rev 67960)
+++ zope.generic/trunk/src/zope/generic/factory/metaconfigure.py	2006-05-04 12:35:11 UTC (rev 67961)
@@ -28,12 +28,9 @@
 from zope.security.checker import CheckerPublic
 from zope.security.checker import InterfaceChecker
 
-from zope.generic.face import IKeyfaceType
 from zope.generic.face import IUndefinedContext
 from zope.generic.face.api import toDescription
 from zope.generic.face.api import toDottedName
-from zope.generic.informationprovider.api import getInformationProvider
-from zope.generic.informationprovider.api import provideInformation
 from zope.generic.informationprovider.metaconfigure import InformationProviderDirective
 from zope.generic.operation import IOperationConfiguration
 from zope.generic.operation.api import assertOperation

Modified: zope.generic/trunk/src/zope/generic/informationprovider/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/README.txt	2006-05-04 08:00:22 UTC (rev 67960)
+++ zope.generic/trunk/src/zope/generic/informationprovider/README.txt	2006-05-04 12:35:11 UTC (rev 67961)
@@ -147,15 +147,15 @@
     ...     keyface="example.IMyFoo"
     ...     conface="example.ISpecialContext"
     ...     >
-    ...        <information
-    ...            key="example.my_annotation"
-    ...            annotation="example.my_annotation"
-    ...            />
-    ...        <information
-    ...            keyface="example.IMyConfiguration"
-    ...            configuration="example.my_configuration"
-    ...            />
-    ...     </generic:informationProvider>
+    ...   <information
+    ...       key="example.my_annotation"
+    ...       annotation="example.my_annotation"
+    ...       />
+    ...   <information
+    ...       keyface="example.IMyConfiguration"
+    ...       configuration="example.my_configuration"
+    ...       />
+    ... </generic:informationProvider>
     ... ''')
 
     >>> provider = api.queryInformationProvider(IMyFoo, ISpecialContext)
@@ -349,6 +349,7 @@
     >>> [i.__name__ for i,p in api.getInformationProvidersFor(IBarFoo)]
     ['IOurContext', 'IUndefinedContext']
 
+
 Components can suggest key and context interfaces
 -------------------------------------------------
 
@@ -389,3 +390,77 @@
 
     >>> api.acquireInformationProvider(bar) 
     <GlobalInformationProvider IBar at IUndefinedContext>
+
+
+Ini-file based configurations for an information provider
+---------------------------------------------------------
+
+The configuration file holds several configuration in the ini-file style.
+
+    >>> from zope.interface import Interface
+    >>> from zope.schema import Text, TextLine
+    
+    >>> class IOneConfiguration(Interface):
+    ...    textLine = TextLine(title=u'TextLine')
+    ...    text = Text(title=u'Text', required=False, default=u'Bla\\n')
+
+    >>> registerDirective('''
+    ... <generic:interface
+    ...     interface="example.IOneConfiguration"
+    ...     type="zope.generic.configuration.IConfigurationType"
+    ...     />
+    ... ''') 
+
+    >>> from zope.schema import Bool, Int
+
+    >>> class IOtherConfiguration(Interface):
+    ...    bool = Bool(title=u'Bool')
+    ...    int = Int(title=u'Int', required=False, default=42)
+
+    >>> registerDirective('''
+    ... <generic:interface
+    ...     interface="example.IOtherConfiguration"
+    ...     type="zope.generic.configuration.IConfigurationType"
+    ...     />
+    ... ''') 
+
+    >>> import os, tempfile
+    >>> temp_dir = tempfile.mkdtemp()
+    >>> iniFile = os.path.join(temp_dir, 'example.ini')
+    >>> open(iniFile, 'w').write('''
+    ... [example.IOneConfiguration]
+    ... textline = Foo
+    ... text : Bla bla bla bla.
+    ... 
+    ... [example.IOtherConfiguration]
+    ... bool = True
+    ... int = 77
+    ... ''')
+
+    >>> registerDirective('''
+    ... <generic:informationProvider
+    ...     keyface="example.IFoo"
+    ...     conface="example.ISpecialContext"
+    ...     >
+    ...   <informations
+    ...       iniFiles="%s"
+    ...       />
+    ...     </generic:informationProvider>
+    ... ''' % iniFile)
+
+    >>> foo_config = api.getInformation(IOneConfiguration, IFoo, ISpecialContext)
+    >>> foo_config.textLine
+    u'Foo'
+
+    >>> foo_config.text
+    u'Bla bla bla bla.'
+
+    >>> bar_config =  api.getInformation(IOtherConfiguration, IFoo, ISpecialContext)
+    >>> bar_config.bool
+    True
+
+    >>> bar_config.int
+    77
+
+    >>> import shutil
+    >>> shutil.rmtree(temp_dir)

Modified: zope.generic/trunk/src/zope/generic/informationprovider/meta.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/meta.zcml	2006-05-04 08:00:22 UTC (rev 67960)
+++ zope.generic/trunk/src/zope/generic/informationprovider/meta.zcml	2006-05-04 12:35:11 UTC (rev 67961)
@@ -15,6 +15,11 @@
           schema=".metadirectives.IInformationSubdirective"
           />
 
+      <meta:subdirective
+          name="informations"
+          schema=".metadirectives.IInformationsSubdirective"
+          />
+
     </meta:complexDirective>
 
   </meta:directives>

Modified: zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py	2006-05-04 08:00:22 UTC (rev 67960)
+++ zope.generic/trunk/src/zope/generic/informationprovider/metaconfigure.py	2006-05-04 12:35:11 UTC (rev 67961)
@@ -18,6 +18,8 @@
 
 __docformat__ = 'restructuredtext'
 
+from ConfigParser import SafeConfigParser
+
 from zope.annotation import IAnnotations
 from zope.component import provideUtility
 from zope.component import getUtility
@@ -25,6 +27,7 @@
 from zope.component.interface import provideInterface
 from zope.configuration.exceptions import ConfigurationError
 from zope.interface import alsoProvides
+from zope.schema.interfaces import IFromUnicode
 
 from zope.generic.configuration import IConfigurations
 from zope.generic.configuration.api import ConfigurationData
@@ -36,6 +39,7 @@
 from zope.generic.face.api import getKeyface
 from zope.generic.face.api import toDescription
 from zope.generic.face.api import toDottedName
+from zope.generic.face.api import toInterface
 
 from zope.generic.informationprovider.base import GlobalInformationProvider
 
@@ -113,8 +117,42 @@
 
 
 
+_marker = object()
+
+def iniFileToConfiguration(path):
+    """Parse ini file to an iterator over keyface, configuration pairs."""
+
+    configparser = SafeConfigParser()
+    configparser.read(path)
+
+    for section in configparser.sections():
+        # convert section to configuration interface
+        keyface = toInterface(section)
+
+        data = {}
+    
+        for name in keyface:
+            field = keyface[name]
+            # evalutate name: config parser options are always lower case
+            try:
+                value = configparser.get(section, name.lower())
+
+            except:
+                value = _marker
+
+            if value is not _marker:
+                try:
+                    data[name] = field.fromUnicode(unicode(value))
+    
+                except:
+                    data[name] = IFromUnicode(field).fromUnicode(unicode(value))
+
+        yield (keyface, data)
+
+
+
 class InformationProviderDirective(object):
-    """Provide a new information of a certain information registry."""
+    """Provide a new information provider."""
 
     def __init__(self, _context, keyface=IUndefinedKeyface, conface=IUndefinedContext):
         # preconditions
@@ -176,4 +214,13 @@
         else:
             raise ConfigurationError('Information subdirective must provide ' +
                 'key and annotation or keyface and configuration.')
+
+    def informations(self, _context, iniFiles=()):
+        """Ini-file based configurations for an information provider."""
+        
+        for path in iniFiles:
+            for keyface, configuration in iniFileToConfiguration(path):
+                # register corresponding configuration information
+                self.information(_context, keyface, configuration)
+                
                 
\ No newline at end of file

Modified: zope.generic/trunk/src/zope/generic/informationprovider/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/metadirectives.py	2006-05-04 08:00:22 UTC (rev 67960)
+++ zope.generic/trunk/src/zope/generic/informationprovider/metadirectives.py	2006-05-04 12:35:11 UTC (rev 67961)
@@ -22,6 +22,8 @@
 from zope.configuration.fields import GlobalInterface
 from zope.configuration.fields import GlobalObject
 from zope.configuration.fields import MessageID
+from zope.configuration.fields import Path
+from zope.configuration.fields import Tokens
 from zope.interface import Interface
 from zope.schema import DottedName
 
@@ -102,3 +104,16 @@
         description=_('Annotation component expected undert the key.'),
         required=False
         )
+
+
+class IInformationsSubdirective(Interface):
+    """Ini-file based configurations for an information provider."""
+
+    iniFiles = Tokens(
+        title=_('*.ini-like File'),
+        description=_('Parse configuration key interfaces from sections. '
+                      'and the configuration data from theirs options using '
+                      'the config parser and IFromUnicode(field).fromUnicode().'),
+        required=False,
+        value_type=Path(constraint=lambda v: v.endswith('.ini'))
+        )

Modified: zope.generic/trunk/src/zope/generic/informationprovider/testing.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/testing.py	2006-05-04 08:00:22 UTC (rev 67960)
+++ zope.generic/trunk/src/zope/generic/informationprovider/testing.py	2006-05-04 12:35:11 UTC (rev 67961)
@@ -24,7 +24,6 @@
 import zope.generic.face.testing
 import zope.generic.testing.testing
 
-from zope.interface import classImplements
 from zope.configuration.xmlconfig import XMLConfig
 
 
@@ -57,9 +56,6 @@
     from zope.generic.informationprovider.api import GlobalInformationProvider
     from zope.generic.informationprovider.api import LocalInformationProvider
 
-    classImplements(GlobalInformationProvider, IAttributeConfigurable, IAttributeAnnotatable)
-    classImplements(LocalInformationProvider, IAttributeConfigurable, IAttributeAnnotatable)
-
 def tearDown(doctest=None):
     pass
 



More information about the Checkins mailing list