propertyerror are transitive in consistency, now it's possible to set non-transitive consistency
This commit is contained in:
@ -25,7 +25,7 @@ import warnings
|
||||
from tiramisu.i18n import _
|
||||
from tiramisu.setting import log, undefined
|
||||
from tiramisu.autolib import carry_out_calculation
|
||||
from tiramisu.error import ConfigError, ValueWarning
|
||||
from tiramisu.error import ConfigError, ValueWarning, PropertiesOptionError
|
||||
from tiramisu.storage import get_storages_option
|
||||
|
||||
|
||||
@ -403,7 +403,8 @@ class Option(OnlyOption):
|
||||
_empty = ''
|
||||
|
||||
def _launch_consistency(self, func, option, value, context, index,
|
||||
submulti_index, all_cons_opts, warnings_only):
|
||||
submulti_index, all_cons_opts, warnings_only,
|
||||
transitive):
|
||||
"""Launch consistency now
|
||||
|
||||
:param func: function name, this name should start with _cons_
|
||||
@ -420,47 +421,55 @@ class Option(OnlyOption):
|
||||
:type all_cons_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()
|
||||
|
||||
all_cons_vals = []
|
||||
for opt in all_cons_opts:
|
||||
#get value
|
||||
if (isinstance(opt, DynSymLinkOption) and option._dyn == opt._dyn) or \
|
||||
option == opt:
|
||||
opt_value = value
|
||||
else:
|
||||
#if context, calculate value, otherwise get default value
|
||||
if context is not undefined:
|
||||
if isinstance(opt, DynSymLinkOption):
|
||||
path = opt.impl_getpath(context)
|
||||
else:
|
||||
path = descr.impl_get_path_by_opt(opt)
|
||||
opt_value = context.getattr(path, validate=False,
|
||||
force_permissive=True)
|
||||
try:
|
||||
#get value
|
||||
if (isinstance(opt, DynSymLinkOption) and option._dyn == opt._dyn) or \
|
||||
option == opt:
|
||||
opt_value = value
|
||||
else:
|
||||
opt_value = opt.impl_getdefault()
|
||||
#if context, calculate value, otherwise get default value
|
||||
if context is not undefined:
|
||||
if isinstance(opt, DynSymLinkOption):
|
||||
path = opt.impl_getpath(context)
|
||||
else:
|
||||
path = descr.impl_get_path_by_opt(opt)
|
||||
opt_value = context.getattr(path, validate=False,
|
||||
force_permissive=True)
|
||||
else:
|
||||
opt_value = opt.impl_getdefault()
|
||||
|
||||
#append value
|
||||
if not self.impl_is_multi() or (isinstance(opt, DynSymLinkOption)
|
||||
and option._dyn == opt._dyn) or \
|
||||
option == opt:
|
||||
all_cons_vals.append(opt_value)
|
||||
elif self.impl_is_submulti():
|
||||
try:
|
||||
all_cons_vals.append(opt_value[index][submulti_index])
|
||||
except IndexError:
|
||||
#value is not already set, could be higher index
|
||||
#so return if no value
|
||||
return
|
||||
else:
|
||||
try:
|
||||
all_cons_vals.append(opt_value[index])
|
||||
except IndexError:
|
||||
#value is not already set, could be higher index
|
||||
#so return if no value
|
||||
return
|
||||
#append value
|
||||
if not self.impl_is_multi() or (isinstance(opt, DynSymLinkOption)
|
||||
and option._dyn == opt._dyn) or \
|
||||
option == opt:
|
||||
all_cons_vals.append(opt_value)
|
||||
elif self.impl_is_submulti():
|
||||
try:
|
||||
all_cons_vals.append(opt_value[index][submulti_index])
|
||||
except IndexError:
|
||||
#value is not already set, could be higher index
|
||||
#so return if no value
|
||||
return
|
||||
else:
|
||||
try:
|
||||
all_cons_vals.append(opt_value[index])
|
||||
except IndexError:
|
||||
#value is not already set, could be higher index
|
||||
#so return if no value
|
||||
return
|
||||
except PropertiesOptionError as err:
|
||||
if transitive:
|
||||
raise err
|
||||
else:
|
||||
pass
|
||||
getattr(self, func)(all_cons_opts, all_cons_vals, warnings_only)
|
||||
|
||||
def impl_validate(self, value, context=undefined, validate=True,
|
||||
@ -636,14 +645,22 @@ class Option(OnlyOption):
|
||||
:type func: `str`
|
||||
:param other_opts: options used to validate value
|
||||
:type other_opts: `list` of `tiramisu.option.Option`
|
||||
:param params: extra params (only warnings_only are allowed)
|
||||
:param params: extra params (warnings_only and transitive are allowed)
|
||||
"""
|
||||
if self.impl_is_readonly(): # pragma: optional cover
|
||||
raise AttributeError(_("'{0}' ({1}) cannot add consistency, option is"
|
||||
" read-only").format(
|
||||
self.__class__.__name__,
|
||||
self.impl_getname()))
|
||||
warnings_only = params.get('warnings_only', False)
|
||||
warnings_only = False
|
||||
transitive = True
|
||||
for key, value in params.items():
|
||||
if key == 'warnings_only':
|
||||
warnings_only = value
|
||||
elif key == 'transitive':
|
||||
transitive = value
|
||||
else:
|
||||
raise ValueError(_('unknow parameter {0} in consistency').format(key))
|
||||
if self._is_subdyn():
|
||||
dynod = self._impl_getsubdyn()
|
||||
else:
|
||||
@ -678,16 +695,17 @@ class Option(OnlyOption):
|
||||
if not self.impl_is_submulti():
|
||||
self._launch_consistency(func, self, val, undefined, idx,
|
||||
None, all_cons_opts,
|
||||
warnings_only)
|
||||
warnings_only, transitive)
|
||||
else:
|
||||
for slave_idx, val in enumerate(value):
|
||||
self._launch_consistency(func, self, val, None,
|
||||
idx, slave_idx,
|
||||
all_cons_opts,
|
||||
warnings_only)
|
||||
warnings_only, transitive)
|
||||
else:
|
||||
self._launch_consistency(func, self, value, undefined, None,
|
||||
None, all_cons_opts, warnings_only)
|
||||
None, all_cons_opts, warnings_only,
|
||||
transitive)
|
||||
self._add_consistency(func, all_cons_opts, params)
|
||||
self.impl_validate(self.impl_getdefault())
|
||||
|
||||
|
@ -175,6 +175,7 @@ class OptionDescription(BaseOption, StorageOptionDescription):
|
||||
if consistencies is not None:
|
||||
for func, all_cons_opts, params in consistencies:
|
||||
warnings_only = params.get('warnings_only', False)
|
||||
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])
|
||||
@ -190,7 +191,7 @@ class OptionDescription(BaseOption, StorageOptionDescription):
|
||||
try:
|
||||
opts[0]._launch_consistency(func, option, value, context,
|
||||
index, submulti_idx, opts,
|
||||
warnings_only)
|
||||
warnings_only, transitive)
|
||||
except ValueError as err:
|
||||
if warnings_only:
|
||||
raise ValueWarning(err.message, option)
|
||||
|
Reference in New Issue
Block a user