diff --git a/tests/test_config.py b/tests/test_config.py index 361b9bd..bb8aa47 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -402,12 +402,12 @@ def test_prefix_error(): try: cfg.option('test1').value.set('yes') except Exception as err: - assert str(err) == _('"{0}" is an invalid {1} for "{2}", which is not an integer').format('yes', _('integer'), 'test1') + assert str(err) == _('"{0}" is an invalid {1} for "{2}", it\'s not an integer').format('yes', _('integer'), 'test1') try: cfg.option('test1').value.set('yes') except Exception as err: err.prefix = '' - assert str(err) == _('which is not an integer') + assert str(err) == _('it\'s not an integer') # assert not list_sessions() diff --git a/tiramisu/api.py b/tiramisu/api.py index 78b44a2..1fefb10 100644 --- a/tiramisu/api.py +++ b/tiramisu/api.py @@ -583,6 +583,7 @@ class _TiramisuOptionOptionDescription: convert: bool = False, ): """Get identifiers for dynamic option""" + subconfig = self._subconfig if not only_self: if self._subconfig.is_dynamic_without_identifiers and not uncalculated: raise AttributeOptionError(self._subconfig.path, "option-dynamic") @@ -590,7 +591,6 @@ class _TiramisuOptionOptionDescription: return self._subconfig.identifiers identifiers = [] dynconfig = None - subconfig = self._subconfig while not dynconfig: if subconfig.option.impl_is_optiondescription() and subconfig.option.impl_is_dynoptiondescription(): dynconfig = subconfig @@ -607,7 +607,8 @@ class _TiramisuOptionOptionDescription: raise ConfigError( _( "the option {0} is not a dynamic option, cannot get identifiers with only_self parameter to True" - ).format(self._subconfig.path) + ).format(self._subconfig.path), + subconfig=subconfig, ) return self._subconfig.option.get_identifiers( self._subconfig.parent, diff --git a/tiramisu/autolib.py b/tiramisu/autolib.py index 1ef4bdf..de3efdb 100644 --- a/tiramisu/autolib.py +++ b/tiramisu/autolib.py @@ -462,7 +462,7 @@ def manager_callback( or param.raisepropertyerror ): raise err from err - raise ConfigError(err) + raise ConfigError(err, subconfig=subconfig) except ValueError as err: display_name = subconfig.option.impl_get_display_name( subconfig, with_quote=True @@ -626,7 +626,7 @@ def manager_callback( properties = config_bag.context.get_settings().getproperties( subconfig, uncalculated=True, - ) - {'validator'} + ) - {'validator', 'mandatory', 'empty'} for subconfig_ in subconfigs: if subconfig.path == subconfig_.path: values.append(orig_value) @@ -958,6 +958,7 @@ def calculate( raise err from err error = err except ConfigError as err: + err.subconfig = subconfig raise err from err except Exception as err: error = err diff --git a/tiramisu/config.py b/tiramisu/config.py index 0965832..9868777 100644 --- a/tiramisu/config.py +++ b/tiramisu/config.py @@ -522,7 +522,7 @@ class SubConfig: ) if check_index and index is not None: if option.impl_is_optiondescription() or not option.impl_is_follower(): - raise ConfigError("index must be set only with a follower option") + raise ConfigError("index must be set only with a follower option", subconfig=subsubconfig,) length = self.get_length_leadership() if index >= length: raise LeadershipError( @@ -1426,7 +1426,7 @@ class KernelGroupConfig(_CommonConfig): # pylint: disable=protected-access ret.append( PropertiesOptionError( - err._subconfig, + err.subconfig, err.proptype, err._settings, err._opt_type, @@ -1674,7 +1674,7 @@ class KernelMixConfig(KernelGroupConfig): # pylint: disable=protected-access ret.append( PropertiesOptionError( - err._subconfig, + err.subconfig, err.proptype, err._settings, err._opt_type, diff --git a/tiramisu/error.py b/tiramisu/error.py index 38e2e18..dd2607e 100644 --- a/tiramisu/error.py +++ b/tiramisu/error.py @@ -18,7 +18,7 @@ import weakref from .i18n import _ -from typing import Literal, Union +from typing import Literal, Union, Optional TiramisuErrorCode = Literal[ @@ -101,7 +101,7 @@ class PropertiesOptionError(AttributeError): subconfig, with_quote=True ) self._orig_opt = None - self._subconfig = subconfig + self.subconfig = subconfig self.proptype = proptype self.help_properties = help_properties self._settings = settings @@ -136,7 +136,7 @@ class PropertiesOptionError(AttributeError): self._orig_opt.impl_get_display_name(subconfig, with_quote=True) ) arguments.append(self._name) - index = self._subconfig.index + index = self.subconfig.index if index is not None: arguments.append(index) if self.code == "property-frozen": @@ -215,10 +215,22 @@ class ConfigError(Exception): def __init__( self, exp, - ori_err=None, + *, + prefix: Optional[str] = None, + subconfig: Optional["Subconfig"]=None, ): super().__init__(exp) - self.ori_err = ori_err + self.err_msg = exp + self.subconfig = subconfig + self.prefix = prefix + + def __str__(self): + msg = self.prefix + if msg: + msg += ", {}".format(self.err_msg) + else: + msg = self.err_msg + return msg class ConflictError(Exception): @@ -419,9 +431,9 @@ class Errors: display_name = option.impl_get_display_name(subconfig, with_quote=True) if original_error: raise ConfigError( - message.format(display_name, original_error, *extra_keys) + message.format(display_name, original_error, *extra_keys), subconfig=subconfig, ) from original_error - raise ConfigError(message.format(display_name, extra_keys)) + raise ConfigError(message.format(display_name, extra_keys), subconfig=subconfig) errors = Errors() diff --git a/tiramisu/option/baseoption.py b/tiramisu/option/baseoption.py index b8df7de..19ab5ef 100644 --- a/tiramisu/option/baseoption.py +++ b/tiramisu/option/baseoption.py @@ -395,6 +395,8 @@ class BaseOption(Base): is_identifier: bool = False, type_: str = 'default' ) -> Any: + if not isinstance(is_identifier, bool): + raise Exception() """parse dependancy to add dependencies""" for param in chain(value.params.args, value.params.kwargs.values()): if isinstance(param, ParamOption): diff --git a/tiramisu/option/choiceoption.py b/tiramisu/option/choiceoption.py index 5965225..b04d647 100644 --- a/tiramisu/option/choiceoption.py +++ b/tiramisu/option/choiceoption.py @@ -45,7 +45,7 @@ class ChoiceOption(Option): :param values: is a list of values the option can possibly take """ if isinstance(values, Calculation): - self.value_dependency(values, "choice") + self.value_dependency(values, type_="choice") elif not isinstance(values, tuple): raise TypeError( _("values must be a tuple or a calculation for {0}").format(name) @@ -73,7 +73,8 @@ class ChoiceOption(Option): raise ConfigError( _('the calculated values "{0}" for "{1}" is not a list' "").format( values, self.impl_getname() - ) + ), + subconfig=subconfig, ) return values diff --git a/tiramisu/option/dynoptiondescription.py b/tiramisu/option/dynoptiondescription.py index 691a691..afaf7f6 100644 --- a/tiramisu/option/dynoptiondescription.py +++ b/tiramisu/option/dynoptiondescription.py @@ -31,7 +31,6 @@ from ..i18n import _ from .optiondescription import OptionDescription from .baseoption import BaseOption from ..setting import ConfigBag, undefined -from ..error import ConfigError from ..autolib import Calculation, get_calculated_value diff --git a/tiramisu/option/intoption.py b/tiramisu/option/intoption.py index 19545bd..3701a9b 100644 --- a/tiramisu/option/intoption.py +++ b/tiramisu/option/intoption.py @@ -56,7 +56,7 @@ class IntOption(Option): value: int, ) -> None: if not isinstance(value, int): - raise ValueError(_("which is not an integer")) + raise ValueError(_("it's not an integer")) def second_level_validation(self, value, warnings_only): min_integer = self.impl_get_extra("min_integer") diff --git a/tiramisu/option/stroption.py b/tiramisu/option/stroption.py index 2b77685..f47825e 100644 --- a/tiramisu/option/stroption.py +++ b/tiramisu/option/stroption.py @@ -39,7 +39,7 @@ class StrOption(Option): ) -> None: """validation""" if not isinstance(value, str): - raise ValueError(_("which is not a string")) + raise ValueError(_("it's not a string")) class RegexpOption(StrOption): diff --git a/tiramisu/option/symlinkoption.py b/tiramisu/option/symlinkoption.py index 290b804..9b54f12 100644 --- a/tiramisu/option/symlinkoption.py +++ b/tiramisu/option/symlinkoption.py @@ -22,7 +22,6 @@ """ from typing import Any, Optional, Dict from .baseoption import BaseOption, valid_name -from ..error import ConfigError from ..i18n import _ diff --git a/tiramisu/setting.py b/tiramisu/setting.py index 2e7a2e2..23df689 100644 --- a/tiramisu/setting.py +++ b/tiramisu/setting.py @@ -638,7 +638,8 @@ class Settings: raise ConfigError( _("cannot add those permissives: {0}").format( " ".join(forbidden_permissives) - ) + ), + subconfig=subconfig, ) self._permissives.setdefault(path, {})[index] = permissives if subconfig is not None: diff --git a/tiramisu/value.py b/tiramisu/value.py index 7fd4bc0..00f010d 100644 --- a/tiramisu/value.py +++ b/tiramisu/value.py @@ -615,7 +615,8 @@ class Values: raise ConfigError( _( '"{0}" is a default value, so we cannot change owner to "{1}"' - ).format(subconfig.path, owner) + ).format(subconfig.path, owner), + subconfig=subconfig, ) subconfig.config_bag.context.get_settings().validate_frozen(subconfig) self._values[subconfig.path][subconfig.index][1] = owner