reorganise consistencies
This commit is contained in:
parent
7ab479f628
commit
a9fed78af0
|
@ -801,18 +801,18 @@ def test_consistency_warnings_error():
|
||||||
assert w == []
|
assert w == []
|
||||||
|
|
||||||
|
|
||||||
#def test_consistency_network_netmask_mandatory():
|
def test_consistency_network_netmask_mandatory():
|
||||||
# a = NetworkOption('a', '', multi=True, properties=('mandatory',), default=[u'0.0.0.0'])
|
a = NetworkOption('a', '', multi=True, properties=('mandatory',), default=[u'0.0.0.0'])
|
||||||
# b = NetmaskOption('b', '', multi=True, properties=('mandatory',), default_multi=u'0.0.0.0')
|
b = NetmaskOption('b', '', multi=True, properties=('mandatory',), default_multi=u'0.0.0.0')
|
||||||
# od = MasterSlaves('a', '', [a, b])
|
od = MasterSlaves('a', '', [a, b])
|
||||||
# b.impl_add_consistency('network_netmask', a)
|
b.impl_add_consistency('network_netmask', a)
|
||||||
# od2 = OptionDescription('od2', '', [od])
|
od2 = OptionDescription('od2', '', [od])
|
||||||
# api = getapi(Config(od2))
|
api = getapi(Config(od2))
|
||||||
# api.property.read_only()
|
api.property.read_only()
|
||||||
# api.property.pop('mandatory')
|
api.property.pop('mandatory')
|
||||||
# api.option.make_dict()
|
api.option.make_dict()
|
||||||
#
|
|
||||||
#
|
|
||||||
def test_consistency_has_dependency():
|
def test_consistency_has_dependency():
|
||||||
a = IPOption('a', '')
|
a = IPOption('a', '')
|
||||||
b = NetmaskOption('b', '')
|
b = NetmaskOption('b', '')
|
||||||
|
|
|
@ -170,142 +170,6 @@ class Option(OnlyOption):
|
||||||
**kwargs):
|
**kwargs):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _launch_consistency(self,
|
|
||||||
current_opt,
|
|
||||||
func,
|
|
||||||
cons_id,
|
|
||||||
option,
|
|
||||||
value,
|
|
||||||
context,
|
|
||||||
index,
|
|
||||||
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`
|
|
||||||
"""
|
|
||||||
if context is not undefined:
|
|
||||||
descr = context.cfgimpl_get_description()
|
|
||||||
if config_bag is not undefined and cons_id in config_bag.fromconsistency:
|
|
||||||
return
|
|
||||||
all_cons_vals = []
|
|
||||||
all_cons_opts = []
|
|
||||||
length = None
|
|
||||||
for opt in opts:
|
|
||||||
if isinstance(opt, weakref.ReferenceType):
|
|
||||||
opt = opt()
|
|
||||||
if option == opt:
|
|
||||||
# option is current option
|
|
||||||
# we have already value, so use it
|
|
||||||
opt_value = value
|
|
||||||
elif context is undefined:
|
|
||||||
opt_value = opt.impl_getdefault()
|
|
||||||
else:
|
|
||||||
#if context, calculate value, otherwise get default value
|
|
||||||
sconfig_bag = config_bag.copy('nooption')
|
|
||||||
sconfig_bag.option = opt
|
|
||||||
sconfig_bag.fromconsistency.append(cons_id)
|
|
||||||
sconfig_bag.force_permissive = True
|
|
||||||
path = opt.impl_getpath(context)
|
|
||||||
if opt.impl_is_master_slaves('slave'):
|
|
||||||
index_ = index
|
|
||||||
else:
|
|
||||||
index_ = None
|
|
||||||
try:
|
|
||||||
opt_value = context.getattr(path,
|
|
||||||
index_,
|
|
||||||
sconfig_bag,
|
|
||||||
iter_slave=True)
|
|
||||||
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)
|
|
||||||
raise err
|
|
||||||
opt_value = None
|
|
||||||
if not option == opt and opt_value is not None and index is not None and \
|
|
||||||
(context is undefined or \
|
|
||||||
not opt.impl_is_master_slaves('slave')):
|
|
||||||
if len(opt_value) <= index:
|
|
||||||
opt_value = opt.impl_getdefault_multi()
|
|
||||||
else:
|
|
||||||
opt_value = opt_value[index]
|
|
||||||
|
|
||||||
if opt.impl_is_multi() and index is None and func not in ALLOWED_CONST_LIST:
|
|
||||||
if length is not None and length != len(opt_value):
|
|
||||||
raise ValueError(_('unexpected length of "{}" in constency "{}", should be "{}"'
|
|
||||||
'').format(len(opt_value),
|
|
||||||
opt.impl_get_display_name(),
|
|
||||||
length))
|
|
||||||
else:
|
|
||||||
length = len(opt_value)
|
|
||||||
is_multi = True
|
|
||||||
else:
|
|
||||||
is_multi = False
|
|
||||||
if isinstance(opt_value, list) and func in ALLOWED_CONST_LIST:
|
|
||||||
for value_ in opt_value:
|
|
||||||
if isinstance(value_, list):
|
|
||||||
for val in value_:
|
|
||||||
all_cons_vals.append((False, val))
|
|
||||||
all_cons_opts.append(opt)
|
|
||||||
else:
|
|
||||||
all_cons_vals.append((False, value_))
|
|
||||||
all_cons_opts.append(opt)
|
|
||||||
else:
|
|
||||||
all_cons_vals.append((is_multi, opt_value))
|
|
||||||
all_cons_opts.append(opt)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
all_values = []
|
|
||||||
if length is None:
|
|
||||||
all_value = []
|
|
||||||
for is_multi, values in all_cons_vals:
|
|
||||||
all_value.append(values)
|
|
||||||
all_values = [all_value]
|
|
||||||
else:
|
|
||||||
for idx in range(length):
|
|
||||||
all_value = []
|
|
||||||
for is_multi, values in all_cons_vals:
|
|
||||||
if not is_multi:
|
|
||||||
all_value.append(values)
|
|
||||||
else:
|
|
||||||
all_value.append(values[idx])
|
|
||||||
all_values.append(all_value)
|
|
||||||
for values in all_values:
|
|
||||||
getattr(self, func)(current_opt,
|
|
||||||
all_cons_opts,
|
|
||||||
values,
|
|
||||||
warnings_only)
|
|
||||||
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, self),
|
|
||||||
ValueWarning,
|
|
||||||
self.__class__.__name__, 0)
|
|
||||||
else:
|
|
||||||
raise err
|
|
||||||
|
|
||||||
def impl_is_unique(self):
|
def impl_is_unique(self):
|
||||||
return getattr(self, '_unique', False)
|
return getattr(self, '_unique', False)
|
||||||
|
|
||||||
|
@ -615,14 +479,16 @@ class Option(OnlyOption):
|
||||||
config_bag):
|
config_bag):
|
||||||
if context is not undefined:
|
if context is not undefined:
|
||||||
descr = context.cfgimpl_get_description()
|
descr = context.cfgimpl_get_description()
|
||||||
|
# no consistency found at all
|
||||||
if descr._cache_consistencies is None:
|
if descr._cache_consistencies is None:
|
||||||
return
|
return
|
||||||
#consistencies is something like [('_cons_not_equal', (opt1, opt2))]
|
# get consistencies for this option
|
||||||
if isinstance(option, DynSymLinkOption):
|
if isinstance(option, DynSymLinkOption):
|
||||||
consistencies = descr._cache_consistencies.get(option.impl_getopt())
|
consistencies = descr._cache_consistencies.get(option.impl_getopt())
|
||||||
else:
|
else:
|
||||||
consistencies = descr._cache_consistencies.get(option)
|
consistencies = descr._cache_consistencies.get(option)
|
||||||
else:
|
else:
|
||||||
|
# is no context, get consistencies in option
|
||||||
consistencies = option._get_consistencies()
|
consistencies = option._get_consistencies()
|
||||||
if consistencies is not None:
|
if consistencies is not None:
|
||||||
for cons_id, func, all_cons_opts, params in consistencies:
|
for cons_id, func, all_cons_opts, params in consistencies:
|
||||||
|
@ -652,6 +518,144 @@ class Option(OnlyOption):
|
||||||
transitive,
|
transitive,
|
||||||
config_bag)
|
config_bag)
|
||||||
|
|
||||||
|
def _launch_consistency(self,
|
||||||
|
current_opt,
|
||||||
|
func,
|
||||||
|
cons_id,
|
||||||
|
option,
|
||||||
|
value,
|
||||||
|
context,
|
||||||
|
index,
|
||||||
|
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`
|
||||||
|
"""
|
||||||
|
if context is not undefined:
|
||||||
|
descr = context.cfgimpl_get_description()
|
||||||
|
if config_bag is not undefined and cons_id in config_bag.fromconsistency:
|
||||||
|
return
|
||||||
|
all_cons_vals = []
|
||||||
|
all_cons_opts = []
|
||||||
|
length = None
|
||||||
|
for opt in opts:
|
||||||
|
if isinstance(opt, weakref.ReferenceType):
|
||||||
|
opt = opt()
|
||||||
|
if option == opt:
|
||||||
|
# option is current option
|
||||||
|
# we have already value, so use it
|
||||||
|
opt_value = value
|
||||||
|
elif context is undefined:
|
||||||
|
opt_value = opt.impl_getdefault()
|
||||||
|
else:
|
||||||
|
#if context, calculate value, otherwise get default value
|
||||||
|
sconfig_bag = config_bag.copy('nooption')
|
||||||
|
sconfig_bag.option = opt
|
||||||
|
sconfig_bag.fromconsistency.append(cons_id)
|
||||||
|
sconfig_bag.force_permissive = True
|
||||||
|
path = opt.impl_getpath(context)
|
||||||
|
if opt.impl_is_master_slaves('slave'):
|
||||||
|
index_ = index
|
||||||
|
else:
|
||||||
|
index_ = None
|
||||||
|
try:
|
||||||
|
opt_value = context.getattr(path,
|
||||||
|
index_,
|
||||||
|
sconfig_bag,
|
||||||
|
iter_slave=True)
|
||||||
|
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)
|
||||||
|
raise err
|
||||||
|
opt_value = None
|
||||||
|
if not option == opt and opt_value is not None and index is not None and \
|
||||||
|
(context is undefined or \
|
||||||
|
not opt.impl_is_master_slaves('slave')):
|
||||||
|
if len(opt_value) <= index:
|
||||||
|
opt_value = opt.impl_getdefault_multi()
|
||||||
|
else:
|
||||||
|
opt_value = opt_value[index]
|
||||||
|
|
||||||
|
if opt_value is not None and opt.impl_is_multi() and index is None and func not in ALLOWED_CONST_LIST:
|
||||||
|
if length is not None and length != len(opt_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))
|
||||||
|
else:
|
||||||
|
length = len(opt_value)
|
||||||
|
is_multi = True
|
||||||
|
else:
|
||||||
|
is_multi = False
|
||||||
|
if isinstance(opt_value, list) and func in ALLOWED_CONST_LIST:
|
||||||
|
for value_ in opt_value:
|
||||||
|
if isinstance(value_, list):
|
||||||
|
for val in value_:
|
||||||
|
all_cons_vals.append((False, val))
|
||||||
|
all_cons_opts.append(opt)
|
||||||
|
else:
|
||||||
|
all_cons_vals.append((False, value_))
|
||||||
|
all_cons_opts.append(opt)
|
||||||
|
else:
|
||||||
|
all_cons_vals.append((is_multi, opt_value))
|
||||||
|
all_cons_opts.append(opt)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
all_values = []
|
||||||
|
if length is None:
|
||||||
|
all_value = []
|
||||||
|
for is_multi, values in all_cons_vals:
|
||||||
|
all_value.append(values)
|
||||||
|
all_values = [all_value]
|
||||||
|
else:
|
||||||
|
for idx in range(length):
|
||||||
|
all_value = []
|
||||||
|
for is_multi, values in all_cons_vals:
|
||||||
|
if not is_multi:
|
||||||
|
all_value.append(values)
|
||||||
|
else:
|
||||||
|
all_value.append(values[idx])
|
||||||
|
all_values.append(all_value)
|
||||||
|
for values in all_values:
|
||||||
|
getattr(self, func)(current_opt,
|
||||||
|
all_cons_opts,
|
||||||
|
values,
|
||||||
|
warnings_only)
|
||||||
|
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, self),
|
||||||
|
ValueWarning,
|
||||||
|
self.__class__.__name__, 0)
|
||||||
|
else:
|
||||||
|
raise err
|
||||||
|
|
||||||
def _cons_not_equal(self,
|
def _cons_not_equal(self,
|
||||||
current_opt,
|
current_opt,
|
||||||
opts,
|
opts,
|
||||||
|
|
Loading…
Reference in New Issue