Merge branch 'master' into lgpl

This commit is contained in:
Emmanuel Garette 2013-09-28 18:43:46 +02:00
commit b7f85b8559
14 changed files with 1028 additions and 571 deletions

View File

@ -0,0 +1,6 @@
tiramisu.storage
================
.. automodule:: tiramisu.storage
:members:
:noindex:

View File

@ -230,3 +230,9 @@ def test_duplicated_option():
root = OptionDescription('root', '', [d1, d2])
#in different OptionDescription
raises(ConflictError, "config = Config(root)")
def test_cannot_assign_value_to_option_description():
descr = make_description()
cfg = Config(descr)
raises(TypeError, "cfg.gc = 3")

View File

@ -7,7 +7,7 @@ from tiramisu.option import IPOption, NetworkOption, NetmaskOption, \
def test_ip():
a = IPOption('a', '')
b = IPOption('b', '', only_private=True)
b = IPOption('b', '', private_only=True)
od = OptionDescription('od', '', [a, b])
c = Config(od)
c.a = '192.168.1.1'

View File

@ -28,6 +28,12 @@ def return_value(value=None):
return value
def return_value2(*args, **kwargs):
value = list(args)
value.extend(kwargs.values())
return value
def make_description():
gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
gcdummy = BoolOption('dummy', 'dummy', default=False)
@ -675,3 +681,13 @@ def test_callback_multi_multi():
raises(ConfigError, "cfg.val4")
assert cfg.val5 == ['val1', 'val4', 'val2', 'val4', 'val3', 'val4']
assert cfg.val7 == ['val1', 'val21', 'val2', 'val22', 'val3', 'val23']
def test_multi_with_no_value():
#First option return [] (so without value)
val1 = StrOption('val1', "", ['val'], multi=True)
val2 = StrOption('val2', "", multi=True)
val3 = StrOption('val3', '', multi=True, callback=return_value, callback_params={'': ((val2, False),), 'value': ((val1, False),)})
od = OptionDescription('od', '', [val1, val2, val3])
c = Config(od)
raises(ConfigError, "c.val3")

View File

@ -4,7 +4,8 @@ from py.test import raises
from tiramisu.setting import owners, groups
from tiramisu.config import Config
from tiramisu.option import IPOption, NetworkOption, NetmaskOption, IntOption,\
SymLinkOption, OptionDescription
BroadcastOption, SymLinkOption, OptionDescription
from tiramisu.error import ConfigError
def test_consistency_not_equal():
@ -22,6 +23,60 @@ def test_consistency_not_equal():
c.b = 2
def test_consistency_not_equal_many_opts():
a = IntOption('a', '')
b = IntOption('b', '')
c = IntOption('c', '')
d = IntOption('d', '')
e = IntOption('e', '')
f = IntOption('f', '')
od = OptionDescription('od', '', [a, b, c, d, e, f])
a.impl_add_consistency('not_equal', b, c, d, e, f)
c = Config(od)
assert c.a is None
assert c.b is None
#
c.a = 1
del(c.a)
#
c.a = 1
raises(ValueError, "c.b = 1")
#
c.b = 2
raises(ValueError, "c.f = 2")
raises(ValueError, "c.f = 1")
#
c.d = 3
raises(ValueError, "c.f = 3")
raises(ValueError, "c.a = 3")
raises(ValueError, "c.c = 3")
raises(ValueError, "c.e = 3")
def test_consistency_not_in_config():
a = IntOption('a', '')
b = IntOption('b', '')
a.impl_add_consistency('not_equal', b)
od1 = OptionDescription('od1', '', [a])
od2 = OptionDescription('od2', '', [b])
od = OptionDescription('root', '', [od1])
raises(ConfigError, "Config(od)")
od = OptionDescription('root', '', [od1, od2])
Config(od)
#with subconfig
raises(ConfigError, "Config(od.od1)")
def test_consistency_afer_config():
a = IntOption('a', '')
b = IntOption('b', '')
od1 = OptionDescription('od1', '', [a])
od2 = OptionDescription('od2', '', [b])
od = OptionDescription('root', '', [od1, od2])
Config(od)
raises(AttributeError, "a.impl_add_consistency('not_equal', b)")
def test_consistency_not_equal_symlink():
a = IntOption('a', '')
b = IntOption('b', '')
@ -29,7 +84,7 @@ def test_consistency_not_equal_symlink():
od = OptionDescription('od', '', [a, b, c])
a.impl_add_consistency('not_equal', b)
c = Config(od)
assert set(od._consistencies.keys()) == set([a, b])
assert set(od._cache_consistencies.keys()) == set([a, b])
def test_consistency_not_equal_multi():
@ -53,6 +108,14 @@ def test_consistency_default():
raises(ValueError, "a.impl_add_consistency('not_equal', b)")
def test_consistency_default_multi():
a = IntOption('a', '', [2, 1], multi=True)
b = IntOption('b', '', [1, 1], multi=True)
c = IntOption('c', '', [1, 2], multi=True)
raises(ValueError, "a.impl_add_consistency('not_equal', b)")
a.impl_add_consistency('not_equal', c)
def test_consistency_default_diff():
a = IntOption('a', '', 3)
b = IntOption('b', '', 1)
@ -99,7 +162,7 @@ def test_consistency_ip_netmask_error_multi():
a = IPOption('a', '', multi=True)
b = NetmaskOption('b', '')
od = OptionDescription('od', '', [a, b])
raises(ValueError, "b.impl_add_consistency('ip_netmask', a)")
raises(ConfigError, "b.impl_add_consistency('ip_netmask', a)")
def test_consistency_ip_netmask_multi():
@ -159,3 +222,53 @@ def test_consistency_network_netmask_multi_master():
c.a = ['192.168.1.0']
c.b = ['255.255.255.0']
raises(ValueError, "c.a = ['192.168.1.1']")
def test_consistency_broadcast():
a = NetworkOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True)
c = BroadcastOption('c', '', multi=True)
od = OptionDescription('a', '', [a, b, c])
od.impl_set_group_type(groups.master)
b.impl_add_consistency('network_netmask', a)
c.impl_add_consistency('broadcast', a, b)
c = Config(od)
#first, test network_netmask
c.a = ['192.168.1.128']
raises(ValueError, "c.b = ['255.255.255.0']")
#
c.a = ['192.168.1.0']
c.b = ['255.255.255.0']
c.c = ['192.168.1.255']
raises(ValueError, "c.a = ['192.168.1.1']")
#
c.a = ['192.168.1.0', '192.168.2.128']
c.b = ['255.255.255.0', '255.255.255.128']
c.c = ['192.168.1.255', '192.168.2.255']
raises(ValueError, "c.c[1] = '192.168.2.128'")
c.c[1] = '192.168.2.255'
def test_consistency_broadcast_default():
a = NetworkOption('a', '', '192.168.1.0')
b = NetmaskOption('b', '', '255.255.255.128')
c = BroadcastOption('c', '', '192.168.2.127')
d = BroadcastOption('d', '', '192.168.1.127')
od = OptionDescription('a', '', [a, b, c])
raises(ValueError, "c.impl_add_consistency('broadcast', a, b)")
od2 = OptionDescription('a', '', [a, b, d])
d.impl_add_consistency('broadcast', a, b)
def test_consistency_not_all():
#_cache_consistencies is not None by not options has consistencies
a = NetworkOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True)
c = BroadcastOption('c', '', multi=True)
od = OptionDescription('a', '', [a, b, c])
od.impl_set_group_type(groups.master)
b.impl_add_consistency('network_netmask', a)
c = Config(od)
c.a = ['192.168.1.0']
c.b = ['255.255.255.0']
c.c = ['192.168.1.255']

View File

@ -1,9 +1,11 @@
import autopath
import warnings
from py.test import raises
from tiramisu.config import Config
from tiramisu.option import StrOption, OptionDescription
from tiramisu.error import ConfigError
from tiramisu.setting import groups
from tiramisu.error import ValueWarning
def return_true(value, param=None):
@ -13,37 +15,36 @@ def return_true(value, param=None):
def return_false(value, param=None):
if value == 'val' and param in [None, 'yes']:
return False
raise ValueError('error')
def return_val(value, param=None):
return 'val'
def return_if_val(value):
if value != 'val':
raise ValueError('error')
def test_validator():
opt1 = StrOption('opt1', '', validator=return_true, default='val')
raises(ValueError, "StrOption('opt2', '', validator=return_false, default='val')")
raises(ConfigError, "StrOption('opt3', '', validator=return_val, default='val')")
opt2 = StrOption('opt2', '', validator=return_false)
opt3 = StrOption('opt3', '', validator=return_val)
root = OptionDescription('root', '', [opt1, opt2, opt3])
root = OptionDescription('root', '', [opt1, opt2])
cfg = Config(root)
assert cfg.opt1 == 'val'
raises(ValueError, "cfg.opt2 = 'val'")
raises(ConfigError, "cfg.opt3 = 'val'")
def test_validator_params():
opt1 = StrOption('opt1', '', validator=return_true, validator_params={'': ('yes',)}, default='val')
raises(ValueError, "StrOption('opt2', '', validator=return_false, validator_params={'': ('yes',)}, default='val')")
raises(ConfigError, "StrOption('opt3', '', validator=return_val, validator_params={'': ('yes',)}, default='val')")
opt2 = StrOption('opt2', '', validator=return_false, validator_params={'': ('yes',)})
opt3 = StrOption('opt3', '', validator=return_val, validator_params={'': ('yes',)})
root = OptionDescription('root', '', [opt1, opt2, opt3])
root = OptionDescription('root', '', [opt1, opt2])
cfg = Config(root)
assert cfg.opt1 == 'val'
raises(ValueError, "cfg.opt2 = 'val'")
raises(ConfigError, "cfg.opt3 = 'val'")
def test_validator_params_key():
@ -57,3 +58,98 @@ def test_validator_params_key():
def test_validator_params_option():
opt0 = StrOption('opt0', '', default='val')
raises(ValueError, "opt1 = StrOption('opt1', '', validator=return_true, validator_params={'': ((opt0, False),)}, default='val')")
def test_validator_multi():
opt1 = StrOption('opt1', '', validator=return_if_val, multi=True)
root = OptionDescription('root', '', [opt1])
cfg = Config(root)
assert cfg.opt1 == []
cfg.opt1.append('val')
assert cfg.opt1 == ['val']
raises(ValueError, "cfg.opt1.append('val1')")
raises(ValueError, "cfg.opt1 = ['val', 'val1']")
def test_validator_warning():
opt1 = StrOption('opt1', '', validator=return_true, default='val', warnings_only=True)
opt2 = StrOption('opt2', '', validator=return_false, warnings_only=True)
opt3 = StrOption('opt3', '', validator=return_if_val, multi=True, warnings_only=True)
root = OptionDescription('root', '', [opt1, opt2, opt3])
cfg = Config(root)
assert cfg.opt1 == 'val'
warnings.simplefilter("always", ValueWarning)
with warnings.catch_warnings(record=True) as w:
cfg.opt1 = 'val'
assert w == []
#
with warnings.catch_warnings(record=True) as w:
cfg.opt2 = 'val'
assert len(w) == 1
assert w[0].message.opt == opt2
assert str(w[0].message) == 'invalid value val for option opt2: error'
#
with warnings.catch_warnings(record=True) as w:
cfg.opt3.append('val')
assert w == []
#
with warnings.catch_warnings(record=True) as w:
cfg.opt3.append('val1')
assert len(w) == 1
assert w[0].message.opt == opt3
assert str(w[0].message) == 'invalid value val1 for option opt3: error'
raises(ValueError, "cfg.opt2 = 1")
#
with warnings.catch_warnings(record=True) as w:
cfg.opt2 = 'val'
cfg.opt3.append('val')
assert len(w) == 2
assert w[0].message.opt == opt2
assert str(w[0].message) == 'invalid value val for option opt2: error'
assert w[1].message.opt == opt3
assert str(w[1].message) == 'invalid value val1 for option opt3: error'
def test_validator_warning_master_slave():
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise", multi=True, validator=return_false, warnings_only=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-reseau", multi=True, validator=return_if_val, warnings_only=True)
interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
interface1.impl_set_group_type(groups.master)
assert interface1.impl_get_group_type() == groups.master
root = OptionDescription('root', '', [interface1])
cfg = Config(root)
warnings.simplefilter("always", ValueWarning)
with warnings.catch_warnings(record=True) as w:
cfg.ip_admin_eth0.ip_admin_eth0.append(None)
assert w == []
#
with warnings.catch_warnings(record=True) as w:
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 val1 for option 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 val for option 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 val for option 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 val for option 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 val for option ip_admin_eth0: error'

