consistencies can make a warning instead of raises
authorEmmanuel Garette <egarette@cadoles.com>
Wed, 12 Mar 2014 20:56:53 +0000 (21:56 +0100)
committerEmmanuel Garette <egarette@cadoles.com>
Wed, 12 Mar 2014 20:56:53 +0000 (21:56 +0100)
for that, you have to set something like:
  a.impl_add_consistency('not_equal', b, warnings_only=True)

warning product now adapted message

test/test_option_consistency.py
test/test_option_validator.py
tiramisu/option.py
translations/fr/tiramisu.po
translations/tiramisu.pot

index b40c340..0a7de3c 100644 (file)
@@ -5,7 +5,8 @@ from tiramisu.setting import owners, groups
 from tiramisu.config import Config
 from tiramisu.option import IPOption, NetworkOption, NetmaskOption, IntOption,\
     BroadcastOption, SymLinkOption, OptionDescription
-from tiramisu.error import ConfigError
+from tiramisu.error import ConfigError, ValueWarning
+import warnings
 
 
 def test_consistency():
@@ -19,6 +20,19 @@ def test_consistency():
     raises(ConfigError, "a.impl_add_consistency('not_equal', 'a')")
 
 
+def test_consistency_warnings_only():
+    a = IntOption('a', '')
+    b = IntOption('b', '')
+    od = OptionDescription('od', '', [a, b])
+    a.impl_add_consistency('not_equal', b, warnings_only=True)
+    c = Config(od)
+    c.a = 1
+    warnings.simplefilter("always", ValueWarning)
+    with warnings.catch_warnings(record=True) as w:
+        c.b = 1
+    assert w != []
+
+
 def test_consistency_not_equal():
     a = IntOption('a', '')
     b = IntOption('b', '')
index dc08c82..76ebfc8 100644 (file)
@@ -88,7 +88,7 @@ def test_validator_warning():
         cfg.opt2 = 'val'
     assert len(w) == 1
     assert w[0].message.opt == opt2
-    assert str(w[0].message) == _('invalid value for option {0}: {1}').format('opt2', 'error')
+    assert str(w[0].message) == _("warning on the value of the option {0}: {1}").format('opt2', 'error')
     #
     with warnings.catch_warnings(record=True) as w:
         cfg.opt3.append('val')
@@ -98,7 +98,7 @@ def test_validator_warning():
         cfg.opt3.append('val1')
     assert len(w) == 1
     assert w[0].message.opt == opt3
-    assert str(w[0].message) == _('invalid value for option {0}: {1}').format('opt3', 'error')
+    assert str(w[0].message) == _("warning on the value of the option {0}: {1}").format('opt3', 'error')
     raises(ValueError, "cfg.opt2 = 1")
     #
     with warnings.catch_warnings(record=True) as w:
@@ -106,9 +106,9 @@ def test_validator_warning():
         cfg.opt3.append('val')
     assert len(w) == 2
     assert w[0].message.opt == opt2
-    assert str(w[0].message) == _('invalid value for option {0}: {1}').format('opt2', 'error')
+    assert str(w[0].message) == _("warning on the value of the option {0}: {1}").format('opt2', 'error')
     assert w[1].message.opt == opt3
-    assert str(w[1].message) == _('invalid value for option {0}: {1}').format('opt3', 'error')
+    assert str(w[1].message) == _("warning on the value of the option {0}: {1}").format('opt3', 'error')
 
 
 def test_validator_warning_master_slave():
@@ -128,29 +128,29 @@ def test_validator_warning_master_slave():
         cfg.ip_admin_eth0.netmask_admin_eth0 = ['val1']
     assert len(w) == 1
     assert w[0].message.opt == netmask_admin_eth0
-    assert str(w[0].message) == _('invalid value for option {0}: {1}').format('netmask_admin_eth0', 'error')
+    assert str(w[0].message) == _("warning on the value of the option {0}: {1}").format('netmask_admin_eth0', 'error')
     #
     with warnings.catch_warnings(record=True) as w:
         cfg.ip_admin_eth0.ip_admin_eth0 = ['val']
     assert len(w) == 1
     assert w[0].message.opt == ip_admin_eth0
-    assert str(w[0].message) == _('invalid value for option {0}: {1}').format('ip_admin_eth0', 'error')
+    assert str(w[0].message) == _("warning on the value of the option {0}: {1}").format('ip_admin_eth0', 'error')
     #
     with warnings.catch_warnings(record=True) as w:
         cfg.ip_admin_eth0.ip_admin_eth0 = ['val', 'val1', 'val1']
     assert len(w) == 1
     assert w[0].message.opt == ip_admin_eth0
-    assert str(w[0].message) == _('invalid value for option {0}: {1}').format('ip_admin_eth0', 'error')
+    assert str(w[0].message) == _("warning on the value of the option {0}: {1}").format('ip_admin_eth0', 'error')
     #
     with warnings.catch_warnings(record=True) as w:
         cfg.ip_admin_eth0.ip_admin_eth0 = ['val1', 'val', 'val1']
     assert len(w) == 1
     assert w[0].message.opt == ip_admin_eth0
-    assert str(w[0].message) == _('invalid value for option {0}: {1}').format('ip_admin_eth0', 'error')
+    assert str(w[0].message) == _("warning on the value of the option {0}: {1}").format('ip_admin_eth0', 'error')
     #
     warnings.resetwarnings()
     with warnings.catch_warnings(record=True) as w:
         cfg.ip_admin_eth0.ip_admin_eth0 = ['val1', 'val1', 'val']
     assert len(w) == 1
     assert w[0].message.opt == ip_admin_eth0
-    assert str(w[0].message) == _('invalid value for option {0}: {1}').format('ip_admin_eth0', 'error')
+    assert str(w[0].message) == _("warning on the value of the option {0}: {1}").format('ip_admin_eth0', 'error')
index 7622811..db6acbd 100644 (file)
@@ -336,7 +336,7 @@ class Option(BaseOption):
         self._consistencies = None
 
     def _launch_consistency(self, func, option, value, context, index,
-                            all_cons_opts):
+                            all_cons_opts, warnings_only):
         """Launch consistency now
 
         :param func: function name, this name should start with _cons_
@@ -351,6 +351,8 @@ class Option(BaseOption):
         :type index: `int`
         :param all_cons_opts: all options concerne by this consistency
         :type all_cons_opts: `list` of `tiramisu.option.Option`
+        :param warnings_only: specific raise error for warning
+        :type warnings_only: `boolean`
         """
         if context is not None:
             descr = context.cfgimpl_get_description()
@@ -379,7 +381,7 @@ class Option(BaseOption):
                 except IndexError:
                     #so return if no value
                     return
