propertyerror are transitive in consistency, now it's possible to set non-transitive consistency

This commit is contained in:
2014-12-01 22:58:53 +01:00
parent 2ccf92f879
commit 7646071efd
4 changed files with 92 additions and 42 deletions

View File

@ -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())

View File

@ -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)