View File

@ -40,7 +40,7 @@ def _diff_opt(opt1, opt2):
if diff2 != set():
raise Exception('more attribute in opt2 {0}'.format(list(diff2)))
for attr in attr1:
if attr in ['_cache_paths']:
if attr in ['_cache_paths', '_cache_consistencies']:
continue
err1 = False
err2 = False
@ -72,7 +72,8 @@ def _diff_opt(opt1, opt2):
if isinstance(val1, list):
for index, consistency in enumerate(val1):
assert consistency[0] == val2[index][0]
assert consistency[1]._name == val2[index][1]._name
for idx, opt in enumerate(consistency[1]):
assert opt._name == val2[index][1][idx]._name
elif attr == '_callback':
assert val1[0] == val2[0]
if val1[1] is not None:

View File

@ -40,6 +40,13 @@ def carry_out_calculation(name, config, callback, callback_params,
:param max_len: max length for a multi
:type max_len: int
The callback_params is a dict. Key is used to build args (if key is '')
and kwargs (otherwise). Values are tuple of:
- values
- tuple with option and boolean's force_permissive (True when don't raise
if PropertiesOptionError)
Values could have multiple values only when key is ''.
* if no callback_params:
=> calculate()
@ -91,7 +98,6 @@ def carry_out_calculation(name, config, callback, callback_params,
- a multi option with an other multi option but with same length
opt1 == [1, 2, 3]
opt2 == [11, 12, 13]
callback_params={'': ((opt1, False), (opt2, False))}
=> calculate(1, 11)
=> calculate(2, 12)
=> calculate(3, 13)
@ -99,9 +105,13 @@ def carry_out_calculation(name, config, callback, callback_params,
- a multi option with an other multi option but with different length
opt1 == [1, 2, 3]
opt2 == [11, 12]
callback_params={'': ((opt1, False), (opt2, False))}
=> ConfigError()
- a multi option without value with a simple option
opt1 == []
opt2 == 11
=> []
* if callback_params={'value': ((opt1, False), (opt2, False))}
=> ConfigError()
@ -113,29 +123,33 @@ def carry_out_calculation(name, config, callback, callback_params,
If calculate return list, this list is extend to return value.
"""
tcparams = {}
# if callback_params has a callback, launch several time calculate()
one_is_multi = False
len_multi = 0
# multi's option should have same value for all option
len_multi = None
for key, callbacks in callback_params.items():
for callbk in callbacks:
if isinstance(callbk, tuple):
# callbk is something link (opt, True|False)
option, force_permissive = callbk
path = config.cfgimpl_get_description().impl_get_path_by_opt(
option)
# get value
try:
path = config.cfgimpl_get_description().impl_get_path_by_opt(option)
value = config._getattr(path, force_permissive=True)
except PropertiesOptionError as err:
if force_permissive:
continue
raise ConfigError(_('unable to carry out a calculation, '
'option {0} has properties: {1} for: '
'{2}').format(option._name, err.proptype,
'{2}').format(option._name,
err.proptype,
name))
is_multi = option.impl_is_multi()
if is_multi:
if value is not None:
len_value = len(value)
if len_multi != 0 and len_multi != len_value:
if len_multi is not None and len_multi != len_value:
raise ConfigError(_('unable to carry out a '
'calculation, option value with'
' multi types must have same '
@ -144,8 +158,12 @@ def carry_out_calculation(name, config, callback, callback_params,
one_is_multi = True
tcparams.setdefault(key, []).append((value, is_multi))
else:
# callbk is a value and not a multi
tcparams.setdefault(key, []).append((callbk, False))
# if one value is a multi, launch several time calculate
# if index is set, return a value
# if no index, return a list
if one_is_multi:
ret = []
if index:
@ -160,19 +178,20 @@ def carry_out_calculation(name, config, callback, callback_params,
else:
range_ = range(len_multi)
for incr in range_:
tcp = {}
params = []
args = []
kwargs = {}
for key, couples in tcparams.items():
for couple in couples:
value, ismulti = couple
if ismulti and value is not None:
if ismulti:
val = value[incr]
else:
val = value
if key == '':
params.append(value[incr])
args.append(val)
else:
tcp[key] = value[incr]
else:
params.append(value)
calc = calculate(name, callback, params, tcp)
kwargs[key] = val
calc = calculate(callback, args, kwargs)
if index:
ret = calc
else:
@ -182,24 +201,26 @@ def carry_out_calculation(name, config, callback, callback_params,
ret.append(calc)
return ret
else:
tcp = {}
params = []
# no value is multi
# return a single value
args = []
kwargs = {}
for key, couples in tcparams.items():
for couple in couples:
# couple[1] (ismulti) is always False
if key == '':
value = couple[0]
params.append(value)
args.append(couple[0])
else:
tcp[key] = couple[0]
return calculate(name, callback, params, tcp)
kwargs[key] = couple[0]
return calculate(callback, args, kwargs)
def calculate(name, callback, params, tcparams):
def calculate(callback, args, kwargs):
"""wrapper that launches the 'callback'
:param callback: callback name
:param params: in the callback's arity, the unnamed parameters
:param tcparams: in the callback's arity, the named parameters
:param callback: callback function
:param args: in the callback's arity, the unnamed parameters
:param kwargs: in the callback's arity, the named parameters
"""
return callback(*params, **tcparams)
return callback(*args, **kwargs)

View File

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
"options handler global entry point"
# Copyright (C) 2012-2013 Team tiramisu (see AUTHORS for all contributors)
#
# This program is free software: you can redistribute it and/or modify it
@ -19,6 +18,7 @@
# the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/
# the whole pypy projet is under MIT licence
# ____________________________________________________________
"options handler global entry point"
import weakref
from tiramisu.error import PropertiesOptionError, ConfigError
from tiramisu.option import OptionDescription, Option, SymLinkOption
@ -30,7 +30,11 @@ from tiramisu.i18n import _
class SubConfig(object):
"sub configuration management entry"
"""Sub configuration management entry.
Tree if OptionDescription's responsability. SubConfig are generated
on-demand. A Config is also a SubConfig.
Root Config is call context below
"""
__slots__ = ('_impl_context', '_impl_descr', '_impl_path')
def __init__(self, descr, context, subpath=None):
@ -55,6 +59,7 @@ class SubConfig(object):
def cfgimpl_reset_cache(self, only_expired=False, only=('values',
'settings')):
"remove cache (in context)"
self._cfgimpl_get_context().cfgimpl_reset_cache(only_expired, only)
def cfgimpl_get_home_by_path(self, path, force_permissive=False,
@ -179,7 +184,9 @@ class SubConfig(object):
homeconfig, name = self.cfgimpl_get_home_by_path(name)
return homeconfig.__setattr__(name, value)
child = getattr(self.cfgimpl_get_description(), name)
if not isinstance(child, SymLinkOption):
if isinstance(child, OptionDescription):
raise TypeError(_("can't assign to an OptionDescription"))
elif not isinstance(child, SymLinkOption):
if self._impl_path is None:
path = name
else:

View File

@ -56,3 +56,35 @@ class SlaveError(Exception):
class ConstError(TypeError):
"no uniq value in _NameSpace"
pass
#Warning
class ValueWarning(UserWarning):
"""Option could warn user and not raise ValueError.
Example:
>>> import warnings
>>> from tiramisu.error import ValueWarning
>>> from tiramisu.option import StrOption, OptionDescription
>>> from tiramisu.config import Config
>>> warnings.simplefilter("always", ValueWarning)
>>> def a(val):
... raise ValueError('pouet')
...
>>> s=StrOption('s', '', validator=a, warnings_only=True)
>>> o=OptionDescription('o', '', [s])
>>> c=Config(o)
>>> c.s = 'val'
StrOption:0: ValueWarning: invalid value val for option s: pouet
>>> with warnings.catch_warnings(record=True) as w:
... c.s = 'val'
...
>>> w[0].message.opt == s
True
>>> print str(w[0].message)
invalid value val for option s: pouet
"""
def __init__(self, msg, opt):
self.opt = opt
super(ValueWarning, self).__init__(msg)

View File

@ -24,8 +24,9 @@ import sys
from copy import copy, deepcopy
from types import FunctionType
from IPy import IP
import warnings
from tiramisu.error import ConflictError, ConfigError
from tiramisu.error import ConfigError, ConflictError, ValueWarning
from tiramisu.setting import groups, multitypes
from tiramisu.i18n import _
from tiramisu.autolib import carry_out_calculation
@ -59,9 +60,8 @@ class BaseOption(object):
__setattr__ method
"""
__slots__ = ('_name', '_requires', '_properties', '_readonly',
'_consistencies', '_calc_properties', '_impl_informations',
'_state_consistencies', '_state_readonly', '_state_requires',
'_stated')
'_calc_properties', '_impl_informations',
'_state_readonly', '_state_requires', '_stated')
def __init__(self, name, doc, requires, properties):
if not valid_name(name):
@ -71,7 +71,6 @@ class BaseOption(object):
self.impl_set_information('doc', doc)
self._calc_properties, self._requires = validate_requires_arg(
requires, self._name)
self._consistencies = None
if properties is None:
properties = tuple()
if not isinstance(properties, tuple):
@ -96,8 +95,7 @@ class BaseOption(object):
"frozen" (which has noting to do with the high level "freeze"
propertie or "read_only" property)
"""
if not name.startswith('_state') and name not in ('_cache_paths',
'_consistencies'):
if not name.startswith('_state') and not name.startswith('_cache'):
is_readonly = False
# never change _name
if name == '_name':
@ -107,15 +105,12 @@ class BaseOption(object):
is_readonly = True
except:
pass
elif name != '_readonly':
try:
if self._readonly is True:
if value is True:
# already readonly and try to re set readonly
# don't raise, just exit
return
is_readonly = True
except AttributeError:
pass
self._readonly = False
if is_readonly:
raise AttributeError(_("'{0}' ({1}) object attribute '{2}' is"
" read-only").format(
@ -147,58 +142,6 @@ class BaseOption(object):
raise ValueError(_("information's item not found: {0}").format(
key))
# serialize/unserialize
def _impl_convert_consistencies(self, descr, load=False):
"""during serialization process, many things have to be done.
one of them is the localisation of the options.
The paths are set once for all.
:type descr: :class:`tiramisu.option.OptionDescription`
:param load: `True` if we are at the init of the option description
:type load: bool
"""
if not load and self._consistencies is None:
self._state_consistencies = None
elif load and self._state_consistencies is None:
self._consistencies = None
del(self._state_consistencies)
else:
if load:
consistencies = self._state_consistencies
else:
consistencies = self._consistencies
if isinstance(consistencies, list):
new_value = []
for consistency in consistencies:
if load:
new_value.append((consistency[0],
descr.impl_get_opt_by_path(
consistency[1])))
else:
new_value.append((consistency[0],
descr.impl_get_path_by_opt(
consistency[1])))
else:
new_value = {}
for key, _consistencies in consistencies.items():
new_value[key] = []
for key_cons, _cons in _consistencies:
_list_cons = []
for _con in _cons:
if load:
_list_cons.append(
descr.impl_get_opt_by_path(_con))
else:
_list_cons.append(
descr.impl_get_path_by_opt(_con))
new_value[key].append((key_cons, tuple(_list_cons)))
if load:
del(self._state_consistencies)
self._consistencies = new_value
else:
self._state_consistencies = new_value
def _impl_convert_requires(self, descr, load=False):
"""export of the requires during the serialization process
@ -244,10 +187,7 @@ class BaseOption(object):
for func in dir(self):
if func.startswith('_impl_convert_'):
getattr(self, func)(descr)
try:
self._state_readonly = self._readonly
except AttributeError:
pass
def __getstate__(self, stated=True):
"""special method to enable the serialization with pickle
@ -267,7 +207,8 @@ class BaseOption(object):
for subclass in self.__class__.__mro__:
if subclass is not object:
slots.update(subclass.__slots__)
slots -= frozenset(['_cache_paths', '__weakref__'])
slots -= frozenset(['_cache_paths', '_cache_consistencies',
'__weakref__'])
states = {}
for slot in slots:
# remove variable if save variable converted
@ -326,13 +267,14 @@ class Option(BaseOption):
"""
__slots__ = ('_multi', '_validator', '_default_multi', '_default',
'_state_callback', '_callback', '_multitype',
'_master_slaves', '__weakref__')
'_consistencies', '_warnings_only', '_master_slaves',
'_state_consistencies', '__weakref__')
_empty = ''
def __init__(self, name, doc, default=None, default_multi=None,
requires=None, multi=False, callback=None,
callback_params=None, validator=None, validator_params=None,
properties=None):
properties=None, warnings_only=False):
"""
:param name: the option's name
:param doc: the option's description
@ -350,6 +292,8 @@ class Option(BaseOption):
validation of the value
:param validator_params: the validator's parameters
:param properties: tuple of default properties
:param warnings_only: _validator and _consistencies don't raise if True
Values()._warning contain message
"""
super(Option, self).__init__(name, doc, requires, properties)
@ -387,58 +331,70 @@ class Option(BaseOption):
default = []
self._multitype = multitypes.default
self._default_multi = default_multi
self._warnings_only = warnings_only
self.impl_validate(default)
self._default = default
self._consistencies = None
def _launch_consistency(self, func, opt, vals, context, index, opt_):
def _launch_consistency(self, func, option, value, context, index,
all_cons_opts):
"""Launch consistency now
:param func: function name, this name should start with _cons_
:type func: `str`
:param option: option that value is changing
:type option: `tiramisu.option.Option`
:param value: new value of this option
:param context: Config's context, if None, check default value instead
:type context: `tiramisu.config.Config`
:param index: only for multi option, consistency should be launch for
specified index
:type index: `int`
:param all_cons_opts: all options concerne by this consistency
:type all_cons_opts: `list` of `tiramisu.option.Option`
"""
if context is not None:
descr = context.cfgimpl_get_description()
if opt is self:
#values are for self, search opt_ values
values = vals
if context is not None:
path = descr.impl_get_path_by_opt(opt_)
values_ = context._getattr(path, validate=False)
else:
values_ = opt_.impl_getdefault()
if index is not None:
#value is not already set, could be higher
try:
values_ = values_[index]
except IndexError:
values_ = None
else:
#values are for opt_, search self values
values_ = vals
if context is not None:
path = descr.impl_get_path_by_opt(self)
values = context._getattr(path, validate=False)
else:
values = self.impl_getdefault()
if index is not None:
#value is not already set, could be higher
try:
values = values[index]
except IndexError:
values = None
if index is None and self.impl_is_multi():
for index in range(0, len(values)):
try:
value = values[index]
value_ = values_[index]
except IndexError:
value = None
value_ = None
if None not in (value, value_):
getattr(self, func)(opt_._name, value, value_)
else:
if None not in (values, values_):
getattr(self, func)(opt_._name, values, values_)
#option is also in all_cons_opts
if option not in all_cons_opts:
raise ConfigError(_('option not in all_cons_opts'))
def impl_validate(self, value, context=None, validate=True):
all_cons_vals = []
for opt in all_cons_opts:
#get value
if option == opt:
opt_value = value
else:
#if context, calculate value, otherwise get default value
if context is not None:
opt_value = context._getattr(
descr.impl_get_path_by_opt(opt), validate=False)
else:
opt_value = opt.impl_getdefault()
#append value
if not self.impl_is_multi() or option == opt:
all_cons_vals.append(opt_value)
else:
#value is not already set, could be higher index
try:
all_cons_vals.append(opt_value[index])
except IndexError:
#so return if no value
return
getattr(self, func)(all_cons_opts, all_cons_vals)
def impl_validate(self, value, context=None, validate=True,
force_index=None):
"""
:param value: the option's value
:param context: Config's context
:type context: :class:`tiramisu.config.Config`
:param validate: if true enables ``self._validator`` validation
:type validate: boolean
:param force_no_multi: if multi, value has to be a list
not if force_no_multi is True
:type force_no_multi: boolean
"""
if not validate:
return
@ -455,45 +411,44 @@ class Option(BaseOption):
validator_params[''] = (val,)
else:
validator_params = {'': (val,)}
ret = carry_out_calculation(self._name, config=context,
# Raise ValueError if not valid
carry_out_calculation(self._name, config=context,
callback=self._validator[0],
callback_params=validator_params)
if ret not in [False, True]:
raise ConfigError(_('validator should return a boolean, '
'not {0}').format(ret))
return ret
else:
return True
def do_validation(_value, _index=None):
if _value is None:
return True
if not val_validator(_value):
raise ValueError(_("invalid value {0} "
"for option {1} for object {2}"
).format(_value,
self._name,
self.__class__.__name__))
try:
return
# option validation
self._validate(_value)
except ValueError as err:
raise ValueError(_("invalid value {0} for option {1}: {2}"
"").format(_value, self._name, err))
try:
# valid with self._validator
val_validator(_value)
# if not 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 {0} for option {1}: {2}").format(
_value, self._name, err)
if self._warnings_only:
warnings.warn_explicit(ValueWarning(msg, self),
ValueWarning,
self.__class__.__name__, 0)
else:
raise ValueError(msg)
# generic calculation
if context is not None:
descr = context.cfgimpl_get_description()
if not self._multi:
do_validation(value)
if not self._multi or force_index is not None:
do_validation(value, force_index)
else:
if not isinstance(value, list):
raise ValueError(_("invalid value {0} for option {1} "
"which must be a list").format(value,
raise ValueError(_("which must be a list").format(value,
self._name))
for index in range(0, len(value)):
val = value[index]
for index, val in enumerate(value):
do_validation(val, index)
def impl_getdefault(self, default_multi=False):
@ -538,29 +493,45 @@ class Option(BaseOption):
def impl_is_multi(self):
return self._multi
def impl_add_consistency(self, func, opt):
def impl_add_consistency(self, func, *other_opts):
"""Add consistency means that value will be validate with other_opts
option's values.
:param func: function's name
:type func: `str`
:param other_opts: options used to validate value
:type other_opts: `list` of `tiramisu.option.Option`
"""
if self._consistencies is None:
self._consistencies = []
for opt in other_opts:
if not isinstance(opt, Option):
raise ValueError('consistency must be set with an option')
raise ConfigError(_('consistency should be set with an option'))
if self is opt:
raise ValueError('cannot add consistency with itself')
raise ConfigError(_('cannot add consistency with itself'))
if self.impl_is_multi() != opt.impl_is_multi():
raise ValueError('options in consistency'
' should be multi in two sides')
raise ConfigError(_('every options in consistency should be '
'multi or none'))
func = '_cons_{0}'.format(func)
self._launch_consistency(func,
self,
self.impl_getdefault(),
None, None, opt)
self._consistencies.append((func, opt))
all_cons_opts = tuple([self] + list(other_opts))
value = self.impl_getdefault()
if value is not None:
if self.impl_is_multi():
for idx, val in enumerate(value):
self._launch_consistency(func, self, val, None,
idx, all_cons_opts)
else:
self._launch_consistency(func, self, value, None,
None, all_cons_opts)
self._consistencies.append((func, all_cons_opts))
self.impl_validate(self.impl_getdefault())
def _cons_not_equal(self, optname, value, value_):
if value == value_:
raise ValueError(_("invalid value {0} for option {1} "
"must be different as {2} option"
"").format(value, self._name, optname))
def _cons_not_equal(self, opts, vals):
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))
def _impl_convert_callbacks(self, descr, load=False):
if not load and self._callback is None:
@ -596,6 +567,60 @@ class Option(BaseOption):
else:
self._state_callback = (callback, cllbck_prms)
# serialize/unserialize
def _impl_convert_consistencies(self, descr, load=False):
"""during serialization process, many things have to be done.
one of them is the localisation of the options.
The paths are set once for all.
:type descr: :class:`tiramisu.option.OptionDescription`
:param load: `True` if we are at the init of the option description
:type load: bool
"""
if not load and self._consistencies is None:
self._state_consistencies = None
elif load and self._state_consistencies is None:
self._consistencies = None
del(self._state_consistencies)
else:
if load:
consistencies = self._state_consistencies
else:
consistencies = self._consistencies
if isinstance(consistencies, list):
new_value = []
for consistency in consistencies:
values = []
for obj in consistency[1]:
if load:
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)))
else:
new_value = {}
for key, _consistencies in consistencies.items():
new_value[key] = []
for key_cons, _cons in _consistencies:
_list_cons = []
for _con in _cons:
if load:
_list_cons.append(
descr.impl_get_opt_by_path(_con))
else:
_list_cons.append(
descr.impl_get_path_by_opt(_con))
new_value[key].append((key_cons, tuple(_list_cons)))
if load:
del(self._state_consistencies)
self._consistencies = new_value
else:
self._state_consistencies = new_value
def _second_level_validation(self, value):
pass
class ChoiceOption(Option):
"""represents a choice out of several objects.
@ -609,7 +634,7 @@ class ChoiceOption(Option):
def __init__(self, name, doc, values, default=None, default_multi=None,
requires=None, multi=False, callback=None,
callback_params=None, open_values=False, validator=None,
validator_params=None, properties=()):
validator_params=None, properties=None, warnings_only=False):
"""
:param values: is a list of values the option can possibly take
"""
@ -628,7 +653,8 @@ class ChoiceOption(Option):
multi=multi,
validator=validator,
validator_params=validator_params,
properties=properties)
properties=properties,
warnings_only=warnings_only)
def impl_get_values(self):
return self._values
@ -705,7 +731,7 @@ class SymLinkOption(BaseOption):
__slots__ = ('_name', '_opt', '_state_opt')
_opt_type = 'symlink'
#not return _opt consistencies
_consistencies = {}
_consistencies = None
def __init__(self, name, opt):
self._name = name
@ -731,23 +757,18 @@ class SymLinkOption(BaseOption):
del(self._state_opt)
super(SymLinkOption, self)._impl_setstate(descr)
def _impl_convert_consistencies(self, descr, load=False):
if load:
del(self._state_consistencies)
else:
self._state_consistencies = None
class IPOption(Option):
"represents the choice of an ip"
__slots__ = ('_only_private', '_allow_reserved')
__slots__ = ('_private_only', '_allow_reserved')
_opt_type = 'ip'
def __init__(self, name, doc, default=None, default_multi=None,
requires=None, multi=False, callback=None,
callback_params=None, validator=None, validator_params=None,
properties=None, only_private=False, allow_reserved=False):
self._only_private = only_private
properties=None, private_only=False, allow_reserved=False,
warnings_only=False):
self._private_only = private_only
self._allow_reserved = allow_reserved
super(IPOption, self).__init__(name, doc, default=default,
default_multi=default_multi,
@ -757,13 +778,20 @@ class IPOption(Option):
multi=multi,
validator=validator,
validator_params=validator_params,
properties=properties)
properties=properties,
warnings_only=warnings_only)
def _validate(self, value):
try:
IP('{0}/32'.format(value))
except ValueError:
raise ValueError(_('invalid IP {0}').format(self._name))
def _second_level_validation(self, value):
ip = IP('{0}/32'.format(value))
if not self._allow_reserved and ip.iptype() == 'RESERVED':
raise ValueError(_("IP mustn't not be in reserved class"))
if self._only_private and not ip.iptype() == 'PRIVATE':
if self._private_only and not ip.iptype() == 'PRIVATE':
raise ValueError(_("IP must be in private class"))
@ -785,7 +813,7 @@ class PortOption(Option):
callback_params=None, validator=None, validator_params=None,
properties=None, allow_range=False, allow_zero=False,
allow_wellknown=True, allow_registred=True,
allow_private=False):
allow_private=False, warnings_only=False):
self._allow_range = allow_range
self._min_value = None
self._max_value = None
@ -817,7 +845,8 @@ class PortOption(Option):
multi=multi,
validator=validator,
validator_params=validator_params,
properties=properties)
properties=properties,
warnings_only=warnings_only)
def _validate(self, value):
if self._allow_range and ":" in str(value):
@ -842,6 +871,12 @@ class NetworkOption(Option):
_opt_type = 'network'
def _validate(self, value):
try:
IP(value)
except ValueError:
raise ValueError(_('invalid network address {0}').format(self._name))
def _second_level_validation(self, value):
ip = IP(value)
if ip.iptype() == 'RESERVED':
raise ValueError(_("network shall not be in reserved class"))
@ -853,18 +888,26 @@ class NetmaskOption(Option):
_opt_type = 'netmask'
def _validate(self, value):
try:
IP('0.0.0.0/{0}'.format(value))
except ValueError:
raise ValueError(_('invalid netmask address {0}').format(self._name))
def _cons_network_netmask(self, optname, value, value_):
def _cons_network_netmask(self, opts, vals):
#opts must be (netmask, network) options
self.__cons_netmask(optname, value, value_, False)
if None in vals:
return
self.__cons_netmask(opts, vals[0], vals[1], False)
def _cons_ip_netmask(self, optname, value, value_):
def _cons_ip_netmask(self, opts, vals):
#opts must be (netmask, ip) options
self.__cons_netmask(optname, value, value_, True)
if None in vals:
return
self.__cons_netmask(opts, vals[0], vals[1], True)
#def __cons_netmask(self, opt, value, context, index, opts, make_net):
def __cons_netmask(self, optname, val_netmask, val_ipnetwork, make_net):
def __cons_netmask(self, opts, val_netmask, val_ipnetwork, make_net):
if len(opts) != 2:
raise ConfigError(_('invalid len for opts'))
msg = None
try:
ip = IP('{0}/{1}'.format(val_ipnetwork, val_netmask),
@ -890,23 +933,48 @@ class NetmaskOption(Option):
else:
msg = _("invalid network {0} ({1}) with netmask {2} ({3})")
if msg is not None:
raise ValueError(msg.format(val_ipnetwork, optname,
raise ValueError(msg.format(val_ipnetwork, opts[1]._name,
val_netmask, self._name))
class BroadcastOption(Option):
__slots__ = tuple()
_opt_type = 'broadcast'
def _validate(self, value):
try:
IP('{0}/32'.format(value))
except ValueError:
raise ValueError(_('invalid broadcast address {0}').format(self._name))
def _cons_broadcast(self, opts, vals):
if len(vals) != 3:
raise ConfigError(_('invalid len for vals'))
if None in vals:
return
broadcast, network, netmask = vals
if IP('{0}/{1}'.format(network, netmask)).broadcast() != IP(broadcast):
raise ValueError(_('invalid broadcast {0} ({1}) with network {2} '
'({3}) and netmask {4} ({5})').format(
broadcast, opts[0]._name, network,
opts[1]._name, netmask, opts[2]._name))
class DomainnameOption(Option):
"represents the choice of a domain name"
"""represents the choice of a domain name
netbios: for MS domain
hostname: to identify the device
domainname:
fqdn: with tld, not supported yet
"""
__slots__ = ('_type', '_allow_ip')
_opt_type = 'domainname'
def __init__(self, name, doc, default=None, default_multi=None,
requires=None, multi=False, callback=None,
callback_params=None, validator=None, validator_params=None,
properties=None, allow_ip=False, type_='domainname'):
#netbios: for MS domain
#hostname: to identify the device
#domainname:
#fqdn: with tld, not supported yet
properties=None, allow_ip=False, type_='domainname',
warnings_only=False):
if type_ not in ['netbios', 'hostname', 'domainname']:
raise ValueError(_('unknown type_ {0} for hostname').format(type_))
self._type = type_
@ -921,7 +989,8 @@ class DomainnameOption(Option):
multi=multi,
validator=validator,
validator_params=validator_params,
properties=properties)
properties=properties,
warnings_only=warnings_only)
def _validate(self, value):
if self._allow_ip is True:
@ -959,9 +1028,9 @@ class OptionDescription(BaseOption):
"""
__slots__ = ('_name', '_requires', '_cache_paths', '_group_type',
'_state_group_type', '_properties', '_children',
'_consistencies', '_calc_properties', '__weakref__',
'_cache_consistencies', '_calc_properties', '__weakref__',
'_readonly', '_impl_informations', '_state_requires',
'_state_consistencies', '_stated', '_state_readonly')
'_stated', '_state_readonly')
_opt_type = 'optiondescription'
def __init__(self, name, doc, children, requires=None, properties=None):
@ -982,6 +1051,7 @@ class OptionDescription(BaseOption):
old = child
self._children = (tuple(child_names), tuple(children))
self._cache_paths = None
self._cache_consistencies = None
# the group_type is useful for filtering OptionDescriptions in a config
self._group_type = groups.default
@ -1055,12 +1125,11 @@ class OptionDescription(BaseOption):
if not force_no_consistencies and \
option._consistencies is not None:
for consistency in option._consistencies:
func, opt = consistency
opts = (option, opt)
func, all_cons_opts = consistency
for opt in all_cons_opts:
_consistencies.setdefault(opt,
[]).append((func, opts))
_consistencies.setdefault(option,
[]).append((func, opts))
[]).append((func,
all_cons_opts))
else:
_currpath.append(attr)
option.impl_build_cache(cache_path,
@ -1072,7 +1141,12 @@ class OptionDescription(BaseOption):
if save:
self._cache_paths = (tuple(cache_option), tuple(cache_path))
if not force_no_consistencies:
self._consistencies = _consistencies
if _consistencies != {}:
self._cache_consistencies = {}
for opt, cons in _consistencies.items():
if opt not in cache_option:
raise ConfigError(_('consistency with option {0} which is not in Config').format(opt._name))
self._cache_consistencies[opt] = tuple(cons)
self._readonly = True
def impl_get_opt_by_path(self, path):
@ -1143,17 +1217,18 @@ class OptionDescription(BaseOption):
def impl_get_group_type(self):
return self._group_type
def _valid_consistency(self, opt, value, context=None, index=None):
consistencies = self._consistencies.get(opt)
def _valid_consistency(self, option, value, context, index):
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 consistency in consistencies:
opt_ = consistency[1]
ret = opt_[0]._launch_consistency(consistency[0],
opt,
for func, all_cons_opts in consistencies:
#all_cons_opts[0] is the option where func is set
ret = all_cons_opts[0]._launch_consistency(func, option,
value,
context,
index,
opt_[1])
context, index,
all_cons_opts)
if ret is False:
return False
return True
@ -1193,6 +1268,7 @@ class OptionDescription(BaseOption):
"""
if descr is None:
self._cache_paths = None
self._cache_consistencies = None
self.impl_build_cache(force_no_consistencies=True)
descr = self
self._group_type = getattr(groups, self._state_group_type)
@ -1324,6 +1400,6 @@ def validate_callback(callback, callback_params, type_):
).format(type_, type(option)))
if force_permissive not in [True, False]:
raise ValueError(_('{0}_params should have a boolean'
'not a {0} for second argument'
' not a {0} for second argument'
).format(type_, type(
force_permissive)))

View File

@ -104,7 +104,8 @@ class Values(object):
path = self._get_opt_path(opt)
if self._p_.hasvalue(path):
setting = self.context().cfgimpl_get_settings()
opt.impl_validate(opt.impl_getdefault(), self.context(),
opt.impl_validate(opt.impl_getdefault(),
self.context(),
'validator' in setting)
self.context().cfgimpl_reset_cache()
if (opt.impl_is_multi() and
@ -237,7 +238,7 @@ class Values(object):
force_properties=force_properties,
force_permissives=force_permissives)
if config_error is not None:
raise ConfigError(config_error)
raise config_error
return value
def __setitem__(self, opt, value):
@ -368,6 +369,7 @@ class Values(object):
def __setstate__(self, states):
self._p_ = states['_p_']
# ____________________________________________________________
# multi types
@ -451,10 +453,10 @@ class Multi(list):
value_slave.append(slave.impl_getdefault_multi(),
force=True)
def __setitem__(self, key, value):
self._validate(value)
def __setitem__(self, index, value):
self._validate(value, index)
#assume not checking mandatory property
super(Multi, self).__setitem__(key, value)
super(Multi, self).__setitem__(index, value)
self.context().cfgimpl_get_values()._setvalue(self.opt, self.path, self)
def append(self, value, force=False):
@ -472,15 +474,17 @@ class Multi(list):
#Force None il return a list
if isinstance(value, list):
value = None
self._validate(value)
index = self.__len__()
self._validate(value, index)
super(Multi, self).append(value)
self.context().cfgimpl_get_values()._setvalue(self.opt, self.path, self, validate_properties=not force)
self.context().cfgimpl_get_values()._setvalue(self.opt, self.path,
self,
validate_properties=not force)
if not force and self.opt.impl_get_multitype() == multitypes.master:
for slave in self.opt.impl_get_master_slaves():
path = values._get_opt_path(slave)
if not values._is_default_owner(path):
if slave.impl_has_callback():
index = self.__len__() - 1
dvalue = values._getcallback_value(slave, index=index)
else:
dvalue = slave.impl_getdefault_multi()
@ -532,10 +536,11 @@ class Multi(list):
super(Multi, self).extend(iterable)
self.context().cfgimpl_get_values()._setvalue(self.opt, self.path, self)
def _validate(self, value):
def _validate(self, value, force_index):
if value is not None:
try:
self.opt._validate(value)
self.opt.impl_validate(value, context=self.context(),
force_index=force_index)
except ValueError as err:
raise ValueError(_("invalid value {0} "
"for option {1}: {2}"

View File

@ -2,7 +2,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-08-31 09:52+CEST\n"
"POT-Creation-Date: 2013-09-26 22:33+CEST\n"
"PO-Revision-Date: \n"
"Last-Translator: Emmanuel Garette <egarette@cadoles.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -11,436 +11,486 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.5.4\n"
#: tiramisu/autolib.py:58
msgid "no config specified but needed"
msgstr "aucune config spécifié alors que c'est nécessaire"
#: tiramisu/autolib.py:65
#: tiramisu/autolib.py:145
msgid ""
"unable to carry out a calculation, option {0} has properties: {1} for: {2}"
msgstr ""
"impossible d'effectuer le calcul, l'option {0} a les propriétés : {1} pour : "
"{2}"
#: tiramisu/autolib.py:74
#: tiramisu/autolib.py:154
msgid ""
"unable to carry out a calculation, option value with multi types must have "
"same length for: {0}"
msgstr ""
"impossible d'effectuer le calcul, valeur d'un option avec le type multi doit "
"avoir la même longueur pour : {0}"
"impossible d'effectuer le calcul, la valeur d'une option avec le type multi "
"doit avoir la même longueur pour : {0}"
#: tiramisu/config.py:47
#: tiramisu/config.py:52
msgid "descr must be an optiondescription, not {0}"
msgstr "descr doit être une optiondescription pas un {0}"
#: tiramisu/config.py:121
#: tiramisu/config.py:127
msgid "unknown group_type: {0}"
msgstr "group_type inconnu: {0}"
#: tiramisu/config.py:157
#: tiramisu/config.py:163
msgid ""
"no option description found for this config (may be metaconfig without meta)"
msgstr ""
"pas d'option description pour cette config (peut être une metaconfig sans "
"meta)"
"pas d'option description trouvé pour cette config (peut être une metaconfig "
"sans meta)"
#: tiramisu/config.py:311
#: tiramisu/config.py:189
msgid "can't assign to an OptionDescription"
msgstr "ne peut pas attribuer une valeur à une OptionDescription"
#: tiramisu/config.py:320
msgid "unknown type_ type {0}for _find"
msgstr "type_ type {0} pour _find inconnu"
#: tiramisu/config.py:350
#: tiramisu/config.py:359
msgid "no option found in config with these criteria"
msgstr "aucune option trouvée dans la config avec ces critères"
#: tiramisu/config.py:400
#: tiramisu/config.py:409
msgid "make_dict can't filtering with value without option"
msgstr "make_dict ne peut filtrer sur une valeur mais sans option"
#: tiramisu/config.py:421
#: tiramisu/config.py:430
msgid "unexpected path {0}, should start with {1}"
msgstr "chemin imprévu {0}, devrait commencer par {1}"
#: tiramisu/config.py:481
#: tiramisu/config.py:490
msgid "opt in getowner must be an option not {0}"
msgstr "opt dans getowner doit être une option pas {0}"
#: tiramisu/option.py:71
msgid "{0} has no attribute impl_set_information"
msgstr "{0} n'a pas d'attribut impl_set_information"
#: tiramisu/option.py:86
msgid "information's item not found: {0}"
msgstr "aucune config spécifié alors que c'est nécessaire"
#: tiramisu/option.py:89
msgid "{0} has no attribute impl_get_information"
msgstr "{0} n'a pas d'attribut impl_get_information"
#: tiramisu/option.py:117
msgid "'{0}' ({1}) object attribute '{2}' is read-only"
msgstr "l'attribut {2} de l'objet '{0}' ({1}) est en lecture seul"
#: tiramisu/option.py:159
#: tiramisu/option.py:70
msgid "invalid name: {0} for option"
msgstr "nom invalide : {0} pour l'option"
#: tiramisu/option.py:169
msgid "validator must be a function"
msgstr "validator doit être une fonction"
#: tiramisu/option.py:80
msgid "invalid properties type {0} for {1}, must be a tuple"
msgstr "type des properties invalide {0} pour {1}, doit être un tuple"
#: tiramisu/option.py:176
#: tiramisu/option.py:122
msgid "'{0}' ({1}) object attribute '{2}' is read-only"
msgstr "l'attribut {2} de l'objet '{0}' ({1}) est en lecture seule"
#: tiramisu/option.py:149 tiramisu/value.py:362
msgid "information's item not found: {0}"
msgstr "aucune config spécifié alors que c'est nécessaire"
#: tiramisu/option.py:266
msgid "cannot serialize Option, only in OptionDescription"
msgstr "ne peut serialiser une Option, seulement via une OptionDescription"
#: tiramisu/option.py:367
msgid "a default_multi is set whereas multi is False in option: {0}"
msgstr ""
"une default_multi est renseigné alors que multi est False dans l'option : {0}"
"une default_multi est renseignée alors que multi est False dans l'option : "
"{0}"
#: tiramisu/option.py:182
#: tiramisu/option.py:373
msgid "invalid default_multi value {0} for option {1}: {2}"
msgstr "la valeur default_multi est invalide {0} pour l'option {1} : {2}"
#: tiramisu/option.py:187
#: tiramisu/option.py:378
msgid "default value not allowed if option: {0} is calculated"
msgstr "la valeur par défaut n'est pas possible si l'option {0} est calculé"
msgstr "la valeur par défaut n'est pas possible si l'option {0} est calculée"
#: tiramisu/option.py:190
#: tiramisu/option.py:381
msgid ""
"params defined for a callback function but no callback defined yet for "
"option {0}"
msgstr ""
"params définit pour une fonction callback mais par de callback défini encore "
"pour l'option {0}"
"params définis pour une fonction callback mais par de callback encore "
"définis pour l'option {0}"
#: tiramisu/option.py:212 tiramisu/option.py:753
msgid "invalid properties type {0} for {1}, must be a tuple"
msgstr "type des properties invalide {0} pour {1}, doit être un tuple"
#: tiramisu/option.py:285
msgid "invalid value {0} for option {1} for object {2}"
msgstr "valeur invalide {0} pour l'option {1} pour l'objet {2}"
#: tiramisu/option.py:293 tiramisu/value.py:468
#: tiramisu/option.py:486 tiramisu/value.py:547
msgid "invalid value {0} for option {1}: {2}"
msgstr "valeur invalide {0} pour l'option {1} : {2}"
#: tiramisu/option.py:305
#: tiramisu/option.py:506
msgid "invalid value {0} for option {1} which must be a list"
msgstr "valeur invalide {0} pour l'option {1} qui doit être une liste"
#: tiramisu/option.py:374
#: tiramisu/option.py:577
msgid "invalid value {0} for option {1} must be different as {2} option"
msgstr ""
"valeur invalide {0} pour l'option {1} doit être différent que l'option {2}"
"valeur invalide {0} pour l'option {1} doit être différente de l'option {2}"
#: tiramisu/option.py:396
#: tiramisu/option.py:636
msgid "values must be a tuple for {0}"
msgstr "values doit être un tuple pour {0}"
#: tiramisu/option.py:399
#: tiramisu/option.py:639
msgid "open_values must be a boolean for {0}"
msgstr "open_values doit être un booléen pour {0}"
#: tiramisu/option.py:420
#: tiramisu/option.py:661
msgid "value {0} is not permitted, only {1} is allowed"
msgstr "valeur {0} n'est pas permit, seules {1} sont autorisées"
msgstr "valeur {0} n'est pas permis, seules {1} sont autorisées"
#: tiramisu/option.py:432
#: tiramisu/option.py:673
msgid "value must be a boolean"
msgstr "valeur doit être un booléen"
#: tiramisu/option.py:442
#: tiramisu/option.py:683
msgid "value must be an integer"
msgstr "valeur doit être un numbre"
msgstr "valeur doit être un nombre entier"
#: tiramisu/option.py:452
#: tiramisu/option.py:693
msgid "value must be a float"
msgstr "valeur doit être un nombre flottant"
#: tiramisu/option.py:462
#: tiramisu/option.py:703
msgid "value must be a string, not {0}"
msgstr "valeur doit être une chaîne, pas {0}"
#: tiramisu/option.py:480
#: tiramisu/option.py:721
msgid "value must be an unicode"
msgstr "valeur doit être une valeur unicode"
#: tiramisu/option.py:490
#: tiramisu/option.py:733
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:526
msgid "IP shall not be in reserved class"
#: tiramisu/option.py:788
msgid "invalid IP {0}"
msgstr "adresse IP invalide {0}"
#: tiramisu/option.py:793
msgid "IP mustn't not be in reserved class"
msgstr "IP ne doit pas être d'une classe reservée"
#: tiramisu/option.py:528
#: tiramisu/option.py:795
msgid "IP must be in private class"
msgstr "IP doit être dans la classe privée"
#: tiramisu/option.py:566
#: tiramisu/option.py:833
msgid "inconsistency in allowed range"
msgstr "inconsistence dans la plage autorisée"
#: tiramisu/option.py:571
#: tiramisu/option.py:838
msgid "max value is empty"
msgstr "valeur maximum est vide"
msgstr "la valeur maximum est vide"
#: tiramisu/option.py:608
#: tiramisu/option.py:877
msgid "invalid network address {0}"
msgstr "adresse réseau invalide {0}"
#: tiramisu/option.py:882
msgid "network shall not be in reserved class"
msgstr "réseau ne doit pas être dans la classe reservée"
msgstr "le réseau ne doit pas être dans la classe reservée"
#: tiramisu/option.py:640
#: tiramisu/option.py:894
msgid "invalid netmask address {0}"
msgstr "masque de sous-réseau invalide {0}"
#: tiramisu/option.py:916
msgid "invalid network {0} ({1}) with netmask {2} ({3}), this network is an IP"
msgstr "réseau invalide {0} ({1}) avec masque {2} ({3}), ce réseau est une IP"
#: tiramisu/option.py:645
#: tiramisu/option.py:921
msgid "invalid IP {0} ({1}) with netmask {2} ({3}), this IP is a network"
msgstr "IP invalide {0} ({1}) avec masque {2} ({3}), cette IP est un réseau"
#: tiramisu/option.py:650
#: tiramisu/option.py:926
msgid "invalid IP {0} ({1}) with netmask {2} ({3})"
msgstr "IP invalide {0} ({1}) avec masque {2} ({3})"
#: tiramisu/option.py:652
#: tiramisu/option.py:928
msgid "invalid network {0} ({1}) with netmask {2} ({3})"
msgstr "réseau invalide {0} ({1}) avec masque {2} ({3})"
#: tiramisu/option.py:672
#: tiramisu/option.py:939
msgid "invalid broadcast address {0}"
msgstr "adresse de broadcast invalide {0}"
#: tiramisu/option.py:957
msgid "unknown type_ {0} for hostname"
msgstr "type_ inconnu {0} pour le nom d'hôte"
#: tiramisu/option.py:675
#: tiramisu/option.py:960
msgid "allow_ip must be a boolean"
msgstr "allow_ip doit être un booléen"
#: tiramisu/option.py:704
#: tiramisu/option.py:990
msgid "invalid value for {0}, must have dot"
msgstr "valeur invalide pour {0}, doit avoir un point"
#: tiramisu/option.py:707
#: tiramisu/option.py:993
msgid "invalid domainname's length for {0} (max {1})"
msgstr "longueur du nom de domaine invalide pour {0} (maximum {1})"
#: tiramisu/option.py:710
#: tiramisu/option.py:996
msgid "invalid domainname's length for {0} (min 2)"
msgstr "longueur du nom de domaine invalide pour {0} (minimum 2)"
#: tiramisu/option.py:714
#: tiramisu/option.py:1000
msgid "invalid domainname"
msgstr "nom de domaine invalide"
#: tiramisu/option.py:731
msgid "invalid name: {0} for optiondescription"
msgstr "nom invalide : {0} pour l'optiondescription"
#: tiramisu/option.py:743
#: tiramisu/option.py:1027
msgid "duplicate option name: {0}"
msgstr "nom de l'option dupliqué : {0}"
#: tiramisu/option.py:769
#: tiramisu/option.py:1044
msgid "unknown Option {0} in OptionDescription {1}"
msgstr "Option {} inconnue pour l'OptionDescription{}"
msgstr "Option {0} inconnue pour l'OptionDescription {1}"
#: tiramisu/option.py:820
#: tiramisu/option.py:1095
msgid "duplicate option: {0}"
msgstr "option dupliquée : {0}"
#: tiramisu/option.py:850
#: tiramisu/option.py:1129
msgid "no option for path {0}"
msgstr "pas d'option pour le chemin {0}"
#: tiramisu/option.py:856
#: tiramisu/option.py:1135
msgid "no option {0} found"
msgstr "pas d'option {0} trouvée"
#: tiramisu/option.py:866
#: tiramisu/option.py:1145
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:879
#: tiramisu/option.py:1158
msgid "master group {0} shall not have a subgroup"
msgstr "groupe maître {0} ne doit pas avoir de sous-groupe"
#: tiramisu/option.py:882
#: tiramisu/option.py:1161
msgid "master group {0} shall not have a symlinkoption"
msgstr "groupe maître {0} ne doit pas avoir de symlinkoption"
#: tiramisu/option.py:885
#: tiramisu/option.py:1164
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:896
#: tiramisu/option.py:1175
msgid "master group with wrong master name for {0}"
msgstr "le groupe maître avec un nom de maître éroné pour {0}"
msgstr "le groupe maître avec un nom de maître érroné pour {0}"
#: tiramisu/option.py:905
#: tiramisu/option.py:1184
msgid "no child has same nom has master group for: {0}"
msgstr "pas d'enfant avec le nom du groupe maître pour {0} "
#: tiramisu/option.py:908
#: tiramisu/option.py:1187
msgid "group_type: {0} not allowed"
msgstr "group_type : {0} non autorisé"
#: tiramisu/option.py:946
#: tiramisu/option.py:1277
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:962
#: tiramisu/option.py:1294
msgid ""
"malformed requirements for option: {0} require must have option, expected "
"and action keys"
msgstr ""
"requirements malformé pour l'option : {0} l'exigence doit avoir les clefs "
"option, exptected et action"
"option, expected et action"
#: tiramisu/option.py:967
#: tiramisu/option.py:1299
msgid "malformed requirements for option: {0} inverse must be boolean"
msgstr "requirements malformé pour l'option : {0} inverse doit être un booléen"
msgstr ""
"requirements mal formés pour l'option : {0} inverse doit être un booléen"
#: tiramisu/option.py:971
#: tiramisu/option.py:1303
msgid "malformed requirements for option: {0} transitive must be boolean"
msgstr "requirements malformé pour l'option : {0} transitive doit être booléen"
msgstr ""
"requirements mal formés pour l'option : {0} transitive doit être booléen"
#: tiramisu/option.py:975
#: tiramisu/option.py:1307
msgid "malformed requirements for option: {0} same_action must be boolean"
msgstr ""
"requirements malformé 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:979
#: tiramisu/option.py:1311
msgid "malformed requirements must be an option in option {0}"
msgstr "requirements malformé doit être une option dans l'option {0}"
msgstr "requirements mal formés doit être une option dans l'option {0}"
#: tiramisu/option.py:982
#: tiramisu/option.py:1314
msgid "malformed requirements option {0} should not be a multi"
msgstr "requirements malformé 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:988
#: tiramisu/option.py:1320
msgid ""
"malformed requirements second argument must be valid for option {0}: {1}"
msgstr ""
"requirements malformé deuxième argument doit être valide pour l'option {0} : "
"{1}"
"requirements mal formés deuxième argument doit être valide pour l'option "
"{0} : {1}"
#: tiramisu/option.py:993
#: tiramisu/option.py:1325
msgid "inconsistency in action types for option: {0} action: {1}"
msgstr "incohérence dans les types action pour l'option : {0} action {1}"
#: tiramisu/setting.py:47
msgid "storage_type is already set, cannot rebind it"
msgstr "storage_type est déjà défini, impossible de le redéfinir"
#: tiramisu/option.py:1350
msgid "{0} should be a function"
msgstr "{0} doit être une fonction"
#: tiramisu/setting.py:67
#: tiramisu/option.py:1353
msgid "{0}_params should be a dict"
msgstr "{0}_params devrait être un dict"
#: tiramisu/option.py:1356
msgid "{0}_params with key {1} should not have length different to 1"
msgstr ""
"{0}_params avec la clef {1} devrait ne pas avoir une longueur différent de 1"
#: tiramisu/option.py:1360
msgid "{0}_params should be tuple for key \"{1}\""
msgstr "{0}_params devrait être un tuple pour la clef \"{1}\""
#: tiramisu/option.py:1366
msgid "validator not support tuple"
msgstr "validator n'accepte pas de tuple"
#: tiramisu/option.py:1369
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:1373
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/setting.py:116
msgid "can't rebind {0}"
msgstr "ne peut redéfinir ({0})"
#: tiramisu/setting.py:72
#: tiramisu/setting.py:121
msgid "can't unbind {0}"
msgstr "ne peut supprimer ({0})"
#: tiramisu/setting.py:185
#: tiramisu/setting.py:259
msgid "cannot append {0} property for option {1}: this property is calculated"
msgstr ""
"ne peut ajouter la propriété {0} dans l'option {1}: cette propriété est "
"calculée"
#: tiramisu/setting.py:215
msgid "option {0} not already exists in storage {1}"
msgstr "option {0} n'existe pas dans l'espace de stockage {1}"
#: tiramisu/setting.py:282
#: tiramisu/setting.py:322
msgid "opt and all_properties must not be set together in reset"
msgstr "opt et all_properties ne doit pas être renseigné ensemble dans reset"
#: tiramisu/setting.py:297
#: tiramisu/setting.py:337
msgid "if opt is not None, path should not be None in _getproperties"
msgstr ""
"si opt n'est pas None, path devrait ne pas être à None dans _getproperties"
#: tiramisu/setting.py:391
#: tiramisu/setting.py:440
msgid "cannot change the value for option {0} this option is frozen"
msgstr ""
"ne peut modifié la valeur de l'option {0} cette option n'est pas modifiable"
"ne peut modifier la valeur de l'option {0} cette option n'est pas modifiable"
#: tiramisu/setting.py:397
#: tiramisu/setting.py:446
msgid "trying to access to an option named: {0} with properties {1}"
msgstr "tentative d'accès à une option nommée : {0} avec les propriétés {1}"
#: tiramisu/setting.py:415
#: tiramisu/setting.py:464
msgid "permissive must be a tuple"
msgstr "permissive doit être un tuple"
#: tiramisu/setting.py:422 tiramisu/value.py:277
#: tiramisu/setting.py:471 tiramisu/value.py:301
msgid "invalid generic owner {0}"
msgstr "invalide owner générique {0}"
#: tiramisu/setting.py:503
#: tiramisu/setting.py:558
msgid ""
"malformed requirements imbrication detected for option: '{0}' with "
"requirement on: '{1}'"
msgstr ""
"imbrication de requirements malformé detectée pour l'option : '{0}' avec "
"imbrication de requirements mal formés detectée pour l'option : '{0}' avec "
"requirement sur : '{1}'"
#: tiramisu/setting.py:515
#: tiramisu/setting.py:570
msgid "option '{0}' has requirement's property error: {1} {2}"
msgstr "l'option '{0}' a une erreur de propriété pour le requirement : {1} {2}"
#: tiramisu/storage/dictionary/storage.py:37
#: tiramisu/storage/__init__.py:52
msgid "storage_type is already set, cannot rebind it"
msgstr "storage_type est déjà défini, impossible de le redéfinir"
#: tiramisu/storage/__init__.py:86
msgid "option {0} not already exists in storage {1}"
msgstr "option {0} n'existe pas dans l'espace de stockage {1}"
#: tiramisu/storage/dictionary/storage.py:39
msgid "dictionary storage cannot delete session"
msgstr ""
"impossible de supprimer une session dans un espace de stockage dictionary"
#: tiramisu/storage/dictionary/storage.py:46
#: tiramisu/storage/dictionary/storage.py:50
msgid "session already used"
msgstr "session déjà utilisée"
#: tiramisu/storage/dictionary/storage.py:48
#: tiramisu/storage/dictionary/storage.py:52
msgid "a dictionary cannot be persistent"
msgstr "un espace de stockage dictionary ne peut être persistant"
#: tiramisu/value.py:284
#: tiramisu/value.py:308
msgid "no value for {0} cannot change owner to {1}"
msgstr "pas de valeur pour {0} ne peut changer d'utilisateur pour {1}"
#: tiramisu/value.py:356
#: tiramisu/value.py:416
msgid "invalid len for the slave: {0} which has {1} as master"
msgstr "longueur invalide pour une esclave : {0} qui a {1} comme maître"
#: tiramisu/value.py:373
#: tiramisu/value.py:440
msgid "invalid len for the master: {0} which has {1} as slave with greater len"
msgstr ""
"longueur invalide pour un maître : {0} qui a {1} une esclave avec une plus "
"grande longueur"
#: tiramisu/value.py:394
#: tiramisu/value.py:470
msgid "cannot append a value on a multi option {0} which is a slave"
msgstr "ne peut ajouter une valeur sur l'option multi {0} qui est une esclave"
#: tiramisu/value.py:429
#: tiramisu/value.py:507
msgid "cannot sort multi option {0} if master or slave"
msgstr "ne peut trier une option multi {0} pour une maître ou une esclave"
#: tiramisu/value.py:433
#: tiramisu/value.py:511
msgid "cmp is not permitted in python v3 or greater"
msgstr "cmp n'est pas permis en python v3 ou supérieure"
#: tiramisu/value.py:442
#: tiramisu/value.py:520
msgid "cannot reverse multi option {0} if master or slave"
msgstr "ne peut inverser une option multi {0} pour une maître ou une esclave"
#: tiramisu/value.py:450
#: tiramisu/value.py:528
msgid "cannot insert multi option {0} if master or slave"
msgstr "ne peut insérer une option multi {0} pour une maître ou une esclave"
#: tiramisu/value.py:458
#: tiramisu/value.py:536
msgid "cannot extend multi option {0} if master or slave"
msgstr "ne peut étendre une option multi {0} pour une maître ou une esclave"
#: tiramisu/value.py:482
#: tiramisu/value.py:564
msgid "cannot pop a value on a multi option {0} which is a slave"
msgstr "ne peut supprimer une valeur dans l'option multi {0} qui est esclave"
#~ msgid "validator should return a boolean, not {0}"
#~ msgstr "le validator devrait retourner un boolean, pas un {0}"
#~ msgid "invalid value {0} for option {1} for object {2}"
#~ msgstr "valeur invalide {0} pour l'option {1} pour l'objet {2}"
#~ msgid "no config specified but needed"
#~ msgstr "aucune config spécifié alors que c'est nécessaire"
#~ msgid "{0} has no attribute impl_set_information"
#~ msgstr "{0} n'a pas d'attribut impl_set_information"
#~ msgid "{0} has no attribute impl_get_information"
#~ msgstr "{0} n'a pas d'attribut impl_get_information"
#~ msgid "invalid name: {0} for optiondescription"
#~ msgstr "nom invalide : {0} pour l'optiondescription"
#~ msgid "metaconfig's children must be a list"
#~ msgstr "enfants d'une metaconfig doit être une liste"

View File

@ -5,7 +5,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2013-09-02 11:30+CEST\n"
"POT-Creation-Date: 2013-09-26 22:33+CEST\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"
@ -15,395 +15,423 @@ msgstr ""
"Generated-By: pygettext.py 1.5\n"
#: tiramisu/autolib.py:58
msgid "no config specified but needed"
msgstr ""
#: tiramisu/autolib.py:65
#: tiramisu/autolib.py:145
msgid "unable to carry out a calculation, option {0} has properties: {1} for: {2}"
msgstr ""
#: tiramisu/autolib.py:74
#: tiramisu/autolib.py:154
msgid "unable to carry out a calculation, option value with multi types must have same length for: {0}"
msgstr ""
#: tiramisu/config.py:47
#: tiramisu/config.py:52
msgid "descr must be an optiondescription, not {0}"
msgstr ""
#: tiramisu/config.py:121
#: tiramisu/config.py:127
msgid "unknown group_type: {0}"
msgstr ""
#: tiramisu/config.py:157
#: tiramisu/config.py:163
msgid "no option description found for this config (may be metaconfig without meta)"
msgstr ""
#: tiramisu/config.py:311
#: tiramisu/config.py:189
msgid "can't assign to an OptionDescription"
msgstr ""
#: tiramisu/config.py:320
msgid "unknown type_ type {0}for _find"
msgstr ""
#: tiramisu/config.py:350
#: tiramisu/config.py:359
msgid "no option found in config with these criteria"
msgstr ""
#: tiramisu/config.py:400
#: tiramisu/config.py:409
msgid "make_dict can't filtering with value without option"
msgstr ""
#: tiramisu/config.py:421
#: tiramisu/config.py:430
msgid "unexpected path {0}, should start with {1}"
msgstr ""
#: tiramisu/config.py:481
#: tiramisu/config.py:490
msgid "opt in getowner must be an option not {0}"
msgstr ""
#: tiramisu/option.py:71
msgid "{0} has no attribute impl_set_information"
msgstr ""
#: tiramisu/option.py:86
msgid "information's item not found: {0}"
msgstr ""
#: tiramisu/option.py:89
msgid "{0} has no attribute impl_get_information"
msgstr ""
#: tiramisu/option.py:117
msgid "'{0}' ({1}) object attribute '{2}' is read-only"
msgstr ""
#: tiramisu/option.py:208
#: tiramisu/option.py:70
msgid "invalid name: {0} for option"
msgstr ""
#: tiramisu/option.py:218
msgid "validator must be a function"
msgstr ""
#: tiramisu/option.py:225
msgid "a default_multi is set whereas multi is False in option: {0}"
msgstr ""
#: tiramisu/option.py:231
msgid "invalid default_multi value {0} for option {1}: {2}"
msgstr ""
#: tiramisu/option.py:236
msgid "default value not allowed if option: {0} is calculated"
msgstr ""
#: tiramisu/option.py:239
msgid "params defined for a callback function but no callback defined yet for option {0}"
msgstr ""
#: tiramisu/option.py:261 tiramisu/option.py:809
#: tiramisu/option.py:80
msgid "invalid properties type {0} for {1}, must be a tuple"
msgstr ""
#: tiramisu/option.py:334
msgid "invalid value {0} for option {1} for object {2}"
#: tiramisu/option.py:122
msgid "'{0}' ({1}) object attribute '{2}' is read-only"
msgstr ""
#: tiramisu/option.py:342 tiramisu/value.py:468
#: tiramisu/option.py:149 tiramisu/value.py:362
msgid "information's item not found: {0}"
msgstr ""
#: tiramisu/option.py:266
msgid "cannot serialize Option, only in OptionDescription"
msgstr ""
#: tiramisu/option.py:367
msgid "a default_multi is set whereas multi is False in option: {0}"
msgstr ""
#: tiramisu/option.py:373
msgid "invalid default_multi value {0} for option {1}: {2}"
msgstr ""
#: tiramisu/option.py:378
msgid "default value not allowed if option: {0} is calculated"
msgstr ""
#: tiramisu/option.py:381
msgid "params defined for a callback function but no callback defined yet for option {0}"
msgstr ""
#: tiramisu/option.py:486 tiramisu/value.py:547
msgid "invalid value {0} for option {1}: {2}"
msgstr ""
#: tiramisu/option.py:354
#: tiramisu/option.py:506
msgid "invalid value {0} for option {1} which must be a list"
msgstr ""
#: tiramisu/option.py:423
#: tiramisu/option.py:577
msgid "invalid value {0} for option {1} must be different as {2} option"
msgstr ""
#: tiramisu/option.py:445
#: tiramisu/option.py:636
msgid "values must be a tuple for {0}"
msgstr ""
#: tiramisu/option.py:448
#: tiramisu/option.py:639
msgid "open_values must be a boolean for {0}"
msgstr ""
#: tiramisu/option.py:469
#: tiramisu/option.py:661
msgid "value {0} is not permitted, only {1} is allowed"
msgstr ""
#: tiramisu/option.py:481
#: tiramisu/option.py:673
msgid "value must be a boolean"
msgstr ""
#: tiramisu/option.py:491
#: tiramisu/option.py:683
msgid "value must be an integer"
msgstr ""
#: tiramisu/option.py:501
#: tiramisu/option.py:693
msgid "value must be a float"
msgstr ""
#: tiramisu/option.py:511
#: tiramisu/option.py:703
msgid "value must be a string, not {0}"
msgstr ""
#: tiramisu/option.py:529
#: tiramisu/option.py:721
msgid "value must be an unicode"
msgstr ""
#: tiramisu/option.py:539
#: tiramisu/option.py:733
msgid "malformed symlinkoption must be an option for symlink {0}"
msgstr ""
#: tiramisu/option.py:581
msgid "IP shall not be in reserved class"
#: tiramisu/option.py:788
msgid "invalid IP {0}"
msgstr ""
#: tiramisu/option.py:583
#: tiramisu/option.py:793
msgid "IP mustn't not be in reserved class"
msgstr ""
#: tiramisu/option.py:795
msgid "IP must be in private class"
msgstr ""
#: tiramisu/option.py:621
#: tiramisu/option.py:833
msgid "inconsistency in allowed range"
msgstr ""
#: tiramisu/option.py:626
#: tiramisu/option.py:838
msgid "max value is empty"
msgstr ""
#: tiramisu/option.py:663
#: tiramisu/option.py:877
msgid "invalid network address {0}"
msgstr ""
#: tiramisu/option.py:882
msgid "network shall not be in reserved class"
msgstr ""
#: tiramisu/option.py:695
#: tiramisu/option.py:894
msgid "invalid netmask address {0}"
msgstr ""
#: tiramisu/option.py:916
msgid "invalid network {0} ({1}) with netmask {2} ({3}), this network is an IP"
msgstr ""
#: tiramisu/option.py:700
#: tiramisu/option.py:921
msgid "invalid IP {0} ({1}) with netmask {2} ({3}), this IP is a network"
msgstr ""
#: tiramisu/option.py:705
#: tiramisu/option.py:926
msgid "invalid IP {0} ({1}) with netmask {2} ({3})"
msgstr ""
#: tiramisu/option.py:707
#: tiramisu/option.py:928
msgid "invalid network {0} ({1}) with netmask {2} ({3})"
msgstr ""
#: tiramisu/option.py:727
#: tiramisu/option.py:939
msgid "invalid broadcast address {0}"
msgstr ""
#: tiramisu/option.py:957
msgid "unknown type_ {0} for hostname"
msgstr ""
#: tiramisu/option.py:730
#: tiramisu/option.py:960
msgid "allow_ip must be a boolean"
msgstr ""
#: tiramisu/option.py:759
#: tiramisu/option.py:990
msgid "invalid value for {0}, must have dot"
msgstr ""
#: tiramisu/option.py:762
#: tiramisu/option.py:993
msgid "invalid domainname's length for {0} (max {1})"
msgstr ""
#: tiramisu/option.py:765
#: tiramisu/option.py:996
msgid "invalid domainname's length for {0} (min 2)"
msgstr ""
#: tiramisu/option.py:769
#: tiramisu/option.py:1000
msgid "invalid domainname"
msgstr ""
#: tiramisu/option.py:787
msgid "invalid name: {0} for optiondescription"
msgstr ""
#: tiramisu/option.py:799
#: tiramisu/option.py:1027
msgid "duplicate option name: {0}"
msgstr ""
#: tiramisu/option.py:825
#: tiramisu/option.py:1044
msgid "unknown Option {0} in OptionDescription {1}"
msgstr ""
#: tiramisu/option.py:874
#: tiramisu/option.py:1095
msgid "duplicate option: {0}"
msgstr ""
#: tiramisu/option.py:904
#: tiramisu/option.py:1129
msgid "no option for path {0}"
msgstr ""
#: tiramisu/option.py:910
#: tiramisu/option.py:1135
msgid "no option {0} found"
msgstr ""
#: tiramisu/option.py:920
#: tiramisu/option.py:1145
msgid "cannot change group_type if already set (old {0}, new {1})"
msgstr ""
#: tiramisu/option.py:933
#: tiramisu/option.py:1158
msgid "master group {0} shall not have a subgroup"
msgstr ""
#: tiramisu/option.py:936
#: tiramisu/option.py:1161
msgid "master group {0} shall not have a symlinkoption"
msgstr ""
#: tiramisu/option.py:939
#: tiramisu/option.py:1164
msgid "not allowed option {0} in group {1}: this option is not a multi"
msgstr ""
#: tiramisu/option.py:950
#: tiramisu/option.py:1175
msgid "master group with wrong master name for {0}"
msgstr ""
#: tiramisu/option.py:959
#: tiramisu/option.py:1184
msgid "no child has same nom has master group for: {0}"
msgstr ""
#: tiramisu/option.py:962
#: tiramisu/option.py:1187
msgid "group_type: {0} not allowed"
msgstr ""
#: tiramisu/option.py:1021
#: tiramisu/option.py:1277
msgid "malformed requirements type for option: {0}, must be a dict"
msgstr ""
#: tiramisu/option.py:1037
#: tiramisu/option.py:1294
msgid "malformed requirements for option: {0} require must have option, expected and action keys"
msgstr ""
#: tiramisu/option.py:1042
#: tiramisu/option.py:1299
msgid "malformed requirements for option: {0} inverse must be boolean"
msgstr ""
#: tiramisu/option.py:1046
#: tiramisu/option.py:1303
msgid "malformed requirements for option: {0} transitive must be boolean"
msgstr ""
#: tiramisu/option.py:1050
#: tiramisu/option.py:1307
msgid "malformed requirements for option: {0} same_action must be boolean"
msgstr ""
#: tiramisu/option.py:1054
#: tiramisu/option.py:1311
msgid "malformed requirements must be an option in option {0}"
msgstr ""
#: tiramisu/option.py:1057
#: tiramisu/option.py:1314
msgid "malformed requirements option {0} should not be a multi"
msgstr ""
#: tiramisu/option.py:1063
#: tiramisu/option.py:1320
msgid "malformed requirements second argument must be valid for option {0}: {1}"
msgstr ""
#: tiramisu/option.py:1068
#: tiramisu/option.py:1325
msgid "inconsistency in action types for option: {0} action: {1}"
msgstr ""
#: tiramisu/setting.py:47
msgid "storage_type is already set, cannot rebind it"
#: tiramisu/option.py:1350
msgid "{0} should be a function"
msgstr ""
#: tiramisu/setting.py:67
#: tiramisu/option.py:1353
msgid "{0}_params should be a dict"
msgstr ""
#: tiramisu/option.py:1356
msgid "{0}_params with key {1} should not have length different to 1"
msgstr ""
#: tiramisu/option.py:1360
msgid "{0}_params should be tuple for key \"{1}\""
msgstr ""
#: tiramisu/option.py:1366
msgid "validator not support tuple"
msgstr ""
#: tiramisu/option.py:1369
msgid "{0}_params should have an option not a {0} for first argument"
msgstr ""
#: tiramisu/option.py:1373
msgid "{0}_params should have a boolean not a {0} for second argument"
msgstr ""
#: tiramisu/setting.py:116
msgid "can't rebind {0}"
msgstr ""
#: tiramisu/setting.py:72
#: tiramisu/setting.py:121
msgid "can't unbind {0}"
msgstr ""
#: tiramisu/setting.py:185
#: tiramisu/setting.py:259
msgid "cannot append {0} property for option {1}: this property is calculated"
msgstr ""
#: tiramisu/setting.py:215
msgid "option {0} not already exists in storage {1}"
msgstr ""
#: tiramisu/setting.py:282
#: tiramisu/setting.py:322
msgid "opt and all_properties must not be set together in reset"
msgstr ""
#: tiramisu/setting.py:297
#: tiramisu/setting.py:337
msgid "if opt is not None, path should not be None in _getproperties"
msgstr ""
#: tiramisu/setting.py:391
#: tiramisu/setting.py:440
msgid "cannot change the value for option {0} this option is frozen"
msgstr ""
#: tiramisu/setting.py:397
#: tiramisu/setting.py:446
msgid "trying to access to an option named: {0} with properties {1}"
msgstr ""
#: tiramisu/setting.py:415
#: tiramisu/setting.py:464
msgid "permissive must be a tuple"
msgstr ""
#: tiramisu/setting.py:422 tiramisu/value.py:277
#: tiramisu/setting.py:471 tiramisu/value.py:301
msgid "invalid generic owner {0}"
msgstr ""
#: tiramisu/setting.py:503
#: tiramisu/setting.py:558
msgid "malformed requirements imbrication detected for option: '{0}' with requirement on: '{1}'"
msgstr ""
#: tiramisu/setting.py:515
#: tiramisu/setting.py:570
msgid "option '{0}' has requirement's property error: {1} {2}"
msgstr ""
#: tiramisu/storage/dictionary/storage.py:37
#: tiramisu/storage/__init__.py:52
msgid "storage_type is already set, cannot rebind it"
msgstr ""
#: tiramisu/storage/__init__.py:86
msgid "option {0} not already exists in storage {1}"
msgstr ""
#: tiramisu/storage/dictionary/storage.py:39
msgid "dictionary storage cannot delete session"
msgstr ""
#: tiramisu/storage/dictionary/storage.py:46
#: tiramisu/storage/dictionary/storage.py:50
msgid "session already used"
msgstr ""
#: tiramisu/storage/dictionary/storage.py:48
#: tiramisu/storage/dictionary/storage.py:52
msgid "a dictionary cannot be persistent"
msgstr ""
#: tiramisu/value.py:284
#: tiramisu/value.py:308
msgid "no value for {0} cannot change owner to {1}"
msgstr ""
#: tiramisu/value.py:356
#: tiramisu/value.py:416
msgid "invalid len for the slave: {0} which has {1} as master"
msgstr ""
#: tiramisu/value.py:373
#: tiramisu/value.py:440
msgid "invalid len for the master: {0} which has {1} as slave with greater len"
msgstr ""
#: tiramisu/value.py:394
#: tiramisu/value.py:470
msgid "cannot append a value on a multi option {0} which is a slave"
msgstr ""
#: tiramisu/value.py:429
#: tiramisu/value.py:507
msgid "cannot sort multi option {0} if master or slave"
msgstr ""
#: tiramisu/value.py:433
#: tiramisu/value.py:511
msgid "cmp is not permitted in python v3 or greater"
msgstr ""
#: tiramisu/value.py:442
#: tiramisu/value.py:520
msgid "cannot reverse multi option {0} if master or slave"
msgstr ""
#: tiramisu/value.py:450
#: tiramisu/value.py:528
msgid "cannot insert multi option {0} if master or slave"
msgstr ""
#: tiramisu/value.py:458
#: tiramisu/value.py:536
msgid "cannot extend multi option {0} if master or slave"
msgstr ""
#: tiramisu/value.py:482
#: tiramisu/value.py:564
msgid "cannot pop a value on a multi option {0} which is a slave"
msgstr ""