-        getattr(self, func)(all_cons_opts, all_cons_vals)
+        getattr(self, func)(all_cons_opts, all_cons_vals, warnings_only)
 
     def impl_validate(self, value, context=None, validate=True,
                       force_index=None):
@@ -422,22 +424,31 @@ class Option(BaseOption):
             except ValueError as err:
                 raise ValueError(_('invalid value for option {0}: {1}'
                                    '').format(self._name, err))
+            error = None
+            warning = None
             try:
                 # valid with self._validator
                 val_validator(_value)
-                # if not context launch consistency validation
+                # if context launch consistency validation
                 if context is not None:
-                    descr._valid_consistency(self, _value, context, _index)
-                self._second_level_validation(_value)
-            except ValueError as err:
-                msg = _("invalid value for option {0}: {1}").format(
-                    self._name, err)
+                    descr._valid_consistency(self, _value, context, _index,
+                                             self._warnings_only)
+                self._second_level_validation(_value, self._warnings_only)
+            except ValueError as error:
                 if self._warnings_only:
-                    warnings.warn_explicit(ValueWarning(msg, self),
-                                           ValueWarning,
-                                           self.__class__.__name__, 0)
-                else:
-                    raise ValueError(msg)
+                    warning = error
+                    error = None
+            except ValueWarning as warning:
+                pass
+            if warning:
+                msg = _("warning on the value of the option {0}: {1}").format(
+                    self._name, warning)
+                warnings.warn_explicit(ValueWarning(msg, self),
+                                       ValueWarning,
+                                       self.__class__.__name__, 0)
+            elif error:
+                raise ValueError(_("invalid value for option {0}: {1}").format(
+                    self._name, error))
 
         # generic calculation
         if context is not None:
@@ -490,7 +501,7 @@ class Option(BaseOption):
     def impl_is_multi(self):
         return self._multi
 
-    def impl_add_consistency(self, func, *other_opts):
+    def impl_add_consistency(self, func, *other_opts, **params):
         """Add consistency means that value will be validate with other_opts
         option's values.
 
@@ -498,16 +509,18 @@ class Option(BaseOption):
         :type func: `str`
         :param other_opts: options used to validate value
         :type other_opts: `list` of `tiramisu.option.Option`
+        :param params: extra params (only warnings_only are allowed)
         """
         if self._consistencies is None:
             self._consistencies = []
+        warnings_only = params.get('warnings_only', False)
         for opt in other_opts:
             if not isinstance(opt, Option):
-                raise ConfigError(_('consistency should be set with an option'))
+                raise ConfigError(_('consistency must be set with an option'))
             if self is opt:
                 raise ConfigError(_('cannot add consistency with itself'))
             if self.impl_is_multi() != opt.impl_is_multi():
-                raise ConfigError(_('every options in consistency should be '
+                raise ConfigError(_('every options in consistency must be '
                                     'multi or none'))
         func = '_cons_{0}'.format(func)
         all_cons_opts = tuple([self] + list(other_opts))
@@ -516,19 +529,23 @@ class Option(BaseOption):
             if self.impl_is_multi():
                 for idx, val in enumerate(value):
                     self._launch_consistency(func, self, val, None,
-                                             idx, all_cons_opts)
+                                             idx, all_cons_opts, warnings_only)
             else:
                 self._launch_consistency(func, self, value, None,
-                                         None, all_cons_opts)
-        self._consistencies.append((func, all_cons_opts))
+                                         None, all_cons_opts, warnings_only)
+        self._consistencies.append((func, all_cons_opts, params))
         self.impl_validate(self.impl_getdefault())
 
-    def _cons_not_equal(self, opts, vals):
+    def _cons_not_equal(self, opts, vals, warnings_only):
         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:
-                    raise ValueError(_("same value for {0} and {1}").format(
-                        opts[idx_inf]._name, opts[idx_inf + idx_sup + 1]._name))
+                    if warnings_only:
+                        msg = _("same value for {0} and {1}, should be different")
+                    else:
+                        msg = _("same value for {0} and {1}, must be different")
+                    raise ValueError(msg.format(opts[idx_inf]._name,
+                                                opts[idx_inf + idx_sup + 1]._name))
 
     def _impl_convert_callbacks(self, descr, load=False):
         if not load and self._callback is None:
@@ -592,14 +609,14 @@ class Option(BaseOption):
                         values.append(descr.impl_get_opt_by_path(obj))
                     else:
                         values.append(descr.impl_get_path_by_opt(obj))
-                new_value.append((consistency[0], tuple(values)))
+                new_value.append((consistency[0], tuple(values), consistency[2]))
             if load:
                 del(self._state_consistencies)
                 self._consistencies = new_value
             else:
                 self._state_consistencies = new_value
 
-    def _second_level_validation(self, value):
+    def _second_level_validation(self, value, warnings_only):
         pass
 
 
@@ -777,24 +794,36 @@ class IPOption(Option):
         except ValueError:
             raise ValueError(_('invalid IP'))
 
-    def _second_level_validation(self, value):
+    def _second_level_validation(self, value, warnings_only):
         ip = IP('{0}/32'.format(value))
         if not self._allow_reserved and ip.iptype() == 'RESERVED':
-            raise ValueError(_("invalid IP, mustn't not be in reserved class"))
+            if warnings_only:
+                msg = _("IP shouldn't be in reserved class")
+            else:
+                msg = _("invalid IP, mustn't be in reserved class")
+            raise ValueError(msg)
         if self._private_only and not ip.iptype() == 'PRIVATE':
-            raise ValueError(_("invalid IP, must be in private class"))
+            if warnings_only:
+                msg = _("IP should be in private class")
+            else:
+                msg = _("invalid IP, must be in private class")
+            raise ValueError(msg)
 
-    def _cons_in_network(self, opts, vals):
+    def _cons_in_network(self, opts, vals, warnings_only):
         if len(vals) != 3:
             raise ConfigError(_('invalid len for vals'))
         if None in vals:
             return
         ip, network, netmask = vals
         if IP(ip) not in IP('{0}/{1}'.format(network, netmask)):
-            raise ValueError(_('invalid IP {0} ({1}) with network {2} '
-                               '({3}) and netmask {4} ({5})').format(
-                                   ip, opts[0]._name, network,
-                                   opts[1]._name, netmask, opts[2]._name))
+            if warnings_only:
+                msg = _('IP {0} ({1}) not in network {2} ({3}) with netmask {4}'
+                        ' ({5})')
+            else:
+                msg = _('invalid IP {0} ({1}) not in network {2} ({3}) with '
+                        'netmask {4} ({5})')
+            raise ValueError(msg.format(ip, opts[0]._name, network,
+                             opts[1]._name, netmask, opts[2]._name))
 
 
 class PortOption(Option):
