Merge branch 'master' into force-cache

Conflicts:
	translations/fr/tiramisu.po
	translations/tiramisu.pot
This commit is contained in:
Emmanuel Garette 2014-03-15 10:09:19 +01:00
commit f7d31bfa92
7 changed files with 493 additions and 310 deletions

View file

@ -115,6 +115,18 @@ def test_make_dict():
raises(ValueError, 'd2 = config.make_dict(withvalue="3")') raises(ValueError, 'd2 = config.make_dict(withvalue="3")')
def test_make_dict_with_disabled():
descr = OptionDescription("opt", "", [
OptionDescription("s1", "", [
BoolOption("a", "", default=False),
BoolOption("b", "", default=False, properties=('disabled',))]),
IntOption("int", "", default=42)])
config = Config(descr)
config.read_only()
d = config.make_dict()
assert d == {"s1.a": False, "int": 42}
def test_find_in_config(): def test_find_in_config():
"finds option in config" "finds option in config"
descr = make_description() descr = make_description()

View file

@ -5,7 +5,8 @@ from tiramisu.setting import owners, groups
from tiramisu.config import Config from tiramisu.config import Config
from tiramisu.option import IPOption, NetworkOption, NetmaskOption, IntOption,\ from tiramisu.option import IPOption, NetworkOption, NetmaskOption, IntOption,\
BroadcastOption, SymLinkOption, OptionDescription BroadcastOption, SymLinkOption, OptionDescription
from tiramisu.error import ConfigError from tiramisu.error import ConfigError, ValueWarning
import warnings
def test_consistency(): def test_consistency():
@ -19,6 +20,19 @@ def test_consistency():
raises(ConfigError, "a.impl_add_consistency('not_equal', 'a')") 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(): def test_consistency_not_equal():
a = IntOption('a', '') a = IntOption('a', '')
b = IntOption('b', '') b = IntOption('b', '')
@ -169,6 +183,29 @@ def test_consistency_network_netmask():
raises(ValueError, "c.a = '192.168.1.1'") raises(ValueError, "c.a = '192.168.1.1'")
def test_consistency_ip_in_network():
a = NetworkOption('a', '')
b = NetmaskOption('b', '')
c = IPOption('c', '')
od = OptionDescription('od', '', [a, b, c])
c.impl_add_consistency('in_network', a, b)
cfg = Config(od)
cfg.a = '192.168.1.0'
cfg.b = '255.255.255.0'
cfg.c = '192.168.1.1'
raises(ValueError, "cfg.c = '192.168.2.1'")
def test_consistency_ip_in_network_len_error():
a = NetworkOption('a', '')
b = NetmaskOption('b', '')
c = IPOption('c', '')
od = OptionDescription('od', '', [a, b, c])
c.impl_add_consistency('in_network', a)
cfg = Config(od)
raises(ConfigError, "cfg.a = '192.168.2.0'")
def test_consistency_ip_netmask_network_error(): def test_consistency_ip_netmask_network_error():
a = IPOption('a', '') a = IPOption('a', '')
b = NetworkOption('b', '') b = NetworkOption('b', '')
@ -322,3 +359,17 @@ def test_consistency_permissive():
c.cfgimpl_get_settings().setpermissive(('hidden',)) c.cfgimpl_get_settings().setpermissive(('hidden',))
c.read_write() c.read_write()
c.a = 1 c.a = 1
def return_val(*args, **kwargs):
return '192.168.1.1'
def test_consistency_with_callback():
a = NetworkOption('a', '', default='192.168.1.0')
b = NetmaskOption('b', '', default='255.255.255.0')
c = IPOption('c', '', callback=return_val, callback_params={'': ((a, False),)})
od = OptionDescription('od', '', [a, b, c])
c.impl_add_consistency('in_network', a, b)
cfg = Config(od)
cfg.c

View file

@ -88,7 +88,7 @@ def test_validator_warning():
cfg.opt2 = 'val' cfg.opt2 = 'val'
assert len(w) == 1 assert len(w) == 1
assert w[0].message.opt == opt2 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: with warnings.catch_warnings(record=True) as w:
cfg.opt3.append('val') cfg.opt3.append('val')
@ -98,7 +98,7 @@ def test_validator_warning():
cfg.opt3.append('val1') cfg.opt3.append('val1')
assert len(w) == 1 assert len(w) == 1
assert w[0].message.opt == opt3 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") raises(ValueError, "cfg.opt2 = 1")
# #
with warnings.catch_warnings(record=True) as w: with warnings.catch_warnings(record=True) as w:
@ -106,9 +106,9 @@ def test_validator_warning():
cfg.opt3.append('val') cfg.opt3.append('val')
assert len(w) == 2 assert len(w) == 2
assert w[0].message.opt == opt2 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 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(): def test_validator_warning_master_slave():
@ -128,29 +128,29 @@ def test_validator_warning_master_slave():
cfg.ip_admin_eth0.netmask_admin_eth0 = ['val1'] cfg.ip_admin_eth0.netmask_admin_eth0 = ['val1']
assert len(w) == 1 assert len(w) == 1
assert w[0].message.opt == netmask_admin_eth0 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: with warnings.catch_warnings(record=True) as w:
cfg.ip_admin_eth0.ip_admin_eth0 = ['val'] cfg.ip_admin_eth0.ip_admin_eth0 = ['val']
assert len(w) == 1 assert len(w) == 1
assert w[0].message.opt == ip_admin_eth0 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: with warnings.catch_warnings(record=True) as w:
cfg.ip_admin_eth0.ip_admin_eth0 = ['val', 'val1', 'val1'] cfg.ip_admin_eth0.ip_admin_eth0 = ['val', 'val1', 'val1']
assert len(w) == 1 assert len(w) == 1
assert w[0].message.opt == ip_admin_eth0 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: with warnings.catch_warnings(record=True) as w:
cfg.ip_admin_eth0.ip_admin_eth0 = ['val1', 'val', 'val1'] cfg.ip_admin_eth0.ip_admin_eth0 = ['val1', 'val', 'val1']
assert len(w) == 1 assert len(w) == 1
assert w[0].message.opt == ip_admin_eth0 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() warnings.resetwarnings()
with warnings.catch_warnings(record=True) as w: with warnings.catch_warnings(record=True) as w:
cfg.ip_admin_eth0.ip_admin_eth0 = ['val1', 'val1', 'val'] cfg.ip_admin_eth0.ip_admin_eth0 = ['val1', 'val1', 'val']
assert len(w) == 1 assert len(w) == 1
assert w[0].message.opt == ip_admin_eth0 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')

View file

@ -448,6 +448,7 @@ class SubConfig(object):
return pathsvalues return pathsvalues
def _make_sub_dict(self, opt, path, pathsvalues, _currpath, flatten): def _make_sub_dict(self, opt, path, pathsvalues, _currpath, flatten):
try:
if isinstance(opt, OptionDescription): if isinstance(opt, OptionDescription):
pathsvalues += getattr(self, path).make_dict(flatten, pathsvalues += getattr(self, path).make_dict(flatten,
_currpath + _currpath +
@ -459,6 +460,8 @@ class SubConfig(object):
else: else:
name = '.'.join(_currpath + [opt._name]) name = '.'.join(_currpath + [opt._name])
pathsvalues.append((name, value)) pathsvalues.append((name, value))
except PropertiesOptionError:
pass
def cfgimpl_get_path(self): def cfgimpl_get_path(self):
descr = self.cfgimpl_get_description() descr = self.cfgimpl_get_description()

View file

@ -336,7 +336,7 @@ class Option(BaseOption):
self._consistencies = None self._consistencies = None
def _launch_consistency(self, func, option, value, context, index, def _launch_consistency(self, func, option, value, context, index,
all_cons_opts): all_cons_opts, warnings_only):
"""Launch consistency now """Launch consistency now
:param func: function name, this name should start with _cons_ :param func: function name, this name should start with _cons_
@ -351,6 +351,8 @@ class Option(BaseOption):
:type index: `int` :type index: `int`
:param all_cons_opts: all options concerne by this consistency :param all_cons_opts: all options concerne by this consistency
:type all_cons_opts: `list` of `tiramisu.option.Option` :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: if context is not None:
descr = context.cfgimpl_get_description() descr = context.cfgimpl_get_description()
@ -379,7 +381,7 @@ class Option(BaseOption):
except IndexError: except IndexError:
#so return if no value #so return if no value
return 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, def impl_validate(self, value, context=None, validate=True,
force_index=None): force_index=None):
@ -422,22 +424,36 @@ class Option(BaseOption):
except ValueError as err: except ValueError as err:
raise ValueError(_('invalid value for option {0}: {1}' raise ValueError(_('invalid value for option {0}: {1}'
'').format(self._name, err)) '').format(self._name, err))
error = None
warning = None
try: try:
# valid with self._validator # valid with self._validator
val_validator(_value) val_validator(_value)
# if not context launch consistency validation self._second_level_validation(_value, self._warnings_only)
except ValueError as error:
if self._warnings_only:
warning = error
error = None
except ValueWarning as warning:
pass
if error is None and warning is None:
try:
# if context launch consistency validation
if context is not None: if context is not None:
descr._valid_consistency(self, _value, context, _index) descr._valid_consistency(self, _value, context, _index)
self._second_level_validation(_value) except ValueError as error:
except ValueError as err: pass
msg = _("invalid value for option {0}: {1}").format( except ValueWarning as warning:
self._name, err) pass
if self._warnings_only: if warning:
msg = _("warning on the value of the option {0}: {1}").format(
self._name, warning)
warnings.warn_explicit(ValueWarning(msg, self), warnings.warn_explicit(ValueWarning(msg, self),
ValueWarning, ValueWarning,
self.__class__.__name__, 0) self.__class__.__name__, 0)
else: elif error:
raise ValueError(msg) raise ValueError(_("invalid value for option {0}: {1}").format(
self._name, error))
# generic calculation # generic calculation
if context is not None: if context is not None:
@ -490,7 +506,7 @@ class Option(BaseOption):
def impl_is_multi(self): def impl_is_multi(self):
return self._multi 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 """Add consistency means that value will be validate with other_opts
option's values. option's values.
@ -498,16 +514,18 @@ class Option(BaseOption):
:type func: `str` :type func: `str`
:param other_opts: options used to validate value :param other_opts: options used to validate value
:type other_opts: `list` of `tiramisu.option.Option` :type other_opts: `list` of `tiramisu.option.Option`
:param params: extra params (only warnings_only are allowed)
""" """
if self._consistencies is None: if self._consistencies is None:
self._consistencies = [] self._consistencies = []
warnings_only = params.get('warnings_only', False)
for opt in other_opts: for opt in other_opts:
if not isinstance(opt, Option): 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: if self is opt:
raise ConfigError(_('cannot add consistency with itself')) raise ConfigError(_('cannot add consistency with itself'))
if self.impl_is_multi() != opt.impl_is_multi(): 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')) 'multi or none'))
func = '_cons_{0}'.format(func) func = '_cons_{0}'.format(func)
all_cons_opts = tuple([self] + list(other_opts)) all_cons_opts = tuple([self] + list(other_opts))
@ -516,19 +534,23 @@ class Option(BaseOption):
if self.impl_is_multi(): if self.impl_is_multi():
for idx, val in enumerate(value): for idx, val in enumerate(value):
self._launch_consistency(func, self, val, None, self._launch_consistency(func, self, val, None,
idx, all_cons_opts) idx, all_cons_opts, warnings_only)
else: else:
self._launch_consistency(func, self, value, None, self._launch_consistency(func, self, value, None,
None, all_cons_opts) None, all_cons_opts, warnings_only)
self._consistencies.append((func, all_cons_opts)) self._consistencies.append((func, all_cons_opts, params))
self.impl_validate(self.impl_getdefault()) 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_inf, val_inf in enumerate(vals):
for idx_sup, val_sup in enumerate(vals[idx_inf + 1:]): for idx_sup, val_sup in enumerate(vals[idx_inf + 1:]):
if val_inf == val_sup is not None: if val_inf == val_sup is not None:
raise ValueError(_("same value for {0} and {1}").format( if warnings_only:
opts[idx_inf]._name, opts[idx_inf + idx_sup + 1]._name)) 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): def _impl_convert_callbacks(self, descr, load=False):
if not load and self._callback is None: if not load and self._callback is None:
@ -592,14 +614,14 @@ class Option(BaseOption):
values.append(descr.impl_get_opt_by_path(obj)) values.append(descr.impl_get_opt_by_path(obj))
else: else:
values.append(descr.impl_get_path_by_opt(obj)) 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: if load:
del(self._state_consistencies) del(self._state_consistencies)
self._consistencies = new_value self._consistencies = new_value
else: else:
self._state_consistencies = new_value self._state_consistencies = new_value
def _second_level_validation(self, value): def _second_level_validation(self, value, warnings_only):
pass pass
@ -777,12 +799,36 @@ class IPOption(Option):
except ValueError: except ValueError:
raise ValueError(_('invalid IP')) raise ValueError(_('invalid IP'))
def _second_level_validation(self, value): def _second_level_validation(self, value, warnings_only):
ip = IP('{0}/32'.format(value)) ip = IP('{0}/32'.format(value))
if not self._allow_reserved and ip.iptype() == 'RESERVED': 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': 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, 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)):
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): class PortOption(Option):
@ -872,10 +918,14 @@ class NetworkOption(Option):
except ValueError: except ValueError:
raise ValueError(_('invalid network address')) raise ValueError(_('invalid network address'))
def _second_level_validation(self, value): def _second_level_validation(self, value, warnings_only):
ip = IP(value) ip = IP(value)
if ip.iptype() == 'RESERVED': 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): class NetmaskOption(Option):
@ -889,19 +939,20 @@ class NetmaskOption(Option):
except ValueError: except ValueError:
raise ValueError(_('invalid netmask address')) 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 #opts must be (netmask, network) options
if None in vals: if None in vals:
return 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 #opts must be (netmask, ip) options
if None in vals: if None in vals:
return 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: if len(opts) != 2:
raise ConfigError(_('invalid len for opts')) raise ConfigError(_('invalid len for opts'))
msg = None msg = None
@ -938,7 +989,7 @@ class BroadcastOption(Option):
except ValueError: except ValueError:
raise ValueError(_('invalid broadcast address')) raise ValueError(_('invalid broadcast address'))
def _cons_broadcast(self, opts, vals): def _cons_broadcast(self, opts, vals, warnings_only):
if len(vals) != 3: if len(vals) != 3:
raise ConfigError(_('invalid len for vals')) raise ConfigError(_('invalid len for vals'))
if None in vals: if None in vals:
@ -1035,7 +1086,7 @@ class EmailOption(DomainnameOption):
try: try:
username, domain = splitted username, domain = splitted
except ValueError: 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): if not self.username_re.search(username):
raise ValueError(_('invalid username in email address')) raise ValueError(_('invalid username in email address'))
@ -1051,7 +1102,7 @@ class URLOption(DomainnameOption):
def _validate(self, value): def _validate(self, value):
match = self.proto_re.search(value) match = self.proto_re.search(value)
if not match: if not match:
raise ValueError(_('invalid url, should start with http:// or ' raise ValueError(_('invalid url, must start with http:// or '
'https://')) 'https://'))
value = value[len(match.group(0)):] value = value[len(match.group(0)):]
# get domain/files # get domain/files
@ -1076,7 +1127,7 @@ class URLOption(DomainnameOption):
super(URLOption, self)._validate(domain) super(URLOption, self)._validate(domain)
# validate file # validate file
if files is not None and files != '' and not self.path_re.search(files): 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): class UsernameOption(Option):
@ -1205,11 +1256,12 @@ class OptionDescription(BaseOption):
if not force_no_consistencies and \ if not force_no_consistencies and \
option._consistencies is not None: option._consistencies is not None:
for consistency in option._consistencies: for consistency in option._consistencies:
func, all_cons_opts = consistency func, all_cons_opts, params = consistency
for opt in all_cons_opts: for opt in all_cons_opts:
_consistencies.setdefault(opt, _consistencies.setdefault(opt,
[]).append((func, []).append((func,
all_cons_opts)) all_cons_opts,
params))
else: else:
_currpath.append(attr) _currpath.append(attr)
option.impl_build_cache(cache_path, option.impl_build_cache(cache_path,
@ -1305,12 +1357,20 @@ class OptionDescription(BaseOption):
#consistencies is something like [('_cons_not_equal', (opt1, opt2))] #consistencies is something like [('_cons_not_equal', (opt1, opt2))]
consistencies = self._cache_consistencies.get(option) consistencies = self._cache_consistencies.get(option)
if consistencies is not None: if consistencies is not None:
for func, all_cons_opts in consistencies: for func, all_cons_opts, params in consistencies:
warnings_only = params.get('warnings_only', False)
#all_cons_opts[0] is the option where func is set #all_cons_opts[0] is the option where func is set
try:
all_cons_opts[0]._launch_consistency(func, option, all_cons_opts[0]._launch_consistency(func, option,
value, value,
context, index, context, index,
all_cons_opts) all_cons_opts,
warnings_only)
except ValueError as err:
if warnings_only:
raise ValueWarning(err.message, option)
else:
raise err
def _impl_getstate(self, descr=None): def _impl_getstate(self, descr=None):
"""enables us to export into a dict """enables us to export into a dict
@ -1420,7 +1480,7 @@ def validate_requires_arg(requires, name):
'must be an option in option {0}').format(name)) 'must be an option in option {0}').format(name))
if option.impl_is_multi(): if option.impl_is_multi():
raise ValueError(_('malformed requirements option {0} ' 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: if expected is not None:
try: try:
option._validate(expected) option._validate(expected)
@ -1455,17 +1515,17 @@ def validate_requires_arg(requires, name):
def validate_callback(callback, callback_params, type_): def validate_callback(callback, callback_params, type_):
if type(callback) != FunctionType: 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 callback_params is not None:
if not isinstance(callback_params, dict): 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(): for key, callbacks in callback_params.items():
if key != '' and len(callbacks) != 1: if key != '' and len(callbacks) != 1:
raise ValueError(_('{0}_params with key {1} should not have ' raise ValueError(_("{0}_params with key {1} mustn't have "
'length different to 1').format(type_, "length different to 1").format(type_,
key)) key))
if not isinstance(callbacks, tuple): 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)) ).format(type_, key))
for callbk in callbacks: for callbk in callbacks:
if isinstance(callbk, tuple): if isinstance(callbk, tuple):
@ -1474,11 +1534,11 @@ def validate_callback(callback, callback_params, type_):
raise ValueError(_('validator not support tuple')) raise ValueError(_('validator not support tuple'))
if not isinstance(option, Option) and not \ if not isinstance(option, Option) and not \
isinstance(option, SymLinkOption): 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' 'not a {0} for first argument'
).format(type_, type(option))) ).format(type_, type(option)))
if force_permissive not in [True, False]: 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' ' not a {0} for second argument'
).format(type_, type( ).format(type_, type(
force_permissive))) force_permissive)))

View file

@ -2,7 +2,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Tiramisu\n" "Project-Id-Version: Tiramisu\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-03-09 20:14+CET\n" "POT-Creation-Date: 2014-03-12 21:49+CET\n"
"PO-Revision-Date: \n" "PO-Revision-Date: \n"
"Last-Translator: Emmanuel Garette <egarette@cadoles.com>\n" "Last-Translator: Emmanuel Garette <egarette@cadoles.com>\n"
"Language-Team: Tiramisu's team <egarette@cadoles.com>\n" "Language-Team: Tiramisu's team <egarette@cadoles.com>\n"
@ -130,260 +130,289 @@ msgstr ""
"params définis pour une fonction callback mais par de callback encore " "params définis pour une fonction callback mais par de callback encore "
"définis pour l'option {0}" "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}" msgid "invalid value for option {0}: {1}"
msgstr "valeur invalide pour l'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" 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" msgstr "valeur invalide pour l'option {0} : {1} laquelle doit être une liste"
#: tiramisu/option.py:506 #: tiramisu/option.py:519
msgid "consistency should be set with an option" msgid "consistency must be set with an option"
msgstr "consistency doit être configuré avec une option" msgstr "consistency doit être configuré avec une option"
#: tiramisu/option.py:508 #: tiramisu/option.py:521
msgid "cannot add consistency with itself" msgid "cannot add consistency with itself"
msgstr "ne peut ajouter une consistency avec lui même" msgstr "ne peut ajouter une consistency avec lui même"
#: tiramisu/option.py:510 #: tiramisu/option.py:523
msgid "every options in consistency should be multi or none" msgid "every options in consistency must be multi or none"
msgstr "" 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:530 #: tiramisu/option.py:544
msgid "same value for {0} and {1}" msgid "same value for {0} and {1}, should be different"
msgstr "même valeur pour {0} et {1}" msgstr "même valeur pour {0} et {1}, devrait être différent"
#: tiramisu/option.py:623 #: 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:640
msgid "values must be a tuple for {0}" msgid "values must be a tuple for {0}"
msgstr "values doit être un tuple pour {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}" msgid "open_values must be a boolean for {0}"
msgstr "open_values doit être un booléen pour {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" msgid "value {0} is not permitted, only {1} is allowed"
msgstr "valeur {0} n'est pas permis, seules {1} sont autorisées" msgstr "valeur {0} n'est pas permis, seules {1} sont autorisées"
#: tiramisu/option.py:660 #: tiramisu/option.py:677
msgid "invalid boolean" msgid "invalid boolean"
msgstr "booléen invalide" msgstr "booléen invalide"
#: tiramisu/option.py:670 #: tiramisu/option.py:687
msgid "invalid integer" msgid "invalid integer"
msgstr "nombre invalide" msgstr "nombre invalide"
#: tiramisu/option.py:680 #: tiramisu/option.py:697
msgid "invalid float" msgid "invalid float"
msgstr "invalide nombre flottan" msgstr "invalide nombre flottan"
#: tiramisu/option.py:690 #: tiramisu/option.py:707
msgid "invalid string" msgid "invalid string"
msgstr "invalide caractère" msgstr "invalide caractère"
#: tiramisu/option.py:707 #: tiramisu/option.py:724
msgid "invalid unicode" msgid "invalid unicode"
msgstr "invalide unicode" msgstr "invalide unicode"
#: tiramisu/option.py:719 #: tiramisu/option.py:736
msgid "malformed symlinkoption must be an option for symlink {0}" msgid "malformed symlinkoption must be an option for symlink {0}"
msgstr "symlinkoption mal formé, doit être une option pour 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" msgid "invalid IP"
msgstr "adresse IP invalide" msgstr "adresse IP invalide"
#: tiramisu/option.py:783 #: tiramisu/option.py:801
msgid "invalid IP, mustn't not be in reserved class" msgid "IP shouldn't be in reserved class"
msgstr "adresse IP invalide, ne doit pas être d'une classe reservée" msgstr "l'adresse IP ne devrait pas être d'une classe réservée"
#: tiramisu/option.py:785 #: 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: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" msgid "invalid IP, must be in private class"
msgstr "adresse IP invalide, doit être dans la classe privée" msgstr "adresse IP invalide, doit être dans la classe privée"
#: tiramisu/option.py:814 tiramisu/option.py:989
msgid "invalid len for vals"
msgstr "longueur invalide pour vals"
#: 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 #: 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:864
msgid "inconsistency in allowed range" msgid "inconsistency in allowed range"
msgstr "inconsistence dans la plage autorisée" msgstr "inconsistence dans la plage autorisée"
#: tiramisu/option.py:828 #: tiramisu/option.py:869
msgid "max value is empty" msgid "max value is empty"
msgstr "la valeur maximum est vide" msgstr "la valeur maximum est vide"
#: tiramisu/option.py:845 #: tiramisu/option.py:886
msgid "invalid port, range must have two values only" msgid "invalid port, range must have two values only"
msgstr "port invalide, une plage doit avoir deux valeurs seulement" msgstr "port invalide, une plage doit avoir deux valeurs seulement"
#: tiramisu/option.py:848 #: tiramisu/option.py:889
msgid "invalid port, first port in range must be smaller than the second one" msgid "invalid port, first port in range must be smaller than the second one"
msgstr "" msgstr ""
"port invalide, le premier port d'une plage doit être plus petit que le second" "port invalide, le premier port d'une plage doit être plus petit que le second"
#: tiramisu/option.py:857 #: tiramisu/option.py:898
msgid "invalid port" msgid "invalid port"
msgstr "port invalide" msgstr "port invalide"
#: tiramisu/option.py:859 #: tiramisu/option.py:900
msgid "invalid port, must be an between {0} and {1}" msgid "invalid port, must be an between {0} and {1}"
msgstr "port invalide, port doit être entre {0} et {1}" msgstr "port invalide, port doit être entre {0} et {1}"
#: tiramisu/option.py:873 #: tiramisu/option.py:914
msgid "invalid network address" msgid "invalid network address"
msgstr "adresse réseau invalide" msgstr "adresse réseau invalide"
#: tiramisu/option.py:878 #: tiramisu/option.py:920
msgid "invalid network address, must not be in reserved class" msgid "network address shouldn't be in reserved class"
msgstr "adresse réseau invalide, ne doit pas être dans la classe reservée" msgstr "l'adresse réseau ne devait pas être dans la classe réservée"
#: tiramisu/option.py:890 #: 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" msgid "invalid netmask address"
msgstr "masque de sous-réseau invalide" msgstr "masque de sous-réseau invalide"
#: tiramisu/option.py:906 #: tiramisu/option.py:952
msgid "invalid len for opts" msgid "invalid len for opts"
msgstr "longueur invalide pour opts" msgstr "longueur invalide pour opts"
#: tiramisu/option.py:920 #: tiramisu/option.py:966
msgid "invalid IP {0} ({1}) with netmask {2}, this IP is a network" 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" msgstr "IP invalide {0} ({1}) avec masque {2}, cette IP est un réseau"
#: tiramisu/option.py:925 #: tiramisu/option.py:971
msgid "invalid network {0} ({1}) with netmask {2}" msgid "invalid network {0} ({1}) with netmask {2}"
msgstr "réseau invalide {0} ({1}) avec masque {2}" msgstr "réseau invalide {0} ({1}) avec masque {2}"
#: tiramisu/option.py:939 #: tiramisu/option.py:985
msgid "invalid broadcast address" msgid "invalid broadcast address"
msgstr "adresse de broadcast invalide" msgstr "adresse de broadcast invalide"
#: tiramisu/option.py:943 #: tiramisu/option.py:994
msgid "invalid len for vals"
msgstr "longueur invalide pour vals"
#: tiramisu/option.py:948
msgid "" msgid ""
"invalid broadcast {0} ({1}) with network {2} ({3}) and netmask {4} ({5})" "invalid broadcast {0} ({1}) with network {2} ({3}) and netmask {4} ({5})"
msgstr "" msgstr ""
"Broadcast invalide {0} ({1}) avec le réseau {2} ({3}) et le masque {4} ({5})" "Broadcast invalide {0} ({1}) avec le réseau {2} ({3}) et le masque {4} ({5})"
#: tiramisu/option.py:970 #: tiramisu/option.py:1016
msgid "unknown type_ {0} for hostname" msgid "unknown type_ {0} for hostname"
msgstr "type_ inconnu {0} pour le nom d'hôte" msgstr "type_ inconnu {0} pour le nom d'hôte"
#: tiramisu/option.py:973 #: tiramisu/option.py:1019
msgid "allow_ip must be a boolean" msgid "allow_ip must be a boolean"
msgstr "allow_ip doit être un booléen" msgstr "allow_ip doit être un booléen"
#: tiramisu/option.py:975 #: tiramisu/option.py:1021
msgid "allow_without_dot must be a boolean" msgid "allow_without_dot must be a boolean"
msgstr "allow_without_dot doit être un booléen" msgstr "allow_without_dot doit être un booléen"
#: tiramisu/option.py:1019 #: tiramisu/option.py:1065
msgid "invalid domainname, must have dot" msgid "invalid domainname, must have dot"
msgstr "nom de domaine invalide, doit avoir un point" msgstr "nom de domaine invalide, doit avoir un point"
#: tiramisu/option.py:1021 #: tiramisu/option.py:1067
msgid "invalid domainname's length (max 255)" msgid "invalid domainname's length (max 255)"
msgstr "longueur du nom de domaine invalide (maximum {1})" msgstr "longueur du nom de domaine invalide (maximum {1})"
#: tiramisu/option.py:1023 #: tiramisu/option.py:1069
msgid "invalid domainname's length (min 2)" msgid "invalid domainname's length (min 2)"
msgstr "longueur du nom de domaine invalide (minimum 2)" msgstr "longueur du nom de domaine invalide (minimum 2)"
#: tiramisu/option.py:1025 #: tiramisu/option.py:1071
msgid "invalid domainname" msgid "invalid domainname"
msgstr "nom de domaine invalide" msgstr "nom de domaine invalide"
#: tiramisu/option.py:1038 #: tiramisu/option.py:1084
msgid "invalid email address, should contains one @" msgid "invalid email address, must contains one @"
msgstr "adresse email invalide, devrait contenir un @" msgstr "adresse email invalide, doit contenir un @"
#: tiramisu/option.py:1041 #: tiramisu/option.py:1087
msgid "invalid username in email address" msgid "invalid username in email address"
msgstr "nom d'utilisateur invalide dans une adresse email" msgstr "nom d'utilisateur invalide dans une adresse email"
#: tiramisu/option.py:1054 #: tiramisu/option.py:1100
msgid "invalid url, should start with http:// or https://" msgid "invalid url, must start with http:// or https://"
msgstr "URL invalide, devrait démarré avec http:// ou https://" msgstr "URL invalide, doit démarrer avec http:// ou https://"
#: tiramisu/option.py:1073 #: tiramisu/option.py:1119
msgid "invalid url, port must be an between 0 and 65536" msgid "invalid url, port must be an between 0 and 65536"
msgstr "URL invalide, port doit être entre 0 et 65536" msgstr "URL invalide, port doit être entre 0 et 65536"
#: tiramisu/option.py:1079 #: tiramisu/option.py:1125
msgid "invalid url, should ends with filename" msgid "invalid url, must ends with filename"
msgstr "URL invalide, devrait finir avec un nom de fichier" msgstr "URL invalide, doit finir avec un nom de fichier"
#: tiramisu/option.py:1091 #: tiramisu/option.py:1137
msgid "invalid username" msgid "invalid username"
msgstr "utilisateur invalide" msgstr "utilisateur invalide"
#: tiramisu/option.py:1102 #: tiramisu/option.py:1148
msgid "invalid filename" msgid "invalid filename"
msgstr "nom de fichier invalide" msgstr "nom de fichier invalide"
#: tiramisu/option.py:1129 #: tiramisu/option.py:1175
msgid "duplicate option name: {0}" msgid "duplicate option name: {0}"
msgstr "nom de l'option dupliqué : {0}" msgstr "nom de l'option dupliqué : {0}"
#: tiramisu/option.py:1147 #: tiramisu/option.py:1193
msgid "unknown Option {0} in OptionDescription {1}" msgid "unknown Option {0} in OptionDescription {1}"
msgstr "Option {0} inconnue pour l'OptionDescription {1}" msgstr "Option {0} inconnue pour l'OptionDescription {1}"
#: tiramisu/option.py:1198 #: tiramisu/option.py:1244
msgid "duplicate option: {0}" msgid "duplicate option: {0}"
msgstr "option dupliquée : {0}" msgstr "option dupliquée : {0}"
#: tiramisu/option.py:1228 #: tiramisu/option.py:1275
msgid "consistency with option {0} which is not in Config" msgid "consistency with option {0} which is not in Config"
msgstr "consistency avec l'option {0} qui n'est pas dans une Config" msgstr "consistency avec l'option {0} qui n'est pas dans une Config"
#: tiramisu/option.py:1236 #: tiramisu/option.py:1283
msgid "no option for path {0}" msgid "no option for path {0}"
msgstr "pas d'option pour le chemin {0}" msgstr "pas d'option pour le chemin {0}"
#: tiramisu/option.py:1242 #: tiramisu/option.py:1289
msgid "no option {0} found" msgid "no option {0} found"
msgstr "pas d'option {0} trouvée" msgstr "pas d'option {0} trouvée"
#: tiramisu/option.py:1252 #: tiramisu/option.py:1299
msgid "cannot change group_type if already set (old {0}, new {1})" 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})" msgstr "ne peut changer group_type si déjà spécifié (ancien {0}, nouveau {1})"
#: tiramisu/option.py:1264 #: tiramisu/option.py:1311
msgid "master group {0} shall not have a subgroup" msgid "master group {0} shall not have a subgroup"
msgstr "groupe maître {0} ne doit pas avoir de sous-groupe" msgstr "groupe maître {0} ne doit pas avoir de sous-groupe"
#: tiramisu/option.py:1267 #: tiramisu/option.py:1314
msgid "master group {0} shall not have a symlinkoption" msgid "master group {0} shall not have a symlinkoption"
msgstr "groupe maître {0} ne doit pas avoir de symlinkoption" msgstr "groupe maître {0} ne doit pas avoir de symlinkoption"
#: tiramisu/option.py:1270 #: tiramisu/option.py:1317
msgid "not allowed option {0} in group {1}: this option is not a multi" msgid "not allowed option {0} in group {1}: this option is not a multi"
msgstr "" msgstr ""
"option non autorisée {0} dans le groupe {1} : cette option n'est pas une " "option non autorisée {0} dans le groupe {1} : cette option n'est pas une "
"multi" "multi"
#: tiramisu/option.py:1280 #: tiramisu/option.py:1327
msgid "master group with wrong master name for {0}" msgid "master group with wrong master name for {0}"
msgstr "le groupe maître avec un nom de maître érroné pour {0}" msgstr "le groupe maître avec un nom de maître érroné pour {0}"
#: tiramisu/option.py:1288 #: tiramisu/option.py:1335
msgid "callback of master's option shall not refered a slave's ones" msgid "callback of master's option shall not refered a slave's ones"
msgstr "" msgstr ""
"callback d'une variable maitre ne devrait pas référencer des variables " "callback d'une variable maitre ne devrait pas référencer des variables "
"esclaves" "esclaves"
#: tiramisu/option.py:1296 #: tiramisu/option.py:1343
msgid "group_type: {0} not allowed" msgid "group_type: {0} not allowed"
msgstr "group_type : {0} non autorisé" msgstr "group_type : {0} non autorisé"
#: tiramisu/option.py:1385 #: tiramisu/option.py:1443
msgid "malformed requirements type for option: {0}, must be a dict" msgid "malformed requirements type for option: {0}, must be a dict"
msgstr "" msgstr ""
"type requirements malformé pour l'option : {0}, doit être un dictionnaire" "type requirements malformé pour l'option : {0}, doit être un dictionnaire"
#: tiramisu/option.py:1402 #: tiramisu/option.py:1460
msgid "" msgid ""
"malformed requirements for option: {0} require must have option, expected " "malformed requirements for option: {0} require must have option, expected "
"and action keys" "and action keys"
@ -391,68 +420,68 @@ msgstr ""
"requirements malformé pour l'option : {0} l'exigence doit avoir les clefs " "requirements malformé pour l'option : {0} l'exigence doit avoir les clefs "
"option, expected et action" "option, expected et action"
#: tiramisu/option.py:1407 #: tiramisu/option.py:1465
msgid "malformed requirements for option: {0} inverse must be boolean" msgid "malformed requirements for option: {0} inverse must be boolean"
msgstr "" msgstr ""
"requirements mal formés pour l'option : {0} inverse doit être un booléen" "requirements mal formés pour l'option : {0} inverse doit être un booléen"
#: tiramisu/option.py:1411 #: tiramisu/option.py:1469
msgid "malformed requirements for option: {0} transitive must be boolean" msgid "malformed requirements for option: {0} transitive must be boolean"
msgstr "" msgstr ""
"requirements mal formés pour l'option : {0} transitive doit être booléen" "requirements mal formés pour l'option : {0} transitive doit être booléen"
#: tiramisu/option.py:1415 #: tiramisu/option.py:1473
msgid "malformed requirements for option: {0} same_action must be boolean" msgid "malformed requirements for option: {0} same_action must be boolean"
msgstr "" msgstr ""
"requirements mal formés pour l'option : {0} same_action doit être un booléen" "requirements mal formés pour l'option : {0} same_action doit être un booléen"
#: tiramisu/option.py:1419 #: tiramisu/option.py:1477
msgid "malformed requirements must be an option in option {0}" msgid "malformed requirements must be an option in option {0}"
msgstr "requirements mal formés doit être une option dans l'option {0}" msgstr "requirements mal formés doit être une option dans l'option {0}"
#: tiramisu/option.py:1422 #: tiramisu/option.py:1480
msgid "malformed requirements option {0} should not be a multi" msgid "malformed requirements option {0} must not be a multi"
msgstr "requirements mal formés l'option {0} ne doit pas être une multi" msgstr "requirements mal formés l'option {0} ne doit pas être une multi"
#: tiramisu/option.py:1428 #: tiramisu/option.py:1486
msgid "" msgid ""
"malformed requirements second argument must be valid for option {0}: {1}" "malformed requirements second argument must be valid for option {0}: {1}"
msgstr "" msgstr ""
"requirements mal formés deuxième argument doit être valide pour l'option " "requirements mal formés deuxième argument doit être valide pour l'option "
"{0} : {1}" "{0} : {1}"
#: tiramisu/option.py:1433 #: tiramisu/option.py:1491
msgid "inconsistency in action types for option: {0} action: {1}" msgid "inconsistency in action types for option: {0} action: {1}"
msgstr "incohérence dans les types action pour l'option : {0} action {1}" msgstr "incohérence dans les types action pour l'option : {0} action {1}"
#: tiramisu/option.py:1458 #: tiramisu/option.py:1516
msgid "{0} should be a function" msgid "{0} must be a function"
msgstr "{0} doit être une fonction" msgstr "{0} doit être une fonction"
#: tiramisu/option.py:1461 #: tiramisu/option.py:1519
msgid "{0}_params should be a dict" msgid "{0}_params must be a dict"
msgstr "{0}_params devrait être un dict" msgstr "{0}_params doit être un dict"
#: tiramisu/option.py:1464 #: tiramisu/option.py:1522
msgid "{0}_params with key {1} should not have length different to 1" msgid "{0}_params with key {1} mustn't have length different to 1"
msgstr "" 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:1468 #: tiramisu/option.py:1526
msgid "{0}_params should be tuple for key \"{1}\"" msgid "{0}_params must be tuple for key \"{1}\""
msgstr "{0}_params devrait être un tuple pour la clef \"{1}\"" msgstr "{0}_params doit être un tuple pour la clef \"{1}\""
#: tiramisu/option.py:1474 #: tiramisu/option.py:1532
msgid "validator not support tuple" msgid "validator not support tuple"
msgstr "validator n'accepte pas de tuple" msgstr "validator n'accepte pas de tuple"
#: tiramisu/option.py:1477 #: tiramisu/option.py:1535
msgid "{0}_params should have an option not a {0} for first argument" msgid "{0}_params must have an option not a {0} for first argument"
msgstr "{0}_params devrait avoir une option pas un {0} pour premier argument" msgstr "{0}_params doit avoir une option pas un {0} pour premier argument"
#: tiramisu/option.py:1481 #: tiramisu/option.py:1539
msgid "{0}_params should have a boolean not a {0} for second argument" msgid "{0}_params must have a boolean not a {0} for second argument"
msgstr "{0}_params devrait avoir un boolean pas un {0} pour second argument" msgstr "{0}_params doit avoir un booléen pas un {0} pour second argument"
#: tiramisu/setting.py:116 #: tiramisu/setting.py:116
msgid "can't rebind {0}" msgid "can't rebind {0}"

View file

@ -5,7 +5,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2014-03-09 20:14+CET\n" "POT-Creation-Date: 2014-03-12 21:49+CET\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -120,308 +120,336 @@ msgstr ""
msgid "params defined for a callback function but no callback defined yet for option {0}" msgid "params defined for a callback function but no callback defined yet for option {0}"
msgstr "" msgstr ""
#: tiramisu/option.py:423 tiramisu/option.py:433 #: tiramisu/option.py:425 tiramisu/option.py:450
msgid "invalid value for option {0}: {1}" msgid "invalid value for option {0}: {1}"
msgstr "" 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" msgid "invalid value {0} for option {1} which must be a list"
msgstr "" msgstr ""
#: tiramisu/option.py:506 #: tiramisu/option.py:519
msgid "consistency should be set with an option" msgid "consistency must be set with an option"
msgstr "" msgstr ""
#: tiramisu/option.py:508 #: tiramisu/option.py:521
msgid "cannot add consistency with itself" msgid "cannot add consistency with itself"
msgstr "" msgstr ""
#: tiramisu/option.py:510 #: tiramisu/option.py:523
msgid "every options in consistency should be multi or none" msgid "every options in consistency must be multi or none"
msgstr "" msgstr ""
#: tiramisu/option.py:530 #: tiramisu/option.py:544
msgid "same value for {0} and {1}" msgid "same value for {0} and {1}, should be different"
msgstr "" msgstr ""
#: tiramisu/option.py:623 #: tiramisu/option.py:546
msgid "same value for {0} and {1}, must be different"
msgstr ""
#: tiramisu/option.py:640
msgid "values must be a tuple for {0}" msgid "values must be a tuple for {0}"
msgstr "" msgstr ""
#: tiramisu/option.py:626 #: tiramisu/option.py:643
msgid "open_values must be a boolean for {0}" msgid "open_values must be a boolean for {0}"
msgstr "" msgstr ""
#: tiramisu/option.py:648 #: tiramisu/option.py:665
msgid "value {0} is not permitted, only {1} is allowed" msgid "value {0} is not permitted, only {1} is allowed"
msgstr "" msgstr ""
#: tiramisu/option.py:660 #: tiramisu/option.py:677
msgid "invalid boolean" msgid "invalid boolean"
msgstr "" msgstr ""
#: tiramisu/option.py:670 #: tiramisu/option.py:687
msgid "invalid integer" msgid "invalid integer"
msgstr "" msgstr ""
#: tiramisu/option.py:680 #: tiramisu/option.py:697
msgid "invalid float" msgid "invalid float"
msgstr "" msgstr ""
#: tiramisu/option.py:690 #: tiramisu/option.py:707
msgid "invalid string" msgid "invalid string"
msgstr "" msgstr ""
#: tiramisu/option.py:707 #: tiramisu/option.py:724
msgid "invalid unicode" msgid "invalid unicode"
msgstr "" msgstr ""
#: tiramisu/option.py:719 #: tiramisu/option.py:736
msgid "malformed symlinkoption must be an option for symlink {0}" msgid "malformed symlinkoption must be an option for symlink {0}"
msgstr "" 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" msgid "invalid IP"
msgstr "" msgstr ""
#: tiramisu/option.py:783 #: tiramisu/option.py:801
msgid "invalid IP, mustn't not be in reserved class" msgid "IP shouldn't be in reserved class"
msgstr "" 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" msgid "invalid IP, must be in private class"
msgstr "" msgstr ""
#: tiramisu/option.py:823 #: tiramisu/option.py:814 tiramisu/option.py:989
msgid "inconsistency in allowed range"
msgstr ""
#: tiramisu/option.py:828
msgid "max value is empty"
msgstr ""
#: tiramisu/option.py:845
msgid "invalid port, range must have two values only"
msgstr ""
#: tiramisu/option.py:848
msgid "invalid port, first port in range must be smaller than the second one"
msgstr ""
#: tiramisu/option.py:857
msgid "invalid port"
msgstr ""
#: tiramisu/option.py:859
msgid "invalid port, must be an between {0} and {1}"
msgstr ""
#: tiramisu/option.py:873
msgid "invalid network address"
msgstr ""
#: tiramisu/option.py:878
msgid "invalid network address, must not be in reserved class"
msgstr ""
#: tiramisu/option.py:890
msgid "invalid netmask address"
msgstr ""
#: tiramisu/option.py:906
msgid "invalid len for opts"
msgstr ""
#: tiramisu/option.py:920
msgid "invalid IP {0} ({1}) with netmask {2}, this IP is a network"
msgstr ""
#: tiramisu/option.py:925
msgid "invalid network {0} ({1}) with netmask {2}"
msgstr ""
#: tiramisu/option.py:939
msgid "invalid broadcast address"
msgstr ""
#: tiramisu/option.py:943
msgid "invalid len for vals" msgid "invalid len for vals"
msgstr "" msgstr ""
#: tiramisu/option.py:948 #: 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:864
msgid "inconsistency in allowed range"
msgstr ""
#: tiramisu/option.py:869
msgid "max value is empty"
msgstr ""
#: tiramisu/option.py:886
msgid "invalid port, range must have two values only"
msgstr ""
#: tiramisu/option.py:889
msgid "invalid port, first port in range must be smaller than the second one"
msgstr ""
#: tiramisu/option.py:898
msgid "invalid port"
msgstr ""
#: tiramisu/option.py:900
msgid "invalid port, must be an between {0} and {1}"
msgstr ""
#: tiramisu/option.py:914
msgid "invalid network address"
msgstr ""
#: 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:935
msgid "invalid netmask address"
msgstr ""
#: tiramisu/option.py:952
msgid "invalid len for opts"
msgstr ""
#: tiramisu/option.py:966
msgid "invalid IP {0} ({1}) with netmask {2}, this IP is a network"
msgstr ""
#: tiramisu/option.py:971
msgid "invalid network {0} ({1}) with netmask {2}"
msgstr ""
#: tiramisu/option.py:985
msgid "invalid broadcast address"
msgstr ""
#: tiramisu/option.py:994
msgid "invalid broadcast {0} ({1}) with network {2} ({3}) and netmask {4} ({5})" msgid "invalid broadcast {0} ({1}) with network {2} ({3}) and netmask {4} ({5})"
msgstr "" msgstr ""
#: tiramisu/option.py:970 #: tiramisu/option.py:1016
msgid "unknown type_ {0} for hostname" msgid "unknown type_ {0} for hostname"
msgstr "" msgstr ""
#: tiramisu/option.py:973 #: tiramisu/option.py:1019
msgid "allow_ip must be a boolean" msgid "allow_ip must be a boolean"
msgstr "" msgstr ""
#: tiramisu/option.py:975 #: tiramisu/option.py:1021
msgid "allow_without_dot must be a boolean" msgid "allow_without_dot must be a boolean"
msgstr "" msgstr ""
#: tiramisu/option.py:1019 #: tiramisu/option.py:1065
msgid "invalid domainname, must have dot" msgid "invalid domainname, must have dot"
msgstr "" msgstr ""
#: tiramisu/option.py:1021 #: tiramisu/option.py:1067
msgid "invalid domainname's length (max 255)" msgid "invalid domainname's length (max 255)"
msgstr "" msgstr ""
#: tiramisu/option.py:1023 #: tiramisu/option.py:1069
msgid "invalid domainname's length (min 2)" msgid "invalid domainname's length (min 2)"
msgstr "" msgstr ""
#: tiramisu/option.py:1025 #: tiramisu/option.py:1071
msgid "invalid domainname" msgid "invalid domainname"
msgstr "" msgstr ""
#: tiramisu/option.py:1038 #: tiramisu/option.py:1084
msgid "invalid email address, should contains one @" msgid "invalid email address, must contains one @"
msgstr "" msgstr ""
#: tiramisu/option.py:1041 #: tiramisu/option.py:1087
msgid "invalid username in email address" msgid "invalid username in email address"
msgstr "" msgstr ""
#: tiramisu/option.py:1054 #: tiramisu/option.py:1100
msgid "invalid url, should start with http:// or https://" msgid "invalid url, must start with http:// or https://"
msgstr "" msgstr ""
#: tiramisu/option.py:1073 #: tiramisu/option.py:1119
msgid "invalid url, port must be an between 0 and 65536" msgid "invalid url, port must be an between 0 and 65536"
msgstr "" msgstr ""
#: tiramisu/option.py:1079 #: tiramisu/option.py:1125
msgid "invalid url, should ends with filename" msgid "invalid url, must ends with filename"
msgstr "" msgstr ""
#: tiramisu/option.py:1091 #: tiramisu/option.py:1137
msgid "invalid username" msgid "invalid username"
msgstr "" msgstr ""
#: tiramisu/option.py:1102 #: tiramisu/option.py:1148
msgid "invalid filename" msgid "invalid filename"
msgstr "" msgstr ""
#: tiramisu/option.py:1129 #: tiramisu/option.py:1175
msgid "duplicate option name: {0}" msgid "duplicate option name: {0}"
msgstr "" msgstr ""
#: tiramisu/option.py:1147 #: tiramisu/option.py:1193
msgid "unknown Option {0} in OptionDescription {1}" msgid "unknown Option {0} in OptionDescription {1}"
msgstr "" msgstr ""
#: tiramisu/option.py:1198 #: tiramisu/option.py:1244
msgid "duplicate option: {0}" msgid "duplicate option: {0}"
msgstr "" msgstr ""
#: tiramisu/option.py:1228 #: tiramisu/option.py:1275
msgid "consistency with option {0} which is not in Config" msgid "consistency with option {0} which is not in Config"
msgstr "" msgstr ""
#: tiramisu/option.py:1236 #: tiramisu/option.py:1283
msgid "no option for path {0}" msgid "no option for path {0}"
msgstr "" msgstr ""
#: tiramisu/option.py:1242 #: tiramisu/option.py:1289
msgid "no option {0} found" msgid "no option {0} found"
msgstr "" msgstr ""
#: tiramisu/option.py:1252 #: tiramisu/option.py:1299
msgid "cannot change group_type if already set (old {0}, new {1})" msgid "cannot change group_type if already set (old {0}, new {1})"
msgstr "" msgstr ""
#: tiramisu/option.py:1264 #: tiramisu/option.py:1311
msgid "master group {0} shall not have a subgroup" msgid "master group {0} shall not have a subgroup"
msgstr "" msgstr ""
#: tiramisu/option.py:1267 #: tiramisu/option.py:1314
msgid "master group {0} shall not have a symlinkoption" msgid "master group {0} shall not have a symlinkoption"
msgstr "" msgstr ""
#: tiramisu/option.py:1270 #: tiramisu/option.py:1317
msgid "not allowed option {0} in group {1}: this option is not a multi" msgid "not allowed option {0} in group {1}: this option is not a multi"
msgstr "" msgstr ""
#: tiramisu/option.py:1280 #: tiramisu/option.py:1327
msgid "master group with wrong master name for {0}" msgid "master group with wrong master name for {0}"
msgstr "" msgstr ""
#: tiramisu/option.py:1288 #: tiramisu/option.py:1335
msgid "callback of master's option shall not refered a slave's ones" msgid "callback of master's option shall not refered a slave's ones"
msgstr "" msgstr ""
#: tiramisu/option.py:1296 #: tiramisu/option.py:1343
msgid "group_type: {0} not allowed" msgid "group_type: {0} not allowed"
msgstr "" msgstr ""
#: tiramisu/option.py:1385 #: tiramisu/option.py:1443
msgid "malformed requirements type for option: {0}, must be a dict" msgid "malformed requirements type for option: {0}, must be a dict"
msgstr "" msgstr ""
#: tiramisu/option.py:1402 #: tiramisu/option.py:1460
msgid "malformed requirements for option: {0} require must have option, expected and action keys" msgid "malformed requirements for option: {0} require must have option, expected and action keys"
msgstr "" msgstr ""
#: tiramisu/option.py:1407 #: tiramisu/option.py:1465
msgid "malformed requirements for option: {0} inverse must be boolean" msgid "malformed requirements for option: {0} inverse must be boolean"
msgstr "" msgstr ""
#: tiramisu/option.py:1411 #: tiramisu/option.py:1469
msgid "malformed requirements for option: {0} transitive must be boolean" msgid "malformed requirements for option: {0} transitive must be boolean"
msgstr "" msgstr ""
#: tiramisu/option.py:1415 #: tiramisu/option.py:1473
msgid "malformed requirements for option: {0} same_action must be boolean" msgid "malformed requirements for option: {0} same_action must be boolean"
msgstr "" msgstr ""
#: tiramisu/option.py:1419 #: tiramisu/option.py:1477
msgid "malformed requirements must be an option in option {0}" msgid "malformed requirements must be an option in option {0}"
msgstr "" msgstr ""
#: tiramisu/option.py:1422 #: tiramisu/option.py:1480
msgid "malformed requirements option {0} should not be a multi" msgid "malformed requirements option {0} must not be a multi"
msgstr "" msgstr ""
#: tiramisu/option.py:1428 #: tiramisu/option.py:1486
msgid "malformed requirements second argument must be valid for option {0}: {1}" msgid "malformed requirements second argument must be valid for option {0}: {1}"
msgstr "" msgstr ""
#: tiramisu/option.py:1433 #: tiramisu/option.py:1491
msgid "inconsistency in action types for option: {0} action: {1}" msgid "inconsistency in action types for option: {0} action: {1}"
msgstr "" msgstr ""
#: tiramisu/option.py:1458 #: tiramisu/option.py:1516
msgid "{0} should be a function" msgid "{0} must be a function"
msgstr "" msgstr ""
#: tiramisu/option.py:1461 #: tiramisu/option.py:1519
msgid "{0}_params should be a dict" msgid "{0}_params must be a dict"
msgstr "" msgstr ""
#: tiramisu/option.py:1464 #: tiramisu/option.py:1522
msgid "{0}_params with key {1} should not have length different to 1" msgid "{0}_params with key {1} mustn't have length different to 1"
msgstr "" msgstr ""
#: tiramisu/option.py:1468 #: tiramisu/option.py:1526
msgid "{0}_params should be tuple for key \"{1}\"" msgid "{0}_params must be tuple for key \"{1}\""
msgstr "" msgstr ""
#: tiramisu/option.py:1474 #: tiramisu/option.py:1532
msgid "validator not support tuple" msgid "validator not support tuple"
msgstr "" msgstr ""
#: tiramisu/option.py:1477 #: tiramisu/option.py:1535
msgid "{0}_params should have an option not a {0} for first argument" msgid "{0}_params must have an option not a {0} for first argument"
msgstr "" msgstr ""
#: tiramisu/option.py:1481 #: tiramisu/option.py:1539
msgid "{0}_params should have a boolean not a {0} for second argument" msgid "{0}_params must have a boolean not a {0} for second argument"
msgstr "" msgstr ""
#: tiramisu/setting.py:116 #: tiramisu/setting.py:116