several corrections about dependency

This commit is contained in:
2017-09-17 15:55:32 +02:00
parent 635b71d291
commit 3567e18256
12 changed files with 225 additions and 78 deletions

View File

@ -67,7 +67,8 @@ def validate_callback(callback, callback_params, type_, callbackoption):
' not a {} for first argument'
).format(type_, type(option)))
if cur_opt != callbackoption:
cur_opt._add_dependencies(callbackoption)
cur_opt._add_dependency(callbackoption)
callbackoption._has_dependency = True
def _validate_force_permissive(force_permissive):
#validate force_permissive
@ -84,6 +85,8 @@ def validate_callback(callback, callback_params, type_, callbackoption):
raise ValueError(_('{0}_params with length of '
'tuple as 1 must only have '
'None as first value').format(type_))
if callbk == ((None,)):
callbackoption._has_calc_context = True
return
elif len(callbk) != 2:
raise ValueError(_('{0}_params must only have 1 or 2 '
@ -126,6 +129,7 @@ class Base(object):
#other
'_has_dependency',
'_dependencies',
'_has_calc_context',
'__weakref__'
)
@ -198,12 +202,26 @@ class Base(object):
validator_params[''] = tuple(params)
return validator_params
def _set_has_dependency(self):
if not self._is_symlinkoption():
self._has_dependency = True
def impl_has_dependency(self, self_is_dep=True):
if self_is_dep is True:
if self.impl_is_master_slaves():
return True
return getattr(self, '_has_dependency', False)
else:
return hasattr(self, '_dependencies')
def impl_has_dependency(self):
return getattr(self, '_has_dependency', False)
def _get_dependencies(self, context):
if context:
od = context.cfgimpl_get_description()
if context and hasattr(od, '_dependencies'):
return set(od._dependencies) | set(getattr(self, '_dependencies', STATIC_TUPLE))
else:
return getattr(self, '_dependencies', STATIC_TUPLE)
def _add_dependency(self, option):
options = set(self._get_dependencies(None))
options.add(option)
self._dependencies = tuple(options)
def impl_set_callback(self, callback, callback_params=None, _init=False):
if callback is None and callback_params is not None:
@ -242,7 +260,7 @@ class Base(object):
def impl_getproperties(self):
return self._properties
def _set_readonly(self, has_extra):
def _set_readonly(self):
if not self.impl_is_readonly():
_setattr = object.__setattr__
dico = self._informations
@ -252,10 +270,9 @@ class Base(object):
else:
dico = tuple([keys, tuple(dico.values())])
_setattr(self, '_informations', dico)
if has_extra:
extra = getattr(self, '_extra', None)
if extra is not None:
_setattr(self, '_extra', tuple([tuple(extra.keys()), tuple(extra.values())]))
extra = getattr(self, '_extra', None)
if extra is not None:
_setattr(self, '_extra', tuple([tuple(extra.keys()), tuple(extra.values())]))
def _impl_setsubdyn(self, subdyn):
self._subdyn = subdyn
@ -385,13 +402,15 @@ class BaseOption(Base):
name = name.encode('utf8')
return name
def reset_cache(self, opt, obj, type_):
def reset_cache(self, opt, obj, type_, orig_opts):
context = obj._getcontext()
path = self.impl_getpath(context)
obj._p_.delcache(path)
orig_opts.add(opt)
context.cfgimpl_reset_cache(only=(type_,),
opt=self,
path=path)
path=path,
orig_opts=orig_opts)
def _is_symlinkoption(self):
return False
@ -410,14 +429,6 @@ def validate_requires_arg(new_option, multi, requires, name):
know more about
the description of the requires dictionary
"""
def set_dependency(option):
if not getattr(option, '_dependencies', None):
options = set()
else:
options = set(option._dependencies)
options.add(new_option)
option._dependencies = tuple(options)
def get_option(require):
option = require['option']
if not hasattr(option, '_is_symlinkoption'):
@ -427,7 +438,7 @@ def validate_requires_arg(new_option, multi, requires, name):
raise ValueError(_('malformed requirements '
'multi option must not set '
'as requires of non multi option {0}').format(name))
set_dependency(option)
option._add_dependency(new_option)
return option
def _set_expected(action, inverse, transitive, same_action, option, expected, operator):
@ -453,7 +464,7 @@ def validate_requires_arg(new_option, multi, requires, name):
raise ValueError(_('malformed requirements expected must have '
'option and value for option {0}').format(name))
option = exp['option']
set_dependency(option)
option._add_dependency(new_option)
if option is not None:
err = option._validate(exp['value'])
if err:
@ -561,7 +572,13 @@ class SymLinkOption(OnlyOption):
_setattr = object.__setattr__
_setattr(self, '_name', name)
_setattr(self, '_opt', opt)
opt._set_has_dependency()
opt._add_dependency(self)
def impl_has_dependency(self, self_is_dep=True):
"""If self_is_dep is True, it has dependency (self._opt), so return True
if self_is_dep is False, cannot has validation or callback, so return False
"""
return self_is_dep is True
def _is_symlinkoption(self):
return True

View File

@ -58,6 +58,9 @@ class MasterSlaves(object):
if add:
for child in childs:
child._master_slaves = self
if child != self.master:
child._add_dependency(self)
self.master._add_dependency(self)
def is_master(self, opt):
master = self.master.impl_getname()
@ -270,7 +273,9 @@ class MasterSlaves(object):
" which has {1} as master").format(
name, self.getmaster(opt).impl_getname()))
def reset_cache(self, opt, values, type_):
def reset_cache(self, opt, values, type_, orig_opts):
path = self.getmaster(opt).impl_getpath(values._getcontext())
values._p_.delcache(path)
for slave in self.getslaves(opt):
slave_path = slave.impl_getpath(values._getcontext())
values._p_.delcache(slave_path)

View File

@ -28,6 +28,7 @@ from ..setting import log, undefined, debug
from ..autolib import carry_out_calculation
from ..error import (ConfigError, ValueWarning, PropertiesOptionError,
display_list)
from itertools import combinations
ALLOWED_CONST_LIST = ['_cons_not_equal']
@ -93,7 +94,6 @@ class Option(OnlyOption):
else:
val_call = (validator, validator_params)
self._val_call = (val_call, None)
self._set_has_dependency()
if extra is not None:
_setattr(self, '_extra', extra)
if unique != undefined and not isinstance(unique, bool):
@ -131,11 +131,6 @@ class Option(OnlyOption):
def impl_is_multi(self):
return getattr(self, '_multi', 1) != 1
def _add_dependencies(self, option):
options = set(getattr(self, '_dependencies', tuple()))
options.add(option)
self._dependencies = tuple(options)
def _launch_consistency(self, current_opt, func, option, value, context,
index, submulti_index, opts, warnings_only,
transitive):
@ -480,7 +475,7 @@ class Option(OnlyOption):
if init:
# FIXME
if func != 'not_equal':
opt._set_has_dependency()
opt._has_dependency = True
def impl_add_consistency(self, func, *other_opts, **params):
"""Add consistency means that value will be validate with other_opts
@ -517,7 +512,11 @@ class Option(OnlyOption):
opt._unique = True
if func != '_cons_not_equal':
#consistency could generate warnings or errors
self._set_has_dependency()
self._has_dependency = True
for opt in all_cons_opts:
if opt != self:
self._add_dependency(opt)
opt._add_dependency(self)
def _valid_consistency(self, option, value, context, index, submulti_idx,
display_warnings, display_error):