@@ -884,10 +913,14 @@ class NetworkOption(Option):
         except ValueError:
             raise ValueError(_('invalid network address'))
 
-    def _second_level_validation(self, value):
+    def _second_level_validation(self, value, warnings_only):
         ip = IP(value)
         if ip.iptype() == 'RESERVED':
-            raise ValueError(_("invalid network address, must not be in reserved class"))
+            if warnings_only:
+                msg = _("network address shouldn't be in reserved class")
+            else:
+                msg = _("invalid network address, mustn't be in reserved class")
+            raise ValueError(msg)
 
 
 class NetmaskOption(Option):
@@ -901,19 +934,20 @@ class NetmaskOption(Option):
         except ValueError:
             raise ValueError(_('invalid netmask address'))
 
-    def _cons_network_netmask(self, opts, vals):
+    def _cons_network_netmask(self, opts, vals, warnings_only):
         #opts must be (netmask, network) options
         if None in vals:
             return
-        self.__cons_netmask(opts, vals[0], vals[1], False)
+        self.__cons_netmask(opts, vals[0], vals[1], False, warnings_only)
 
-    def _cons_ip_netmask(self, opts, vals):
+    def _cons_ip_netmask(self, opts, vals, warnings_only):
         #opts must be (netmask, ip) options
         if None in vals:
             return
-        self.__cons_netmask(opts, vals[0], vals[1], True)
+        self.__cons_netmask(opts, vals[0], vals[1], True, warnings_only)
 
-    def __cons_netmask(self, opts, val_netmask, val_ipnetwork, make_net):
+    def __cons_netmask(self, opts, val_netmask, val_ipnetwork, make_net,
+                       warnings_only):
         if len(opts) != 2:
             raise ConfigError(_('invalid len for opts'))
         msg = None
@@ -950,7 +984,7 @@ class BroadcastOption(Option):
         except ValueError:
             raise ValueError(_('invalid broadcast address'))
 
-    def _cons_broadcast(self, opts, vals):
+    def _cons_broadcast(self, opts, vals, warnings_only):
         if len(vals) != 3:
             raise ConfigError(_('invalid len for vals'))
         if None in vals:
@@ -1047,7 +1081,7 @@ class EmailOption(DomainnameOption):
         try:
             username, domain = splitted
         except ValueError:
