fix: better error message
This commit is contained in:
parent
c14a34f232
commit
fcbb9c6812
16 changed files with 392 additions and 178 deletions
|
|
@ -788,6 +788,19 @@ def test_values_with_leader_and_followers_leader_pop():
|
|||
# assert not list_sessions()
|
||||
|
||||
|
||||
def test_values_with_leader_and_followers_leader_pop_default_value():
|
||||
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", default=["192.168.230.145", "192.168.230.146"], multi=True, properties=('notunique',))
|
||||
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", default_multi="255.255.255.0", multi=True)
|
||||
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
|
||||
od1 = OptionDescription('toto', '', [interface1])
|
||||
cfg = Config(od1)
|
||||
cfg.property.read_write()
|
||||
cfg.option('ip_admin_eth0.ip_admin_eth0').value.pop(0)
|
||||
compare(cfg.value.exportation(), {'ip_admin_eth0.ip_admin_eth0': {None: [['192.168.230.146'], 'user']}})
|
||||
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ["192.168.230.146"]
|
||||
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.255.0'
|
||||
|
||||
|
||||
def test_follower_unique():
|
||||
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
|
||||
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True, properties=('unique',))
|
||||
|
|
|
|||
|
|
@ -945,7 +945,7 @@ def test_consistency_leader_and_followers_leader_mandatory_transitive():
|
|||
try:
|
||||
cfg.option('val1.val2', 0).value.get()
|
||||
except PropertiesOptionError as error:
|
||||
assert str(error) == str(_('cannot access to {0} {1} because has {2} {3}').format('option', '"val2"', _('property'), '"disabled"'))
|
||||
assert str(error) == str(_('cannot access to {0} {1} at index "{2}" because has {3} {4}').format('option', '"val2"', 0, _('property'), '"disabled"'))
|
||||
else:
|
||||
raise Exception('must raises')
|
||||
assert list(cfg.value.mandatory()) == []
|
||||
|
|
|
|||
|
|
@ -271,9 +271,18 @@ class _TiramisuOptionWalk:
|
|||
|
||||
class _TiramisuOptionOptionDescription:
|
||||
"""Manage option"""
|
||||
|
||||
_validate_properties = False
|
||||
|
||||
@option_type(["optiondescription", "option", "with_or_without_index", "symlink", "allow_dynoption"])
|
||||
@option_type(
|
||||
[
|
||||
"optiondescription",
|
||||
"option",
|
||||
"with_or_without_index",
|
||||
"symlink",
|
||||
"allow_dynoption",
|
||||
]
|
||||
)
|
||||
def get(self):
|
||||
"""Get Tiramisu option"""
|
||||
return self._subconfig.option
|
||||
|
|
@ -291,11 +300,14 @@ class _TiramisuOptionOptionDescription:
|
|||
@option_type(["optiondescription", "option", "with_or_without_index", "symlink"])
|
||||
def description(
|
||||
self,
|
||||
with_quote: bool = False,
|
||||
uncalculated: bool = False,
|
||||
):
|
||||
"""Get option description"""
|
||||
if not uncalculated:
|
||||
return self._subconfig.option.impl_get_display_name(self._subconfig)
|
||||
return self._subconfig.option.impl_get_display_name(
|
||||
self._subconfig, with_quote=with_quote
|
||||
)
|
||||
return self._subconfig.option._get_information(
|
||||
self._subconfig,
|
||||
"doc",
|
||||
|
|
@ -354,7 +366,7 @@ class _TiramisuOptionOptionDescription:
|
|||
if option.impl_is_optiondescription():
|
||||
return "optiondescription"
|
||||
if only_self and option.impl_is_symlinkoption():
|
||||
return 'symlink'
|
||||
return "symlink"
|
||||
return option.get_type()
|
||||
|
||||
@option_type(["option", "symlink", "with_or_without_index"])
|
||||
|
|
@ -808,11 +820,7 @@ class TiramisuOptionValue(CommonTiramisuOption, _TiramisuODGet):
|
|||
and option.impl_is_leader()
|
||||
and len(value) < self._subconfig.parent.get_length_leadership()
|
||||
):
|
||||
raise LeadershipError(
|
||||
_("cannot reduce length of the leader {}" "").format(
|
||||
option.impl_get_display_name(self._subconfig, with_quote=True)
|
||||
)
|
||||
)
|
||||
raise LeadershipError(self._subconfig, "leadership-reduce")
|
||||
values = self._config_bag.context.get_values()
|
||||
return values.set_value(self._subconfig, value)
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,15 @@ from typing import Any, Optional, Union, Callable, Dict, List
|
|||
from itertools import chain
|
||||
import weakref
|
||||
|
||||
from .error import PropertiesOptionError, ConfigError, LeadershipError, ValueWarning, CancelParam, display_list, errors
|
||||
from .error import (
|
||||
PropertiesOptionError,
|
||||
ConfigError,
|
||||
LeadershipError,
|
||||
ValueWarning,
|
||||
CancelParam,
|
||||
display_list,
|
||||
errors,
|
||||
)
|
||||
from .i18n import _
|
||||
from .setting import undefined, ConfigBag
|
||||
from .function import FUNCTION_WAITING_FOR_DICT, FUNCTION_WAITING_FOR_ERROR
|
||||
|
|
@ -149,11 +157,15 @@ class ParamDynOption(ParamOption):
|
|||
)
|
||||
if not isinstance(identifiers, list):
|
||||
raise Exception(
|
||||
_("identifiers in ParamDynOption must be a list, not {0}").format(identifiers)
|
||||
_("identifiers in ParamDynOption must be a list, not {0}").format(
|
||||
identifiers
|
||||
)
|
||||
)
|
||||
if not isinstance(optional, bool):
|
||||
raise Exception(
|
||||
_("optional in ParamDynOption must be a boolean, not {0}").format(optional)
|
||||
_("optional in ParamDynOption must be a boolean, not {0}").format(
|
||||
optional
|
||||
)
|
||||
)
|
||||
self.identifiers = identifiers
|
||||
self.optional = optional
|
||||
|
|
@ -204,7 +216,9 @@ class ParamInformation(Param):
|
|||
|
||||
def set_option(self, option: "Option" = None) -> None:
|
||||
if not hasattr(self, "self_option"):
|
||||
raise ConfigError(_("cannot add option in information after creating config"))
|
||||
raise ConfigError(
|
||||
_("cannot add option in information after creating config")
|
||||
)
|
||||
if self.option:
|
||||
raise ConfigError(_("cannot redefine option in information"))
|
||||
if not option.impl_is_optiondescription():
|
||||
|
|
@ -464,7 +478,9 @@ def manager_callback(
|
|||
["configerror"],
|
||||
config_bag.context.get_settings(),
|
||||
)
|
||||
errors.raise_carry_out_calculation_error(subconfig, _("unable to get value for calculating {0}, {1}"), err)
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig, _("unable to get value for calculating {0}, {1}"), err
|
||||
)
|
||||
return value
|
||||
|
||||
def get_option_bag(
|
||||
|
|
@ -496,7 +512,12 @@ def manager_callback(
|
|||
# raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation
|
||||
if param.notraisepropertyerror or param.raisepropertyerror:
|
||||
raise err from err
|
||||
errors.raise_carry_out_calculation_error(subconfig, _("unable to carry out a calculation for {0}, {1}"), err, option=option)
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig,
|
||||
_("unable to carry out a calculation for {0}, {1}"),
|
||||
err,
|
||||
option=option,
|
||||
)
|
||||
except ValueError as err:
|
||||
display_name = option.impl_get_display_name(subconfig, with_quote=True)
|
||||
raise ValueError(
|
||||
|
|
@ -512,7 +533,12 @@ def manager_callback(
|
|||
["configerror"],
|
||||
config_bag.context.get_settings(),
|
||||
)
|
||||
errors.raise_carry_out_calculation_error(subconfig, _("unable to get value for calculating {0}, {1}"), err, option=option)
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig,
|
||||
_("unable to get value for calculating {0}, {1}"),
|
||||
err,
|
||||
option=option,
|
||||
)
|
||||
return subsubconfig
|
||||
|
||||
if isinstance(param, ParamValue):
|
||||
|
|
@ -532,7 +558,13 @@ def manager_callback(
|
|||
search_name = search_option.impl_get_display_name(
|
||||
None, with_quote=True
|
||||
)
|
||||
errors.raise_carry_out_calculation_error(subconfig, _("cannot find information for {0}, {1} is a dynamic option"), None, option=option, extra_keys=[search_name])
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig,
|
||||
_("cannot find information for {0}, {1} is a dynamic option"),
|
||||
None,
|
||||
option=option,
|
||||
extra_keys=[search_name],
|
||||
)
|
||||
else:
|
||||
isubconfig = get_option_bag(
|
||||
config_bag,
|
||||
|
|
@ -551,7 +583,12 @@ def manager_callback(
|
|||
param.default_value,
|
||||
)
|
||||
except ValueError as err:
|
||||
errors.raise_carry_out_calculation_error(subconfig, _("unable to get value for calculating {0}, {1}"), err, option=option)
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig,
|
||||
_("unable to get value for calculating {0}, {1}"),
|
||||
err,
|
||||
option=option,
|
||||
)
|
||||
|
||||
if isinstance(param, ParamIndex):
|
||||
return index
|
||||
|
|
@ -561,7 +598,14 @@ def manager_callback(
|
|||
not option.impl_is_optiondescription()
|
||||
or not option.impl_is_dynoptiondescription()
|
||||
):
|
||||
errors.raise_carry_out_calculation_error(subconfig, _("option {0} is not a dynoptiondescription or in a dynoptiondescription"), None, option=option)
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig,
|
||||
_(
|
||||
"option {0} is not a dynoptiondescription or in a dynoptiondescription"
|
||||
),
|
||||
None,
|
||||
option=option,
|
||||
)
|
||||
if subconfig.identifiers is None:
|
||||
# if uncalculated
|
||||
return
|
||||
|
|
@ -637,18 +681,36 @@ def manager_callback(
|
|||
)
|
||||
except AttributeError as err:
|
||||
if parent.path:
|
||||
child_path = parent.path + '.' + name
|
||||
child_path = parent.path + "." + name
|
||||
else:
|
||||
child_path = name
|
||||
if param.optional:
|
||||
raise CancelParam(callbk_option.impl_getpath(), child_path)
|
||||
raise CancelParam(
|
||||
callbk_option.impl_getpath(), child_path
|
||||
)
|
||||
|
||||
identifiers = doption.get_identifiers(parent)
|
||||
if not identifiers:
|
||||
errors.raise_carry_out_calculation_error(subconfig, _('cannot calculate arguments for {0}, {1} with identifier "{2}", there is no identifiers'), err, extra_keys=[identifier])
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig,
|
||||
_(
|
||||
'cannot calculate arguments for {0}, {1} with identifier "{2}", there is no identifiers'
|
||||
),
|
||||
err,
|
||||
extra_keys=[identifier],
|
||||
)
|
||||
else:
|
||||
identifiers_list = display_list(identifiers, add_quote=True)
|
||||
errors.raise_carry_out_calculation_error(subconfig, _('cannot calculate arguments for {0}, {1} with identifier "{2}", list of valid identifiers: {3}'), err, extra_keys=[identifier, identifiers_list])
|
||||
identifiers_list = display_list(
|
||||
identifiers, add_quote=True
|
||||
)
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig,
|
||||
_(
|
||||
'cannot calculate arguments for {0}, {1} with identifier "{2}", list of valid identifiers: {3}'
|
||||
),
|
||||
err,
|
||||
extra_keys=[identifier, identifiers_list],
|
||||
)
|
||||
new_parents.append(
|
||||
parent.get_child(
|
||||
doption,
|
||||
|
|
@ -752,7 +814,12 @@ def carry_out_calculation(
|
|||
and option.impl_is_follower()
|
||||
and index is None
|
||||
):
|
||||
errors.raise_carry_out_calculation_error(subconfig, _("the follower {0} must have index in carry_out_calculation!"), None, option=option)
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig,
|
||||
_("the follower {0} must have index in carry_out_calculation!"),
|
||||
None,
|
||||
option=option,
|
||||
)
|
||||
|
||||
def fake_items(iterator):
|
||||
return ((None, i) for i in iterator)
|
||||
|
|
@ -822,32 +889,13 @@ def carry_out_calculation(
|
|||
and option.impl_is_follower()
|
||||
and not option.impl_is_submulti()
|
||||
):
|
||||
if args or kwargs:
|
||||
raise LeadershipError(
|
||||
_(
|
||||
'the "{}" function with positional arguments "{}" '
|
||||
'and keyword arguments "{}" must not return '
|
||||
'a list ("{}") for the follower option {}'
|
||||
""
|
||||
).format(
|
||||
callback.__name__,
|
||||
args,
|
||||
kwargs,
|
||||
ret,
|
||||
option.impl_get_display_name(subconfig, with_quote=True),
|
||||
)
|
||||
)
|
||||
else:
|
||||
raise LeadershipError(
|
||||
_(
|
||||
'the "{}" function must not return a list ("{}") '
|
||||
"for the follower option {}"
|
||||
""
|
||||
).format(
|
||||
callback.__name__,
|
||||
ret,
|
||||
option.impl_get_display_name(subconfig, with_quote=True),
|
||||
)
|
||||
subconfig,
|
||||
"leadership-follower-callback-list",
|
||||
callback=callback.__name__,
|
||||
args=args,
|
||||
kwargs=kwargs,
|
||||
ret=ret,
|
||||
)
|
||||
return ret
|
||||
|
||||
|
|
@ -884,11 +932,14 @@ def calculate(
|
|||
'unexpected error "{1}" in function "{2}" with arguments "{3}" and "{4}" '
|
||||
"for option {0}"
|
||||
)
|
||||
extra_keys = [callback.__name__,
|
||||
extra_keys = [
|
||||
callback.__name__,
|
||||
args,
|
||||
kwargs,
|
||||
]
|
||||
else:
|
||||
msg = _('unexpected error "{1}" in function "{2}" for option {0}')
|
||||
extra_keys = [callback.__name__]
|
||||
errors.raise_carry_out_calculation_error(subconfig, msg, error, extra_keys=extra_keys)
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig, msg, error, extra_keys=extra_keys
|
||||
)
|
||||
|
|
|
|||
|
|
@ -417,13 +417,7 @@ class SubConfig:
|
|||
length = self.get_length_leadership()
|
||||
if index >= length:
|
||||
raise LeadershipError(
|
||||
_(
|
||||
'index "{0}" is greater than the leadership length "{1}" for option {2}'
|
||||
).format(
|
||||
index,
|
||||
length,
|
||||
option.impl_get_display_name(subsubconfig, with_quote=True),
|
||||
)
|
||||
subsubconfig, "leadership-greater", index=index, length=length
|
||||
)
|
||||
return subsubconfig
|
||||
|
||||
|
|
@ -869,9 +863,10 @@ class _Config(CCache):
|
|||
subconfig, with_quote=True
|
||||
)
|
||||
raise LeadershipError(
|
||||
_(
|
||||
"the follower option {0} has greater length ({1}) than the leader length ({2})"
|
||||
).format(option_name, follower_len, length)
|
||||
subconfig,
|
||||
"leadership-follower-greater",
|
||||
index=follower_len,
|
||||
length=length,
|
||||
)
|
||||
self.get_settings().validate_mandatory(
|
||||
subconfig,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,23 @@
|
|||
import weakref
|
||||
from .i18n import _
|
||||
|
||||
from typing import Literal, Union
|
||||
|
||||
|
||||
TiramisuErrorCode = Literal[
|
||||
"option-dynamic",
|
||||
"option-not-found",
|
||||
"property-frozen",
|
||||
"property-error",
|
||||
"property-mandatory",
|
||||
"leadership-group_type",
|
||||
"leadership-wrong_property",
|
||||
"leadership-force_default_on_freeze",
|
||||
"leadership-greater",
|
||||
"leadership-follower-greater",
|
||||
"leadership-follower-callback-list",
|
||||
]
|
||||
|
||||
|
||||
def display_list(
|
||||
lst,
|
||||
|
|
@ -69,6 +86,8 @@ class PropertiesOptionError(AttributeError):
|
|||
orig_opt=None,
|
||||
help_properties=None,
|
||||
):
|
||||
if orig_opt:
|
||||
raise Exception("a la")
|
||||
if opt_type:
|
||||
self._opt_type = opt_type
|
||||
self._name = name
|
||||
|
|
@ -87,10 +106,23 @@ class PropertiesOptionError(AttributeError):
|
|||
self.help_properties = help_properties
|
||||
self._settings = settings
|
||||
self.msg = None
|
||||
if not self.help_properties:
|
||||
self.help_properties = self.proptype
|
||||
properties = list(self.help_properties)
|
||||
if properties == ["frozen"]:
|
||||
self.code = "property-frozen"
|
||||
elif properties == ["mandatory"]:
|
||||
self.code = "property-mandatory"
|
||||
else:
|
||||
self.code = "property-error"
|
||||
super().__init__(None)
|
||||
|
||||
def set_orig_opt(self, opt):
|
||||
self._orig_opt = opt
|
||||
def display_properties(self, force_property=False, add_quote=True):
|
||||
if force_property:
|
||||
properties = self.proptype
|
||||
else:
|
||||
properties = self.help_properties
|
||||
return display_list(list(properties), add_quote=add_quote)
|
||||
|
||||
def __str__(self):
|
||||
# this part is a bit slow, so only execute when display
|
||||
|
|
@ -98,47 +130,81 @@ class PropertiesOptionError(AttributeError):
|
|||
return self.msg
|
||||
if self._settings is None:
|
||||
return "error"
|
||||
if self.help_properties:
|
||||
properties = list(self.help_properties)
|
||||
else:
|
||||
properties = list(self.proptype)
|
||||
only_one = len(properties) == 1
|
||||
properties_msg = display_list(properties, add_quote=True)
|
||||
if only_one:
|
||||
prop_msg = _("property")
|
||||
else:
|
||||
prop_msg = _("properties")
|
||||
if properties == ["frozen"]:
|
||||
arguments = [self._opt_type]
|
||||
if self._orig_opt:
|
||||
msg = _('cannot modify the {0} {1} because "{2}" has {3} {4}')
|
||||
else:
|
||||
msg = _("cannot modify the {0} {1} because has {2} {3}")
|
||||
elif properties == ["mandatory"]:
|
||||
arguments.append(
|
||||
self._orig_opt.impl_get_display_name(subconfig, with_quote=True)
|
||||
)
|
||||
arguments.append(self._name)
|
||||
index = self._subconfig.index
|
||||
if index is not None:
|
||||
arguments.append(index)
|
||||
if self.code == "property-frozen":
|
||||
if index is not None:
|
||||
if self._orig_opt:
|
||||
msg = _("cannot access to {0} {1} because \"{2}\" hasn't value")
|
||||
msg = _(
|
||||
'cannot modify the {0} {1} at index "{2}" because {3} is frozen'
|
||||
)
|
||||
else:
|
||||
msg = _(
|
||||
'cannot modify the {0} {1} at index "{2}" because is frozen'
|
||||
)
|
||||
else:
|
||||
if self._orig_opt:
|
||||
msg = _("cannot modify the {0} {1} because {2} is frozen")
|
||||
else:
|
||||
msg = _("cannot modify the {0} {1} because is frozen")
|
||||
elif self.code == "property-mandatory":
|
||||
if index is not None:
|
||||
if self._orig_opt:
|
||||
msg = _(
|
||||
'cannot access to {0} {1} at index "{2}" because {2} hasn\'t value'
|
||||
)
|
||||
else:
|
||||
msg = _('{0} {1} at index "{2}" is mandatory but hasn\'t value')
|
||||
else:
|
||||
if self._orig_opt:
|
||||
msg = _("cannot access to {0} {1} because {2} hasn't value")
|
||||
else:
|
||||
msg = _("{0} {1} is mandatory but hasn't value")
|
||||
else:
|
||||
if index is not None:
|
||||
if self._orig_opt:
|
||||
msg = _('cannot access to {0} {1} because "{2}" has {3} {4}')
|
||||
else:
|
||||
msg = _("cannot access to {0} {1} because has {2} {3}")
|
||||
if self._orig_opt:
|
||||
# FIXME _orig_opt ?
|
||||
self.msg = msg.format(
|
||||
self._opt_type,
|
||||
self._orig_opt.impl_get_display_name(subconfig, with_quote=True),
|
||||
self._name,
|
||||
prop_msg,
|
||||
properties_msg,
|
||||
msg = _(
|
||||
'cannot access to {0} {1} at index "{2}" because {3} has {4} {5}'
|
||||
)
|
||||
else:
|
||||
self.msg = msg.format(self._opt_type, self._name, prop_msg, properties_msg)
|
||||
msg = _(
|
||||
'cannot access to {0} {1} at index "{2}" because has {3} {4}'
|
||||
)
|
||||
else:
|
||||
if self._orig_opt:
|
||||
msg = _("cannot access to {0} {1} because {2} has {3} {4}")
|
||||
else:
|
||||
msg = _("cannot access to {0} {1} because has {2} {3}")
|
||||
only_one = len(self.help_properties) == 1
|
||||
if only_one:
|
||||
arguments.append(_("property"))
|
||||
else:
|
||||
arguments.append(_("properties"))
|
||||
arguments.append(self.display_properties())
|
||||
self.msg = msg.format(*arguments)
|
||||
del self._opt_type, self._name
|
||||
del self._settings, self._orig_opt
|
||||
return self.msg
|
||||
|
||||
|
||||
class AttributeOptionError(AttributeError):
|
||||
def __init__(self, path: str, code: TiramisuErrorCode) -> None:
|
||||
self.path = path
|
||||
self.code = code
|
||||
|
||||
def __str__(self) -> str:
|
||||
if self.code == "option-dynamic":
|
||||
return _('cannot access to "{0}" it\'s a dynamic option').format(self.path)
|
||||
return _('"{0}" is not an option').format(self.path)
|
||||
|
||||
|
||||
# ____________________________________________________________
|
||||
# Exceptions for a Config
|
||||
class ConfigError(Exception):
|
||||
|
|
@ -163,8 +229,74 @@ class ConflictError(Exception):
|
|||
# ____________________________________________________________
|
||||
# miscellaneous exceptions
|
||||
class LeadershipError(Exception):
|
||||
"problem with a leadership's value length"
|
||||
pass
|
||||
def __init__(
|
||||
self,
|
||||
subconfig: Union[str, "SubConfig"],
|
||||
code,
|
||||
*,
|
||||
prop=None,
|
||||
index=None,
|
||||
length=None,
|
||||
callback=None,
|
||||
args=None,
|
||||
kwargs=None,
|
||||
ret=None,
|
||||
):
|
||||
if isinstance(subconfig, str):
|
||||
self.path = self.display_name = subconfig
|
||||
else:
|
||||
self.path = subconfig.path
|
||||
option = subconfig.option
|
||||
self.display_name = option.impl_get_display_name(subconfig, with_quote=True)
|
||||
self.code = code
|
||||
if prop:
|
||||
self.prop = prop
|
||||
if index:
|
||||
self.index = index
|
||||
if length:
|
||||
self.length = length
|
||||
if callback:
|
||||
self.callback = callback
|
||||
if args:
|
||||
self.args = args
|
||||
if kwargs:
|
||||
self.kwargs = kwargs
|
||||
if ret:
|
||||
self.ret = ret
|
||||
|
||||
def __str__(self):
|
||||
if self.code == "leadership-group_type":
|
||||
return _('cannot set "group_type" attribute for the Leadership {0}').format(
|
||||
self.display_name
|
||||
)
|
||||
if self.code == "leadership-wrong_property":
|
||||
return _('the leader {0} cannot have "{1}" property').format(
|
||||
self.display_name, self.prop
|
||||
)
|
||||
if self.code == "leadership-force_default_on_freeze":
|
||||
return _(
|
||||
'the leader {0} cannot have "force_default_on_freeze" or "force_metaconfig_on_freeze" property without "frozen"'
|
||||
).format(self.display_name)
|
||||
if self.code == "leadership-reduce":
|
||||
return _("cannot reduce length of the leader {0}").format(self.display_name)
|
||||
if self.code == "leadership-greater":
|
||||
return _(
|
||||
'index "{0}" is greater than the leadership length "{1}" for option {2}'
|
||||
).format(self.index, self.length, self.display_name)
|
||||
if self.code == "leadership-follower-greater":
|
||||
return _(
|
||||
"the follower option {0} has greater length ({1}) than the leader length ({2})"
|
||||
).format(self.display_name, self.index, self.length)
|
||||
if self.code == "leadership-follower-callback-list":
|
||||
if self.args or self.kwargs:
|
||||
return _(
|
||||
'the "{0}" function with positional arguments "{1}" and keyword arguments "{2}" must not return a list ("{3}") for the follower option {4}'
|
||||
).format(
|
||||
self.callback, self.args, self.kwargs, self.ret, self.display_name
|
||||
)
|
||||
return _(
|
||||
'the "{0}" function must not return a list ("{1}") for the follower option {2}'
|
||||
).format(self.callback, self.ret, self.display_name)
|
||||
|
||||
|
||||
class ConstError(TypeError):
|
||||
|
|
@ -186,7 +318,9 @@ class _CommonError:
|
|||
try:
|
||||
msg = self.prefix
|
||||
except AttributeError:
|
||||
self.prefix = self.tmpl.format(self.val, _(self.display_type), self.name, self.index)
|
||||
self.prefix = self.tmpl.format(
|
||||
self.val, _(self.display_type), self.name, self.index
|
||||
)
|
||||
msg = self.prefix
|
||||
if self.err_msg:
|
||||
if msg:
|
||||
|
|
@ -203,12 +337,16 @@ class ValueWarning(_CommonError, UserWarning):
|
|||
|
||||
def __init__(self, **kwargs):
|
||||
if ValueWarning.tmpl is None:
|
||||
if kwargs.get('index') is None:
|
||||
ValueWarning.tmpl = _('attention, "{0}" could be an invalid {1} for {2}')
|
||||
if kwargs.get("index") is None:
|
||||
ValueWarning.tmpl = _(
|
||||
'attention, "{0}" could be an invalid {1} for {2}'
|
||||
)
|
||||
else:
|
||||
ValueWarning.tmpl = _('attention, "{0}" could be an invalid {1} for {2} at index "{3}"')
|
||||
if list(kwargs) == ['msg']:
|
||||
self.msg = kwargs['msg']
|
||||
ValueWarning.tmpl = _(
|
||||
'attention, "{0}" could be an invalid {1} for {2} at index "{3}"'
|
||||
)
|
||||
if list(kwargs) == ["msg"]:
|
||||
self.msg = kwargs["msg"]
|
||||
else:
|
||||
super().__init__(**kwargs)
|
||||
self.msg = None
|
||||
|
|
@ -224,7 +362,7 @@ class ValueOptionError(_CommonError, ValueError):
|
|||
|
||||
def __init__(self, **kwargs):
|
||||
if ValueOptionError.tmpl is None:
|
||||
if kwargs.get('index') is None:
|
||||
if kwargs.get("index") is None:
|
||||
self.tmpl = _('"{0}" is an invalid {1} for {2}')
|
||||
else:
|
||||
self.tmpl = _('"{0}" is an invalid {1} for {2} at index "{3}"')
|
||||
|
|
@ -258,12 +396,12 @@ class CancelParam(Exception):
|
|||
|
||||
class Errors:
|
||||
@staticmethod
|
||||
def raise_carry_out_calculation_error(subconfig, message, original_error, option=None, extra_keys=[]):
|
||||
def raise_carry_out_calculation_error(
|
||||
subconfig, message, original_error, option=None, extra_keys=[]
|
||||
):
|
||||
if option is None:
|
||||
option = subconfig.option
|
||||
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:
|
||||
raise ConfigError(
|
||||
message.format(display_name, original_error, *extra_keys)
|
||||
|
|
|
|||
|
|
@ -176,9 +176,7 @@ class DomainnameOption(StrOption):
|
|||
try:
|
||||
socket.gethostbyname(value)
|
||||
except socket.gaierror as err:
|
||||
raise ValueError(
|
||||
_("DNS resolution failed").format(value)
|
||||
) from err
|
||||
raise ValueError(_("DNS resolution failed").format(value)) from err
|
||||
except Exception as err:
|
||||
raise ValueError(
|
||||
_("error resolving DNS: {1}").format(value, err)
|
||||
|
|
|
|||
|
|
@ -74,9 +74,12 @@ class FilenameOption(StrOption):
|
|||
if not found and "directory" in types and file.is_dir():
|
||||
found = True
|
||||
if not found:
|
||||
translated_types = [{"file": _("file"), "directory": _("directory")}.get(typ) for typ in types]
|
||||
translated_types = [
|
||||
{"file": _("file"), "directory": _("directory")}.get(typ)
|
||||
for typ in types
|
||||
]
|
||||
raise ValueError(
|
||||
_('cannot find this {0}').format(
|
||||
_("cannot find this {0}").format(
|
||||
display_list(translated_types, separator="or"), value
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class IntOption(Option):
|
|||
value: int,
|
||||
) -> None:
|
||||
if not isinstance(value, int):
|
||||
raise ValueError(_('which is not an integer'))
|
||||
raise ValueError(_("which is not an integer"))
|
||||
|
||||
def second_level_validation(self, value, warnings_only):
|
||||
min_number = self.impl_get_extra("min_number")
|
||||
|
|
|
|||
|
|
@ -51,9 +51,7 @@ class Leadership(OptionDescription):
|
|||
**kwargs,
|
||||
) -> None:
|
||||
if "group_type" in kwargs:
|
||||
raise LeadershipError(
|
||||
_('cannot set "group_type" attribute for a Leadership')
|
||||
)
|
||||
raise LeadershipError(name, "leadership-group_type")
|
||||
super().__init__(
|
||||
name,
|
||||
doc,
|
||||
|
|
@ -85,9 +83,7 @@ class Leadership(OptionDescription):
|
|||
if prop not in ALLOWED_LEADER_PROPERTIES and not isinstance(
|
||||
prop, Calculation
|
||||
):
|
||||
raise LeadershipError(
|
||||
_('leader cannot have "{}" property').format(prop)
|
||||
)
|
||||
raise LeadershipError(name, "leadership-wrong_property", prop=prop)
|
||||
|
||||
def _check_child_is_valid(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -269,8 +269,11 @@ class Option(BaseOption):
|
|||
config_properties = subconfig.config_bag.properties
|
||||
self_properties = subconfig.properties
|
||||
else:
|
||||
config_properties = {'validator'}
|
||||
if "validator" not in config_properties or "validator" not in self_properties:
|
||||
config_properties = {"validator"}
|
||||
if (
|
||||
"validator" not in config_properties
|
||||
or "validator" not in self_properties
|
||||
):
|
||||
return False
|
||||
if subconfig:
|
||||
force_index = subconfig.index
|
||||
|
|
@ -443,11 +446,21 @@ class Option(BaseOption):
|
|||
or "demoting_error_warning" not in subconfig.config_bag.properties
|
||||
):
|
||||
raise ValueOptionError(
|
||||
subconfig=subconfig, val=val, display_type=_(self.get_type()), opt=self, err_msg=str(err), index=err_index
|
||||
subconfig=subconfig,
|
||||
val=val,
|
||||
display_type=_(self.get_type()),
|
||||
opt=self,
|
||||
err_msg=str(err),
|
||||
index=err_index,
|
||||
) from err
|
||||
warnings.warn_explicit(
|
||||
ValueErrorWarning(
|
||||
subconfig=subconfig, val=val, display_type=_(self.get_type()), opt=self, err_msg=str(err), index=err_index
|
||||
subconfig=subconfig,
|
||||
val=val,
|
||||
display_type=_(self.get_type()),
|
||||
opt=self,
|
||||
err_msg=str(err),
|
||||
index=err_index,
|
||||
),
|
||||
ValueErrorWarning,
|
||||
self.__class__.__name__,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ from ..setting import ConfigBag, groups, undefined, owners, Undefined
|
|||
from .baseoption import BaseOption
|
||||
|
||||
# from .syndynoption import SubDynOptionDescription, SynDynOptionDescription
|
||||
from ..error import ConfigError, ConflictError
|
||||
from ..error import ConfigError, ConflictError, AttributeOptionError
|
||||
|
||||
|
||||
class CacheOptionDescription(BaseOption):
|
||||
|
|
@ -242,12 +242,10 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
|||
] # pylint: disable=no-member
|
||||
if option.impl_is_dynoptiondescription() and not allow_dynoption:
|
||||
if parent.path:
|
||||
path = parent.path + '.' + name
|
||||
path = parent.path + "." + name
|
||||
else:
|
||||
path = name
|
||||
raise AttributeError(
|
||||
_('cannot access to "{0}" it\'s a dynamic option').format(path)
|
||||
)
|
||||
raise AttributeOptionError(path, "option-dynamic")
|
||||
return option
|
||||
|
||||
def get_child(
|
||||
|
|
@ -279,14 +277,10 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
|||
return child
|
||||
return identifier, child
|
||||
if parent.path is None:
|
||||
raise AttributeError(
|
||||
_('cannot find "{0}"').format(name)
|
||||
)
|
||||
raise AttributeError(
|
||||
_('cannot find "{0}" in "{1}"').format(
|
||||
name, parent.path
|
||||
)
|
||||
)
|
||||
path = name
|
||||
else:
|
||||
path = parent.path + "." + name
|
||||
raise AttributeOptionError(path, "option-not-found")
|
||||
|
||||
def get_children(self) -> List[BaseOption]:
|
||||
"""get children"""
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class StrOption(Option):
|
|||
) -> None:
|
||||
"""validation"""
|
||||
if not isinstance(value, str):
|
||||
raise ValueError(_('which is not a string'))
|
||||
raise ValueError(_("which is not a string"))
|
||||
|
||||
|
||||
class RegexpOption(StrOption):
|
||||
|
|
|
|||
|
|
@ -476,7 +476,7 @@ class Settings:
|
|||
and new_prop not in ALLOWED_LEADER_PROPERTIES
|
||||
):
|
||||
raise LeadershipError(
|
||||
_('leader cannot have "{new_prop}" property')
|
||||
subconfig, "leadership-wrong_property", prop=new_prop
|
||||
)
|
||||
props.add(new_prop)
|
||||
props -= self.getpermissives(subconfig)
|
||||
|
|
@ -564,19 +564,15 @@ class Settings:
|
|||
not_allowed_properties = properties - ALLOWED_LEADER_PROPERTIES
|
||||
if not_allowed_properties:
|
||||
raise LeadershipError(
|
||||
_('leader cannot have "{0}" property').format(
|
||||
display_list(not_allowed_properties)
|
||||
)
|
||||
subconfig,
|
||||
"leadership-wrong_property",
|
||||
prop=display_list(not_allowed_properties),
|
||||
)
|
||||
if (
|
||||
"force_default_on_freeze" in properties
|
||||
or "force_metaconfig_on_freeze" in properties
|
||||
) and "frozen" not in properties:
|
||||
raise LeadershipError(
|
||||
_(
|
||||
'a leader ({0}) cannot have "force_default_on_freeze" or "force_metaconfig_on_freeze" property without "frozen"'
|
||||
).format(opt.impl_get_display_name())
|
||||
)
|
||||
raise LeadershipError(subconfig, "leadership-force_default_on_freeze")
|
||||
self._properties.setdefault(subconfig.path, {})[subconfig.index] = properties
|
||||
# values too because of follower values could have a PropertiesOptionError has value
|
||||
subconfig.config_bag.context.reset_cache(subconfig)
|
||||
|
|
|
|||
|
|
@ -295,9 +295,9 @@ class Values:
|
|||
owners.forced,
|
||||
)
|
||||
validator = (
|
||||
"validator" in setting_properties and
|
||||
"validator" in self_properties and
|
||||
"demoting_error_warning" not in setting_properties
|
||||
"validator" in setting_properties
|
||||
and "validator" in self_properties
|
||||
and "demoting_error_warning" not in setting_properties
|
||||
)
|
||||
if validator and not has_calculation:
|
||||
cache = subconfig.config_bag.context.get_values_cache()
|
||||
|
|
@ -306,7 +306,11 @@ class Values:
|
|||
value,
|
||||
validated=validator,
|
||||
)
|
||||
elif "validator" in setting_properties and "validator" in self_properties and has_calculation:
|
||||
elif (
|
||||
"validator" in setting_properties
|
||||
and "validator" in self_properties
|
||||
and has_calculation
|
||||
):
|
||||
cache = subconfig.config_bag.context.get_values_cache()
|
||||
cache.delcache(subconfig.path)
|
||||
|
||||
|
|
@ -592,7 +596,12 @@ class Values:
|
|||
self_properties = subconfig.properties
|
||||
context = config_bag.context
|
||||
setting_properties = config_bag.properties
|
||||
if validate and hasvalue and "validator" in setting_properties and "validator" in self_properties:
|
||||
if (
|
||||
validate
|
||||
and hasvalue
|
||||
and "validator" in setting_properties
|
||||
and "validator" in self_properties
|
||||
):
|
||||
fake_context = context.gen_fake_context()
|
||||
fake_config_bag = config_bag.copy()
|
||||
fake_config_bag.remove_validation()
|
||||
|
|
|
|||
Loading…
Reference in a new issue