consistency "not_equal" works now with multi

This commit is contained in:
2016-11-16 22:31:42 +01:00
parent 8249b8eb20
commit fc36f674eb
7 changed files with 266 additions and 151 deletions

View File

@ -32,12 +32,17 @@ from ..storage import get_storages_option
from . import MasterSlaves
if sys.version_info[0] >= 3: # pragma: optional cover
xrange = range
StorageBase = get_storages_option('base')
submulti = 2
name_regexp = re.compile(r'^[a-z][a-zA-Z\d\-_]*$')
forbidden_names = frozenset(['iter_all', 'iter_group', 'find', 'find_first',
'make_dict', 'unwrap_from_path', 'read_only',
'read_write', 'getowner', 'set_contexts'])
allowed_const_list = ['_cons_not_equal']
def valid_name(name):
@ -382,7 +387,7 @@ class Option(OnlyOption):
_empty = ''
def _launch_consistency(self, current_opt, func, option, value, context,
index, submulti_index, all_cons_opts, warnings_only,
index, submulti_index, opts, warnings_only,
transitive):
"""Launch consistency now
@ -396,8 +401,8 @@ class Option(OnlyOption):
:param index: only for multi option, consistency should be launch for
specified index
:type index: `int`
:param all_cons_opts: all options concerne by this consistency
:type all_cons_opts: `list` of `tiramisu.option.Option`
: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
@ -407,14 +412,16 @@ class Option(OnlyOption):
descr = context.cfgimpl_get_description()
all_cons_vals = []
all_cons_opts = []
val_consistencies = True
for opt in all_cons_opts:
if (isinstance(opt, DynSymLinkOption) and option._dyn == opt._dyn) or \
option == opt:
for opt in opts:
is_multi = opt.impl_is_multi() and not opt.impl_is_master_slaves()
if not is_multi and ((isinstance(opt, DynSymLinkOption) and option._dyn == opt._dyn) or \
option == opt):
# option is current option
# we have already value, so use it
all_cons_vals.append(value)
all_cons_opts.append(opt)
else:
#if context, calculate value, otherwise get default value
path = None
@ -423,8 +430,12 @@ class Option(OnlyOption):
path = opt.impl_getpath(context)
else:
path = descr.impl_get_path_by_opt(opt)
if is_multi:
_index = None
else:
_index = index
opt_value = context.getattr(path, validate=False,
index=index,
index=_index,
force_permissive=True,
returns_raise=True)
if isinstance(opt_value, Exception):
@ -445,7 +456,13 @@ class Option(OnlyOption):
if self.impl_is_multi() and index is None:
# only check propertyerror for master/slaves is transitive
val_consistencies = False
all_cons_vals.append(opt_value)
if is_multi and isinstance(opt_value, list):
all_cons_vals.extend(opt_value)
for len_ in xrange(len(opt_value)):
all_cons_opts.append(opt)
else:
all_cons_vals.append(opt_value)
all_cons_opts.append(opt)
if val_consistencies:
return getattr(self, func)(current_opt, all_cons_opts, all_cons_vals, warnings_only)
@ -750,17 +767,21 @@ class Option(OnlyOption):
for opt_ in [opts[idx_inf], opts[idx_inf + idx_sup + 1]]:
if opt_ == current_opt:
is_current = True
else:
equal.add('"{}"'.format(opt_.impl_get_display_name()))
equal.add('"{}"'.format(opt_.impl_get_display_name()))
if equal:
if debug:
log.debug(_('_cons_not_equal: {} are not different').format(display_list(list(equal))))
if is_current:
if warnings_only:
msg = _('should be different from the value of {}')
equal.remove('"' + current_opt.impl_get_display_name() + '"')
if len(equal) == 0:
msg = _('this value is already present')
return ValueError(msg)
else:
msg = _('must be different from the value of {}')
return ValueError(msg.format(display_list(list(equal))))
if warnings_only:
msg = _('should be different from the value of {}')
else:
msg = _('must be different from the value of {}')
return ValueError(msg.format(display_list(list(equal))))
else:
if warnings_only:
msg = _('value for {} should be different')

View File

@ -24,7 +24,7 @@ import re
from ..i18n import _
from ..setting import groups, undefined, owners # , log
from .baseoption import BaseOption, SymLinkOption, Option
from .baseoption import BaseOption, SymLinkOption, Option, allowed_const_list
from . import MasterSlaves
from ..error import ConfigError, ConflictError
from ..storage import get_storages_option
@ -131,22 +131,22 @@ class OptionDescription(BaseOption, StorageOptionDescription):
force_store_values.append((subpath, option))
for func, all_cons_opts, params in option._get_consistencies():
option._valid_consistencies(all_cons_opts[1:], init=False)
if is_multi:
if func not in allowed_const_list and is_multi:
is_slave = option.impl_is_master_slaves()
if not is_slave:
raise ValueError(_('malformed consistency option {0} '
raise ValueError(_('malformed consistency option "{0}" '
'must be a master/slaves').format(
option.impl_getname()))
masterslaves = option.impl_get_master_slaves()
for opt in all_cons_opts:
if is_multi:
if func not in allowed_const_list and is_multi:
if not opt.impl_is_master_slaves():
raise ValueError(_('malformed consistency option {0} '
'must not be a multi for {1}').format(
raise ValueError(_('malformed consistency option "{0}" '
'must not be a multi for "{1}"').format(
option.impl_getname(), opt.impl_getname()))
elif masterslaves != opt.impl_get_master_slaves():
raise ValueError(_('malformed consistency option {0} '
'must be in same master/slaves for {1}').format(
raise ValueError(_('malformed consistency option "{0}" '
'must be in same master/slaves for "{1}"').format(
option.impl_getname(), opt.impl_getname()))
_consistencies.setdefault(opt,
[]).append((func,