Merge branch 'master' into lgpl

This commit is contained in:
2014-03-15 10:11:17 +01:00
32 changed files with 2711 additions and 1230 deletions

View File

@ -19,7 +19,7 @@ from time import time
from copy import copy
import weakref
from tiramisu.error import (RequirementError, PropertiesOptionError,
ConstError)
ConstError, ConfigError)
from tiramisu.i18n import _
@ -237,6 +237,14 @@ multitypes = MultiTypeModule()
populate_multitypes()
# ____________________________________________________________
class Undefined():
pass
undefined = Undefined()
# ____________________________________________________________
class Property(object):
"a property is responsible of the option's value access rules"
@ -249,6 +257,11 @@ class Property(object):
self._properties = prop
def append(self, propname):
"""Appends a property named propname
:param propname: a predefined or user defined property name
:type propname: string
"""
if self._opt is not None and self._opt._calc_properties is not None \
and propname in self._opt._calc_properties:
raise ValueError(_('cannot append {0} property for option {1}: '
@ -258,12 +271,29 @@ class Property(object):
self._setting._setproperties(self._properties, self._opt, self._path)
def remove(self, propname):
"""Removes a property named propname
:param propname: a predefined or user defined property name
:type propname: string
"""
if propname in self._properties:
self._properties.remove(propname)
self._setting._setproperties(self._properties, self._opt,
self._path)
def extend(self, propnames):
"""Extends properties to the existing properties
:param propnames: an iterable made of property names
:type propnames: iterable of string
"""
for propname in propnames:
self.append(propname)
def reset(self):
"""resets the properties (does not **clear** the properties,
default properties are still present)
"""
self._setting.reset(_path=self._path)
def __contains__(self, propname):
@ -275,7 +305,7 @@ class Property(object):
#____________________________________________________________
class Settings(object):
"``Config()``'s configuration options"
"``config.Config()``'s configuration options settings"
__slots__ = ('context', '_owner', '_p_', '__weakref__')
def __init__(self, context, storage):
@ -293,6 +323,17 @@ class Settings(object):
self.context = weakref.ref(context)
self._p_ = storage
def _getcontext(self):
"""context could be None, we need to test it
context is None only if all reference to `Config` object is deleted
(for example we delete a `Config` and we manipulate a reference to
old `SubConfig`, `Values`, `Multi` or `Settings`)
"""
context = self.context()
if context is None:
raise ConfigError(_('the context does not exist anymore'))
return context
#____________________________________________________________
# properties methods
def __contains__(self, propname):
@ -317,16 +358,16 @@ class Settings(object):
raise ValueError(_('opt and all_properties must not be set '
'together in reset'))
if all_properties:
self._p_.reset_all_propertives()
self._p_.reset_all_properties()
else:
if opt is not None and _path is None:
_path = self._get_path_by_opt(opt)
self._p_.reset_properties(_path)
self.context().cfgimpl_reset_cache()
self._getcontext().cfgimpl_reset_cache()
def _getproperties(self, opt=None, path=None, is_apply_req=True):
if opt is None:
props = self._p_.getproperties(path, default_properties)
props = copy(self._p_.getproperties(path, default_properties))
else:
if path is None:
raise ValueError(_('if opt is not None, path should not be'
@ -337,8 +378,8 @@ class Settings(object):
ntime = int(time())
is_cached, props = self._p_.getcache(path, ntime)
if is_cached:
return props
props = self._p_.getproperties(path, opt._properties)
return copy(props)
props = copy(self._p_.getproperties(path, opt._properties))
if is_apply_req:
props |= self.apply_requires(opt, path)
if 'cache' in self:
@ -346,7 +387,7 @@ class Settings(object):
if ntime is None:
ntime = int(time())
ntime = ntime + expires_time
self._p_.setcache(path, props, ntime)
self._p_.setcache(path, copy(props), ntime)
return props
def append(self, propname):
@ -362,6 +403,10 @@ class Settings(object):
props.remove(propname)
self._setproperties(props, None, None)
def extend(self, propnames):
for propname in propnames:
self.append(propname)
def _setproperties(self, properties, opt, path):
"""save properties for specified opt
(never save properties if same has option properties)
@ -375,7 +420,7 @@ class Settings(object):
self._p_.reset_properties(path)
else:
self._p_.setproperties(path, properties)
self.context().cfgimpl_reset_cache()
self._getcontext().cfgimpl_reset_cache()
#____________________________________________________________
def validate_properties(self, opt_or_descr, is_descr, is_write, path,
@ -400,11 +445,13 @@ class Settings(object):
(typically with the `frozen` property)
"""
# opt properties
properties = copy(self._getproperties(opt_or_descr, path))
properties = self._getproperties(opt_or_descr, path)
self_properties = self._getproperties()
# remove opt permissive
# permissive affect option's permission with or without permissive
# global property
properties -= self._p_.getpermissive(path)
# remove global permissive if need
self_properties = copy(self._getproperties())
if force_permissive is True or 'permissive' in self_properties:
properties -= self._p_.getpermissive()
if force_permissives is not None:
@ -421,7 +468,7 @@ class Settings(object):
properties -= frozenset(('mandatory', 'frozen'))
else:
if 'mandatory' in properties and \
not self.context().cfgimpl_get_values()._isempty(
not self._getcontext().cfgimpl_get_values()._isempty(
opt_or_descr, value):
properties.remove('mandatory')
if is_write and 'everything_frozen' in self_properties:
@ -544,6 +591,7 @@ class Settings(object):
# filters the callbacks
calc_properties = set()
context = self._getcontext()
for requires in opt._requires:
for require in requires:
option, expected, action, inverse, \
@ -555,8 +603,7 @@ class Settings(object):
" '{0}' with requirement on: "
"'{1}'").format(path, reqpath))
try:
value = self.context()._getattr(reqpath,
force_permissive=True)
value = context._getattr(reqpath, force_permissive=True)
except PropertiesOptionError as err:
if not transitive:
continue
@ -585,7 +632,7 @@ class Settings(object):
:param opt: `Option`'s object
:returns: path
"""
return self.context().cfgimpl_get_description().impl_get_path_by_opt(opt)
return self._getcontext().cfgimpl_get_description().impl_get_path_by_opt(opt)
def get_modified_properties(self):
return self._p_.get_modified_properties()