feat: add subconfig in errors
This commit is contained in:
parent
050979f6d3
commit
fe108b1238
13 changed files with 41 additions and 24 deletions
|
|
@ -402,12 +402,12 @@ def test_prefix_error():
|
||||||
try:
|
try:
|
||||||
cfg.option('test1').value.set('yes')
|
cfg.option('test1').value.set('yes')
|
||||||
except Exception as err:
|
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:
|
try:
|
||||||
cfg.option('test1').value.set('yes')
|
cfg.option('test1').value.set('yes')
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
err.prefix = ''
|
err.prefix = ''
|
||||||
assert str(err) == _('which is not an integer')
|
assert str(err) == _('it\'s not an integer')
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -583,6 +583,7 @@ class _TiramisuOptionOptionDescription:
|
||||||
convert: bool = False,
|
convert: bool = False,
|
||||||
):
|
):
|
||||||
"""Get identifiers for dynamic option"""
|
"""Get identifiers for dynamic option"""
|
||||||
|
subconfig = self._subconfig
|
||||||
if not only_self:
|
if not only_self:
|
||||||
if self._subconfig.is_dynamic_without_identifiers and not uncalculated:
|
if self._subconfig.is_dynamic_without_identifiers and not uncalculated:
|
||||||
raise AttributeOptionError(self._subconfig.path, "option-dynamic")
|
raise AttributeOptionError(self._subconfig.path, "option-dynamic")
|
||||||
|
|
@ -590,7 +591,6 @@ class _TiramisuOptionOptionDescription:
|
||||||
return self._subconfig.identifiers
|
return self._subconfig.identifiers
|
||||||
identifiers = []
|
identifiers = []
|
||||||
dynconfig = None
|
dynconfig = None
|
||||||
subconfig = self._subconfig
|
|
||||||
while not dynconfig:
|
while not dynconfig:
|
||||||
if subconfig.option.impl_is_optiondescription() and subconfig.option.impl_is_dynoptiondescription():
|
if subconfig.option.impl_is_optiondescription() and subconfig.option.impl_is_dynoptiondescription():
|
||||||
dynconfig = subconfig
|
dynconfig = subconfig
|
||||||
|
|
@ -607,7 +607,8 @@ class _TiramisuOptionOptionDescription:
|
||||||
raise ConfigError(
|
raise ConfigError(
|
||||||
_(
|
_(
|
||||||
"the option {0} is not a dynamic option, cannot get identifiers with only_self parameter to True"
|
"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(
|
return self._subconfig.option.get_identifiers(
|
||||||
self._subconfig.parent,
|
self._subconfig.parent,
|
||||||
|
|
|
||||||
|
|
@ -462,7 +462,7 @@ def manager_callback(
|
||||||
or param.raisepropertyerror
|
or param.raisepropertyerror
|
||||||
):
|
):
|
||||||
raise err from err
|
raise err from err
|
||||||
raise ConfigError(err)
|
raise ConfigError(err, subconfig=subconfig)
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
display_name = subconfig.option.impl_get_display_name(
|
display_name = subconfig.option.impl_get_display_name(
|
||||||
subconfig, with_quote=True
|
subconfig, with_quote=True
|
||||||
|
|
@ -626,7 +626,7 @@ def manager_callback(
|
||||||
properties = config_bag.context.get_settings().getproperties(
|
properties = config_bag.context.get_settings().getproperties(
|
||||||
subconfig,
|
subconfig,
|
||||||
uncalculated=True,
|
uncalculated=True,
|
||||||
) - {'validator'}
|
) - {'validator', 'mandatory', 'empty'}
|
||||||
for subconfig_ in subconfigs:
|
for subconfig_ in subconfigs:
|
||||||
if subconfig.path == subconfig_.path:
|
if subconfig.path == subconfig_.path:
|
||||||
values.append(orig_value)
|
values.append(orig_value)
|
||||||
|
|
@ -958,6 +958,7 @@ def calculate(
|
||||||
raise err from err
|
raise err from err
|
||||||
error = err
|
error = err
|
||||||
except ConfigError as err:
|
except ConfigError as err:
|
||||||
|
err.subconfig = subconfig
|
||||||
raise err from err
|
raise err from err
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
error = err
|
error = err
|
||||||
|
|
|
||||||
|
|
@ -522,7 +522,7 @@ class SubConfig:
|
||||||
)
|
)
|
||||||
if check_index and index is not None:
|
if check_index and index is not None:
|
||||||
if option.impl_is_optiondescription() or not option.impl_is_follower():
|
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()
|
length = self.get_length_leadership()
|
||||||
if index >= length:
|
if index >= length:
|
||||||
raise LeadershipError(
|
raise LeadershipError(
|
||||||
|
|
@ -1426,7 +1426,7 @@ class KernelGroupConfig(_CommonConfig):
|
||||||
# pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
ret.append(
|
ret.append(
|
||||||
PropertiesOptionError(
|
PropertiesOptionError(
|
||||||
err._subconfig,
|
err.subconfig,
|
||||||
err.proptype,
|
err.proptype,
|
||||||
err._settings,
|
err._settings,
|
||||||
err._opt_type,
|
err._opt_type,
|
||||||
|
|
@ -1674,7 +1674,7 @@ class KernelMixConfig(KernelGroupConfig):
|
||||||
# pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
ret.append(
|
ret.append(
|
||||||
PropertiesOptionError(
|
PropertiesOptionError(
|
||||||
err._subconfig,
|
err.subconfig,
|
||||||
err.proptype,
|
err.proptype,
|
||||||
err._settings,
|
err._settings,
|
||||||
err._opt_type,
|
err._opt_type,
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
import weakref
|
import weakref
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
|
|
||||||
from typing import Literal, Union
|
from typing import Literal, Union, Optional
|
||||||
|
|
||||||
|
|
||||||
TiramisuErrorCode = Literal[
|
TiramisuErrorCode = Literal[
|
||||||
|
|
@ -101,7 +101,7 @@ class PropertiesOptionError(AttributeError):
|
||||||
subconfig, with_quote=True
|
subconfig, with_quote=True
|
||||||
)
|
)
|
||||||
self._orig_opt = None
|
self._orig_opt = None
|
||||||
self._subconfig = subconfig
|
self.subconfig = subconfig
|
||||||
self.proptype = proptype
|
self.proptype = proptype
|
||||||
self.help_properties = help_properties
|
self.help_properties = help_properties
|
||||||
self._settings = settings
|
self._settings = settings
|
||||||
|
|
@ -136,7 +136,7 @@ class PropertiesOptionError(AttributeError):
|
||||||
self._orig_opt.impl_get_display_name(subconfig, with_quote=True)
|
self._orig_opt.impl_get_display_name(subconfig, with_quote=True)
|
||||||
)
|
)
|
||||||
arguments.append(self._name)
|
arguments.append(self._name)
|
||||||
index = self._subconfig.index
|
index = self.subconfig.index
|
||||||
if index is not None:
|
if index is not None:
|
||||||
arguments.append(index)
|
arguments.append(index)
|
||||||
if self.code == "property-frozen":
|
if self.code == "property-frozen":
|
||||||
|
|
@ -215,10 +215,22 @@ class ConfigError(Exception):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
exp,
|
exp,
|
||||||
ori_err=None,
|
*,
|
||||||
|
prefix: Optional[str] = None,
|
||||||
|
subconfig: Optional["Subconfig"]=None,
|
||||||
):
|
):
|
||||||
super().__init__(exp)
|
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):
|
class ConflictError(Exception):
|
||||||
|
|
@ -419,9 +431,9 @@ class Errors:
|
||||||
display_name = option.impl_get_display_name(subconfig, with_quote=True)
|
display_name = option.impl_get_display_name(subconfig, with_quote=True)
|
||||||
if original_error:
|
if original_error:
|
||||||
raise ConfigError(
|
raise ConfigError(
|
||||||
message.format(display_name, original_error, *extra_keys)
|
message.format(display_name, original_error, *extra_keys), subconfig=subconfig,
|
||||||
) from original_error
|
) from original_error
|
||||||
raise ConfigError(message.format(display_name, extra_keys))
|
raise ConfigError(message.format(display_name, extra_keys), subconfig=subconfig)
|
||||||
|
|
||||||
|
|
||||||
errors = Errors()
|
errors = Errors()
|
||||||
|
|
|
||||||
|
|
@ -395,6 +395,8 @@ class BaseOption(Base):
|
||||||
is_identifier: bool = False,
|
is_identifier: bool = False,
|
||||||
type_: str = 'default'
|
type_: str = 'default'
|
||||||
) -> Any:
|
) -> Any:
|
||||||
|
if not isinstance(is_identifier, bool):
|
||||||
|
raise Exception()
|
||||||
"""parse dependancy to add dependencies"""
|
"""parse dependancy to add dependencies"""
|
||||||
for param in chain(value.params.args, value.params.kwargs.values()):
|
for param in chain(value.params.args, value.params.kwargs.values()):
|
||||||
if isinstance(param, ParamOption):
|
if isinstance(param, ParamOption):
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ class ChoiceOption(Option):
|
||||||
:param values: is a list of values the option can possibly take
|
:param values: is a list of values the option can possibly take
|
||||||
"""
|
"""
|
||||||
if isinstance(values, Calculation):
|
if isinstance(values, Calculation):
|
||||||
self.value_dependency(values, "choice")
|
self.value_dependency(values, type_="choice")
|
||||||
elif not isinstance(values, tuple):
|
elif not isinstance(values, tuple):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
_("values must be a tuple or a calculation for {0}").format(name)
|
_("values must be a tuple or a calculation for {0}").format(name)
|
||||||
|
|
@ -73,7 +73,8 @@ class ChoiceOption(Option):
|
||||||
raise ConfigError(
|
raise ConfigError(
|
||||||
_('the calculated values "{0}" for "{1}" is not a list' "").format(
|
_('the calculated values "{0}" for "{1}" is not a list' "").format(
|
||||||
values, self.impl_getname()
|
values, self.impl_getname()
|
||||||
)
|
),
|
||||||
|
subconfig=subconfig,
|
||||||
)
|
)
|
||||||
return values
|
return values
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ from ..i18n import _
|
||||||
from .optiondescription import OptionDescription
|
from .optiondescription import OptionDescription
|
||||||
from .baseoption import BaseOption
|
from .baseoption import BaseOption
|
||||||
from ..setting import ConfigBag, undefined
|
from ..setting import ConfigBag, undefined
|
||||||
from ..error import ConfigError
|
|
||||||
from ..autolib import Calculation, get_calculated_value
|
from ..autolib import Calculation, get_calculated_value
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ class IntOption(Option):
|
||||||
value: int,
|
value: int,
|
||||||
) -> None:
|
) -> None:
|
||||||
if not isinstance(value, int):
|
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):
|
def second_level_validation(self, value, warnings_only):
|
||||||
min_integer = self.impl_get_extra("min_integer")
|
min_integer = self.impl_get_extra("min_integer")
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ class StrOption(Option):
|
||||||
) -> None:
|
) -> None:
|
||||||
"""validation"""
|
"""validation"""
|
||||||
if not isinstance(value, str):
|
if not isinstance(value, str):
|
||||||
raise ValueError(_("which is not a string"))
|
raise ValueError(_("it's not a string"))
|
||||||
|
|
||||||
|
|
||||||
class RegexpOption(StrOption):
|
class RegexpOption(StrOption):
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@
|
||||||
"""
|
"""
|
||||||
from typing import Any, Optional, Dict
|
from typing import Any, Optional, Dict
|
||||||
from .baseoption import BaseOption, valid_name
|
from .baseoption import BaseOption, valid_name
|
||||||
from ..error import ConfigError
|
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -638,7 +638,8 @@ class Settings:
|
||||||
raise ConfigError(
|
raise ConfigError(
|
||||||
_("cannot add those permissives: {0}").format(
|
_("cannot add those permissives: {0}").format(
|
||||||
" ".join(forbidden_permissives)
|
" ".join(forbidden_permissives)
|
||||||
)
|
),
|
||||||
|
subconfig=subconfig,
|
||||||
)
|
)
|
||||||
self._permissives.setdefault(path, {})[index] = permissives
|
self._permissives.setdefault(path, {})[index] = permissives
|
||||||
if subconfig is not None:
|
if subconfig is not None:
|
||||||
|
|
|
||||||
|
|
@ -615,7 +615,8 @@ class Values:
|
||||||
raise ConfigError(
|
raise ConfigError(
|
||||||
_(
|
_(
|
||||||
'"{0}" is a default value, so we cannot change owner to "{1}"'
|
'"{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)
|
subconfig.config_bag.context.get_settings().validate_frozen(subconfig)
|
||||||
self._values[subconfig.path][subconfig.index][1] = owner
|
self._values[subconfig.path][subconfig.index][1] = owner
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue