simplify consistency validation
reorder function (logical order) remove duplicate arity (context, config_bag, option_bag, ...) master cannot have length lower than slave length
This commit is contained in:
parent
1d6e0c0dcd
commit
b31a94e449
2 changed files with 317 additions and 337 deletions
|
@ -21,6 +21,7 @@
|
|||
# ____________________________________________________________
|
||||
import warnings
|
||||
import weakref
|
||||
from typing import Any, List, Callable, Optional
|
||||
|
||||
from .baseoption import OnlyOption, submulti, STATIC_TUPLE
|
||||
from ..i18n import _
|
||||
|
@ -197,7 +198,6 @@ class Option(OnlyOption):
|
|||
# just to check propertieserror
|
||||
self.valid_consistency(option_bag,
|
||||
value,
|
||||
context,
|
||||
check_error,
|
||||
is_warnings_only)
|
||||
return
|
||||
|
@ -302,7 +302,6 @@ class Option(OnlyOption):
|
|||
if not is_warnings_only or not check_error:
|
||||
self.valid_consistency(option_bag,
|
||||
value,
|
||||
context,
|
||||
check_error,
|
||||
is_warnings_only)
|
||||
except ValueError as err:
|
||||
|
@ -346,338 +345,6 @@ class Option(OnlyOption):
|
|||
"accesses the Option's doc"
|
||||
return self.impl_get_information('doc')
|
||||
|
||||
def _valid_consistencies(self,
|
||||
other_opts,
|
||||
init=True,
|
||||
func=None):
|
||||
if self.issubdyn():
|
||||
dynod = self.getsubdyn()
|
||||
else:
|
||||
dynod = None
|
||||
if self.impl_is_submulti():
|
||||
raise ConfigError(_('cannot add consistency with submulti option'))
|
||||
is_multi = self.impl_is_multi()
|
||||
for opt in other_opts:
|
||||
if isinstance(opt, weakref.ReferenceType):
|
||||
opt = opt()
|
||||
if opt.impl_is_submulti(): # pragma: no cover
|
||||
raise ConfigError(_('cannot add consistency with submulti option'))
|
||||
if not isinstance(opt, Option): # pragma: no cover
|
||||
raise ConfigError(_('consistency must be set with an option, not {}').format(opt))
|
||||
if opt.issubdyn():
|
||||
if dynod is None:
|
||||
raise ConfigError(_('almost one option in consistency is '
|
||||
'in a dynoptiondescription but not all'))
|
||||
subod = opt.getsubdyn()
|
||||
if dynod != subod:
|
||||
raise ConfigError(_('option in consistency must be in same'
|
||||
' dynoptiondescription'))
|
||||
dynod = subod
|
||||
elif dynod is not None:
|
||||
raise ConfigError(_('almost one option in consistency is in a '
|
||||
'dynoptiondescription but not all'))
|
||||
if self is opt:
|
||||
raise ConfigError(_('cannot add consistency with itself'))
|
||||
if is_multi != opt.impl_is_multi():
|
||||
raise ConfigError(_('every options in consistency must be '
|
||||
'multi or none'))
|
||||
if init:
|
||||
# FIXME
|
||||
if func != 'not_equal':
|
||||
opt._has_dependency = True
|
||||
|
||||
def impl_add_consistency(self,
|
||||
func,
|
||||
*other_opts,
|
||||
**params):
|
||||
"""Add consistency means that value will be validate with other_opts
|
||||
option's values.
|
||||
|
||||
:param func: function's name
|
||||
:type func: `str`
|
||||
:param other_opts: options used to validate value
|
||||
:type other_opts: `list` of `tiramisu.option.Option`
|
||||
:param params: extra params (warnings_only and transitive are allowed)
|
||||
"""
|
||||
if self.impl_is_readonly():
|
||||
raise AttributeError(_("'{0}' ({1}) cannot add consistency, option is"
|
||||
" read-only").format(
|
||||
self.__class__.__name__,
|
||||
self.impl_getname()))
|
||||
self._valid_consistencies(other_opts,
|
||||
func=func)
|
||||
func = '_cons_{0}'.format(func)
|
||||
if func not in dir(self):
|
||||
raise ConfigError(_('consistency {0} not available for this option').format(func))
|
||||
options = [weakref.ref(self)]
|
||||
for option in other_opts:
|
||||
options.append(weakref.ref(option))
|
||||
all_cons_opts = tuple(options)
|
||||
unknown_params = set(params.keys()) - set(['warnings_only', 'transitive'])
|
||||
if unknown_params != set():
|
||||
raise ValueError(_('unknown parameter {0} in consistency').format(unknown_params))
|
||||
self._add_consistency(func,
|
||||
all_cons_opts,
|
||||
params)
|
||||
#validate default value when add consistency
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(self,
|
||||
undefined,
|
||||
None,
|
||||
undefined)
|
||||
self.impl_validate(self.impl_getdefault(),
|
||||
option_bag)
|
||||
self.impl_validate(self.impl_getdefault(),
|
||||
option_bag,
|
||||
check_error=False)
|
||||
if func != '_cons_not_equal':
|
||||
#consistency could generate warnings or errors
|
||||
self._has_dependency = True
|
||||
for wopt in all_cons_opts:
|
||||
opt = wopt()
|
||||
if func in ALLOWED_CONST_LIST:
|
||||
if getattr(opt, '_unique', undefined) == undefined:
|
||||
opt._unique = True
|
||||
if opt != self:
|
||||
self._add_dependency(opt)
|
||||
opt._add_dependency(self)
|
||||
|
||||
def valid_consistency(self,
|
||||
option_bag,
|
||||
value,
|
||||
context,
|
||||
check_error,
|
||||
option_warnings_only):
|
||||
if context is not undefined:
|
||||
descr = context.cfgimpl_get_description()
|
||||
# no consistency found at all
|
||||
if descr._cache_consistencies is None:
|
||||
return
|
||||
# get consistencies for this option
|
||||
if option_bag.option.impl_is_dynsymlinkoption():
|
||||
consistencies = descr._cache_consistencies.get(option_bag.option.impl_getopt())
|
||||
else:
|
||||
consistencies = descr._cache_consistencies.get(option_bag.option)
|
||||
else:
|
||||
# is no context, get consistencies in option
|
||||
consistencies = option_bag.option.get_consistencies()
|
||||
if consistencies:
|
||||
if option_bag.config_bag is undefined:
|
||||
cconfig_bag = undefined
|
||||
else:
|
||||
cconfig_bag = option_bag.config_bag.copy()
|
||||
cconfig_bag.properties = cconfig_bag.properties - {'warnings'}
|
||||
cconfig_bag.set_permissive()
|
||||
if not option_bag.fromconsistency:
|
||||
fromconsistency_is_empty = True
|
||||
option_bag.fromconsistency = [cons_id for cons_id, f, a, p in consistencies]
|
||||
else:
|
||||
fromconsistency_is_empty = False
|
||||
for cons_id, func, all_cons_opts, params in consistencies:
|
||||
if not fromconsistency_is_empty and cons_id in option_bag.fromconsistency:
|
||||
return
|
||||
warnings_only = option_warnings_only or params.get('warnings_only', False)
|
||||
if (warnings_only and not check_error) or (not warnings_only and check_error):
|
||||
transitive = params.get('transitive', True)
|
||||
#all_cons_opts[0] is the option where func is set
|
||||
if option_bag.ori_option.impl_is_dynsymlinkoption():
|
||||
opts = []
|
||||
for opt in all_cons_opts:
|
||||
opts.append(opt().impl_get_dynoption(option_bag.ori_option._rootpath,
|
||||
option_bag.ori_option._suffix))
|
||||
wopt = opts[0]
|
||||
else:
|
||||
opts = all_cons_opts
|
||||
wopt = opts[0]()
|
||||
wopt.launch_consistency(self,
|
||||
func,
|
||||
cons_id,
|
||||
option_bag,
|
||||
value,
|
||||
context,
|
||||
opts,
|
||||
warnings_only,
|
||||
transitive,
|
||||
cconfig_bag)
|
||||
if fromconsistency_is_empty:
|
||||
option_bag.fromconsistency = []
|
||||
|
||||
def _get_consistency_value(self,
|
||||
index,
|
||||
current_option,
|
||||
fromoption,
|
||||
fromconsistency,
|
||||
cons_id,
|
||||
context,
|
||||
config_bag,
|
||||
value,
|
||||
func):
|
||||
if func in ALLOWED_CONST_LIST:
|
||||
index = None
|
||||
index_ = None
|
||||
elif not current_option.impl_is_master_slaves('slave'):
|
||||
index_ = None
|
||||
else:
|
||||
index_ = index
|
||||
if fromoption == current_option:
|
||||
# orig_option is current option
|
||||
# we have already value, so use it
|
||||
return value
|
||||
if context is undefined:
|
||||
#if no context get default value
|
||||
return current_option.impl_getdefault()
|
||||
#otherwise calculate value
|
||||
path = current_option.impl_getpath()
|
||||
coption_bag = OptionBag()
|
||||
coption_bag.set_option(current_option,
|
||||
path,
|
||||
index_,
|
||||
config_bag)
|
||||
fromconsistency.append(cons_id)
|
||||
coption_bag.fromconsistency = fromconsistency
|
||||
|
||||
opt_value = context.getattr(path,
|
||||
coption_bag)
|
||||
if index_ is None and index is not None:
|
||||
if len(opt_value) <= index:
|
||||
opt_value = current_option.impl_getdefault_multi()
|
||||
else:
|
||||
opt_value = opt_value[index]
|
||||
return opt_value
|
||||
|
||||
def launch_consistency(self,
|
||||
current_opt,
|
||||
func,
|
||||
cons_id,
|
||||
option_bag,
|
||||
value,
|
||||
context,
|
||||
opts,
|
||||
warnings_only,
|
||||
transitive,
|
||||
config_bag):
|
||||
"""Launch consistency now
|
||||
|
||||
:param func: function name, this name should start with _cons_
|
||||
:type func: `str`
|
||||
:param option: option that value is changing
|
||||
:type option: `tiramisu.option.Option`
|
||||
:param value: new value of this opion
|
||||
:param context: Config's context, if None, check default value instead
|
||||
:type context: `tiramisu.config.Config`
|
||||
:param index: only for multi option, consistency should be launch for
|
||||
specified index
|
||||
:type index: `int`
|
||||
:param opts: all options concerne by this consistency
|
||||
:type opts: `list` of `tiramisu.option.Option`
|
||||
:param warnings_only: specific raise error for warning
|
||||
:type warnings_only: `boolean`
|
||||
:param transitive: propertyerror is transitive
|
||||
:type transitive: `boolean`
|
||||
"""
|
||||
all_cons_vals = []
|
||||
all_cons_opts = []
|
||||
length = None
|
||||
for opt in opts:
|
||||
if isinstance(opt, weakref.ReferenceType):
|
||||
opt = opt()
|
||||
try:
|
||||
opt_value = self._get_consistency_value(option_bag.index,
|
||||
opt,
|
||||
option_bag.ori_option,
|
||||
option_bag.fromconsistency.copy(),
|
||||
cons_id,
|
||||
context,
|
||||
config_bag,
|
||||
value,
|
||||
func)
|
||||
except PropertiesOptionError as err:
|
||||
if debug: # pragma: no cover
|
||||
log.debug('propertyerror in launch_consistency: {0}'.format(err))
|
||||
if transitive:
|
||||
err.set_orig_opt(option_bag.option)
|
||||
raise err
|
||||
else:
|
||||
if opt.impl_is_multi() and option_bag.index is None and \
|
||||
func not in ALLOWED_CONST_LIST:
|
||||
len_value = len(opt_value)
|
||||
if length is not None and length != len_value:
|
||||
if context is undefined:
|
||||
return
|
||||
raise ValueError(_('unexpected length of "{}" in constency "{}", '
|
||||
'should be "{}"').format(len(opt_value),
|
||||
opt.impl_get_display_name(),
|
||||
length)) # pragma: no cover
|
||||
length = len_value
|
||||
if isinstance(opt_value, list) and func in ALLOWED_CONST_LIST:
|
||||
for value_ in opt_value:
|
||||
all_cons_vals.append(value_)
|
||||
all_cons_opts.append(opt)
|
||||
else:
|
||||
all_cons_vals.append(opt_value)
|
||||
all_cons_opts.append(opt)
|
||||
if config_bag is not undefined and not 'validator' in config_bag.properties:
|
||||
return
|
||||
all_values = []
|
||||
if length is None:
|
||||
all_values = [all_cons_vals]
|
||||
elif length:
|
||||
all_values = zip(*all_cons_vals)
|
||||
try:
|
||||
for values in all_values:
|
||||
getattr(self, func)(current_opt,
|
||||
all_cons_opts,
|
||||
values,
|
||||
warnings_only,
|
||||
context)
|
||||
except ValueError as err:
|
||||
if warnings_only:
|
||||
msg = _('attention, "{0}" could be an invalid {1} for "{2}", {3}'
|
||||
'').format(value,
|
||||
self._display_name,
|
||||
current_opt.impl_get_display_name(),
|
||||
err)
|
||||
warnings.warn_explicit(ValueWarning(msg, weakref.ref(self)),
|
||||
ValueWarning,
|
||||
self.__class__.__name__, 0)
|
||||
else:
|
||||
raise err
|
||||
|
||||
def _cons_not_equal(self,
|
||||
current_opt,
|
||||
opts,
|
||||
vals,
|
||||
warnings_only,
|
||||
context):
|
||||
equal = []
|
||||
is_current = False
|
||||
for idx_inf, val_inf in enumerate(vals):
|
||||
for idx_sup, val_sup in enumerate(vals[idx_inf + 1:]):
|
||||
if val_inf == val_sup is not None:
|
||||
for opt_ in [opts[idx_inf], opts[idx_inf + idx_sup + 1]]:
|
||||
if opt_ == current_opt:
|
||||
is_current = True
|
||||
else:
|
||||
if opt_ not in equal:
|
||||
equal.append(opt_)
|
||||
if equal:
|
||||
if debug: # pragma: no cover
|
||||
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 "{}"')
|
||||
else:
|
||||
msg = _('must be different from the value of "{}"')
|
||||
else:
|
||||
if warnings_only:
|
||||
msg = _('value for {} should be different')
|
||||
else:
|
||||
msg = _('value for {} must be different')
|
||||
equal_name = []
|
||||
for opt in equal:
|
||||
equal_name.append(opt.impl_get_display_name())
|
||||
raise ValueError(msg.format(display_list(list(equal_name))))
|
||||
|
||||
def _second_level_validation(self,
|
||||
value,
|
||||
warnings_only):
|
||||
|
@ -737,14 +404,110 @@ class Option(OnlyOption):
|
|||
|
||||
def impl_allow_empty_list(self):
|
||||
return getattr(self, '_allow_empty_list', undefined)
|
||||
|
||||
#____________________________________________________________
|
||||
# consistency
|
||||
# consistencies
|
||||
|
||||
def impl_add_consistency(self,
|
||||
func,
|
||||
*other_opts,
|
||||
**params):
|
||||
"""Add consistency means that value will be validate with other_opts
|
||||
option's values.
|
||||
|
||||
:param func: function's name
|
||||
:type func: `str`
|
||||
:param other_opts: options used to validate value
|
||||
:type other_opts: `list` of `tiramisu.option.Option`
|
||||
:param params: extra params (warnings_only and transitive are allowed)
|
||||
"""
|
||||
if self.impl_is_readonly():
|
||||
raise AttributeError(_("'{0}' ({1}) cannot add consistency, option is"
|
||||
" read-only").format(
|
||||
self.__class__.__name__,
|
||||
self.impl_getname()))
|
||||
self._valid_consistencies(other_opts,
|
||||
func=func)
|
||||
func = '_cons_{0}'.format(func)
|
||||
if func not in dir(self):
|
||||
raise ConfigError(_('consistency {0} not available for this option').format(func))
|
||||
options = [weakref.ref(self)]
|
||||
for option in other_opts:
|
||||
options.append(weakref.ref(option))
|
||||
all_cons_opts = tuple(options)
|
||||
unknown_params = set(params.keys()) - set(['warnings_only', 'transitive'])
|
||||
if unknown_params != set():
|
||||
raise ValueError(_('unknown parameter {0} in consistency').format(unknown_params))
|
||||
self._add_consistency(func,
|
||||
all_cons_opts,
|
||||
params)
|
||||
#validate default value when add consistency
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(self,
|
||||
undefined,
|
||||
None,
|
||||
undefined)
|
||||
self.impl_validate(self.impl_getdefault(),
|
||||
option_bag)
|
||||
self.impl_validate(self.impl_getdefault(),
|
||||
option_bag,
|
||||
check_error=False)
|
||||
if func != '_cons_not_equal':
|
||||
#consistency could generate warnings or errors
|
||||
self._has_dependency = True
|
||||
for wopt in all_cons_opts:
|
||||
opt = wopt()
|
||||
if func in ALLOWED_CONST_LIST:
|
||||
if getattr(opt, '_unique', undefined) == undefined:
|
||||
opt._unique = True
|
||||
if opt != self:
|
||||
self._add_dependency(opt)
|
||||
opt._add_dependency(self)
|
||||
|
||||
def _valid_consistencies(self,
|
||||
other_opts,
|
||||
init=True,
|
||||
func=None):
|
||||
if self.issubdyn():
|
||||
dynod = self.getsubdyn()
|
||||
else:
|
||||
dynod = None
|
||||
if self.impl_is_submulti():
|
||||
raise ConfigError(_('cannot add consistency with submulti option'))
|
||||
is_multi = self.impl_is_multi()
|
||||
for opt in other_opts:
|
||||
if isinstance(opt, weakref.ReferenceType):
|
||||
opt = opt()
|
||||
if opt.impl_is_submulti(): # pragma: no cover
|
||||
raise ConfigError(_('cannot add consistency with submulti option'))
|
||||
if not isinstance(opt, Option): # pragma: no cover
|
||||
raise ConfigError(_('consistency must be set with an option, not {}').format(opt))
|
||||
if opt.issubdyn():
|
||||
if dynod is None:
|
||||
raise ConfigError(_('almost one option in consistency is '
|
||||
'in a dynoptiondescription but not all'))
|
||||
subod = opt.getsubdyn()
|
||||
if dynod != subod:
|
||||
raise ConfigError(_('option in consistency must be in same'
|
||||
' dynoptiondescription'))
|
||||
dynod = subod
|
||||
elif dynod is not None:
|
||||
raise ConfigError(_('almost one option in consistency is in a '
|
||||
'dynoptiondescription but not all'))
|
||||
if self is opt:
|
||||
raise ConfigError(_('cannot add consistency with itself'))
|
||||
if is_multi != opt.impl_is_multi():
|
||||
raise ConfigError(_('every options in consistency must be '
|
||||
'multi or none'))
|
||||
if init:
|
||||
# FIXME
|
||||
if func != 'not_equal':
|
||||
opt._has_dependency = True
|
||||
|
||||
def _add_consistency(self,
|
||||
func,
|
||||
all_cons_opts,
|
||||
params):
|
||||
cons = (None, func, all_cons_opts, params)
|
||||
cons = (-1, func, all_cons_opts, params)
|
||||
consistencies = getattr(self, '_consistencies', None)
|
||||
if consistencies is None:
|
||||
self._consistencies = [cons]
|
||||
|
@ -760,6 +523,218 @@ class Option(OnlyOption):
|
|||
return False
|
||||
return self in descr._cache_consistencies
|
||||
|
||||
def valid_consistency(self,
|
||||
option_bag,
|
||||
value,
|
||||
check_error,
|
||||
option_warnings_only):
|
||||
if option_bag.config_bag is not undefined:
|
||||
descr = option_bag.config_bag.context.cfgimpl_get_description()
|
||||
# no consistency found at all
|
||||
if descr._cache_consistencies is None:
|
||||
return
|
||||
# get consistencies for this option
|
||||
if option_bag.option.impl_is_dynsymlinkoption():
|
||||
consistencies = descr._cache_consistencies.get(option_bag.option.impl_getopt())
|
||||
else:
|
||||
consistencies = descr._cache_consistencies.get(option_bag.option)
|
||||
else:
|
||||
# is no context, get consistencies in option
|
||||
consistencies = option_bag.option.get_consistencies()
|
||||
if consistencies:
|
||||
if option_bag.config_bag is undefined:
|
||||
coption_bag = option_bag.copy()
|
||||
else:
|
||||
cconfig_bag = option_bag.config_bag.copy()
|
||||
cconfig_bag.remove_warnings()
|
||||
cconfig_bag.set_permissive()
|
||||
coption_bag = option_bag.copy()
|
||||
coption_bag.config_bag = cconfig_bag
|
||||
if not option_bag.fromconsistency:
|
||||
fromconsistency_is_empty = True
|
||||
option_bag.fromconsistency = [cons_id for cons_id, f, a, p in consistencies]
|
||||
else:
|
||||
fromconsistency_is_empty = False
|
||||
for cons_id, func, all_cons_opts, params in consistencies:
|
||||
if not fromconsistency_is_empty and cons_id in option_bag.fromconsistency:
|
||||
continue
|
||||
warnings_only = option_warnings_only or params.get('warnings_only', False)
|
||||
if (warnings_only and not check_error) or (not warnings_only and check_error):
|
||||
transitive = params.get('transitive', True)
|
||||
#all_cons_opts[0] is the option where func is set
|
||||
if option_bag.ori_option.impl_is_dynsymlinkoption():
|
||||
opts = []
|
||||
for opt in all_cons_opts:
|
||||
opts.append(opt().impl_get_dynoption(option_bag.ori_option._rootpath,
|
||||
option_bag.ori_option._suffix))
|
||||
wopt = opts[0]
|
||||
else:
|
||||
opts = all_cons_opts
|
||||
wopt = opts[0]()
|
||||
wopt.launch_consistency(self,
|
||||
func,
|
||||
cons_id,
|
||||
coption_bag,
|
||||
value,
|
||||
opts,
|
||||
warnings_only,
|
||||
transitive)
|
||||
if fromconsistency_is_empty:
|
||||
option_bag.fromconsistency = []
|
||||
|
||||
def launch_consistency(self,
|
||||
current_opt: OnlyOption,
|
||||
func: Callable,
|
||||
cons_id: int,
|
||||
option_bag: OptionBag,
|
||||
value: Any,
|
||||
opts: List[OnlyOption],
|
||||
warnings_only: bool,
|
||||
transitive: bool):
|
||||
"""Launch consistency now
|
||||
"""
|
||||
all_cons_vals = []
|
||||
all_cons_opts = []
|
||||
length = None
|
||||
for opt in opts:
|
||||
if isinstance(opt, weakref.ReferenceType):
|
||||
opt = opt()
|
||||
try:
|
||||
opt_value = self.get_consistency_value(option_bag,
|
||||
opt,
|
||||
cons_id,
|
||||
value,
|
||||
func)
|
||||
except PropertiesOptionError as err:
|
||||
if debug: # pragma: no cover
|
||||
log.debug('propertyerror in launch_consistency: {0}'.format(err))
|
||||
if transitive:
|
||||
err.set_orig_opt(option_bag.option)
|
||||
raise err
|
||||
else:
|
||||
if opt.impl_is_multi() and option_bag.index is None and \
|
||||
func not in ALLOWED_CONST_LIST:
|
||||
len_value = len(opt_value)
|
||||
if length is not None and length != len_value:
|
||||
if option_bag.config_bag is undefined:
|
||||
return
|
||||
raise ValueError(_('unexpected length of "{}" in constency "{}", '
|
||||
'should be "{}"').format(len(opt_value),
|
||||
opt.impl_get_display_name(),
|
||||
length)) # pragma: no cover
|
||||
length = len_value
|
||||
if isinstance(opt_value, list) and func in ALLOWED_CONST_LIST:
|
||||
for value_ in opt_value:
|
||||
all_cons_vals.append(value_)
|
||||
all_cons_opts.append(opt)
|
||||
else:
|
||||
all_cons_vals.append(opt_value)
|
||||
all_cons_opts.append(opt)
|
||||
if option_bag.config_bag is not undefined and \
|
||||
not 'validator' in option_bag.config_bag.properties:
|
||||
return
|
||||
all_values = []
|
||||
if length is None:
|
||||
all_values = [all_cons_vals]
|
||||
elif length:
|
||||
all_values = zip(*all_cons_vals)
|
||||
try:
|
||||
context = option_bag.config_bag if option_bag.config_bag is undefined else option_bag.config_bag.context
|
||||
for values in all_values:
|
||||
getattr(self, func)(current_opt,
|
||||
all_cons_opts,
|
||||
values,
|
||||
warnings_only,
|
||||
context)
|
||||
except ValueError as err:
|
||||
if warnings_only:
|
||||
msg = _('attention, "{0}" could be an invalid {1} for "{2}", {3}'
|
||||
'').format(value,
|
||||
self._display_name,
|
||||
current_opt.impl_get_display_name(),
|
||||
err)
|
||||
warnings.warn_explicit(ValueWarning(msg, weakref.ref(self)),
|
||||
ValueWarning,
|
||||
self.__class__.__name__, 0)
|
||||
else:
|
||||
raise err
|
||||
|
||||
def get_consistency_value(self,
|
||||
option_bag,
|
||||
current_option,
|
||||
cons_id,
|
||||
value,
|
||||
func):
|
||||
if func in ALLOWED_CONST_LIST:
|
||||
index = None
|
||||
index_ = None
|
||||
elif current_option.impl_is_master_slaves('master'):
|
||||
index = option_bag.index
|
||||
index_ = None
|
||||
else:
|
||||
index = option_bag.index
|
||||
index_ = index
|
||||
if option_bag.ori_option == current_option:
|
||||
# orig_option is current option
|
||||
# we have already value, so use it
|
||||
return value
|
||||
if option_bag.config_bag is undefined:
|
||||
#if no context get default value
|
||||
return current_option.impl_getdefault()
|
||||
#otherwise calculate value
|
||||
path = current_option.impl_getpath()
|
||||
coption_bag = OptionBag()
|
||||
coption_bag.set_option(current_option,
|
||||
path,
|
||||
index_,
|
||||
option_bag.config_bag)
|
||||
fromconsistency = option_bag.fromconsistency.copy()
|
||||
fromconsistency.append(cons_id)
|
||||
coption_bag.fromconsistency = fromconsistency
|
||||
current_value = option_bag.config_bag.context.getattr(path,
|
||||
coption_bag)
|
||||
if index_ is None and index is not None:
|
||||
#if self is a slave and current_option is a master and func not in ALLOWED_CONST_LIST
|
||||
#return only the value of the master for isolate slave
|
||||
current_value = current_value[index]
|
||||
return current_value
|
||||
|
||||
def _cons_not_equal(self,
|
||||
current_opt,
|
||||
opts,
|
||||
vals,
|
||||
warnings_only,
|
||||
context):
|
||||
equal = []
|
||||
is_current = False
|
||||
for idx_inf, val_inf in enumerate(vals):
|
||||
for idx_sup, val_sup in enumerate(vals[idx_inf + 1:]):
|
||||
if val_inf == val_sup is not None:
|
||||
for opt_ in [opts[idx_inf], opts[idx_inf + idx_sup + 1]]:
|
||||
if opt_ == current_opt:
|
||||
is_current = True
|
||||
else:
|
||||
if opt_ not in equal:
|
||||
equal.append(opt_)
|
||||
if equal:
|
||||
if debug: # pragma: no cover
|
||||
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 "{}"')
|
||||
else:
|
||||
msg = _('must be different from the value of "{}"')
|
||||
else:
|
||||
if warnings_only:
|
||||
msg = _('value for {} should be different')
|
||||
else:
|
||||
msg = _('value for {} must be different')
|
||||
equal_name = []
|
||||
for opt in equal:
|
||||
equal_name.append(opt.impl_get_display_name())
|
||||
raise ValueError(msg.format(display_list(list(equal_name))))
|
||||
|
||||
|
||||
|
||||
class RegexpOption(Option):
|
||||
__slots__ = tuple()
|
||||
|
|
|
@ -165,6 +165,8 @@ class OptionBag:
|
|||
kwargs = {}
|
||||
option_bag = OptionBag()
|
||||
for key in self.__slots__:
|
||||
if key == 'properties' and self.config_bag is undefined:
|
||||
continue
|
||||
setattr(option_bag, key, getattr(self, key))
|
||||
return option_bag
|
||||
|
||||
|
@ -188,6 +190,9 @@ class ConfigBag:
|
|||
return self.permissives
|
||||
raise KeyError('unknown key {} for ConfigBag'.format(key)) # pragma: no cover
|
||||
|
||||
def remove_warnings(self):
|
||||
self.properties = frozenset(self.properties - {'warnings'})
|
||||
|
||||
def remove_validation(self):
|
||||
self.properties = frozenset(self.properties - {'validator'})
|
||||
|
||||
|
|
Loading…
Reference in a new issue