"""Configuration Management API""" |
"""Configuration Management API""" |
|
|
from peak.api import binding, exceptions, NOT_FOUND, NOT_GIVEN |
from config_components import ConfigurationRoot, Value, lookup |
|
from peak.util.EigenData import AlreadyRead |
from interfaces import * |
from interfaces import * |
from peak.util.EigenData import * |
from peak.api import * |
from config_components import * |
|
from weakref import WeakKeyDictionary |
|
|
|
|
|
__all__ = [ |
__all__ = [ |
'getGlobal','setGlobal', 'registerGlobalProvider', |
'makeRoot', 'registeredProtocol' |
'getLocal', 'setLocal', 'registerLocalProvider', 'newDefaultConfig', |
|
|
|
'getProperty', |
|
|
|
'setGlobalProperty', 'setGlobalRule', 'setGlobalDefault', |
|
'setPropertyFor', 'setRuleFor', 'setDefaultFor', |
|
] |
] |
|
|
|
|
_globalCfg = EigenCell() |
def makeRoot(**options): |
|
|
|
|
def getGlobal(): |
|
|
|
"""Return the global configuration object""" |
|
|
|
if not _globalCfg.locked: |
|
setGlobal(GlobalConfig()) |
|
|
|
return _globalCfg.get() |
|
|
|
|
|
def setGlobal(cfg): |
|
|
|
"""Replace the global configuration, as long as it hasn't been used yet""" |
|
|
|
_globalCfg.set(cfg) |
|
setLocal(cfg, None) # force local config for global config to be None |
|
|
|
|
"""Create a configuration root, suitable for use as a parent component |
|
|
_defaultCfg = EigenCell() |
This creates and returns a new 'IConfigurationRoot' with its default |
_localCfgs = EigenDict() |
configuration loading from 'peak.ini'. The returned root component |
_localCfgs.data = WeakKeyDictionary() |
will "know" it is a root, so any components that use it as a parent |
|
will get their 'uponAssembly()' events invoked immediately. |
|
|
|
Normally, this function is called without any parameters, but it will |
|
also accept keyword arguments that it will pass along when it calls the |
|
'peak.config.config_components.ConfigurationRoot' constructor. |
|
|
def getLocal(forRoot=None): |
Currently, the only acceptable keyword argument is 'iniFiles', which must |
|
be a sequence of filename strings or '(moduleName,fileName)' tuples. |
|
|
"""Return a local configuration object for 'forRoot'""" |
The default value of 'iniFiles' is '[("peak","peak.ini")]', which loads |
|
useful system defaults from 'peak.ini' in the 'peak' package directory. |
|
Files are loaded in the order specified, with later files overriding |
|
earlier ones, unless the setting to be overridden has already been used |
|
(in which case an 'AlreadyRead' error occurs).""" |
|
|
forRoot = binding.getRootComponent(forRoot) |
return ConfigurationRoot(None, **options) |
|
|
if forRoot is not None and _localCfgs.has_key(forRoot): |
|
return _localCfgs[forRoot] |
|
|
|
if not _defaultCfg.locked: |
|
setLocal(None, newDefaultConfig()) |
|
|
|
return _defaultCfg.get() |
|
|
|
|
|
def setLocal(forRoot, cfg): |
|
|
|
"""Replace local config for 'forRoot', as long as it hasn't been used""" |
def registeredProtocol(ob, configKey, baseProtocol=None): |
|
|
if forRoot is None: |
"""Obtain a local protocol object suitable for registering local adapters |
_defaultCfg.set(cfg) |
|
else: |
|
_localCfgs[forRoot] = cfg |
|
|
|
|
|
|
|
def newDefaultConfig(): |
|
|
|
"""Return a new, default local configuration object based on getGlobal()""" |
|
|
|
return LocalConfig(getGlobal()) |
|
|
|
|
Usage:: |
|
|
|
# Register a local adapter from type 'xyz' to the 'foo.bar' named |
|
# protocol: |
|
localProto = config.registeredProtocol(ctx,'foo.bar') |
|
protocols.declareAdapter(someFunc, [localProto], forTypes=[xyz]) |
|
|
|
# ...later, obtain a localized adaptation in 'someContext' |
|
adapt(someObject, config.lookup(ctx,'foo.bar')) |
|
|
|
This function is used to define named and/or contextual protocols, |
|
which provide functionality similar to Zope 3's named adapters and |
|
local adapters. If no local protocol has been created under the specified |
|
'configKey' for 'ob', this function creates a 'protocols.Variation' of |
|
the protocol found under 'configKey' in any of the parent components of |
|
'ob'. If no parent has a protocol registered under 'configKey', the |
|
supplied 'baseProtocol' is used as the base for the 'Variation'. (If |
|
'None', a new 'protocols.Protocol' is registered instead of a 'Variation'.) |
|
|
def getProperty(obj, propName, default=NOT_GIVEN): |
You only need to use 'registeredProtocol()' when declaring adapters, not |
|
when looking them up. Use 'config.lookup()' with the same arguments |
|
instead, since 'config.lookup()' doesn't attempt to register new protocols, |
|
and will thus be faster. |
|
|
"""Find property 'propName' for 'obj' |
Note that you cannot register a local protocol for a given 'configKey' |
|
once it has been looked up on 'ob'. Doing so will result in an |
Returns 'default' if the property is not found. If no 'default' |
'AlreadyRead' error. Also note that this function doesn't check that |
is supplied, raises 'PropertyNotFound'. |
a value already registered for 'configKey' is actually a protocol; if |
|
there is some other value already registered, it will be returned as long |
Properties are located by querying all the 'IPropertyMap' utilities |
as it is not the same value found for 'configKey' on the parent component |
available from 'obj' and its parent components, up through the local |
of 'ob' (i.e., so long as it is "local" to 'ob'.) |
and global configuration objects, if applicable. |
|
""" |
""" |
|
|
if not isinstance(propName,Property): |
|
propName = Property(propName) |
|
|
|
if not propName.isPlain(): |
|
raise exceptions.InvalidName( |
|
"getProperty() can't use wildcard/default properties", propName |
|
) |
|
|
|
prop = binding.findUtility(obj, propName, NOT_FOUND) |
|
|
|
if prop is not NOT_FOUND: |
|
return prop |
|
|
|
if default is NOT_GIVEN: |
|
raise exceptions.PropertyNotFound(propName, obj) |
|
|
|
return default |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def registerGlobalProvider(ifaces, provider): |
|
getGlobal().registerProvider(ifaces, provider) |
|
|
|
|
|
def setGlobalProperty(propName, value): |
|
|
|
pm = binding.findUtility(getGlobal(), IPropertyMap) |
|
pm.setValue(propName, value) |
|
|
|
|
|
def setGlobalRule(propName, ruleFactory): |
|
|
|
pm = binding.findUtility(getGlobal(), IPropertyMap) |
|
pm.setRule(propName, ruleFactory) |
|
|
|
|
|
def setGlobalDefault(propName, defaultObj): |
|
|
|
pm = binding.findUtility(getGlobal(), IPropertyMap) |
|
pm.setDefault(propName, ruleObj) |
|
|
|
|
|
|
|
|
|
|
|
|
key = IConfigKey(configKey) |
|
oldProtocol = lookup(binding.getParentComponent(ob), key, baseProtocol) |
|
|
|
if oldProtocol is None: |
|
newProtocol = protocols.Protocol() |
|
else: |
|
newProtocol = protocols.Variation(oldProtocol) |
|
|
|
try: |
|
IConfigurable(ob).registerProvider(key, Value(newProtocol)) |
|
except AlreadyRead: |
|
pass |
|
|
|
newProtocol = lookup(ob,key,baseProtocol) |
|
|
|
if newProtocol is oldProtocol: |
|
raise AlreadyRead("Too late to register protocol", configKey, ob) |
|
|
|
return newProtocol |
|
|
|
|
|
|
|
|
|
|
|
|
def registerLocalProvider(forRoot, ifaces, provider): |
|
getLocal(forRoot).registerProvider(ifaces, provider) |
|
|
|
|
|
def setPropertyFor(obj, propName, value): |
|
|
|
pm = binding.findUtility(obj, IPropertyMap) |
|
pm.setValue(propName, value) |
|
|
|
|
|
def setRuleFor(obj, propName, ruleFactory): |
|
|
|
pm = binding.findUtility(obj, IPropertyMap) |
|
pm.setRule(propName, ruleFactory) |
|
|
|
|
|
def setDefaultFor(obj, propName, defaultObj): |
|
|
|
pm = binding.findUtility(obj, IPropertyMap) |
|
pm.setDefault(propName, defaultObj) |
|
|
|
|
|