some improvements
[tiramisu.git] / tiramisu / option / baseoption.py
index 55aaf71..de2e35f 100644 (file)
@@ -367,8 +367,8 @@ class Option(OnlyOption):
     __slots__ = tuple()
     _empty = ''
 
-    def _launch_consistency(self, func, option, value, context, index,
-                            submulti_index, all_cons_opts, warnings_only,
+    def _launch_consistency(self, current_opt, func, option, value, context,
+                            index, submulti_index, all_cons_opts, warnings_only,
                             transitive):
         """Launch consistency now
 
@@ -434,7 +434,7 @@ class Option(OnlyOption):
                     #only check properties for slaves
                     val_consistencies = False
         if val_consistencies:
-            return getattr(self, func)(all_cons_opts, all_cons_vals, warnings_only)
+            return getattr(self, func)(current_opt, all_cons_opts, all_cons_vals, warnings_only)
 
     def impl_validate(self, value, context=undefined, validate=True,
                       force_index=None, force_submulti_index=None,
@@ -483,37 +483,41 @@ class Option(OnlyOption):
 
         def do_validation(_value, _index, submulti_index):
             if _value is None:
-                return
-            # option validation
-            err = self._validate(_value, context, current_opt,
-                                 returns_raise=True)
-            if err:
-                if debug:
-                    log.debug('do_validation: value: {0}, index: {1}, '
-                              'submulti_index: {2}'.format(_value, _index,
-                                                           submulti_index),
-                              exc_info=True)
-                err_msg = '{0}'.format(err)
-                if err_msg:
-                    msg = _('{0} is an invalid {1} for option {2}, {3}'
-                            '').format(_value, self.display_name,
-                                       self.impl_getname(), err_msg)
-                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:
-                error = self._second_level_validation(_value, self._is_warnings_only())
-            if error:
-                if debug:
-                    log.debug(_('do_validation for {0}: error in value').format(
-                        self.impl_getname()), exc_info=True)
-                if self._is_warnings_only():
-                    warning = error
-                    error = None
+                error = warning = None
+            else:
+                # option validation
+                err = self._validate(_value, context, current_opt,
+                                     returns_raise=True)
+                if err:
+                    if debug:
+                        log.debug('do_validation: value: {0}, index: {1}, '
+                                  'submulti_index: {2}'.format(_value, _index,
+                                                               submulti_index),
+                                  exc_info=True)
+                    err_msg = '{0}'.format(err)
+                    name = self.impl_getdoc()
+                    if name is None or name == '':
+                        name = self.impl_getname()
+                    if err_msg:
+                        msg = _('"{0}" is an invalid {1} for "{2}", {3}'
+                                '').format(_value, self._display_name,
+                                           self.impl_get_display_name(), err_msg)
+                    else:
+                        msg = _('"{0}" is an invalid {1} for "{2}"'
+                                '').format(_value, self._display_name,
+                                           self.impl_get_display_name())
+                    return ValueError(msg)
+                warning = None
+                error = calculation_validator(_value)
+                if not error:
+                    error = self._second_level_validation(_value, self._is_warnings_only())
+                if error:
+                    if debug:
+                        log.debug(_('do_validation for {0}: error in value').format(
+                            self.impl_getname()), exc_info=True)
+                    if self._is_warnings_only():
+                        warning = error
+                        error = None
             if error is None and warning is None:
                 # if context launch consistency validation
                 #if context is not undefined:
@@ -527,8 +531,8 @@ class Option(OnlyOption):
                     else:
                         return ret
             if warning:
-                msg = _("attention, {0} could be an invalid {1} for option {2}, {3}").format(
-                    _value, self.display_name, self.impl_getname(), warning)
+                msg = _('attention, "{0}" could be an invalid {1} for "{2}", {3}').format(
+                    _value, self._display_name, self.impl_get_display_name(), warning)
                 if context is undefined or 'warnings' in \
                         context.cfgimpl_get_settings():
                     warnings.warn_explicit(ValueWarning(msg, self),
@@ -537,13 +541,13 @@ class Option(OnlyOption):
             elif error:
                 err_msg = '{0}'.format(error)
                 if err_msg:
-                    msg = _("{0} is an invalid {1} for option {2}, {3}"
-                            "").format(_value, self.display_name,
-                                       self.impl_getname(), err_msg)
+                    msg = _('"{0}" is an invalid {1} for "{2}", {3}'
+                            '').format(_value, self._display_name,
+                                       self.impl_get_display_name(), err_msg)
                 else:
-                    msg = _("{0} is an invalid {1} for option {2}"
-                            "").format(_value, self.display_name,
-                                       self.impl_getname())
+                    msg = _('"{0}" is an invalid {1} for "{2}"'
+                            '').format(_value, self._display_name,
+                                       self.impl_get_display_name())
                 return ValueError(msg)
 
         # generic calculation
@@ -618,6 +622,12 @@ class Option(OnlyOption):
         "accesses the Option's doc"
         return self.impl_get_information('doc')
 
+    def impl_get_display_name(self):
+        name = self.impl_getdoc()
+        if name is None or name == '':
+            name = self.impl_getname()
+        return name
+
     def _valid_consistencies(self, other_opts):
         if self._is_subdyn():
             dynod = self._impl_getsubdyn()
@@ -706,27 +716,42 @@ class Option(OnlyOption):
                         opts.append(opt._impl_to_dyn(name, path))
                 else:
                     opts = all_cons_opts
-                err = opts[0]._launch_consistency(func, option, value, context,
-                                                  index, submulti_idx, opts,
-                                                  warnings_only, transitive)
+                err = opts[0]._launch_consistency(self, func, option, value,
+                                                  context, index, submulti_idx,
+                                                  opts, warnings_only,
+                                                  transitive)
                 if err:
                     if warnings_only:
                         return ValueWarning(str(err), option)
                     else:
                         return err
 
-    def _cons_not_equal(self, opts, vals, warnings_only):
+    def _cons_not_equal(self, current_opt, opts, vals, warnings_only):
+        equal = set()
+        is_current = False
         for idx_inf, val_inf in enumerate(vals):
             for idx_sup, val_sup in enumerate(vals[idx_inf + 1:]):
                 if val_inf == val_sup is not None:
-                    if warnings_only:
-                        msg = _("value for {0} and {1} should be different")
-                    else:
-                        msg = _("value for {0} and {1} must be different")
-                    if debug:
-                        log.debug('_cons_not_equal: {0} and {1} are not different'.format(val_inf, val_sup))
-                    return ValueError(msg.format(opts[idx_inf].impl_getname(),
-                                                 opts[idx_inf + idx_sup + 1].impl_getname()))
+                    for opt_ in [opts[idx_inf], opts[idx_inf + idx_sup + 1]]:
+                        if opt_ == current_opt:
+                            is_current = True
+                        else:
+                            equal.add('"{}"'.format(opt_.impl_get_display_name()))
+        if equal:
+            if debug:
+                log.debug(_('_cons_not_equal: {} are not different').format(display_list(list(equal))))
+            if is_current:
+                if warnings_only:
+                    msg = _('should be different from the value of {}')
+                else:
+                    msg = _('must be different from the value of {}')
+                return ValueError(msg.format(display_list(list(equal))))
+            else:
+                if warnings_only:
+                    msg = _('value for {} should be different')
+                else:
+                    msg = _('value for {} must be different')
+                return ValueError(msg.format(display_list(list(equal))))
 
     # serialize/unserialize
     def _impl_convert_consistencies(self, descr, load=False):