Merge branch 'master' into lgpl
This commit is contained in:
@ -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()
|
||||
|
Reference in New Issue
Block a user