From c21949c637a2497266762b2d8b2eda07f62579af Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Sun, 11 Sep 2016 16:18:23 +0200 Subject: [PATCH] better error messages --- tiramisu/option/baseoption.py | 28 +++++++++++++++++++++------- tiramisu/option/option.py | 32 ++++++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/tiramisu/option/baseoption.py b/tiramisu/option/baseoption.py index 2ccfd0a..bc639ac 100644 --- a/tiramisu/option/baseoption.py +++ b/tiramisu/option/baseoption.py @@ -490,8 +490,15 @@ class Option(OnlyOption): 'submulti_index: {2}'.format(_value, _index, submulti_index), exc_info=True) - return ValueError(_('invalid value for option {0}: {1}' - '').format(self.impl_getname(), err)) + if '{0}'.format(err): + msg = _('{0} is an invalid {1} for option {2}: {3}' + '').format(_value, self.display_name, + self.impl_getname(), err) + else: + msg = _('{0} is an invalid {1} for option {2}' + '').format(_value, self.display_name, + self.impl_getname()) + return ValueError(msg) warning = None error = calculation_validator(_value) if not error: @@ -515,16 +522,23 @@ class Option(OnlyOption): else: return ret if warning: - msg = _("warning on the value of the option {0}: {1}").format( - self.impl_getname(), warning) + msg = _("attention, {0} could be an invalid {1} for option {2}: {3}").format( + _value, self.display_name, self.impl_getname(), warning) if context is undefined or 'warnings' in \ context.cfgimpl_get_settings(): warnings.warn_explicit(ValueWarning(msg, self), ValueWarning, self.__class__.__name__, 0) elif error: - return ValueError(_("invalid value for option {0}: {1}").format( - self.impl_getname(), error)) + if '{0}'.format(err): + msg = _("{0} is an invalid {1} for option {2}: {3}" + "").format(_value, self.display_name, + self.impl_getname(), error) + else: + msg = _("{0} is an invalid {1} for option {2}" + "").format(_value, self.display_name, + self.impl_getname()) + return ValueError(msg) # generic calculation #if context is not undefined: @@ -568,7 +582,7 @@ class Option(OnlyOption): return err else: return self._valid_consistency(current_opt, None, context, - None, None) + None, None) def impl_is_master_slaves(self, type_='both'): """FIXME diff --git a/tiramisu/option/option.py b/tiramisu/option/option.py index fed1d72..afdd35a 100644 --- a/tiramisu/option/option.py +++ b/tiramisu/option/option.py @@ -37,6 +37,7 @@ class ChoiceOption(Option): The option can also have the value ``None`` """ __slots__ = tuple() + display_name = _('choice') def __init__(self, name, doc, values, default=None, values_params=None, default_multi=None, requires=None, @@ -108,6 +109,7 @@ class ChoiceOption(Option): class BoolOption(Option): "represents a choice between ``True`` and ``False``" __slots__ = tuple() + display_name = _('boolean') def _validate(self, value, context=undefined, current_opt=undefined, returns_raise=False): @@ -118,6 +120,7 @@ class BoolOption(Option): class IntOption(Option): "represents a choice of an integer" __slots__ = tuple() + display_name = _('integer') def _validate(self, value, context=undefined, current_opt=undefined, returns_raise=False): @@ -128,6 +131,7 @@ class IntOption(Option): class FloatOption(Option): "represents a choice of a floating point number" __slots__ = tuple() + display_name = _('float') def _validate(self, value, context=undefined, current_opt=undefined, returns_raise=False): @@ -138,6 +142,7 @@ class FloatOption(Option): class StrOption(Option): "represents the choice of a string" __slots__ = tuple() + display_name = _('string') def _validate(self, value, context=undefined, current_opt=undefined, returns_raise=False): @@ -155,6 +160,7 @@ else: "represents the choice of a unicode string" __slots__ = tuple() _empty = u'' + display_name = _('string') def _validate(self, value, context=undefined, current_opt=undefined, returns_raise=False): @@ -165,6 +171,7 @@ else: class PasswordOption(Option): "represents the choice of a password" __slots__ = tuple() + display_name = _('password') def _validate(self, value, context=undefined, current_opt=undefined, returns_raise=False): @@ -176,6 +183,7 @@ class PasswordOption(Option): class IPOption(Option): "represents the choice of an ip" __slots__ = tuple() + display_name = _('IP') def __init__(self, name, doc, default=None, default_multi=None, requires=None, multi=False, callback=None, @@ -204,29 +212,29 @@ class IPOption(Option): if err: return err if value.count('.') != 3: - return ValueError(_('invalid IP')) + return ValueError() for val in value.split('.'): if val.startswith("0") and len(val) > 1: - return ValueError(_('invalid IP')) # pragma: optional cover + return ValueError() # pragma: optional cover # 'standard' validation try: IP('{0}/32'.format(value)) except ValueError: # pragma: optional cover - return ValueError(_('invalid IP')) + return ValueError() def _second_level_validation(self, value, warnings_only): ip = IP('{0}/32'.format(value)) if not self._get_extra('_allow_reserved') and ip.iptype() == 'RESERVED': # pragma: optional cover if warnings_only: - msg = _("IP is in reserved class") + msg = _("shouldn't in reserved class") else: - msg = _("invalid IP, mustn't be in reserved class") + msg = _("mustn't be in reserved class") return ValueError(msg) if self._get_extra('_private_only') and not ip.iptype() == 'PRIVATE': # pragma: optional cover if warnings_only: - msg = _("IP is not in private class") + msg = _("should be in private class") else: - msg = _("invalid IP, must be in private class") + msg = _("must be in private class") return ValueError(msg) def _cons_in_network(self, opts, vals, warnings_only): @@ -260,6 +268,7 @@ class PortOption(Option): """ __slots__ = tuple() port_re = re.compile(r"^[0-9]*$") + display_name = _('port') def __init__(self, name, doc, default=None, default_multi=None, requires=None, multi=False, callback=None, @@ -290,7 +299,6 @@ class PortOption(Option): if extra['_max_value'] is None: raise ValueError(_('max value is empty')) # pragma: optional cover - super(PortOption, self).__init__(name, doc, default=default, default_multi=default_multi, callback=callback, @@ -337,6 +345,7 @@ class PortOption(Option): class NetworkOption(Option): "represents the choice of a network" __slots__ = tuple() + display_name = _('network') def _validate(self, value, context=undefined, current_opt=undefined, returns_raise=False): @@ -366,6 +375,7 @@ class NetworkOption(Option): class NetmaskOption(Option): "represents the choice of a netmask" __slots__ = tuple() + display_name = _('netmask') def _validate(self, value, context=undefined, current_opt=undefined, returns_raise=False): @@ -422,6 +432,7 @@ class NetmaskOption(Option): class BroadcastOption(Option): __slots__ = tuple() + display_name = _('broadcast') def _validate(self, value, context=undefined, current_opt=undefined, returns_raise=False): @@ -454,6 +465,7 @@ class DomainnameOption(Option): fqdn: with tld, not supported yet """ __slots__ = tuple() + display_name = _('domain name') def __init__(self, name, doc, default=None, default_multi=None, requires=None, multi=False, callback=None, @@ -552,6 +564,7 @@ class DomainnameOption(Option): class EmailOption(DomainnameOption): __slots__ = tuple() username_re = re.compile(r"^[\w!#$%&'*+\-/=?^`{|}~.]+$") + display_name = _('email') def _validate(self, value, context=undefined, current_opt=undefined, returns_raise=False): @@ -577,6 +590,7 @@ class URLOption(DomainnameOption): __slots__ = tuple() proto_re = re.compile(r'(http|https)://') path_re = re.compile(r"^[A-Za-z0-9\-\._~:/\?#\[\]@!%\$&\'\(\)\*\+,;=]+$") + display_name = _('URL') def _validate(self, value, context=undefined, current_opt=undefined, returns_raise=False): @@ -624,6 +638,7 @@ class UsernameOption(Option): __slots__ = tuple() #regexp build with 'man 8 adduser' informations username_re = re.compile(r"^[a-z_][a-z0-9_-]{0,30}[$a-z0-9_-]{0,1}$") + display_name = _('username') def _validate(self, value, context=undefined, current_opt=undefined, returns_raise=False): @@ -638,6 +653,7 @@ class UsernameOption(Option): class FilenameOption(Option): __slots__ = tuple() path_re = re.compile(r"^[a-zA-Z0-9\-\._~/+]+$") + display_name = _('file name') def _validate(self, value, context=undefined, current_opt=undefined, returns_raise=False):