add config_bag and convert some tests
This commit is contained in:
@ -48,14 +48,19 @@ def valid_name(name):
|
||||
not name.startswith('cfgimpl_')
|
||||
|
||||
|
||||
def validate_callback(callback,
|
||||
callback_params,
|
||||
type_,
|
||||
callbackoption):
|
||||
def validate_calculator(callback,
|
||||
callback_params,
|
||||
type_,
|
||||
callbackoption):
|
||||
"""validate function and parameter set for callback, validation, ...
|
||||
"""
|
||||
|
||||
def _validate_option(option):
|
||||
#validate option
|
||||
if not isinstance(option, OnlyOption):
|
||||
raise ValueError(_('{}_params must have an option'
|
||||
' not a {} for first argument'
|
||||
).format(type_, type(option)))
|
||||
if option.impl_is_symlinkoption():
|
||||
cur_opt = option.impl_getopt()
|
||||
else:
|
||||
@ -72,7 +77,7 @@ def validate_callback(callback,
|
||||
).format(type_,
|
||||
type(force_permissive)))
|
||||
|
||||
def _validate_callback(callbk):
|
||||
def _validate_calculator(callbk):
|
||||
if isinstance(callbk, tuple):
|
||||
if len(callbk) == 1:
|
||||
if callbk not in ((None,), ('index',)):
|
||||
@ -103,7 +108,7 @@ def validate_callback(callback,
|
||||
raise ValueError(_('{0}_params must be tuple for key "{1}"'
|
||||
).format(type_, key))
|
||||
for callbk in callbacks:
|
||||
_validate_callback(callbk)
|
||||
_validate_calculator(callbk)
|
||||
|
||||
|
||||
#____________________________________________________________
|
||||
@ -167,36 +172,105 @@ class Base(object):
|
||||
if properties:
|
||||
_setattr(self, '_properties', properties)
|
||||
|
||||
def _build_validator_params(self,
|
||||
validator,
|
||||
validator_params):
|
||||
|
||||
func_params = signature(validator).parameters
|
||||
args = [f.name for f in func_params.values() if f.default is f.empty]
|
||||
if validator_params is not None:
|
||||
kwargs = list(validator_params.keys())
|
||||
if '' in kwargs:
|
||||
kwargs.remove('')
|
||||
for kwarg in kwargs:
|
||||
if kwarg in args:
|
||||
args = args[0:args.index(kwarg)]
|
||||
len_args = len(validator_params.get('', []))
|
||||
if len_args != 0 and len(args) >= len_args:
|
||||
args = args[0:len(args)-len_args]
|
||||
if len(args) >= 2:
|
||||
if validator_params is not None and '' in validator_params:
|
||||
params = list(validator_params[''])
|
||||
params.append((self, False))
|
||||
validator_params[''] = tuple(params)
|
||||
def _get_function_args(self,
|
||||
function):
|
||||
args = set()
|
||||
kwargs = set()
|
||||
positional = False
|
||||
keyword = False
|
||||
for param in signature(function).parameters.values():
|
||||
if param.kind == param.VAR_POSITIONAL:
|
||||
positional = True
|
||||
elif param.kind == param.VAR_KEYWORD:
|
||||
keyword = True
|
||||
elif param.default is param.empty:
|
||||
args.add(param.name)
|
||||
else:
|
||||
if validator_params is None:
|
||||
validator_params = {}
|
||||
validator_params[''] = ((self, False),)
|
||||
if len(args) == 3 and args[2] not in validator_params:
|
||||
params = list(validator_params[''])
|
||||
params.append(('index',))
|
||||
validator_params[''] = tuple(params)
|
||||
return validator_params
|
||||
kwargs.add(param.name)
|
||||
return args, kwargs, positional, keyword
|
||||
|
||||
def _get_parameters_args(self,
|
||||
calculator_params,
|
||||
add_value):
|
||||
|
||||
args = set()
|
||||
kwargs = set()
|
||||
if add_value:
|
||||
args.add('value')
|
||||
for param in calculator_params.keys():
|
||||
if param == '':
|
||||
for idx, _ in enumerate(calculator_params['']):
|
||||
# construct an appropriate name
|
||||
args.add('param{}'.format(idx))
|
||||
else:
|
||||
kwargs.add(param)
|
||||
return args, kwargs
|
||||
|
||||
def _build_calculator_params(self,
|
||||
calculator,
|
||||
calculator_params,
|
||||
add_value=False):
|
||||
|
||||
if calculator_params is not None:
|
||||
func_args, func_kwargs, func_positional, func_keyword = self._get_function_args(calculator)
|
||||
calculator_args, calculator_kwargs = self._get_parameters_args(calculator_params, add_value)
|
||||
# remove knowned kwargs
|
||||
common_kwargs = func_kwargs & calculator_kwargs
|
||||
func_kwargs -= common_kwargs
|
||||
calculator_kwargs -= common_kwargs
|
||||
# remove knowned calculator's kwargs in func's args
|
||||
common = func_args & calculator_kwargs
|
||||
func_args -= common
|
||||
calculator_kwargs -= common
|
||||
# remove unknown calculator's args in func's args
|
||||
for idx in range(min(len(calculator_args), len(func_args))):
|
||||
func_args.pop()
|
||||
calculator_args.pop()
|
||||
# remove unknown calculator's args in func's kwargs
|
||||
func_kwargs_left = func_kwargs - {'index', 'self'}
|
||||
func_kwargs_pop = set()
|
||||
for idx in range(min(len(calculator_args), len(func_kwargs_left))):
|
||||
func_kwargs_pop.add(func_kwargs_left.pop())
|
||||
calculator_args.pop()
|
||||
func_kwargs -= func_kwargs_pop
|
||||
if func_positional:
|
||||
calculator_args = set()
|
||||
if func_keyword:
|
||||
calculator_kwargs = set()
|
||||
if calculator_args or calculator_kwargs:
|
||||
# there is more args/kwargs than expected!
|
||||
raise ConfigError(_('cannot find those arguments "{}" in function "{}" for "{}"'
|
||||
'').format(list(calculator_args | calculator_kwargs),
|
||||
calculator.__name__,
|
||||
self.impl_get_display_name()))
|
||||
has_self = False
|
||||
has_index = False
|
||||
if func_args:
|
||||
# there is extra args/kwargs
|
||||
if not self.impl_is_optiondescription() and self.impl_is_multi():
|
||||
params = list(calculator_params[''])
|
||||
if add_value:
|
||||
# only for validator
|
||||
has_self = True
|
||||
params.append((self, False))
|
||||
func_args.pop()
|
||||
if func_args:
|
||||
has_index = True
|
||||
params.append(('index',))
|
||||
func_args.pop()
|
||||
if func_args:
|
||||
raise ConfigError(_('missing those arguements "{}" in function "{}" for "{}"'
|
||||
'').format(list(func_args),
|
||||
calculator.__name__,
|
||||
self.impl_get_display_name()))
|
||||
calculator_params[''] = tuple(params)
|
||||
if not self.impl_is_optiondescription() and self.impl_is_multi():
|
||||
if add_value and not has_self and 'self' in func_kwargs:
|
||||
# only for validator
|
||||
calculator_params['self'] = (self, False)
|
||||
if not has_index and 'index' in func_kwargs:
|
||||
calculator_params['index'] = (('index',),)
|
||||
return calculator_params
|
||||
|
||||
def impl_has_dependency(self,
|
||||
self_is_dep=True):
|
||||
@ -236,13 +310,15 @@ class Base(object):
|
||||
if not _init and self.impl_get_callback()[0] is not None:
|
||||
raise ConfigError(_("a callback is already set for {0}, "
|
||||
"cannot set another one's").format(self.impl_getname()))
|
||||
self._validate_callback(callback,
|
||||
callback_params)
|
||||
self._validate_calculator(callback,
|
||||
callback_params)
|
||||
if callback is not None:
|
||||
validate_callback(callback,
|
||||
callback_params,
|
||||
'callback',
|
||||
self)
|
||||
validate_calculator(callback,
|
||||
callback_params,
|
||||
'callback',
|
||||
self)
|
||||
callback_params = self._build_calculator_params(callback,
|
||||
callback_params)
|
||||
val = getattr(self, '_val_call', (None,))[0]
|
||||
if callback_params is None or callback_params == {}:
|
||||
val_call = (callback,)
|
||||
@ -424,7 +500,7 @@ class BaseOption(Base):
|
||||
obj._p_.delcache(path)
|
||||
if type_ in ['settings', 'permissives']:
|
||||
obj._pp_.delcache(path)
|
||||
resetted_opts.add(opt)
|
||||
resetted_opts.append(opt)
|
||||
|
||||
def impl_is_symlinkoption(self):
|
||||
return False
|
||||
|
@ -31,8 +31,7 @@ class BoolOption(Option):
|
||||
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
*args,
|
||||
**kwargs):
|
||||
if not isinstance(value, bool):
|
||||
raise ValueError()
|
||||
|
@ -32,9 +32,8 @@ class BroadcastOption(Option):
|
||||
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
*args,
|
||||
**kwargs):
|
||||
self._impl_valid_string(value)
|
||||
if value.count('.') != 3:
|
||||
raise ValueError()
|
||||
|
@ -22,7 +22,7 @@ from types import FunctionType
|
||||
|
||||
from ..setting import undefined
|
||||
from ..i18n import _
|
||||
from .baseoption import validate_callback
|
||||
from .baseoption import validate_calculator
|
||||
from .option import Option
|
||||
from ..autolib import carry_out_calculation
|
||||
from ..error import ConfigError, display_list
|
||||
@ -56,10 +56,10 @@ class ChoiceOption(Option):
|
||||
:param values: is a list of values the option can possibly take
|
||||
"""
|
||||
if isinstance(values, FunctionType):
|
||||
validate_callback(values,
|
||||
values_params,
|
||||
'values',
|
||||
self)
|
||||
validate_calculator(values,
|
||||
values_params,
|
||||
'values',
|
||||
self)
|
||||
else:
|
||||
if values_params is not None:
|
||||
raise ValueError(_('values is not a function, so values_params must be None'))
|
||||
@ -83,22 +83,22 @@ class ChoiceOption(Option):
|
||||
warnings_only=warnings_only)
|
||||
|
||||
def impl_get_values(self,
|
||||
setting_properties,
|
||||
context,
|
||||
config_bag,
|
||||
current_opt=undefined):
|
||||
if current_opt is undefined:
|
||||
current_opt = self
|
||||
#FIXME cache? but in context...
|
||||
values = self._choice_values
|
||||
if isinstance(values, FunctionType):
|
||||
if context is None:
|
||||
values = []
|
||||
if config_bag is undefined:
|
||||
values = undefined
|
||||
else:
|
||||
values = carry_out_calculation(current_opt,
|
||||
setting_properties=setting_properties,
|
||||
context=context,
|
||||
callback=values,
|
||||
callback_params=getattr(self, '_choice_values_params', {}))
|
||||
config_bag.config,
|
||||
values,
|
||||
getattr(self, '_choice_values_params', {}),
|
||||
None,
|
||||
config_bag)
|
||||
if values is not undefined and not isinstance(values, list):
|
||||
raise ConfigError(_('calculated values for {0} is not a list'
|
||||
'').format(self.impl_getname()))
|
||||
@ -107,16 +107,14 @@ class ChoiceOption(Option):
|
||||
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
config_bag,
|
||||
current_opt=undefined):
|
||||
values = self.impl_get_values(setting_properties,
|
||||
context,
|
||||
values = self.impl_get_values(config_bag,
|
||||
current_opt=current_opt)
|
||||
if values is not undefined and not value in values:
|
||||
if len(values) == 1:
|
||||
raise ValueError(_('only {0} is allowed'
|
||||
raise ValueError(_('only "{0}" is allowed'
|
||||
'').format(values[0]))
|
||||
else:
|
||||
raise ValueError(_('only {0} are allowed'
|
||||
raise ValueError(_('only "{0}" are allowed'
|
||||
'').format(display_list(values)))
|
||||
|
@ -31,9 +31,8 @@ class DateOption(Option):
|
||||
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
*args,
|
||||
**kwargs):
|
||||
self._impl_valid_string(value)
|
||||
try:
|
||||
datetime.strptime(value, "%Y-%m-%d")
|
||||
|
@ -99,9 +99,8 @@ class DomainnameOption(Option):
|
||||
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
*args,
|
||||
**kwargs):
|
||||
self._impl_valid_string(value)
|
||||
|
||||
def _valid_length(val):
|
||||
|
@ -53,7 +53,7 @@ class DynOptionDescription(OptionDescription):
|
||||
if child.impl_get_group_type() != groups.master:
|
||||
raise ConfigError(_('cannot set optiondescription in a '
|
||||
'dynoptiondescription'))
|
||||
for chld in child.impl_getchildren(setting_properties=undefined):
|
||||
for chld in child.impl_getchildren(config_bag=undefined):
|
||||
chld._impl_setsubdyn(self)
|
||||
if child.impl_is_symlinkoption():
|
||||
raise ConfigError(_('cannot set symlinkoption in a '
|
||||
@ -63,22 +63,22 @@ class DynOptionDescription(OptionDescription):
|
||||
self.impl_set_callback(callback,
|
||||
callback_params)
|
||||
|
||||
def _validate_callback(self,
|
||||
callback,
|
||||
callback_params):
|
||||
def _validate_calculator(self,
|
||||
callback,
|
||||
callback_params):
|
||||
if callback is None:
|
||||
raise ConfigError(_('callback is mandatory for the dynoptiondescription "{}"'
|
||||
'').format(self.impl_get_display_name()))
|
||||
|
||||
def _impl_get_suffixes(self,
|
||||
context,
|
||||
setting_properties):
|
||||
config_bag):
|
||||
callback, callback_params = self.impl_get_callback()
|
||||
values = carry_out_calculation(self,
|
||||
context=context,
|
||||
callback=callback,
|
||||
callback_params=callback_params,
|
||||
setting_properties=setting_properties)
|
||||
config_bag.config,
|
||||
callback,
|
||||
callback_params,
|
||||
None,
|
||||
config_bag)
|
||||
if not isinstance(values, list):
|
||||
raise ValueError(_('invalid suffix "{}" for option "{}", must be a list'
|
||||
'').format(values,
|
||||
|
@ -31,8 +31,7 @@ class FloatOption(Option):
|
||||
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
*args,
|
||||
**kwargs):
|
||||
if not isinstance(value, float):
|
||||
raise ValueError()
|
||||
|
@ -31,8 +31,7 @@ class IntOption(Option):
|
||||
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
*args,
|
||||
**kwargs):
|
||||
if not isinstance(value, int):
|
||||
raise ValueError()
|
||||
|
@ -64,9 +64,8 @@ class IPOption(Option):
|
||||
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
*args,
|
||||
**kwargs):
|
||||
# sometimes an ip term starts with a zero
|
||||
# but this does not fit in some case, for example bind does not like it
|
||||
self._impl_valid_string(value)
|
||||
|
@ -104,26 +104,23 @@ class MasterSlaves(OptionDescription):
|
||||
return c_opt in self._children[1]
|
||||
|
||||
def reset(self,
|
||||
opt,
|
||||
values,
|
||||
setting_properties,
|
||||
_commit=True,
|
||||
force_permissive=False):
|
||||
config_bag,
|
||||
_commit=True):
|
||||
|
||||
for slave in self.getslaves():
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.option = slave
|
||||
sconfig_bag.validate = False
|
||||
slave_path = slave.impl_getpath(values._getcontext())
|
||||
values.reset(slave,
|
||||
slave_path,
|
||||
setting_properties,
|
||||
validate=False,
|
||||
_commit=_commit,
|
||||
force_permissive=force_permissive)
|
||||
values.reset(slave_path,
|
||||
sconfig_bag,
|
||||
_commit=_commit)
|
||||
|
||||
def pop(self,
|
||||
values,
|
||||
index,
|
||||
setting_properties,
|
||||
force_permissive,
|
||||
config_bag,
|
||||
slaves=undefined):
|
||||
|
||||
context = values._getcontext()
|
||||
@ -132,12 +129,12 @@ class MasterSlaves(OptionDescription):
|
||||
for slave in slaves:
|
||||
slave_path = slave.impl_getpath(context)
|
||||
slavelen = values._p_.get_max_length(slave_path)
|
||||
if not values.is_default_owner(slave,
|
||||
slave_path,
|
||||
setting_properties,
|
||||
validate_meta=False,
|
||||
index=index,
|
||||
force_permissive=force_permissive):
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.option = slave
|
||||
if not values.is_default_owner(slave_path,
|
||||
index,
|
||||
config_bag,
|
||||
validate_meta=False):
|
||||
if slavelen > index:
|
||||
values._p_.resetvalue_index(slave_path,
|
||||
index)
|
||||
|
@ -33,9 +33,8 @@ class NetmaskOption(Option):
|
||||
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
*args,
|
||||
**kwargs):
|
||||
self._impl_valid_string(value)
|
||||
if value.count('.') != 3:
|
||||
raise ValueError()
|
||||
|
@ -32,9 +32,8 @@ class NetworkOption(Option):
|
||||
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
*args,
|
||||
**kwargs):
|
||||
self._impl_valid_string(value)
|
||||
if value.count('.') != 3:
|
||||
raise ValueError()
|
||||
|
@ -23,7 +23,7 @@ import warnings
|
||||
import sys
|
||||
import weakref
|
||||
|
||||
from .baseoption import OnlyOption, submulti, validate_callback, STATIC_TUPLE
|
||||
from .baseoption import OnlyOption, submulti, validate_calculator, STATIC_TUPLE
|
||||
from .symlinkoption import DynSymLinkOption
|
||||
from ..i18n import _
|
||||
from ..setting import log, undefined, debug
|
||||
@ -102,14 +102,13 @@ class Option(OnlyOption):
|
||||
if multi is not False and default is None:
|
||||
default = []
|
||||
if validator is not None:
|
||||
if multi: # and validator_params is None:
|
||||
validator_params = self._build_validator_params(validator,
|
||||
validator_params)
|
||||
|
||||
validate_callback(validator,
|
||||
validator_params,
|
||||
'validator',
|
||||
self)
|
||||
validate_calculator(validator,
|
||||
validator_params,
|
||||
'validator',
|
||||
self)
|
||||
validator_params = self._build_calculator_params(validator,
|
||||
validator_params,
|
||||
add_value=True)
|
||||
if validator_params is None:
|
||||
val_call = (validator,)
|
||||
else:
|
||||
@ -133,9 +132,10 @@ class Option(OnlyOption):
|
||||
is_multi=is_multi)
|
||||
if is_multi and default_multi is not None:
|
||||
def test_multi_value(value):
|
||||
err = self._validate(value,
|
||||
undefined)
|
||||
if err:
|
||||
try:
|
||||
self._validate(value,
|
||||
undefined)
|
||||
except ValueError as err:
|
||||
raise ValueError(_("invalid default_multi value {0} "
|
||||
"for option {1}: {2}").format(str(value),
|
||||
self.impl_getname(),
|
||||
@ -154,7 +154,8 @@ class Option(OnlyOption):
|
||||
if unique is not undefined:
|
||||
_setattr(self, '_unique', unique)
|
||||
self.impl_validate(default,
|
||||
is_multi=is_multi)
|
||||
is_multi=is_multi,
|
||||
config_bag=undefined)
|
||||
if (is_multi and default != []) or \
|
||||
(not is_multi and default is not None):
|
||||
if is_multi:
|
||||
@ -183,7 +184,7 @@ class Option(OnlyOption):
|
||||
opts,
|
||||
warnings_only,
|
||||
transitive,
|
||||
setting_properties):
|
||||
config_bag):
|
||||
"""Launch consistency now
|
||||
|
||||
:param func: function name, this name should start with _cons_
|
||||
@ -205,37 +206,39 @@ class Option(OnlyOption):
|
||||
"""
|
||||
if context is not undefined:
|
||||
descr = context.cfgimpl_get_description()
|
||||
|
||||
if config_bag is not undefined and config_bag.fromconsistency == option:
|
||||
return
|
||||
all_cons_vals = []
|
||||
all_cons_opts = []
|
||||
val_consistencies = True
|
||||
for wopt in opts:
|
||||
opt = wopt()
|
||||
if (isinstance(opt, DynSymLinkOption) and option._dyn == opt._dyn) or \
|
||||
option == opt:
|
||||
for opt in opts:
|
||||
if isinstance(opt, weakref.ReferenceType):
|
||||
opt = opt()
|
||||
if config_bag is not undefined:
|
||||
if config_bag.fromconsistency == opt:
|
||||
break
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.option = opt
|
||||
sconfig_bag.fromconsistency = option
|
||||
else:
|
||||
sconfig_bag = undefined
|
||||
if option == opt:
|
||||
# option is current option
|
||||
# we have already value, so use it
|
||||
all_cons_vals.append(value)
|
||||
all_cons_opts.append(opt)
|
||||
else:
|
||||
path = None
|
||||
is_multi = opt.impl_is_multi() and not opt.impl_is_master_slaves()
|
||||
#if context, calculate value, otherwise get default value
|
||||
if context is not undefined:
|
||||
if isinstance(opt, DynSymLinkOption):
|
||||
path = opt.impl_getpath(context)
|
||||
else:
|
||||
#FIXME ca devrait etre impl_getpath ??)
|
||||
path = descr.impl_get_path_by_opt(opt)
|
||||
if is_multi:
|
||||
_index = None
|
||||
else:
|
||||
_index = index
|
||||
try:
|
||||
opt_value = context.getattr(path,
|
||||
setting_properties,
|
||||
validate=False,
|
||||
index=_index,
|
||||
force_permissive=True)
|
||||
index,
|
||||
sconfig_bag)
|
||||
except PropertiesOptionError as err:
|
||||
if debug: # pragma: no cover
|
||||
log.debug('propertyerror in _launch_consistency: {0}'.format(err))
|
||||
@ -248,14 +251,15 @@ class Option(OnlyOption):
|
||||
else:
|
||||
opt_value = opt.impl_getdefault()
|
||||
if index is not None:
|
||||
if len(opt_value) >= index:
|
||||
if len(opt_value) <= index:
|
||||
opt_value = opt.impl_getdefault_multi()
|
||||
else:
|
||||
opt_value = opt_value[index]
|
||||
|
||||
if self.impl_is_multi() and index is None:
|
||||
is_multi = self.impl_is_multi()
|
||||
if is_multi and index is None:
|
||||
# only check propertyerror for master/slaves is transitive
|
||||
val_consistencies = False
|
||||
break
|
||||
if is_multi and isinstance(opt_value, list):
|
||||
all_cons_vals.extend(opt_value)
|
||||
for len_ in xrange(len(opt_value)):
|
||||
@ -263,10 +267,12 @@ class Option(OnlyOption):
|
||||
else:
|
||||
all_cons_vals.append(opt_value)
|
||||
all_cons_opts.append(opt)
|
||||
|
||||
if val_consistencies:
|
||||
else:
|
||||
try:
|
||||
getattr(self, func)(current_opt, all_cons_opts, all_cons_vals, warnings_only)
|
||||
getattr(self, func)(current_opt,
|
||||
all_cons_opts,
|
||||
all_cons_vals,
|
||||
warnings_only)
|
||||
except ValueError as err:
|
||||
if warnings_only:
|
||||
msg = _('attention, "{0}" could be an invalid {1} for "{2}", {3}'
|
||||
@ -295,13 +301,13 @@ class Option(OnlyOption):
|
||||
|
||||
def impl_validate(self,
|
||||
value,
|
||||
config_bag,
|
||||
context=undefined,
|
||||
force_index=None,
|
||||
current_opt=undefined,
|
||||
is_multi=None,
|
||||
check_error=True,
|
||||
multi=None,
|
||||
setting_properties=undefined):
|
||||
multi=None):
|
||||
"""
|
||||
:param value: the option's value
|
||||
:param context: Config's context
|
||||
@ -314,7 +320,9 @@ class Option(OnlyOption):
|
||||
if current_opt is undefined:
|
||||
current_opt = self
|
||||
|
||||
if check_error is False and not 'warnings' in setting_properties:
|
||||
if config_bag is not undefined and \
|
||||
((check_error is True and not 'validator' in config_bag.setting_properties) or \
|
||||
(check_error is False and not 'warnings' in config_bag.setting_properties)):
|
||||
return
|
||||
|
||||
def _is_not_unique(value):
|
||||
@ -348,8 +356,8 @@ class Option(OnlyOption):
|
||||
context=context,
|
||||
callback=validator,
|
||||
callback_params=validator_params_,
|
||||
setting_properties=setting_properties,
|
||||
index=_index,
|
||||
config_bag=config_bag,
|
||||
is_validator=True)
|
||||
|
||||
def do_validation(_value,
|
||||
@ -364,9 +372,12 @@ class Option(OnlyOption):
|
||||
if _value is not None:
|
||||
if check_error:
|
||||
# option validation
|
||||
if config_bag is undefined:
|
||||
setting_properties = None
|
||||
else:
|
||||
setting_properties = config_bag.setting_properties
|
||||
self._validate(_value,
|
||||
setting_properties,
|
||||
context,
|
||||
config_bag,
|
||||
current_opt)
|
||||
if ((check_error and not is_warnings_only) or
|
||||
(not check_error and is_warnings_only)):
|
||||
@ -379,7 +390,7 @@ class Option(OnlyOption):
|
||||
context,
|
||||
_index,
|
||||
check_error,
|
||||
setting_properties)
|
||||
config_bag)
|
||||
except ValueError as err:
|
||||
if debug: # pragma: no cover
|
||||
log.debug('do_validation: value: {0}, index: {1}:'
|
||||
@ -436,28 +447,37 @@ class Option(OnlyOption):
|
||||
'must be a list').format(value,
|
||||
self.impl_getname()))
|
||||
elif self.impl_is_submulti():
|
||||
for idx, val in enumerate(value):
|
||||
_is_not_unique(val)
|
||||
if not isinstance(val, list):
|
||||
raise ValueError(_('invalid value "{0}" for "{1}" '
|
||||
'which must be a list of list'
|
||||
'').format(val,
|
||||
self.impl_getname()))
|
||||
for slave_val in val:
|
||||
do_validation(slave_val,
|
||||
idx)
|
||||
if value:
|
||||
for idx, val in enumerate(value):
|
||||
_is_not_unique(val)
|
||||
if not isinstance(val, list):
|
||||
raise ValueError(_('invalid value "{0}" for "{1}" '
|
||||
'which must be a list of list'
|
||||
'').format(val,
|
||||
self.impl_getname()))
|
||||
for slave_val in val:
|
||||
do_validation(slave_val,
|
||||
idx)
|
||||
else:
|
||||
self._valid_consistency(current_opt,
|
||||
None,
|
||||
context,
|
||||
None,
|
||||
check_error,
|
||||
config_bag)
|
||||
else:
|
||||
_is_not_unique(value)
|
||||
for idx, val in enumerate(value):
|
||||
do_validation(val,
|
||||
idx)
|
||||
#self._valid_consistency(current_opt,
|
||||
# None,
|
||||
# context,
|
||||
# None,
|
||||
# display_warnings,
|
||||
# display_error,
|
||||
# setting_properties)
|
||||
if value:
|
||||
for idx, val in enumerate(value):
|
||||
do_validation(val,
|
||||
idx)
|
||||
else:
|
||||
self._valid_consistency(current_opt,
|
||||
None,
|
||||
context,
|
||||
None,
|
||||
check_error,
|
||||
config_bag)
|
||||
|
||||
def impl_is_dynsymlinkoption(self):
|
||||
return False
|
||||
@ -496,11 +516,9 @@ class Option(OnlyOption):
|
||||
if self.impl_is_submulti():
|
||||
raise ConfigError(_('cannot add consistency with submulti option'))
|
||||
is_multi = self.impl_is_multi()
|
||||
for wopt in other_opts:
|
||||
if isinstance(wopt, weakref.ReferenceType):
|
||||
opt = wopt()
|
||||
else:
|
||||
opt = wopt
|
||||
for opt in other_opts:
|
||||
if isinstance(opt, weakref.ReferenceType):
|
||||
opt = opt()
|
||||
if opt.impl_is_submulti():
|
||||
raise ConfigError(_('cannot add consistency with submulti option'))
|
||||
if not isinstance(opt, Option):
|
||||
@ -561,7 +579,12 @@ class Option(OnlyOption):
|
||||
all_cons_opts,
|
||||
params)
|
||||
#validate default value when add consistency
|
||||
self.impl_validate(self.impl_getdefault())
|
||||
#FIXME validation!
|
||||
self.impl_validate(self.impl_getdefault(),
|
||||
undefined)
|
||||
self.impl_validate(self.impl_getdefault(),
|
||||
undefined,
|
||||
check_error=False)
|
||||
#FIXME
|
||||
#if err:
|
||||
# self._del_consistency()
|
||||
@ -583,7 +606,7 @@ class Option(OnlyOption):
|
||||
context,
|
||||
index,
|
||||
check_error,
|
||||
setting_properties):
|
||||
config_bag):
|
||||
if context is not undefined:
|
||||
descr = context.cfgimpl_get_description()
|
||||
if descr._cache_consistencies is None:
|
||||
@ -602,33 +625,32 @@ class Option(OnlyOption):
|
||||
transitive = params.get('transitive', True)
|
||||
#all_cons_opts[0] is the option where func is set
|
||||
if isinstance(option, DynSymLinkOption):
|
||||
subpath = '.'.join(option._dyn.split('.')[:-1])
|
||||
namelen = len(option.impl_getopt().impl_getname())
|
||||
suffix = option.impl_getname()[namelen:]
|
||||
opts = []
|
||||
for opt in all_cons_opts:
|
||||
opts.append(DynSymLinkOption(opt,
|
||||
subpath,
|
||||
suffix))
|
||||
opts.append(DynSymLinkOption(opt(),
|
||||
option._rootpath,
|
||||
option._suffix))
|
||||
wopt = opts[0]
|
||||
else:
|
||||
opts = all_cons_opts
|
||||
opts[0]()._launch_consistency(self,
|
||||
func,
|
||||
option,
|
||||
value,
|
||||
context,
|
||||
index,
|
||||
opts,
|
||||
warnings_only,
|
||||
transitive,
|
||||
setting_properties)
|
||||
wopt = opts[0]()
|
||||
wopt._launch_consistency(self,
|
||||
func,
|
||||
option,
|
||||
value,
|
||||
context,
|
||||
index,
|
||||
opts,
|
||||
warnings_only,
|
||||
transitive,
|
||||
config_bag)
|
||||
|
||||
def _cons_not_equal(self,
|
||||
current_opt,
|
||||
opts,
|
||||
vals,
|
||||
warnings_only):
|
||||
equal = set()
|
||||
equal = list()
|
||||
is_current = False
|
||||
for idx_inf, val_inf in enumerate(vals):
|
||||
for idx_sup, val_sup in enumerate(vals[idx_inf + 1:]):
|
||||
@ -637,10 +659,10 @@ class Option(OnlyOption):
|
||||
if opt_ == current_opt:
|
||||
is_current = True
|
||||
else:
|
||||
equal.add(opt_)
|
||||
equal.append(opt_)
|
||||
if equal:
|
||||
if debug: # pragma: no cover
|
||||
log.debug(_('_cons_not_equal: {} are not different').format(display_list(list(equal))))
|
||||
log.debug(_('_cons_not_equal: {} are not different').format(display_list(equal)))
|
||||
if is_current:
|
||||
if warnings_only:
|
||||
msg = _('should be different from the value of {}')
|
||||
@ -669,9 +691,9 @@ class Option(OnlyOption):
|
||||
default_value = None
|
||||
return getattr(self, '_default_multi', default_value)
|
||||
|
||||
def _validate_callback(self,
|
||||
callback,
|
||||
callback_params):
|
||||
def _validate_calculator(self,
|
||||
callback,
|
||||
callback_params):
|
||||
"""callback_params:
|
||||
* None
|
||||
* {'': ((option, permissive),), 'ip': ((None,), (option, permissive))
|
||||
@ -742,9 +764,8 @@ class RegexpOption(Option):
|
||||
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
*args,
|
||||
**kwargs):
|
||||
err = self._impl_valid_string(value)
|
||||
if err:
|
||||
return err
|
||||
|
@ -22,7 +22,7 @@ from copy import copy
|
||||
|
||||
|
||||
from ..i18n import _
|
||||
from ..setting import groups, undefined, owners
|
||||
from ..setting import ConfigBag, groups, undefined, owners
|
||||
from .baseoption import BaseOption
|
||||
from .option import ALLOWED_CONST_LIST, DynSymLinkOption
|
||||
from .syndynoptiondescription import SynDynOptionDescription
|
||||
@ -54,7 +54,7 @@ class CacheOptionDescription(BaseOption):
|
||||
else:
|
||||
init = False
|
||||
|
||||
for option in self.impl_getchildren(setting_properties=undefined,
|
||||
for option in self.impl_getchildren(config_bag=undefined,
|
||||
dyn=False):
|
||||
cache_option.append(option)
|
||||
if path == '':
|
||||
@ -83,7 +83,8 @@ class CacheOptionDescription(BaseOption):
|
||||
'must be a master/slaves').format(
|
||||
option.impl_getname()))
|
||||
masterslaves = option.impl_get_master_slaves()
|
||||
for opt in all_cons_opts:
|
||||
for weak_opt in all_cons_opts:
|
||||
opt = weak_opt()
|
||||
if func not in ALLOWED_CONST_LIST and is_multi:
|
||||
if not opt.impl_is_master_slaves():
|
||||
raise ConfigError(_('malformed consistency option "{0}" '
|
||||
@ -93,7 +94,7 @@ class CacheOptionDescription(BaseOption):
|
||||
raise ConfigError(_('malformed consistency option "{0}" '
|
||||
'must be in same master/slaves for "{1}"').format(
|
||||
option.impl_getname(), opt.impl_getname()))
|
||||
_consistencies.setdefault(opt,
|
||||
_consistencies.setdefault(weak_opt,
|
||||
[]).append((func,
|
||||
all_cons_opts,
|
||||
params))
|
||||
@ -133,8 +134,9 @@ class CacheOptionDescription(BaseOption):
|
||||
raise ConflictError(_('duplicate option: {0}').format(opt))
|
||||
if _consistencies != {}:
|
||||
self._cache_consistencies = {}
|
||||
for opt, cons in _consistencies.items():
|
||||
if opt() not in cache_option: # pragma: optional cover
|
||||
for weak_opt, cons in _consistencies.items():
|
||||
opt = weak_opt()
|
||||
if opt not in cache_option: # pragma: optional cover
|
||||
raise ConfigError(_('consistency with option {0} '
|
||||
'which is not in Config').format(
|
||||
opt.impl_getname()))
|
||||
@ -165,12 +167,10 @@ class CacheOptionDescription(BaseOption):
|
||||
if force_store_values is False:
|
||||
raise Exception('ok ca existe ...')
|
||||
if force_store_values and not values._p_.hasvalue(subpath):
|
||||
value = values.getvalue(option,
|
||||
subpath,
|
||||
index=None,
|
||||
setting_properties=None,
|
||||
self_properties=None,
|
||||
validate=False)
|
||||
config_bag = ConfigBag(config=context, option=option)
|
||||
value = values.getvalue(subpath,
|
||||
None,
|
||||
config_bag)
|
||||
value_setted = True
|
||||
values._p_.setvalue(subpath,
|
||||
value,
|
||||
@ -197,7 +197,7 @@ class CacheOptionDescription(BaseOption):
|
||||
if cache_path is None:
|
||||
cache_path = []
|
||||
cache_option = []
|
||||
for option in self.impl_getchildren(setting_properties=undefined,
|
||||
for option in self.impl_getchildren(config_bag=undefined,
|
||||
dyn=False):
|
||||
attr = option.impl_getname()
|
||||
path = str('.'.join(_currpath + [attr]))
|
||||
@ -221,8 +221,7 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||
byname,
|
||||
_subpath,
|
||||
only_first,
|
||||
context,
|
||||
setting_properties):
|
||||
config_bag):
|
||||
find_results = []
|
||||
|
||||
def _rebuild_dynpath(path,
|
||||
@ -250,8 +249,7 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||
found = False
|
||||
if byname.startswith(name):
|
||||
subdyn = option._subdyn()
|
||||
for suffix in subdyn._impl_get_suffixes(context,
|
||||
setting_properties):
|
||||
for suffix in subdyn._impl_get_suffixes(config_bag):
|
||||
if byname == name + suffix:
|
||||
found = True
|
||||
path = _rebuild_dynpath(path,
|
||||
@ -282,8 +280,7 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||
if byname is None:
|
||||
if option._is_subdyn():
|
||||
name = option.impl_getname()
|
||||
for suffix in option._subdyn._impl_get_suffixes(context,
|
||||
setting_properties):
|
||||
for suffix in option._subdyn._impl_get_suffixes(config_bag):
|
||||
path = _rebuild_dynpath(path,
|
||||
suffix,
|
||||
option._subdyn)
|
||||
@ -318,8 +315,7 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||
if bytype == byname is None:
|
||||
if option._is_subdyn():
|
||||
name = option.impl_getname()
|
||||
for suffix in option._subdyn._impl_get_suffixes(context,
|
||||
setting_properties):
|
||||
for suffix in option._subdyn._impl_get_suffixes(config_bag):
|
||||
path = _rebuild_dynpath(path,
|
||||
suffix,
|
||||
option._subdyn)
|
||||
@ -342,7 +338,7 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||
|
||||
def impl_getchild(self,
|
||||
name,
|
||||
setting_properties,
|
||||
config_bag,
|
||||
subconfig):
|
||||
if name in self._children[0]:
|
||||
child = self._children[1][self._children[0].index(name)]
|
||||
@ -350,8 +346,8 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||
return child
|
||||
else:
|
||||
child = self._impl_search_dynchild(name,
|
||||
subconfig=subconfig,
|
||||
setting_properties=setting_properties)
|
||||
subconfig,
|
||||
config_bag)
|
||||
if child:
|
||||
return child
|
||||
raise AttributeError(_('unknown Option {0} '
|
||||
@ -375,14 +371,14 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||
return self._cache_paths[1][self._cache_paths[0].index(opt)]
|
||||
|
||||
def impl_getchildren(self,
|
||||
setting_properties,
|
||||
dyn=True,
|
||||
context=undefined):
|
||||
config_bag,
|
||||
dyn=True):
|
||||
for child in self._impl_st_getchildren():
|
||||
cname = child.impl_getname()
|
||||
if dyn and child.impl_is_dynoptiondescription():
|
||||
for value in child._impl_get_suffixes(context,
|
||||
setting_properties):
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.option = child
|
||||
for value in child._impl_get_suffixes(sconfig_bag):
|
||||
yield SynDynOptionDescription(child,
|
||||
cname + value,
|
||||
value)
|
||||
@ -398,12 +394,13 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||
def _impl_search_dynchild(self,
|
||||
name,
|
||||
subconfig,
|
||||
setting_properties):
|
||||
config_bag):
|
||||
for child in self._impl_st_getchildren(only_dyn=True):
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.option = child
|
||||
cname = child.impl_getname()
|
||||
if name.startswith(cname):
|
||||
for value in child._impl_get_suffixes(subconfig._cfgimpl_get_context(),
|
||||
setting_properties):
|
||||
for value in child._impl_get_suffixes(sconfig_bag):
|
||||
if name == cname + value:
|
||||
return SynDynOptionDescription(child,
|
||||
subconfig.cfgimpl_get_path(),
|
||||
@ -507,7 +504,6 @@ class OptionDescription(OptionDescriptionWalk):
|
||||
return self._group_type
|
||||
|
||||
def impl_validate_value(self,
|
||||
option,
|
||||
value,
|
||||
context):
|
||||
*args,
|
||||
**kwargs):
|
||||
pass
|
||||
|
@ -31,7 +31,6 @@ class PasswordOption(Option):
|
||||
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
*args,
|
||||
**kwargs):
|
||||
self._impl_valid_string(value)
|
||||
|
@ -98,9 +98,8 @@ class PortOption(Option):
|
||||
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
*args,
|
||||
**kwargs):
|
||||
if isinstance(value, int):
|
||||
value = str(value)
|
||||
self._impl_valid_string(value)
|
||||
|
@ -32,9 +32,8 @@ class StrOption(Option):
|
||||
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
*args,
|
||||
**kwargs):
|
||||
if not isinstance(value, str):
|
||||
raise ValueError()
|
||||
|
||||
|
@ -102,6 +102,14 @@ class DynSymLinkOption(object):
|
||||
name):
|
||||
return getattr(self._opt, name)
|
||||
|
||||
def __eq__(self, left):
|
||||
if not isinstance(left, DynSymLinkOption):
|
||||
return False
|
||||
return self._opt == left._opt and \
|
||||
self._rootpath == left._rootpath and \
|
||||
self._suffix == left._suffix
|
||||
return True
|
||||
|
||||
def impl_getname(self):
|
||||
return self._opt.impl_getname() + self._suffix
|
||||
|
||||
@ -122,21 +130,22 @@ class DynSymLinkOption(object):
|
||||
|
||||
def impl_validate(self,
|
||||
value,
|
||||
config_bag,
|
||||
context=undefined,
|
||||
force_index=None,
|
||||
current_opt=undefined,
|
||||
is_multi=None,
|
||||
check_error=True,
|
||||
multi=None,
|
||||
setting_properties=undefined):
|
||||
multi=None):
|
||||
# add current_opt !
|
||||
self._opt.impl_validate(value,
|
||||
config_bag,
|
||||
context,
|
||||
force_index,
|
||||
current_opt=self,
|
||||
is_multi=is_multi,
|
||||
check_error=check_error,
|
||||
multi=multi,
|
||||
setting_properties=setting_properties)
|
||||
multi=multi)
|
||||
|
||||
def impl_is_dynsymlinkoption(self):
|
||||
return True
|
||||
|
@ -45,7 +45,7 @@ class SynDynOptionDescription(object):
|
||||
|
||||
def impl_getchild(self,
|
||||
name,
|
||||
setting_properties,
|
||||
config_bag,
|
||||
subconfig):
|
||||
try:
|
||||
if name.endswith(self._suffix):
|
||||
@ -65,11 +65,10 @@ class SynDynOptionDescription(object):
|
||||
return self._opt.impl_getname() + self._suffix
|
||||
|
||||
def impl_getchildren(self,
|
||||
setting_properties,
|
||||
dyn=True,
|
||||
context=undefined):
|
||||
config_bag,
|
||||
dyn=True):
|
||||
children = []
|
||||
for child in self._opt.impl_getchildren(setting_properties):
|
||||
for child in self._opt.impl_getchildren(config_bag):
|
||||
yield(self._opt._impl_get_dynchild(child,
|
||||
self._suffix,
|
||||
self._subpath))
|
||||
|
@ -34,9 +34,8 @@ class URLOption(DomainnameOption):
|
||||
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
*args,
|
||||
**kwargs):
|
||||
self._impl_valid_string(value)
|
||||
match = self.proto_re.search(value)
|
||||
if not match:
|
||||
@ -62,9 +61,8 @@ class URLOption(DomainnameOption):
|
||||
'65536'))
|
||||
# validate domainname
|
||||
super(URLOption, self)._validate(domain,
|
||||
setting_properties,
|
||||
context,
|
||||
current_opt)
|
||||
*args,
|
||||
**kwargs)
|
||||
super(URLOption, self)._second_level_validation(domain, False)
|
||||
# validate file
|
||||
if files is not None and files != '' and not self.path_re.search(files):
|
||||
|
Reference in New Issue
Block a user