return true error message when validation
authorEmmanuel Garette <egarette@cadoles.com>
Wed, 17 Jul 2013 18:48:46 +0000 (20:48 +0200)
committerEmmanuel Garette <egarette@cadoles.com>
Wed, 17 Jul 2013 18:48:46 +0000 (20:48 +0200)
tiramisu/option.py
tiramisu/value.py

index 94d1aa1..512242a 100644 (file)
@@ -140,9 +140,12 @@ class Option(BaseInformation):
         if not self._multi and default_multi is not None:
             raise ValueError(_("a default_multi is set whereas multi is False"
                              " in option: {0}").format(name))
-        if default_multi is not None and not self._validate(default_multi):
-            raise ValueError(_("invalid default_multi value {0} "
-                             "for option {1}").format(str(default_multi), name))
+        if default_multi is not None:
+            try:
+                self._validate(default_multi)
+            except ValueError, err:
+                raise ValueError(_("invalid default_multi value {0} "
+                                   "for option {1}: {2}").format(str(default_multi), name, err))
         if callback is not None and (default is not None or default_multi is not None):
             raise ValueError(_("defaut values not allowed if option: {0} "
                              "is calculated").format(name))
@@ -253,34 +256,35 @@ class Option(BaseInformation):
         if not validate:
             return
 
-        def _val_validator(val):
-            callback_params = deepcopy(self._validator[1])
-            callback_params.setdefault('', []).insert(0, val)
-            return carry_out_calculation(self._name, config=context,
-                                         callback=self._validator[0],
-                                         callback_params=callback_params)
-
-        def val_validator():
-            #add current value has first argument
-            if self.impl_is_multi():
-                for val in value:
-                    if not _val_validator(val):
-                        return False
-                return True
+        def val_validator(val):
+            if self._validator is not None:
+                callback_params = deepcopy(self._validator[1])
+                callback_params.setdefault('', []).insert(0, val)
+                return carry_out_calculation(self._name, config=context,
+                                             callback=self._validator[0],
+                                             callback_params=callback_params)
             else:
-                return _val_validator(value)
+                return True
+
+        def do_validation(_value, _index=None):
+            if _value is None:
+                return True
+            if not val_validator(_value):
+                raise ValueError(_("invalid value {0} for option {1} for object {2}"
+                                   "").format(_value, self._name, self.__class__))
+            try:
+                self._validate(_value)
+            except ValueError, err:
+                raise ValueError(_("invalid value {0} for option {1}: {2}"
+                                   "").format(_value, self._name, err))
+            if context is not None:
+                descr._valid_consistency(self, _value, context, _index)
 
         # generic calculation
         if context is not None:
             descr = context.cfgimpl_get_description()
         if not self._multi:
-            if value is not None and ((self._validator is not None and
-                                       not val_validator()) or
-                                      not self._validate(value)):
-                raise ValueError(_("invalid value {0} for option {1} (type {2})"
-                                   "").format(value, self._name, self.__class__))
-            if context is not None:
-                descr._valid_consistency(self, value, context, None)
+            do_validation(value)
         else:
             if not isinstance(value, list):
                 raise ValueError(_("invalid value {0} for option {1} "
@@ -288,13 +292,7 @@ class Option(BaseInformation):
                                                                   self._name))
             for index in range(0, len(value)):
                 val = value[index]
-                if val is not None and ((self._validator is not None and
-                                         not val_validator()) or
-                                        not self._validate(val)):
-                        raise ValueError(_("invalid value {0} for option {1}"
-                                           "").format(value, self._name))
-                if context is not None:
-                    descr._valid_consistency(self, val, context, index)
+                do_validation(val, index)
 
     def impl_getdefault(self, default_multi=False):
         "accessing the default value"
@@ -398,10 +396,9 @@ class ChoiceOption(Option):
         return self._open_values
 
     def _validate(self, value):
-        if not self._open_values:
-            return value is None or value in self._values
-        else:
-            return True
+        if not self._open_values and not value in self._values:
+            raise ValueError(_('value {0} is not permitted, only {1} is allowed'
+                               '').format(value, self._values))
 
 
 class BoolOption(Option):
@@ -410,7 +407,8 @@ class BoolOption(Option):
     _opt_type = 'bool'
 
     def _validate(self, value):
-        return isinstance(value, bool)
+        if not isinstance(value, bool):
+            raise ValueError(_('value must be a boolean'))
 
 
 class IntOption(Option):
@@ -419,7 +417,8 @@ class IntOption(Option):
     _opt_type = 'int'
 
     def _validate(self, value):
-        return isinstance(value, int)
+        if not isinstance(value, int):
+            raise ValueError(_('value must be an integer'))
 
 
 class FloatOption(Option):
@@ -428,7 +427,8 @@ class FloatOption(Option):
     _opt_type = 'float'
 
     def _validate(self, value):
-        return isinstance(value, float)
+        if not isinstance(value, float):
+            raise ValueError(_('value must be a float'))
 
 
 class StrOption(Option):
@@ -437,7 +437,8 @@ class StrOption(Option):
     _opt_type = 'string'
 
     def _validate(self, value):
-        return isinstance(value, str)
+        if not isinstance(value, str):
+            raise ValueError(_('value must be a string'))
 
 
 class UnicodeOption(Option):
@@ -447,7 +448,8 @@ class UnicodeOption(Option):
     _empty = u''
 
     def _validate(self, value):