-            raise ValueError(_('invalid email address, should contains one @'
+            raise ValueError(_('invalid email address, must contains one @'
                                ))
         if not self.username_re.search(username):
             raise ValueError(_('invalid username in email address'))
@@ -1063,7 +1097,7 @@ class URLOption(DomainnameOption):
     def _validate(self, value):
         match = self.proto_re.search(value)
         if not match:
-            raise ValueError(_('invalid url, should start with http:// or '
+            raise ValueError(_('invalid url, must start with http:// or '
                                'https://'))
         value = value[len(match.group(0)):]
         # get domain/files
@@ -1088,7 +1122,7 @@ class URLOption(DomainnameOption):
         super(URLOption, self)._validate(domain)
         # validate file
         if files is not None and files != '' and not self.path_re.search(files):
-            raise ValueError(_('invalid url, should ends with filename'))
+            raise ValueError(_('invalid url, must ends with filename'))
 
 
 class UsernameOption(Option):
@@ -1217,11 +1251,12 @@ class OptionDescription(BaseOption):
                 if not force_no_consistencies and \
                         option._consistencies is not None:
                     for consistency in option._consistencies:
-                        func, all_cons_opts = consistency
+                        func, all_cons_opts, params = consistency
                         for opt in all_cons_opts:
                             _consistencies.setdefault(opt,
                                                       []).append((func,
-                                                                  all_cons_opts))
+                                                                  all_cons_opts,
+                                                                  params))
             else:
                 _currpath.append(attr)
                 option.impl_build_cache(cache_path,
@@ -1311,18 +1346,29 @@ class OptionDescription(BaseOption):
     def impl_get_group_type(self):
         return self._group_type
 
-    def _valid_consistency(self, option, value, context, index):
+    def _valid_consistency(self, option, value, context, index, warnings_only):
         if self._cache_consistencies is None:
             return True
         #consistencies is something like [('_cons_not_equal', (opt1, opt2))]
         consistencies = self._cache_consistencies.get(option)
         if consistencies is not None:
-            for func, all_cons_opts in consistencies:
+            for func, all_cons_opts, params in consistencies:
+                if not warnings_only:
+                    l_warnings_only = params.get('warnings_only', False)
+                else:
+                    l_warnings_only = warnings_only
                 #all_cons_opts[0] is the option where func is set
-                all_cons_opts[0]._launch_consistency(func, option,
-                                                     value,
-                                                     context, index,
-                                                     all_cons_opts)
+                try:
+                    all_cons_opts[0]._launch_consistency(func, option,
+                                                         value,
+                                                         context, index,
+                                                         all_cons_opts,
+                                                         l_warnings_only)
+                except ValueError as err:
+                    if l_warnings_only:
+                        raise ValueWarning(err.message, option)
+                    else:
+                        raise err
 
     def _impl_getstate(self, descr=None):
         """enables us to export into a dict
@@ -1432,7 +1478,7 @@ def validate_requires_arg(requires, name):
                                '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))
+                               'must not be a multi').format(name))
         if expected is not None:
             try:
                 option._validate(expected)
@@ -1467,17 +1513,17 @@ def validate_requires_arg(requires, name):
 
 def validate_callback(callback, callback_params, type_):
     if type(callback) != FunctionType:
-        raise ValueError(_('{0} should be a function').format(type_))
+        raise ValueError(_('{0} must be a function').format(type_))
     if callback_params is not None:
         if not isinstance(callback_params, dict):
-            raise ValueError(_('{0}_params should be a dict').format(type_))
+            raise ValueError(_('{0}_params must be a dict').format(type_))
         for key, callbacks in callback_params.items():
             if key != '' and len(callbacks) != 1:
-                raise ValueError(_('{0}_params with key {1} should not have '
-                                   'length different to 1').format(type_,
+                raise ValueError(_("{0}_params with key {1} mustn't have "
+                                   "length different to 1").format(type_,
                                                                    key))
             if not isinstance(callbacks, tuple):
-                raise ValueError(_('{0}_params should be tuple for key "{1}"'
+                raise ValueError(_('{0}_params must be tuple for key "{1}"'
                                    ).format(type_, key))
             for callbk in callbacks:
                 if isinstance(callbk, tuple):
@@ -1486,11 +1532,11 @@ def validate_callback(callback, callback_params, type_):
                         raise ValueError(_('validator not support tuple'))
                     if not isinstance(option, Option) and not \
                             isinstance(option, SymLinkOption):
-                        raise ValueError(_('{0}_params should have an option '
+                        raise ValueError(_('{0}_params must have an option '
                                            'not a {0} for first argument'
                                            ).format(type_, type(option)))
                     if force_permissive not in [True, False]:
-                        raise ValueError(_('{0}_params should have a boolean'
+                        raise ValueError(_('{0}_params must have a boolean'
                                            ' not a {0} for second argument'
                                            ).format(type_, type(
                                                force_permissive)))
index d80b026..e5ce1a1 100644 (file)
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Tiramisu\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-03-11 18:51+CET\n"
+"POT-Creation-Date: 2014-03-12 21:49+CET\n"
 "PO-Revision-Date: \n"
 "Last-Translator: Emmanuel Garette <egarette@cadoles.com>\n"
 "Language-Team: Tiramisu's team <egarette@cadoles.com>\n"
@@ -130,264 +130,289 @@ msgstr ""
 "params définis pour une fonction callback mais par de callback encore "
 "définis pour l'option {0}"
 
-#: tiramisu/option.py:423 tiramisu/option.py:433
+#: tiramisu/option.py:425 tiramisu/option.py:450
 msgid "invalid value for option {0}: {1}"
 msgstr "valeur invalide pour l'option {0} : {1}"
 
-#: tiramisu/option.py:450
+#: tiramisu/option.py:444
+msgid "warning on the value of the option {0}: {1}"
+msgstr "avertissement sur la valeur de l'option {0} : {1}"
+
+#: tiramisu/option.py:461
 msgid "invalid value {0} for option {1} which must be a list"
 msgstr "valeur invalide pour l'option {0} : {1} laquelle doit être une liste"
 
-#: tiramisu/option.py:506
-msgid "consistency should be set with an option"
+#: tiramisu/option.py:519
+msgid "consistency must be set with an option"
 msgstr "consistency doit être configuré avec une option"
 
-#: tiramisu/option.py:508
+#: tiramisu/option.py:521
 msgid "cannot add consistency with itself"
 msgstr "ne peut ajouter une consistency avec lui même"
 
-#: tiramisu/option.py:510
-msgid "every options in consistency should be multi or none"
+#: tiramisu/option.py:523
+msgid "every options in consistency must be multi or none"
 msgstr ""
-"toutes les options d'une consistency devrait être multi ou ne pas l'être"
+"toutes les options d'une consistency doivent être multi ou ne pas l'être"
+
+#: tiramisu/option.py:544
+msgid "same value for {0} and {1}, should be different"
+msgstr "même valeur pour {0} et {1}, devrait être différent"
 
-#: tiramisu/option.py:530
-msgid "same value for {0} and {1}"
-msgstr "même valeur pour {0} et {1}"
+#: tiramisu/option.py:546
+msgid "same value for {0} and {1}, must be different"
+msgstr "même valeur pour {0} et {1}, doit être différent"
 
-#: tiramisu/option.py:623
+#: tiramisu/option.py:640
 msgid "values must be a tuple for {0}"
 msgstr "values doit être un tuple pour {0}"
 
-#: tiramisu/option.py:626
+#: tiramisu/option.py:643
 msgid "open_values must be a boolean for {0}"
 msgstr "open_values doit être un booléen pour {0}"
 
-#: tiramisu/option.py:648
+#: tiramisu/option.py:665
 msgid "value {0} is not permitted, only {1} is allowed"
 msgstr "valeur {0} n'est pas permis, seules {1} sont autorisées"
 
-#: tiramisu/option.py:660
+#: tiramisu/option.py:677
 msgid "invalid boolean"
 msgstr "booléen invalide"
 
-#: tiramisu/option.py:670
+#: tiramisu/option.py:687
 msgid "invalid integer"
 msgstr "nombre invalide"
 
-#: tiramisu/option.py:680
+#: tiramisu/option.py:697
 msgid "invalid float"
 msgstr "invalide nombre flottan"
 
-#: tiramisu/option.py:690
+#: tiramisu/option.py:707
 msgid "invalid string"
 msgstr "invalide caractère"
 
-#: tiramisu/option.py:707
+#: tiramisu/option.py:724
 msgid "invalid unicode"
 msgstr "invalide unicode"
 
-#: tiramisu/option.py:719
+#: tiramisu/option.py:736
 msgid "malformed symlinkoption must be an option for symlink {0}"
 msgstr "symlinkoption mal formé, doit être une option pour symlink {0}"
 
-#: tiramisu/option.py:770 tiramisu/option.py:773 tiramisu/option.py:778
+#: tiramisu/option.py:787 tiramisu/option.py:790 tiramisu/option.py:795
 msgid "invalid IP"
 msgstr "adresse IP invalide"
 
-#: tiramisu/option.py:783
-msgid "invalid IP, mustn't not be in reserved class"
-msgstr "adresse IP invalide, ne doit pas être d'une classe reservée"
+#: tiramisu/option.py:801
+msgid "IP shouldn't be in reserved class"
+msgstr "l'adresse IP ne devrait pas être d'une classe réservée"
+
+#: tiramisu/option.py:803
+msgid "invalid IP, mustn't be in reserved class"
+msgstr "adresse IP invalide, ne doit pas être dans une classe réservée"
 
-#: tiramisu/option.py:785
+#: tiramisu/option.py:807
+msgid "IP should be in private class"
+msgstr "l'adresse IP devrait être dans une classe privée"
+
+#: tiramisu/option.py:809
 msgid "invalid IP, must be in private class"
 msgstr "adresse IP invalide, doit être dans la classe privée"
 
-#: tiramisu/option.py:789 tiramisu/option.py:955
+#: tiramisu/option.py:814 tiramisu/option.py:989
 msgid "invalid len for vals"
 msgstr "longueur invalide pour vals"
 
-#: tiramisu/option.py:794
-msgid "invalid IP {0} ({1}) with network {2} ({3}) and netmask {4} ({5})"
-msgstr "IP invalide {0} ({1}) avec le réseau {2} ({3}) et le masque {4} ({5})"
+#: tiramisu/option.py:820
+msgid "IP {0} ({1}) not in network {2} ({3}) with netmask {4} ({5})"
+msgstr "IP {0} ({1}) pas dans le réseau {2} ({3}) avec le masque {4} ({5})"
+
+#: tiramisu/option.py:823
+msgid "invalid IP {0} ({1}) not in network {2} ({3}) with netmask {4} ({5})"
+msgstr ""
+"IP invalide {0} ({1}) pas dans le réseau {2} ({3}) avec le masque {4} ({5})"
 
-#: tiramisu/option.py:835
+#: tiramisu/option.py:864
 msgid "inconsistency in allowed range"
 msgstr "inconsistence dans la plage autorisée"
 
-#: tiramisu/option.py:840
+#: tiramisu/option.py:869
 msgid "max value is empty"
 msgstr "la valeur maximum est vide"
 
-#: tiramisu/option.py:857
+#: tiramisu/option.py:886
 msgid "invalid port, range must have two values only"
 msgstr "port invalide, une plage doit avoir deux valeurs seulement"
 
-#: tiramisu/option.py:860
+#: tiramisu/option.py:889
 msgid "invalid port, first port in range must be smaller than the second one"
 msgstr ""
 "port invalide, le premier port d'une plage doit être plus petit que le second"
 
-#: tiramisu/option.py:869
+#: tiramisu/option.py:898
 msgid "invalid port"
 msgstr "port invalide"
 
-#: tiramisu/option.py:871
+#: tiramisu/option.py:900
 msgid "invalid port, must be an between {0} and {1}"
 msgstr "port invalide, port doit être entre {0} et {1}"
 
-#: tiramisu/option.py:885
+#: tiramisu/option.py:914
 msgid "invalid network address"
 msgstr "adresse réseau invalide"
 
-#: tiramisu/option.py:890
-msgid "invalid network address, must not be in reserved class"
-msgstr "adresse réseau invalide, ne doit pas être dans la classe reservée"
+#: tiramisu/option.py:920
+msgid "network address shouldn't be in reserved class"
+msgstr "l'adresse réseau ne devait pas être dans la classe réservée"
 
-#: tiramisu/option.py:902
+#: tiramisu/option.py:922
+msgid "invalid network address, mustn't be in reserved class"
+msgstr "adresse réseau invalide, ne doit pas être dans la classe réservée"
+
+#: tiramisu/option.py:935
 msgid "invalid netmask address"
 msgstr "masque de sous-réseau invalide"
 
-#: tiramisu/option.py:918
+#: tiramisu/option.py:952
 msgid "invalid len for opts"
 msgstr "longueur invalide pour opts"
 
-#: tiramisu/option.py:932
+#: tiramisu/option.py:966
 msgid "invalid IP {0} ({1}) with netmask {2}, this IP is a network"
 msgstr "IP invalide {0} ({1}) avec masque {2}, cette IP est un réseau"
 
-#: tiramisu/option.py:937
+#: tiramisu/option.py:971
 msgid "invalid network {0} ({1}) with netmask {2}"
 msgstr "réseau invalide {0} ({1}) avec masque {2}"
 
-#: tiramisu/option.py:951
+#: tiramisu/option.py:985
 msgid "invalid broadcast address"
 msgstr "adresse de broadcast invalide"
 
-#: tiramisu/option.py:960
+#: tiramisu/option.py:994
 msgid ""
 "invalid broadcast {0} ({1}) with network {2} ({3}) and netmask {4} ({5})"
 msgstr ""
 "Broadcast invalide {0} ({1}) avec le réseau {2} ({3}) et le masque {4} ({5})"
 
-#: tiramisu/option.py:982
+#: tiramisu/option.py:1016
 msgid "unknown type_ {0} for hostname"
 msgstr "type_ inconnu {0} pour le nom d'hôte"
 
-#: tiramisu/option.py:985
+#: tiramisu/option.py:1019
 msgid "allow_ip must be a boolean"
 msgstr "allow_ip doit être un booléen"
 
-#: tiramisu/option.py:987
+#: tiramisu/option.py:1021
 msgid "allow_without_dot must be a boolean"
 msgstr "allow_without_dot doit être un booléen"
 
-#: tiramisu/option.py:1031
+#: tiramisu/option.py:1065
 msgid "invalid domainname, must have dot"
 msgstr "nom de domaine invalide, doit avoir un point"
 
-#: tiramisu/option.py:1033
+#: tiramisu/option.py:1067
 msgid "invalid domainname's length (max 255)"
 msgstr "longueur du nom de domaine invalide (maximum {1})"
 
-#: tiramisu/option.py:1035
+#: tiramisu/option.py:1069
 msgid "invalid domainname's length (min 2)"
 msgstr "longueur du nom de domaine invalide (minimum 2)"
 
-#: tiramisu/option.py:1037
+#: tiramisu/option.py:1071
 msgid "invalid domainname"
 msgstr "nom de domaine invalide"
 
-#: tiramisu/option.py:1050
-msgid "invalid email address, should contains one @"
-msgstr "adresse email invalide, devrait contenir un @"
+#: tiramisu/option.py:1084
+msgid "invalid email address, must contains one @"
+msgstr "adresse email invalide, doit contenir un @"
 
-#: tiramisu/option.py:1053
+#: tiramisu/option.py:1087
 msgid "invalid username in email address"
 msgstr "nom d'utilisateur invalide dans une adresse email"
 
-#: tiramisu/option.py:1066
-msgid "invalid url, should start with http:// or https://"
-msgstr "URL invalide, devrait démarré avec http:// ou https://"
+#: tiramisu/option.py:1100
+msgid "invalid url, must start with http:// or https://"
+msgstr "URL invalide, doit démarrer avec http:// ou https://"
 
-#: tiramisu/option.py:1085
+#: tiramisu/option.py:1119
 msgid "invalid url, port must be an between 0 and 65536"
 msgstr "URL invalide, port doit être entre 0 et 65536"
 
-#: tiramisu/option.py:1091
-msgid "invalid url, should ends with filename"
-msgstr "URL invalide, devrait finir avec un nom de fichier"
+#: tiramisu/option.py:1125
+msgid "invalid url, must ends with filename"
+msgstr "URL invalide, doit finir avec un nom de fichier"
 
-#: tiramisu/option.py:1103
+#: tiramisu/option.py:1137
 msgid "invalid username"
 msgstr "utilisateur invalide"
 
-#: tiramisu/option.py:1114
+#: tiramisu/option.py:1148
 msgid "invalid filename"
 msgstr "nom de fichier invalide"
 
-#: tiramisu/option.py:1141
+#: tiramisu/option.py:1175
 msgid "duplicate option name: {0}"
 msgstr "nom de l'option dupliqué : {0}"
 
-#: tiramisu/option.py:1159
+#: tiramisu/option.py:1193
 msgid "unknown Option {0} in OptionDescription {1}"
 msgstr "Option {0} inconnue pour l'OptionDescription {1}"
 
-#: tiramisu/option.py:1210
+#: tiramisu/option.py:1244
 msgid "duplicate option: {0}"
 msgstr "option dupliquée : {0}"
 
-#: tiramisu/option.py:1240
+#: tiramisu/option.py:1275
 msgid "consistency with option {0} which is not in Config"
 msgstr "consistency avec l'option {0} qui n'est pas dans une Config"
 
-#: tiramisu/option.py:1248
+#: tiramisu/option.py:1283
 msgid "no option for path {0}"
 msgstr "pas d'option pour le chemin {0}"
 
-#: tiramisu/option.py:1254
+#: tiramisu/option.py:1289
 msgid "no option {0} found"
 msgstr "pas d'option {0} trouvée"
 
-#: tiramisu/option.py:1264
+#: tiramisu/option.py:1299
 msgid "cannot change group_type if already set (old {0}, new {1})"
 msgstr "ne peut changer group_type si déjà spécifié (ancien {0}, nouveau {1})"
 
-#: tiramisu/option.py:1276
+#: tiramisu/option.py:1311
 msgid "master group {0} shall not have a subgroup"
 msgstr "groupe maître {0} ne doit pas avoir de sous-groupe"
 
-#: tiramisu/option.py:1279
+#: tiramisu/option.py:1314
 msgid "master group {0} shall not have a symlinkoption"
 msgstr "groupe maître {0} ne doit pas avoir de symlinkoption"
 
-#: tiramisu/option.py:1282
+#: tiramisu/option.py:1317
 msgid "not allowed option {0} in group {1}: this option is not a multi"
 msgstr ""
 "option non autorisée {0} dans le groupe {1} : cette option n'est pas une "
 "multi"
 
-#: tiramisu/option.py:1292
+#: tiramisu/option.py:1327
 msgid "master group with wrong master name for {0}"
 msgstr "le groupe maître avec un nom de maître érroné pour {0}"
 
-#: tiramisu/option.py:1300
+#: tiramisu/option.py:1335
 msgid "callback of master's option shall not refered a slave's ones"
 msgstr ""
 "callback d'une variable maitre ne devrait pas référencer des variables "
 "esclaves"
 
-#: tiramisu/option.py:1308
+#: tiramisu/option.py:1343
 msgid "group_type: {0} not allowed"
 msgstr "group_type : {0} non autorisé"
 
-#: tiramisu/option.py:1397
+#: tiramisu/option.py:1443
 msgid "malformed requirements type for option: {0}, must be a dict"
 msgstr ""
 "type requirements malformé pour l'option : {0}, doit être un dictionnaire"
 
-#: tiramisu/option.py:1414
+#: tiramisu/option.py:1460
 msgid ""
 "malformed requirements for option: {0} require must have option, expected "
 "and action keys"
@@ -395,68 +420,68 @@ msgstr ""
 "requirements malformé pour l'option : {0} l'exigence doit avoir les clefs "
 "option, expected et action"
 
-#: tiramisu/option.py:1419
+#: tiramisu/option.py:1465
 msgid "malformed requirements for option: {0} inverse must be boolean"
 msgstr ""
 "requirements mal formés pour l'option : {0} inverse doit être un booléen"
 
-#: tiramisu/option.py:1423
+#: tiramisu/option.py:1469
 msgid "malformed requirements for option: {0} transitive must be boolean"
 msgstr ""
 "requirements mal formés pour l'option : {0} transitive doit être booléen"
 
-#: tiramisu/option.py:1427
+#: tiramisu/option.py:1473
 msgid "malformed requirements for option: {0} same_action must be boolean"
 msgstr ""
 "requirements mal formés pour l'option : {0} same_action doit être un booléen"
 
-#: tiramisu/option.py:1431
+#: tiramisu/option.py:1477
 msgid "malformed requirements must be an option in option {0}"
 msgstr "requirements mal formés doit être une option dans l'option {0}"
 
-#: tiramisu/option.py:1434
-msgid "malformed requirements option {0} should not be a multi"
+#: tiramisu/option.py:1480
+msgid "malformed requirements option {0} must not be a multi"
 msgstr "requirements mal formés l'option {0} ne doit pas être une multi"
 
-#: tiramisu/option.py:1440
+#: tiramisu/option.py:1486
 msgid ""
 "malformed requirements second argument must be valid for option {0}: {1}"
 msgstr ""
 "requirements mal formés deuxième argument doit être valide pour l'option "
 "{0} : {1}"
 
-#: tiramisu/option.py:1445
+#: tiramisu/option.py:1491
 msgid "inconsistency in action types for option: {0} action: {1}"
 msgstr "incohérence dans les types action pour l'option : {0} action {1}"
 
-#: tiramisu/option.py:1470
-msgid "{0} should be a function"
+#: tiramisu/option.py:1516
+msgid "{0} must be a function"
 msgstr "{0} doit être une fonction"
 
-#: tiramisu/option.py:1473
-msgid "{0}_params should be a dict"
-msgstr "{0}_params devrait être un dict"
+#: tiramisu/option.py:1519
+msgid "{0}_params must be a dict"
+msgstr "{0}_params doit être un dict"
 
-#: tiramisu/option.py:1476
-msgid "{0}_params with key {1} should not have length different to 1"
+#: tiramisu/option.py:1522
+msgid "{0}_params with key {1} mustn't have length different to 1"
 msgstr ""
-"{0}_params avec la clef {1} devrait ne pas avoir une longueur différent de 1"
+"{0}_params avec la clef {1} ne doit pas avoir une longueur différent de 1"
 
-#: tiramisu/option.py:1480
-msgid "{0}_params should be tuple for key \"{1}\""
-msgstr "{0}_params devrait être un tuple pour la clef \"{1}\""
+#: tiramisu/option.py:1526
+msgid "{0}_params must be tuple for key \"{1}\""
+msgstr "{0}_params doit être un tuple pour la clef \"{1}\""
 
-#: tiramisu/option.py:1486
+#: tiramisu/option.py:1532
 msgid "validator not support tuple"
 msgstr "validator n'accepte pas de tuple"
 
-#: tiramisu/option.py:1489
-msgid "{0}_params should have an option not a {0} for first argument"
-msgstr "{0}_params devrait avoir une option pas un {0} pour premier argument"
+#: tiramisu/option.py:1535
+msgid "{0}_params must have an option not a {0} for first argument"
+msgstr "{0}_params doit avoir une option pas un {0} pour premier argument"
 
-#: tiramisu/option.py:1493
-msgid "{0}_params should have a boolean not a {0} for second argument"
-msgstr "{0}_params devrait avoir un boolean pas un {0} pour second argument"
+#: tiramisu/option.py:1539
+msgid "{0}_params must have a boolean not a {0} for second argument"
+msgstr "{0}_params doit avoir un booléen pas un {0} pour second argument"
 
 #: tiramisu/setting.py:116
 msgid "can't rebind {0}"
index d35e6a5..738fa53 100644 (file)
@@ -5,7 +5,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2014-03-11 18:51+CET\n"
+"POT-Creation-Date: 2014-03-12 21:49+CET\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -120,312 +120,336 @@ msgstr ""
 msgid "params defined for a callback function but no callback defined yet for option {0}"
 msgstr ""
 
-#: tiramisu/option.py:423 tiramisu/option.py:433
+#: tiramisu/option.py:425 tiramisu/option.py:450
 msgid "invalid value for option {0}: {1}"
 msgstr ""
 
-#: tiramisu/option.py:450
+#: tiramisu/option.py:444
+msgid "warning on the value of the option {0}: {1}"
+msgstr ""
+
+#: tiramisu/option.py:461
 msgid "invalid value {0} for option {1} which must be a list"
 msgstr ""
 
-#: tiramisu/option.py:506
-msgid "consistency should be set with an option"
+#: tiramisu/option.py:519
+msgid "consistency must be set with an option"
 msgstr ""
 
-#: tiramisu/option.py:508
+#: tiramisu/option.py:521
 msgid "cannot add consistency with itself"
 msgstr ""
 
-#: tiramisu/option.py:510
-msgid "every options in consistency should be multi or none"
+#: tiramisu/option.py:523
+msgid "every options in consistency must be multi or none"
+msgstr ""
+
+#: tiramisu/option.py:544
+msgid "same value for {0} and {1}, should be different"
 msgstr ""
 
-#: tiramisu/option.py:530
-msgid "same value for {0} and {1}"
+#: tiramisu/option.py:546
+msgid "same value for {0} and {1}, must be different"
 msgstr ""
 
-#: tiramisu/option.py:623
+#: tiramisu/option.py:640
 msgid "values must be a tuple for {0}"
 msgstr ""
 
-#: tiramisu/option.py:626
+#: tiramisu/option.py:643
 msgid "open_values must be a boolean for {0}"
 msgstr ""
 
-#: tiramisu/option.py:648
+#: tiramisu/option.py:665
 msgid "value {0} is not permitted, only {1} is allowed"
 msgstr ""
 
-#: tiramisu/option.py:660
+#: tiramisu/option.py:677
 msgid "invalid boolean"
 msgstr ""
 
-#: tiramisu/option.py:670
+#: tiramisu/option.py:687
 msgid "invalid integer"
 msgstr ""
 
-#: tiramisu/option.py:680
+#: tiramisu/option.py:697
 msgid "invalid float"
 msgstr ""
 
-#: tiramisu/option.py:690
+#: tiramisu/option.py:707
 msgid "invalid string"
 msgstr ""
 
-#: tiramisu/option.py:707
+#: tiramisu/option.py:724
 msgid "invalid unicode"
 msgstr ""
 
-#: tiramisu/option.py:719
+#: tiramisu/option.py:736
 msgid "malformed symlinkoption must be an option for symlink {0}"
 msgstr ""
 
-#: tiramisu/option.py:770 tiramisu/option.py:773 tiramisu/option.py:778
+#: tiramisu/option.py:787 tiramisu/option.py:790 tiramisu/option.py:795
 msgid "invalid IP"
 msgstr ""
 
-#: tiramisu/option.py:783
-msgid "invalid IP, mustn't not be in reserved class"
+#: tiramisu/option.py:801
+msgid "IP shouldn't be in reserved class"
 msgstr ""
 
-#: tiramisu/option.py:785
+#: tiramisu/option.py:803
+msgid "invalid IP, mustn't be in reserved class"
+msgstr ""
+
+#: tiramisu/option.py:807
+msgid "IP should be in private class"
+msgstr ""
+
+#: tiramisu/option.py:809
 msgid "invalid IP, must be in private class"
 msgstr ""
 
-#: tiramisu/option.py:789 tiramisu/option.py:955
+#: tiramisu/option.py:814 tiramisu/option.py:989
 msgid "invalid len for vals"
 msgstr ""
 
-#: tiramisu/option.py:794
-msgid "invalid IP {0} ({1}) with network {2} ({3}) and netmask {4} ({5})"
+#: tiramisu/option.py:820
+msgid "IP {0} ({1}) not in network {2} ({3}) with netmask {4} ({5})"
+msgstr ""
+
+#: tiramisu/option.py:823
+msgid "invalid IP {0} ({1}) not in network {2} ({3}) with netmask {4} ({5})"
 msgstr ""
 
-#: tiramisu/option.py:835
+#: tiramisu/option.py:864
 msgid "inconsistency in allowed range"
 msgstr ""
 
-#: tiramisu/option.py:840
+#: tiramisu/option.py:869
 msgid "max value is empty"
 msgstr ""
 
-#: tiramisu/option.py:857
+#: tiramisu/option.py:886
 msgid "invalid port, range must have two values only"
 msgstr ""
 
-#: tiramisu/option.py:860
+#: tiramisu/option.py:889
 msgid "invalid port, first port in range must be smaller than the second one"
 msgstr ""
 
-#: tiramisu/option.py:869
+#: tiramisu/option.py:898
 msgid "invalid port"
 msgstr ""
 
-#: tiramisu/option.py:871
+#: tiramisu/option.py:900
 msgid "invalid port, must be an between {0} and {1}"
 msgstr ""
 
-#: tiramisu/option.py:885
+#: tiramisu/option.py:914
 msgid "invalid network address"
 msgstr ""
 
-#: tiramisu/option.py:890
-msgid "invalid network address, must not be in reserved class"
+#: tiramisu/option.py:920
+msgid "network address shouldn't be in reserved class"
+msgstr ""
+
+#: tiramisu/option.py:922
+msgid "invalid network address, mustn't be in reserved class"
 msgstr ""
 
-#: tiramisu/option.py:902
+#: tiramisu/option.py:935
 msgid "invalid netmask address"
 msgstr ""
 
-#: tiramisu/option.py:918
+#: tiramisu/option.py:952
 msgid "invalid len for opts"
 msgstr ""
 
-#: tiramisu/option.py:932
+#: tiramisu/option.py:966
 msgid "invalid IP {0} ({1}) with netmask {2}, this IP is a network"
 msgstr ""
 
-#: tiramisu/option.py:937
+#: tiramisu/option.py:971
 msgid "invalid network {0} ({1}) with netmask {2}"
 msgstr ""
 
-#: tiramisu/option.py:951
+#: tiramisu/option.py:985
 msgid "invalid broadcast address"
 msgstr ""
 
-#: tiramisu/option.py:960
+#: tiramisu/option.py:994
 msgid "invalid broadcast {0} ({1}) with network {2} ({3}) and netmask {4} ({5})"
 msgstr ""
 
-#: tiramisu/option.py:982
+#: tiramisu/option.py:1016
 msgid "unknown type_ {0} for hostname"
 msgstr ""
 
-#: tiramisu/option.py:985
+#: tiramisu/option.py:1019
 msgid "allow_ip must be a boolean"
 msgstr ""
 
-#: tiramisu/option.py:987
+#: tiramisu/option.py:1021
 msgid "allow_without_dot must be a boolean"
 msgstr ""
 
-#: tiramisu/option.py:1031
+#: tiramisu/option.py:1065
 msgid "invalid domainname, must have dot"
 msgstr ""
 
-#: tiramisu/option.py:1033
+#: tiramisu/option.py:1067
 msgid "invalid domainname's length (max 255)"
 msgstr ""
 
-#: tiramisu/option.py:1035
+#: tiramisu/option.py:1069
 msgid "invalid domainname's length (min 2)"
 msgstr ""
 
-#: tiramisu/option.py:1037
+#: tiramisu/option.py:1071
 msgid "invalid domainname"
 msgstr ""
 
-#: tiramisu/option.py:1050
-msgid "invalid email address, should contains one @"
+#: tiramisu/option.py:1084
+msgid "invalid email address, must contains one @"
 msgstr ""
 
-#: tiramisu/option.py:1053
+#: tiramisu/option.py:1087
 msgid "invalid username in email address"
 msgstr ""
 
-#: tiramisu/option.py:1066
-msgid "invalid url, should start with http:// or https://"
+#: tiramisu/option.py:1100
+msgid "invalid url, must start with http:// or https://"
 msgstr ""
 
-#: tiramisu/option.py:1085
+#: tiramisu/option.py:1119
 msgid "invalid url, port must be an between 0 and 65536"
 msgstr ""
 
-#: tiramisu/option.py:1091
-msgid "invalid url, should ends with filename"
+#: tiramisu/option.py:1125
+msgid "invalid url, must ends with filename"
 msgstr ""
 
-#: tiramisu/option.py:1103
+#: tiramisu/option.py:1137
 msgid "invalid username"
 msgstr ""
 
-#: tiramisu/option.py:1114
+#: tiramisu/option.py:1148
 msgid "invalid filename"
 msgstr ""
 
-#: tiramisu/option.py:1141
+#: tiramisu/option.py:1175
 msgid "duplicate option name: {0}"
 msgstr ""
 
-#: tiramisu/option.py:1159
+#: tiramisu/option.py:1193
 msgid "unknown Option {0} in OptionDescription {1}"
 msgstr ""
 
-#: tiramisu/option.py:1210
+#: tiramisu/option.py:1244
 msgid "duplicate option: {0}"
 msgstr ""
 
-#: tiramisu/option.py:1240
+#: tiramisu/option.py:1275
 msgid "consistency with option {0} which is not in Config"
 msgstr ""
 
-#: tiramisu/option.py:1248
+#: tiramisu/option.py:1283
 msgid "no option for path {0}"
 msgstr ""
 
-#: tiramisu/option.py:1254
+#: tiramisu/option.py:1289
 msgid "no option {0} found"
 msgstr ""
 
-#: tiramisu/option.py:1264
+#: tiramisu/option.py:1299
 msgid "cannot change group_type if already set (old {0}, new {1})"
 msgstr ""
 
-#: tiramisu/option.py:1276
+#: tiramisu/option.py:1311
 msgid "master group {0} shall not have a subgroup"
 msgstr ""
 
-#: tiramisu/option.py:1279
+#: tiramisu/option.py:1314
 msgid "master group {0} shall not have a symlinkoption"
 msgstr ""
 
-#: tiramisu/option.py:1282
+#: tiramisu/option.py:1317
 msgid "not allowed option {0} in group {1}: this option is not a multi"
 msgstr ""
 
-#: tiramisu/option.py:1292
+#: tiramisu/option.py:1327
 msgid "master group with wrong master name for {0}"
 msgstr ""
 
-#: tiramisu/option.py:1300
+#: tiramisu/option.py:1335
 msgid "callback of master's option shall not refered a slave's ones"
 msgstr ""
 
-#: tiramisu/option.py:1308
+#: tiramisu/option.py:1343
 msgid "group_type: {0} not allowed"
 msgstr ""
 
-#: tiramisu/option.py:1397
+#: tiramisu/option.py:1443
 msgid "malformed requirements type for option: {0}, must be a dict"
 msgstr ""
 
-#: tiramisu/option.py:1414
+#: tiramisu/option.py:1460
 msgid "malformed requirements for option: {0} require must have option, expected and action keys"
 msgstr ""
 
-#: tiramisu/option.py:1419
+#: tiramisu/option.py:1465
 msgid "malformed requirements for option: {0} inverse must be boolean"
 msgstr ""
 
-#: tiramisu/option.py:1423
+#: tiramisu/option.py:1469
 msgid "malformed requirements for option: {0} transitive must be boolean"
 msgstr ""
 
-#: tiramisu/option.py:1427
+#: tiramisu/option.py:1473
 msgid "malformed requirements for option: {0} same_action must be boolean"
 msgstr ""
 
-#: tiramisu/option.py:1431
+#: tiramisu/option.py:1477
 msgid "malformed requirements must be an option in option {0}"
 msgstr ""
 
-#: tiramisu/option.py:1434
-msgid "malformed requirements option {0} should not be a multi"
+#: tiramisu/option.py:1480
+msgid "malformed requirements option {0} must not be a multi"
 msgstr ""
 
-#: tiramisu/option.py:1440
+#: tiramisu/option.py:1486
 msgid "malformed requirements second argument must be valid for option {0}: {1}"
 msgstr ""
 
-#: tiramisu/option.py:1445
+#: tiramisu/option.py:1491
 msgid "inconsistency in action types for option: {0} action: {1}"
 msgstr ""
 
-#: tiramisu/option.py:1470
-msgid "{0} should be a function"
+#: tiramisu/option.py:1516
+msgid "{0} must be a function"
 msgstr ""
 
-#: tiramisu/option.py:1473
-msgid "{0}_params should be a dict"
+#: tiramisu/option.py:1519
+msgid "{0}_params must be a dict"
 msgstr ""
 
-#: tiramisu/option.py:1476
-msgid "{0}_params with key {1} should not have length different to 1"
+#: tiramisu/option.py:1522
+msgid "{0}_params with key {1} mustn't have length different to 1"
 msgstr ""
 
-#: tiramisu/option.py:1480
-msgid "{0}_params should be tuple for key \"{1}\""
+#: tiramisu/option.py:1526
+msgid "{0}_params must be tuple for key \"{1}\""
 msgstr ""
 
-#: tiramisu/option.py:1486
+#: tiramisu/option.py:1532
 msgid "validator not support tuple"
 msgstr ""
 
-#: tiramisu/option.py:1489
-msgid "{0}_params should have an option not a {0} for first argument"
+#: tiramisu/option.py:1535
+msgid "{0}_params must have an option not a {0} for first argument"
 msgstr ""
 
-#: tiramisu/option.py:1493
-msgid "{0}_params should have a boolean not a {0} for second argument"
+#: tiramisu/option.py:1539
+msgid "{0}_params must have a boolean not a {0} for second argument"
 msgstr ""
 
 #: tiramisu/setting.py:116