View File

@ -42,10 +42,12 @@ del(sys)
class CacheOptionDescription(BaseOption):
__slots__ = ('_cache_paths', '_cache_consistencies', '_cache_force_store_values')
def impl_build_cache(self, config, path='', _consistencies=None,
cache_option=None, force_store_values=None):
def _build_cache(self, config, path='', _consistencies=None,
cache_option=None, force_store_values=None,
_dependencies=None):
"""validate duplicate option and set option has readonly option
"""
# cache_option is None only when we start to build cache
if cache_option is None:
if self.impl_is_readonly():
raise ConfigError(_('option description seems to be part of an other '
@ -54,8 +56,10 @@ class CacheOptionDescription(BaseOption):
_consistencies = {}
cache_option = []
force_store_values = []
_dependencies = []
else:
init = False
for option in self._impl_getchildren(dyn=False):
cache_option.append(option)
if path == '':
@ -63,19 +67,14 @@ class CacheOptionDescription(BaseOption):
else:
subpath = path + '.' + option.impl_getname()
if isinstance(option, OptionDescription):
option._set_readonly(False)
option.impl_build_cache(config, subpath, _consistencies,
cache_option, force_store_values)
#cannot set multi option as OptionDescription requires
option._set_readonly()
option._build_cache(config, subpath, _consistencies,
cache_option, force_store_values,
_dependencies)
else:
if option.impl_is_master_slaves('master'):
if not getattr(option, '_dependencies', None):
options = set()
else:
options = set(option._dependencies)
options.add(option.impl_get_master_slaves())
option._dependencies = tuple(options)
option._set_readonly(True)
option._add_dependency(option.impl_get_master_slaves())
option._set_readonly()
is_multi = option.impl_is_multi()
if not option._is_symlinkoption() and 'force_store_value' in option.impl_getproperties():
force_store_values.append((subpath, option))
@ -102,6 +101,9 @@ class CacheOptionDescription(BaseOption):
[]).append((func,
all_cons_opts,
params))
# if context is set to callback, must be reset each time a value change
if hasattr(option, '_has_calc_context'):
_dependencies.append(option)
is_slave = None
if is_multi:
all_requires = option.impl_getrequires()
@ -142,7 +144,9 @@ class CacheOptionDescription(BaseOption):
opt.impl_getname()))
self._cache_consistencies[opt] = tuple(cons)
self._cache_force_store_values = force_store_values
self._set_readonly(False)
if _dependencies:
self._dependencies = tuple(_dependencies)
self._set_readonly()
def impl_already_build_caches(self):
return getattr(self, '_cache_paths', None) is not None
@ -171,7 +175,7 @@ class CacheOptionDescription(BaseOption):
if value_set:
config._impl_values._p_.commit()
def impl_build_cache_option(self, _currpath=None, cache_path=None,
def _build_cache_option(self, _currpath=None, cache_path=None,
cache_option=None):
if self.impl_is_readonly() or (_currpath is None and getattr(self, '_cache_paths', None) is not None):
@ -192,7 +196,7 @@ class CacheOptionDescription(BaseOption):
cache_path.append(path)
if option.impl_is_optiondescription():
_currpath.append(attr)
option.impl_build_cache_option(_currpath, cache_path,
option._build_cache_option(_currpath, cache_path,
cache_option)
_currpath.pop()
if save:
@ -471,7 +475,6 @@ class OptionDescription(OptionDescriptionWalk):
": this option is not a multi"
"").format(child.impl_getname(), self.impl_getname()))
#length of master change slaves length
self._set_has_dependency()
MasterSlaves(self.impl_getname(), children)
else: # pragma: optional cover
raise ValueError(_('group_type: {0}'