-        return isinstance(value, unicode)
+        if not isinstance(value, unicode):
+            raise ValueError(_('value must be an unicode'))
 
 
 class SymLinkOption(object):
@@ -490,15 +492,11 @@ class IPOption(Option):
                                        properties=properties)
 
     def _validate(self, value):
-        try:
-            ip = IP('{0}/32'.format(value))
-            if ip.iptype() == 'RESERVED':
-                return False
-            if self._only_private:
-                return ip.iptype() == 'PRIVATE'
-            return True
-        except ValueError:
-            return False
+        ip = IP('{0}/32'.format(value))
+        if ip.iptype() == 'RESERVED':
+            raise ValueError(_("IP mustn't not be in reserved class"))
+        if self._only_private and not ip.iptype() == 'PRIVATE':
+            raise ValueError(_("IP must be in private class"))
 
 
 class PortOption(Option):
@@ -552,23 +550,19 @@ class PortOption(Option):
                                          properties=properties)
 
     def _validate(self, value):
-        try:
-            if self._allow_range and ":" in str(value):
-                value = str(value).split(':')
-                if len(value) != 2:
-                    return False
-                if not value[0] < value[1]:
-                    return False
-            else:
-                value = [value]
+        if self._allow_range and ":" in str(value):
+            value = str(value).split(':')
+            if len(value) != 2:
+                raise ValueError('range must have two values only')
+            if not value[0] < value[1]:
+                raise ValueError('first port in range must be smaller than the second one')
+        else:
+            value = [value]
 
-            for val in value:
-                if not self._min_value <= int(val) <= self._max_value:
-                    return False
-
-            return True
-        except ValueError:
-            return False
+        for val in value:
+            if not self._min_value <= int(val) <= self._max_value:
+                raise ValueError('port must be an between {0} and {1}'
+                                 ''.format(self._min_value, self._max_value))
 
 
 class NetworkOption(Option):
@@ -577,13 +571,9 @@ class NetworkOption(Option):
     _opt_type = 'network'
 
     def _validate(self, value):
-        try:
-            ip = IP(value)
-            if ip.iptype() == 'RESERVED':
-                return False
-            return True
-        except ValueError:
-            return False
+        ip = IP(value)
+        if ip.iptype() == 'RESERVED':
+            raise ValueError(_("network mustn't not be in reserved class"))
 
 
 class NetmaskOption(Option):
@@ -592,11 +582,7 @@ class NetmaskOption(Option):
     _opt_type = 'netmask'
 
     def _validate(self, value):
-        try:
-            IP('0.0.0.0/{0}'.format(value))
-            return True
-        except ValueError:
-            return False
+        IP('0.0.0.0/{0}'.format(value))
 
     def _cons_network_netmask(self, optname, value, value_):
         #opts must be (netmask, network) options
@@ -669,7 +655,7 @@ class DomainnameOption(Option):
         if self._allow_ip is True:
             try:
                 IP('{0}/32'.format(value))
-                return True
+                return
             except ValueError:
                 pass
         if self._type == 'netbios':
@@ -688,7 +674,8 @@ class DomainnameOption(Option):
             raise ValueError(_("invalid value's length for {0} (max {1})"
                                "").format(self._name, length))
         regexp = r'^[a-z]([a-z\d{0}-])*[a-z\d]$'.format(extrachar)
-        return re.match(regexp, value) is not None
+        if re.match(regexp, value) is None:
+            raise ValueError(_('invalid domainname'))
 
 
 class OptionDescription(BaseInformation):
@@ -896,6 +883,7 @@ def validate_requires_arg(requires, name):
 
     for require in requires:
         if not type(require) == dict:
+            print require
             raise ValueError(_("malformed requirements type for option:"
                                " {0}, must be a dict").format(name))
         valid_keys = ('option', 'expected', 'action', 'inverse', 'transitive',
@@ -929,14 +917,18 @@ def validate_requires_arg(requires, name):
                                ' same_action must be boolean'))
 
         if not isinstance(option, Option):
-            raise ValueError(_('malformed requirements first argument '
+            print option, type(option)
+            raise ValueError(_('malformed requirements '
                                'must be an option in option {0}').format(name))
         if option.impl_is_multi():
             raise ValueError(_('malformed requirements option {0} '
                                'should not be a multi').format(name))
-        if expected is not None and not option._validate(expected):
-            raise ValueError(_('malformed requirements second argument '
-                               'must be valid for option {0}').format(name))
+        if expected is not None:
+            try:
+                option._validate(expected)
+            except ValueError, err:
+                raise ValueError(_('malformed requirements second argument '
+                                   'must be valid for option {0}: {1}').format(name, err))
         if action in config_action:
             if inverse != config_action[action]:
                 raise ValueError(_("inconsistency in action types for option: {0}"
index 851b340..65a23b1 100644 (file)
@@ -361,10 +361,13 @@ class Multi(list):
         super(Multi, self).extend(iterable)
 
     def _validate(self, value):
-        if value is not None and not self.opt._validate(value):
-            raise ValueError(_("invalid value {0} "
-                             "for option {1}").format(str(value),
-                                                      self.opt._name))
+        if value is not None:
+            try:
+                self.opt._validate(value)
+            except ValueError, err:
+                raise ValueError(_("invalid value {0} "
+                                   "for option {1}: {2}").format(str(value),
+                                                                 self.opt._name, err))
 
     def pop(self, key, force=False):
         """the list value can be updated (poped)