[Checkins] SVN: zope.generic/trunk/src/zope/generic/ .configuration:
Dominik Huber
dominik.huber at perse.ch
Mon May 22 08:31:02 EDT 2006
Log message for revision 68237:
.configuration:
- IConfigurations.update: (keyface, dict) or (configuration) or (keyfa, configuration)
- IConfigurations.__setitem__: raise error if item already exists
- api: deleteConfiguration and updateConfiguration
.informationprovider:
- cleanup and changes of .configuration
Changed:
U zope.generic/trunk/src/zope/generic/configuration/README.txt
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/face/api.py
U zope.generic/trunk/src/zope/generic/factory/factory.py
U zope.generic/trunk/src/zope/generic/informationprovider/NEW_README.txt
U zope.generic/trunk/src/zope/generic/informationprovider/README.txt
U zope.generic/trunk/src/zope/generic/informationprovider/api.py
-=-
Modified: zope.generic/trunk/src/zope/generic/configuration/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/README.txt 2006-05-22 11:29:15 UTC (rev 68236)
+++ zope.generic/trunk/src/zope/generic/configuration/README.txt 2006-05-22 12:31:00 UTC (rev 68237)
@@ -96,44 +96,76 @@
>>> configurations[IFooConfiguration] = object()
Traceback (most recent call last):
...
- ValueError: Value does not provide IFooConfiguration.
+ ValueError: Value does not provide IFooConfiguration or is not a dictionary.
-Furthermore there is an update method that can be used to update a specific
-configuration. This method can be only used if a configuration already exists:
+ >>> from zope.generic.configuration.api import createConfiguration
+ >>> data = createConfiguration(IFooConfiguration, {'foo': u'Foo!'})
- >>> configurations.update(IFooConfiguration, {'foo': u'Foo!'})
+ >>> configurations[IFooConfiguration] = data
+
+You can set a configuraiton only once. Otherwise you should use the update method
+or delete the configuraiton before a new setting:
+
+ >>> configurations[IFooConfiguration] = data
Traceback (most recent call last):
...
- KeyError: <InterfaceClass example.IFooConfiguration>
+ ValueError: Configuration is already provided IFooConfiguration.
+ >>> del configurations[IFooConfiguration]
+
+You can also use only a dictionary as value instead of a configuration:
+
+ >>> configurations[IFooConfiguration] = {'foo': u'Foo!'}
+ >>> configurations[IFooConfiguration].foo
+ u'Foo!'
+
+ >>> del configurations[IFooConfiguration]
+
+Furthermore there is an update method that can be used to update a specific
+configuration. You can use the method to provide an initial configuration or
+to update parts of a configuration:
+
+ >>> configurations.update(IFooConfiguration, {'foo': u'Foo!'})
+ >>> configurations[IFooConfiguration].foo
+ u'Foo!'
+
+ >>> configurations.update(IFooConfiguration, {'foo': u'Foo x!'})
+ >>> configurations[IFooConfiguration].foo
+ u'Foo x!'
+
+ >>> config = createConfiguration(IFooConfiguration, {'foo': u'Foo y!'})
+ >>> configurations.update(IFooConfiguration, config)
+ >>> configurations[IFooConfiguration].foo
+ u'Foo y!'
+
+ >>> config = createConfiguration(IFooConfiguration, {'foo': u'Foo z!'})
+ >>> configurations.update(config)
+ >>> configurations[IFooConfiguration].foo
+ u'Foo z!'
+
You can create valid configuration data using the generic createConfiguration
implementation and a configuration schema. The setting of the configuration is
notified by a object configured event if the parent has a location an the
parent's parent is not None:
>>> from zope.component.eventtesting import getEvents, clearEvents
- >>> from zope.generic.configuration.api import createConfiguration
>>> from zope.generic.configuration.api import IObjectConfiguredEvent
>>> clearEvents()
- >>> data = createConfiguration(IFooConfiguration, {'foo': u'Foo!'})
+ >>> del configurations[IFooConfiguration]
- >>> configurations[IFooConfiguration] = data
-
- >>> events = getEvents()
- >>> len(events)
- 0
-
>>> from zope.location import Location
>>> parent = Location()
>>> configurations.__parent__ = parent
-
+
>>> configurations[IFooConfiguration] = data
>>> events = getEvents()
>>> len(events)
0
+ >>> del configurations[IFooConfiguration]
+
>>> parent.__parent__ = Location()
>>> configurations[IFooConfiguration] = data
>>> events = getEvents()
@@ -163,7 +195,8 @@
You should update a configuration using the update method instead of setting
new configuration data. If the change differs from the configuration an object
-configuration modified event is notify else not:
+configuration modified event is notify else not. This can be done by a dict
+or a configuration:
>>> clearEvents()
>>> configurations.update(IFooConfiguration, {'foo': u'Bar!'})
@@ -174,6 +207,16 @@
>>> [(key.__name__, value) for key, value in event.items()]
[('IFooConfiguration', {'foo': u'Bar!'})]
+ >>> clearEvents()
+ >>> foo_config = api.createConfiguration(IFooConfiguration, {'foo': u'Bar !'})
+ >>> configurations.update(foo_config)
+ >>> events = getEvents()
+ >>> len(events)
+ 1
+ >>> event = events.pop()
+ >>> [(key.__name__, value) for key, value in event.items()]
+ [('IFooConfiguration', {'foo': u'Bar !'})]
+
Also the deletion is notified by an empty dict:
>>> clearEvents()
Modified: zope.generic/trunk/src/zope/generic/configuration/adapter.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/adapter.py 2006-05-22 11:29:15 UTC (rev 68236)
+++ zope.generic/trunk/src/zope/generic/configuration/adapter.py 2006-05-22 12:31:00 UTC (rev 68237)
@@ -28,12 +28,14 @@
from zope.event import notify
from zope.interface import implements
+from zope.generic.face.api import getKeyface
from zope.generic.face.api import toDottedName
from zope.generic.face.api import toInterface
from zope.generic.configuration import IAttributeConfigurable
from zope.generic.configuration import IConfigurationType
from zope.generic.configuration import IConfigurations
+from zope.generic.configuration.base import createConfiguration
from zope.generic.configuration.event import Configuration
from zope.generic.configuration.event import ObjectConfiguredEvent
from zope.generic.configuration.helper import configuratonToDict
@@ -77,23 +79,50 @@
return [toInterface(iface) for iface in configurations.keys()]
- def update(self, keyface, data):
- current_config = self[keyface]
+ def update(self, keyfaced_or_keyface, data=None):
+ """Update a configuration."""
+
+ keyface = getKeyface(keyfaced_or_keyface)
+ # feed by a configuration
+ isconfig = False
+ if keyface != keyfaced_or_keyface:
+ data = keyfaced_or_keyface
+ isconfig = True
+ elif keyface.providedBy(data):
+ isconfig = True
+
+ try:
+ current_config = self[keyface]
+ except KeyError:
+ # there is no existing configuration, try to set a new one
+ self[keyface] = data
+ return
+
updated_data = {}
errors = []
savepoint = transaction.savepoint()
try:
- for name, value in data.items():
- # raise attribute error
+ for name in keyface:
field = keyface[name]
+
+ # readonly attribute cannot be updated
if field.readonly:
raise ValueError(name, 'Data is readonly.')
+
+ if isconfig:
+ value = getattr(data, name, field.missing_value)
+ # assume dict
else:
- if value != getattr(current_config, name, field.missing_value):
- setattr(current_config, name, value)
- updated_data[name] = value
+ try:
+ value = data[name]
+ except KeyError:
+ continue
+
+ if value != getattr(current_config, name, field.missing_value):
+ setattr(current_config, name, value)
+ updated_data[name] = value
# notify update
parent = self.__parent__
@@ -111,20 +140,30 @@
raise KeyError('Interface key %s requires %s.' %
(keyface.__name__, IConfigurationType.__name__))
- if not keyface.providedBy(value):
- raise ValueError('Value does not provide %s.' % keyface.__name__)
+ if not (keyface.providedBy(value) or isinstance(value, dict)):
+ raise ValueError('Value does not provide %s or is not a dictionary.' % keyface.__name__)
# essentials
try:
configurations = self.context.__configurations__
except AttributeError:
configurations = self.context.__configurations__ = OOBTree()
+
+ # avoid unintended overwrittings of a configuration
+ key = toDottedName(keyface)
+ if key in configurations:
+ raise ValueError('Configuration is already provided %s.' % keyface.__name__)
- data = configuratonToDict(value, all=True)
- configurations[toDottedName(keyface)] = value
+ # set configuration or dictionary
+ if keyface.providedBy(value):
+ configurations[key] = value
+ else:
+ configurations[key] = createConfiguration(keyface, value)
+
# notify setting
parent = self.__parent__
if ILocation.providedBy(parent) and parent.__parent__ is not None:
+ data = configuratonToDict(value, all=True)
notify(ObjectConfiguredEvent(parent,
Configuration(keyface, data)))
Modified: zope.generic/trunk/src/zope/generic/configuration/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/api.py 2006-05-22 11:29:15 UTC (rev 68236)
+++ zope.generic/trunk/src/zope/generic/configuration/api.py 2006-05-22 12:31:00 UTC (rev 68237)
@@ -18,6 +18,8 @@
__docformat__ = 'restructuredtext'
+from zope.generic.face.api import getKeyface
+
from zope.generic.configuration import *
from zope.generic.configuration.adapter import AttributeConfigurations
from zope.generic.configuration.base import createConfiguration
@@ -27,22 +29,36 @@
-def getConfiguration(context, configuration):
+def getConfiguration(context, keyface):
"""Evaluate a configuration."""
- return configuration(IConfigurations(context))
+ return keyface(IConfigurations(context))
-def queryConfiguration(context, configuration, default=None):
+def queryConfiguration(context, keyface, default=None):
"""Evaluate a configuration or return default."""
try:
- return getConfiguration(context, configuration)
+ return getConfiguration(context, keyface)
except:
return default
+def updateConfiguration(context, keyfaced_or_keyface, data=None):
+ """Set or update a configuration to/of a context."""
+
+ IConfigurations(context).update(keyfaced_or_keyface, data)
+
+
+
+def deleteConfiguration(context, keyface):
+ """Delete a configuration from a context."""
+
+ del IConfigurations(context)[keyface]
+
+
+
def parameterToConfiguration(__keyface__, *pos, **kws):
"""Create configuration data
Modified: zope.generic/trunk/src/zope/generic/face/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/face/api.py 2006-05-22 11:29:15 UTC (rev 68236)
+++ zope.generic/trunk/src/zope/generic/face/api.py 2006-05-22 12:31:00 UTC (rev 68237)
@@ -34,12 +34,7 @@
if object is None:
return default
- # todo replace IInterface by IKeyfaceType
- if IInterface.providedBy(object):
- if not IKeyfaceType.providedBy(object):
- #print object
- pass
-
+ if IKeyfaceType.providedBy(object):
return object
if IAttributeFaced.providedBy(object):
Modified: zope.generic/trunk/src/zope/generic/factory/factory.py
===================================================================
--- zope.generic/trunk/src/zope/generic/factory/factory.py 2006-05-22 11:29:15 UTC (rev 68236)
+++ zope.generic/trunk/src/zope/generic/factory/factory.py 2006-05-22 12:31:00 UTC (rev 68237)
@@ -142,6 +142,10 @@
If we like to provide parameter we have to declare them by an input
configuration:
+ >>> from zope.generic.informationprovider.api import deleteInformation
+ >>> from zope.generic.operation import IOperationConfiguration
+ >>> deleteInformation(IOperationConfiguration, IMyInstance)
+
>>> from zope.schema import TextLine
>>> class SimpleKeyFacedWithParameter(object):
Modified: zope.generic/trunk/src/zope/generic/informationprovider/NEW_README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/NEW_README.txt 2006-05-22 11:29:15 UTC (rev 68236)
+++ zope.generic/trunk/src/zope/generic/informationprovider/NEW_README.txt 2006-05-22 12:31:00 UTC (rev 68237)
@@ -222,6 +222,8 @@
If we like to acquire from the default user context configuration, we have
to derive our marker from IUndefinedKeyface.
+ >>> api.deleteInformation(ILogConfiguration, IMy, ISupplierContext)
+
>>> class IMy(IUndefinedKeyface):
... """My own key interface."""
Modified: zope.generic/trunk/src/zope/generic/informationprovider/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/README.txt 2006-05-22 11:29:15 UTC (rev 68236)
+++ zope.generic/trunk/src/zope/generic/informationprovider/README.txt 2006-05-22 12:31:00 UTC (rev 68237)
@@ -264,9 +264,13 @@
The other way round we can play with key interface inheritance:
+ >>> from zope.generic.face import IKeyfaceType
+
>>> class IBar(interface.Interface):
... pass
+ >>> interface.alsoProvides(IBar, IKeyfaceType)
+
>>> api.acquireInformationProvider(IBar)
Traceback (most recent call last):
...
@@ -275,6 +279,8 @@
>>> class IFooBar(IFoo, IBar):
... pass
+ >>> interface.alsoProvides(IFooBar, IKeyfaceType)
+
>>> api.acquireInformationProvider(IFooBar)
<GlobalInformationProvider IFoo at IUndefinedContext>
@@ -295,6 +301,8 @@
>>> class IBarFoo(IBar, IFoo):
... pass
+ >>> interface.alsoProvides(IBarFoo, IKeyfaceType)
+
>>> api.acquireInformationProvider(IBarFoo)
<GlobalInformationProvider IBar at IUndefinedContext>
Modified: zope.generic/trunk/src/zope/generic/informationprovider/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/informationprovider/api.py 2006-05-22 11:29:15 UTC (rev 68236)
+++ zope.generic/trunk/src/zope/generic/informationprovider/api.py 2006-05-22 12:31:00 UTC (rev 68237)
@@ -24,7 +24,8 @@
from zope.generic.configuration import IConfigurationType
from zope.generic.configuration import IConfigurations
-from zope.generic.configuration.api import createConfiguration
+from zope.generic.configuration.api import deleteConfiguration
+from zope.generic.configuration.api import updateConfiguration
from zope.generic.face import IConfaceType
from zope.generic.face import IKeyfaceType
from zope.generic.face import IUndefinedContext
@@ -143,10 +144,7 @@
context = getInformationProvider(keyface, conface)
if IConfigurationType.providedBy(informationkey):
- if type(information) is dict:
- information = createConfiguration(informationkey, information)
-
- IConfigurations(context)[informationkey] = information
+ updateConfiguration(context, informationkey, information)
else:
IAnnotations(context)[informationkey] = information
@@ -163,7 +161,7 @@
context = getInformationProvider(keyface, conface)
if IConfigurationType.providedBy(informationkey):
- del IConfigurations(context)[informationkey]
+ deleteConfiguration(context, informationkey)
else:
del IAnnotations(context)[informationkey]
More information about the Checkins
mailing list