Merge branch 'better_auto_save'

Conflicts:
	test/test_freeze.py
	tiramisu/option.py
	translations/fr/tiramisu.po
	translations/tiramisu.pot
This commit is contained in:
Emmanuel Garette 2014-03-29 20:44:10 +01:00
commit 6413d460b2
9 changed files with 242 additions and 132 deletions

View File

@ -142,18 +142,27 @@ def test_freeze_get_multi():
def test_force_store_value(): def test_force_store_value():
descr = make_description_freeze() descr = make_description_freeze()
conf = Config(descr) conf = Config(descr)
assert conf.getowner(conf.unwrap_from_path('wantref')) == 'default' assert conf.cfgimpl_get_values()._p_.get_modified_values() == {}
conf.wantref conf.wantref
assert conf.getowner(conf.unwrap_from_path('wantref')) == 'user' assert conf.cfgimpl_get_values()._p_.get_modified_values() == {'wantref': ('user', False)}
def test_force_store_value_no_requirement():
booloption = BoolOption('bool', 'Test boolean option', default=True)
try:
BoolOption('wantref', 'Test requires', default=False,
requires=({'option': booloption, 'expected': True, 'action': 'force_store_value'},))
except ValueError:
pass
def test_force_store_value_ro(): def test_force_store_value_ro():
descr = make_description_freeze() descr = make_description_freeze()
conf = Config(descr) conf = Config(descr)
conf.read_only() conf.read_only()
assert conf.getowner(conf.unwrap_from_path('wantref')) == 'default' assert conf.cfgimpl_get_values()._p_.get_modified_values() == {}
conf.wantref conf.wantref
assert conf.getowner(conf.unwrap_from_path('wantref')) == 'user' assert conf.cfgimpl_get_values()._p_.get_modified_values() == {'wantref': ('user', False)}
def test_force_store_value_hidden(): def test_force_store_value_hidden():
@ -161,6 +170,60 @@ def test_force_store_value_hidden():
conf = Config(descr) conf = Config(descr)
conf.cfgimpl_get_settings().setpermissive(('hidden',)) conf.cfgimpl_get_settings().setpermissive(('hidden',))
conf.read_write() conf.read_write()
assert conf.getowner(conf.unwrap_from_path('wantref2')) == 'default' assert conf.cfgimpl_get_values()._p_.get_modified_values() == {}
conf._getattr('wantref2', force_permissive=True) conf._getattr('wantref2', force_permissive=True)
assert conf.getowner(conf.unwrap_from_path('wantref2')) == 'user' assert conf.cfgimpl_get_values()._p_.get_modified_values() == {'wantref2': ('user', False)}
def test_force_store_value_owner():
descr = make_description_freeze()
conf = Config(descr)
assert conf.cfgimpl_get_values()._p_.get_modified_values() == {}
conf.getowner(conf.unwrap_from_path('wantref'))
assert conf.cfgimpl_get_values()._p_.get_modified_values() == {'wantref': ('user', False)}
def test_force_store_value_owner_ro():
descr = make_description_freeze()
conf = Config(descr)
conf.read_only()
assert conf.cfgimpl_get_values()._p_.get_modified_values() == {}
conf.getowner(conf.unwrap_from_path('wantref'))
assert conf.cfgimpl_get_values()._p_.get_modified_values() == {'wantref': ('user', False)}
def test_force_store_value_owner_hidden():
descr = make_description_freeze()
conf = Config(descr)
conf.cfgimpl_get_settings().setpermissive(('hidden',))
conf.read_write()
assert conf.cfgimpl_get_values()._p_.get_modified_values() == {}
conf.getowner(conf.unwrap_from_path('wantref2'), force_permissive=True)
assert conf.cfgimpl_get_values()._p_.get_modified_values() == {'wantref2': ('user', False)}
def test_force_store_value_modified():
descr = make_description_freeze()
conf = Config(descr)
assert conf.cfgimpl_get_values()._p_.get_modified_values() == {}
conf.cfgimpl_get_values().get_modified_values()
assert conf.cfgimpl_get_values()._p_.get_modified_values() == {'wantref': ('user', False), 'wantref2': ('user', False)}
def test_force_store_value_modified_ro():
descr = make_description_freeze()
conf = Config(descr)
conf.read_only()
assert conf.cfgimpl_get_values()._p_.get_modified_values() == {}
conf.cfgimpl_get_values().get_modified_values()
assert conf.cfgimpl_get_values()._p_.get_modified_values() == {'wantref': ('user', False), 'wantref2': ('user', False)}
def test_force_store_value_modified_hidden():
descr = make_description_freeze()
conf = Config(descr)
conf.cfgimpl_get_settings().setpermissive(('hidden',))
conf.read_write()
assert conf.cfgimpl_get_values()._p_.get_modified_values() == {}
conf.cfgimpl_get_values().get_modified_values()
assert conf.cfgimpl_get_values()._p_.get_modified_values() == {'wantref': ('user', False), 'wantref2': ('user', False)}

View File

@ -99,8 +99,8 @@ def test_mandatory_multi_none():
descr = make_description() descr = make_description()
config = Config(descr) config = Config(descr)
config.str3 = [None] config.str3 = [None]
config.read_only()
assert config.getowner(config.unwrap_from_path('str3')) == 'user' assert config.getowner(config.unwrap_from_path('str3')) == 'user'
config.read_only()
prop = [] prop = []
try: try:
config.str3 config.str3
@ -109,8 +109,8 @@ def test_mandatory_multi_none():
assert 'mandatory' in prop assert 'mandatory' in prop
config.read_write() config.read_write()
config.str3 = ['yes', None] config.str3 = ['yes', None]
config.read_only()
assert config.getowner(config.unwrap_from_path('str3')) == 'user' assert config.getowner(config.unwrap_from_path('str3')) == 'user'
config.read_only()
prop = [] prop = []
try: try:
config.str3 config.str3
@ -123,8 +123,8 @@ def test_mandatory_multi_empty():
descr = make_description() descr = make_description()
config = Config(descr) config = Config(descr)
config.str3 = [''] config.str3 = ['']
config.read_only()
assert config.getowner(config.unwrap_from_path('str3')) == 'user' assert config.getowner(config.unwrap_from_path('str3')) == 'user'
config.read_only()
prop = [] prop = []
try: try:
config.str3 config.str3
@ -133,8 +133,8 @@ def test_mandatory_multi_empty():
assert 'mandatory' in prop assert 'mandatory' in prop
config.read_write() config.read_write()
config.str3 = ['yes', ''] config.str3 = ['yes', '']
config.read_only()
assert config.getowner(config.unwrap_from_path('str3')) == 'user' assert config.getowner(config.unwrap_from_path('str3')) == 'user'
config.read_only()
prop = [] prop = []
try: try:
config.str3 config.str3

View File

@ -5,7 +5,7 @@ from tiramisu.setting import owners
from tiramisu.config import Config from tiramisu.config import Config
from tiramisu.option import ChoiceOption, BoolOption, IntOption, FloatOption, \ from tiramisu.option import ChoiceOption, BoolOption, IntOption, FloatOption, \
StrOption, OptionDescription StrOption, OptionDescription
from tiramisu.error import ConfigError, ConstError from tiramisu.error import ConfigError, ConstError, PropertiesOptionError
def make_description(): def make_description():
@ -41,6 +41,14 @@ def test_default_owner():
assert cfg.getowner(gcdummy) == owners.user assert cfg.getowner(gcdummy) == owners.user
def test_hidden_owner():
gcdummy = BoolOption('dummy', 'dummy', default=False, properties=('hidden',))
descr = OptionDescription('tiramisu', '', [gcdummy])
cfg = Config(descr)
cfg.read_write()
raises(PropertiesOptionError, "cfg.getowner(gcdummy)")
def test_addowner(): def test_addowner():
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy]) descr = OptionDescription('tiramisu', '', [gcdummy])

View File

@ -483,14 +483,15 @@ class _CommonConfig(SubConfig):
"read write is a global config's setting, see `settings.py`" "read write is a global config's setting, see `settings.py`"
self.cfgimpl_get_settings().read_write() self.cfgimpl_get_settings().read_write()
def getowner(self, opt): def getowner(self, opt, force_permissive=False):
"""convenience method to retrieve an option's owner """convenience method to retrieve an option's owner
from the config itself from the config itself
""" """
if not isinstance(opt, Option) and not isinstance(opt, SymLinkOption): if not isinstance(opt, Option) and not isinstance(opt, SymLinkOption):
raise TypeError(_('opt in getowner must be an option not {0}' raise TypeError(_('opt in getowner must be an option not {0}'
'').format(type(opt))) '').format(type(opt)))
return self.cfgimpl_get_values().getowner(opt) return self.cfgimpl_get_values().getowner(opt,
force_permissive=force_permissive)
def unwrap_from_path(self, path, force_permissive=False): def unwrap_from_path(self, path, force_permissive=False):
"""convenience method to extract and Option() object from the Config() """convenience method to extract and Option() object from the Config()

View File

@ -1461,6 +1461,10 @@ def validate_requires_arg(requires, name):
raise ValueError(_("malformed requirements for option: {0}" raise ValueError(_("malformed requirements for option: {0}"
" require must have option, expected and" " require must have option, expected and"
" action keys").format(name)) " action keys").format(name))
if action == 'force_store_value':
raise ValueError(_("malformed requirements for option: {0}"
" action cannot be force_store_value"
).format(name))
inverse = require.get('inverse', False) inverse = require.get('inverse', False)
if inverse not in [True, False]: if inverse not in [True, False]:
raise ValueError(_('malformed requirements for option: {0}' raise ValueError(_('malformed requirements for option: {0}'
@ -1543,10 +1547,10 @@ def validate_callback(callback, callback_params, type_):
if not isinstance(option, Option) and not \ if not isinstance(option, Option) and not \
isinstance(option, SymLinkOption): isinstance(option, SymLinkOption):
raise ValueError(_('{0}_params must 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 must 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

@ -365,7 +365,10 @@ class Settings(object):
self._p_.reset_properties(_path) self._p_.reset_properties(_path)
self._getcontext().cfgimpl_reset_cache() self._getcontext().cfgimpl_reset_cache()
def _getproperties(self, opt=None, path=None, is_apply_req=True): def _getproperties(self, opt=None, path=None, _is_apply_req=True):
"""
be careful, _is_apply_req doesn't copy properties
"""
if opt is None: if opt is None:
props = copy(self._p_.getproperties(path, default_properties)) props = copy(self._p_.getproperties(path, default_properties))
else: else:
@ -379,15 +382,16 @@ class Settings(object):
is_cached, props = self._p_.getcache(path, ntime) is_cached, props = self._p_.getcache(path, ntime)
if is_cached: if is_cached:
return copy(props) return copy(props)
props = copy(self._p_.getproperties(path, opt._properties)) props = self._p_.getproperties(path, opt._properties)
if is_apply_req: if _is_apply_req:
props = copy(props)
props |= self.apply_requires(opt, path) props |= self.apply_requires(opt, path)
if 'cache' in self: if 'cache' in self:
if 'expire' in self: if 'expire' in self:
if ntime is None: if ntime is None:
ntime = int(time()) ntime = int(time())
ntime = ntime + expires_time ntime = ntime + expires_time
self._p_.setcache(path, copy(props), ntime) self._p_.setcache(path, copy(props), ntime)
return props return props
def append(self, propname): def append(self, propname):
@ -640,6 +644,15 @@ class Settings(object):
def get_modified_permissives(self): def get_modified_permissives(self):
return self._p_.get_modified_permissives() return self._p_.get_modified_permissives()
def get_with_property(self, propname):
opts, paths = self._getcontext().cfgimpl_get_description(
)._cache_paths
for index in range(0, len(paths)):
opt = opts[index]
path = paths[index]
if propname in self._getproperties(opt, path, False):
yield (opt, path)
def __getstate__(self): def __getstate__(self):
return {'_p_': self._p_, '_owner': str(self._owner)} return {'_p_': self._p_, '_owner': str(self._owner)}

View File

@ -88,6 +88,11 @@ class Values(object):
return value return value
def get_modified_values(self): def get_modified_values(self):
context = self._getcontext()
if context._impl_descr is not None:
for opt, path in context.cfgimpl_get_settings(
).get_with_property('force_store_value'):
self._getowner(opt, path, force_permissive=True)
return self._p_.get_modified_values() return self._p_.get_modified_values()
def __contains__(self, opt): def __contains__(self, opt):
@ -196,7 +201,7 @@ class Values(object):
# if value has callback and is not set # if value has callback and is not set
# or frozen with force_default_on_freeze # or frozen with force_default_on_freeze
if opt.impl_has_callback() and ( if opt.impl_has_callback() and (
self._is_default_owner(path) or self._is_default_owner(opt, path, validate_properties=False) or
(is_frozen and 'force_default_on_freeze' in setting[opt])): (is_frozen and 'force_default_on_freeze' in setting[opt])):
lenmaster = None lenmaster = None
no_value_slave = False no_value_slave = False
@ -241,7 +246,8 @@ class Values(object):
value = Multi(value, self.context, opt, path, validate=validate) value = Multi(value, self.context, opt, path, validate=validate)
if config_error is None and validate: if config_error is None and validate:
opt.impl_validate(value, context, 'validator' in setting) opt.impl_validate(value, context, 'validator' in setting)
if config_error is None and self._is_default_owner(path) and \ if config_error is None and \
self._is_default_owner(opt, path, validate_properties=False) and \
'force_store_value' in setting[opt]: 'force_store_value' in setting[opt]:
self.setitem(opt, value, path, is_write=False, self.setitem(opt, value, path, is_write=False,
force_permissive=force_permissive) force_permissive=force_permissive)
@ -303,23 +309,27 @@ class Values(object):
value = list(value) value = list(value)
self._p_.setvalue(path, value, owner) self._p_.setvalue(path, value, owner)
def getowner(self, opt): def getowner(self, opt, force_permissive=False):
""" """
retrieves the option's owner retrieves the option's owner
:param opt: the `option.Option` object :param opt: the `option.Option` object
:param force_permissive: behaves as if the permissive property
was present
:returns: a `setting.owners.Owner` object :returns: a `setting.owners.Owner` object
""" """
if isinstance(opt, SymLinkOption): if isinstance(opt, SymLinkOption):
opt = opt._opt opt = opt._opt
path = self._get_opt_path(opt) path = self._get_opt_path(opt)
return self._getowner(path) return self._getowner(opt, path, force_permissive=force_permissive)
def _getowner(self, path): def _getowner(self, opt, path, validate_properties=True, force_permissive=False):
owner = self._p_.getowner(path, owners.default)
meta = self._getcontext().cfgimpl_get_meta() meta = self._getcontext().cfgimpl_get_meta()
if validate_properties:
self._getitem(opt, path, True, force_permissive, None, True)
owner = self._p_.getowner(path, owners.default)
if owner is owners.default and meta is not None: if owner is owners.default and meta is not None:
owner = meta.cfgimpl_get_values()._getowner(path) owner = meta.cfgimpl_get_values()._getowner(opt, path)
return owner return owner
def setowner(self, opt, owner): def setowner(self, opt, owner):
@ -333,25 +343,25 @@ class Values(object):
raise TypeError(_("invalid generic owner {0}").format(str(owner))) raise TypeError(_("invalid generic owner {0}").format(str(owner)))
path = self._get_opt_path(opt) path = self._get_opt_path(opt)
self._setowner(path, owner) self._setowner(opt, path, owner)
def _setowner(self, path, owner): def _setowner(self, opt, path, owner):
if self._getowner(path) == owners.default: if self._getowner(opt, path) == owners.default:
raise ConfigError(_('no value for {0} cannot change owner to {1}' raise ConfigError(_('no value for {0} cannot change owner to {1}'
'').format(path, owner)) '').format(path, owner))
self._p_.setowner(path, owner) self._p_.setowner(path, owner)
def is_default_owner(self, opt): def is_default_owner(self, opt, validate_properties=True):
""" """
:param config: *must* be only the **parent** config :param config: *must* be only the **parent** config
(not the toplevel config) (not the toplevel config)
:return: boolean :return: boolean
""" """
path = self._get_opt_path(opt) path = self._get_opt_path(opt)
return self._is_default_owner(path) return self._is_default_owner(opt, path, validate_properties)
def _is_default_owner(self, path): def _is_default_owner(self, opt, path, validate_properties=True):
return self._getowner(path) == owners.default return self._getowner(opt, path, validate_properties) == owners.default
def reset_cache(self, only_expired): def reset_cache(self, only_expired):
""" """
@ -550,7 +560,8 @@ class Multi(list):
if not force and self.opt.impl_get_multitype() == multitypes.master: if not force and self.opt.impl_get_multitype() == multitypes.master:
for slave in self.opt.impl_get_master_slaves(): for slave in self.opt.impl_get_master_slaves():
path = values._get_opt_path(slave) path = values._get_opt_path(slave)
if not values._is_default_owner(path): if not values._is_default_owner(slave, path,
validate_properties=False):
if slave.impl_has_callback(): if slave.impl_has_callback():
dvalue = values._getcallback_value(slave, index=index) dvalue = values._getcallback_value(slave, index=index)
else: else:
@ -631,7 +642,7 @@ class Multi(list):
if self.opt.impl_get_multitype() == multitypes.master: if self.opt.impl_get_multitype() == multitypes.master:
for slave in self.opt.impl_get_master_slaves(): for slave in self.opt.impl_get_master_slaves():
values = context.cfgimpl_get_values() values = context.cfgimpl_get_values()
if not values.is_default_owner(slave): if not values.is_default_owner(slave, validate_properties=False):
#get multi without valid properties #get multi without valid properties
values.getitem(slave, validate=False, values.getitem(slave, validate=False,
validate_properties=False validate_properties=False

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-26 20:46+CET\n" "POT-Creation-Date: 2014-03-29 19:01+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"
@ -30,7 +30,7 @@ msgid "unknown group_type: {0}"
msgstr "group_type inconnu: {0}" msgstr "group_type inconnu: {0}"
#: tiramisu/config.py:163 tiramisu/setting.py:334 tiramisu/value.py:55 #: tiramisu/config.py:163 tiramisu/setting.py:334 tiramisu/value.py:55
#: tiramisu/value.py:483 #: tiramisu/value.py:500
msgid "the context does not exist anymore" msgid "the context does not exist anymore"
msgstr "le context n'existe plus" msgstr "le context n'existe plus"
@ -63,27 +63,27 @@ msgstr "chemin imprévu {0}, devrait commencer par {1}"
msgid "opt in getowner must be an option not {0}" msgid "opt in getowner must be an option not {0}"
msgstr "opt dans getowner doit être une option pas {0}" msgstr "opt dans getowner doit être une option pas {0}"
#: tiramisu/config.py:534 #: tiramisu/config.py:535
msgid "cannot serialize Config with MetaConfig" msgid "cannot serialize Config with MetaConfig"
msgstr "impossible de sérialiser une Config avec une MetaConfig" msgstr "impossible de sérialiser une Config avec une MetaConfig"
#: tiramisu/config.py:548 #: tiramisu/config.py:549
msgid "this storage is not serialisable, could be a none persistent storage" msgid "this storage is not serialisable, could be a none persistent storage"
msgstr "ce storage n'est sérialisable, devrait être une storage non persistant" msgstr "ce storage n'est sérialisable, devrait être une storage non persistant"
#: tiramisu/config.py:611 #: tiramisu/config.py:612
msgid "metaconfig's children must be a list" msgid "metaconfig's children must be a list"
msgstr "enfants d'une metaconfig doit être une liste" msgstr "enfants d'une metaconfig doit être une liste"
#: tiramisu/config.py:705 #: tiramisu/config.py:706
msgid "metaconfig's children should be config, not {0}" msgid "metaconfig's children should be config, not {0}"
msgstr "enfants d'une metaconfig doit être une config, pas {0}" msgstr "enfants d'une metaconfig doit être une config, pas {0}"
#: tiramisu/config.py:709 #: tiramisu/config.py:710
msgid "child has already a metaconfig's" msgid "child has already a metaconfig's"
msgstr "enfant a déjà une metaconfig" msgstr "enfant a déjà une metaconfig"
#: tiramisu/config.py:713 #: tiramisu/config.py:714
msgid "all config in metaconfig must have the same optiondescription" msgid "all config in metaconfig must have the same optiondescription"
msgstr "" msgstr ""
"toutes les configs d'une metaconfig doivent avoir la même optiondescription" "toutes les configs d'une metaconfig doivent avoir la même optiondescription"
@ -100,7 +100,7 @@ msgstr "type des properties invalide {0} pour {1}, doit être un tuple"
msgid "'{0}' ({1}) object attribute '{2}' is read-only" msgid "'{0}' ({1}) object attribute '{2}' is read-only"
msgstr "l'attribut {2} de l'objet '{0}' ({1}) est en lecture seule" msgstr "l'attribut {2} de l'objet '{0}' ({1}) est en lecture seule"
#: tiramisu/option.py:140 tiramisu/value.py:393 #: tiramisu/option.py:140 tiramisu/value.py:410
msgid "information's item not found: {0}" msgid "information's item not found: {0}"
msgstr "aucune config spécifiée alors que c'est nécessaire" msgstr "aucune config spécifiée alors que c'est nécessaire"
@ -420,77 +420,83 @@ 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:1466 #: tiramisu/option.py:1465
msgid ""
"malformed requirements for option: {0} action cannot be force_store_value"
msgstr ""
"requirements mal formés pour l'option : {0} action ne peut pas être "
"force_store_value"
#: tiramisu/option.py:1470
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:1470 #: tiramisu/option.py:1474
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:1474 #: tiramisu/option.py:1478
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:1478 #: tiramisu/option.py:1482
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:1481 #: tiramisu/option.py:1485
msgid "malformed requirements option {0} must 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:1487 #: tiramisu/option.py:1491
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:1492 #: tiramisu/option.py:1496
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:1517 #: tiramisu/option.py:1521
msgid "{0} must be a function" msgid "{0} must be a function"
msgstr "{0} doit être une fonction" msgstr "{0} doit être une fonction"
#: tiramisu/option.py:1520 #: tiramisu/option.py:1524
msgid "{0}_params must be a dict" msgid "{0}_params must be a dict"
msgstr "{0}_params doit être un dict" msgstr "{0}_params doit être un dict"
#: tiramisu/option.py:1523 #: tiramisu/option.py:1527
msgid "{0}_params with key {1} mustn't 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} ne doit 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:1527 #: tiramisu/option.py:1531
msgid "{0}_params must be tuple for key \"{1}\"" msgid "{0}_params must be tuple for key \"{1}\""
msgstr "{0}_params doit être un tuple pour la clef \"{1}\"" msgstr "{0}_params doit être un tuple pour la clef \"{1}\""
#: tiramisu/option.py:1533 #: tiramisu/option.py:1537
msgid "{0}_params with length of tuple as 1 must only have None as first value" msgid "{0}_params with length of tuple as 1 must only have None as first value"
msgstr "" msgstr ""
"{0}_params avec un tuple de longueur 1 doit seulement avoir None comme " "{0}_params avec un tuple de longueur 1 doit seulement avoir None comme "
"première valeur" "première valeur"
#: tiramisu/option.py:1537 #: tiramisu/option.py:1541
#, fuzzy
msgid "{0}_params must only have 1 or 2 as length" msgid "{0}_params must only have 1 or 2 as length"
msgstr "{0}_params doit seulement avoir une longueur de 1 ou 2" msgstr "{0}_params doit seulement avoir une longueur de 1 ou 2"
#: tiramisu/option.py:1542 #: tiramisu/option.py:1546
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:1545 #: tiramisu/option.py:1549
msgid "{0}_params must 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 doit 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:1549 #: tiramisu/option.py:1553
msgid "{0}_params must 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 doit avoir un booléen pas un {0} pour second argument" msgstr "{0}_params doit avoir un booléen pas un {0} pour second argument"
@ -512,29 +518,29 @@ msgstr ""
msgid "opt and all_properties must not be set together in reset" 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" msgstr "opt et all_properties ne doit pas être renseigné ensemble dans reset"
#: tiramisu/setting.py:373 #: tiramisu/setting.py:376
msgid "if opt is not None, path should not be None in _getproperties" msgid "if opt is not None, path should not be None in _getproperties"
msgstr "" msgstr ""
"si opt n'est pas None, path devrait ne pas être à None dans _getproperties" "si opt n'est pas None, path devrait ne pas être à None dans _getproperties"
#: tiramisu/setting.py:482 #: tiramisu/setting.py:486
msgid "cannot change the value for option {0} this option is frozen" msgid "cannot change the value for option {0} this option is frozen"
msgstr "" msgstr ""
"ne peut modifier 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:488 #: tiramisu/setting.py:492
msgid "trying to access to an option named: {0} with properties {1}" 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}" msgstr "tentative d'accès à une option nommée : {0} avec les propriétés {1}"
#: tiramisu/setting.py:506 #: tiramisu/setting.py:510
msgid "permissive must be a tuple" msgid "permissive must be a tuple"
msgstr "permissive doit être un tuple" msgstr "permissive doit être un tuple"
#: tiramisu/setting.py:513 tiramisu/value.py:332 #: tiramisu/setting.py:517 tiramisu/value.py:349
msgid "invalid generic owner {0}" msgid "invalid generic owner {0}"
msgstr "invalide owner générique {0}" msgstr "invalide owner générique {0}"
#: tiramisu/setting.py:601 #: tiramisu/setting.py:605
msgid "" msgid ""
"malformed requirements imbrication detected for option: '{0}' with " "malformed requirements imbrication detected for option: '{0}' with "
"requirement on: '{1}'" "requirement on: '{1}'"
@ -542,7 +548,7 @@ msgstr ""
"imbrication de requirements mal formés detectée pour l'option : '{0}' avec " "imbrication de requirements mal formés detectée pour l'option : '{0}' avec "
"requirement sur : '{1}'" "requirement sur : '{1}'"
#: tiramisu/setting.py:612 #: tiramisu/setting.py:616
msgid "option '{0}' has requirement's property error: {1} {2}" 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}" msgstr "l'option '{0}' a une erreur de propriété pour le requirement : {1} {2}"
@ -567,52 +573,52 @@ msgstr "session déjà utilisée"
msgid "a dictionary cannot be persistent" msgid "a dictionary cannot be persistent"
msgstr "un espace de stockage dictionary ne peut être persistant" msgstr "un espace de stockage dictionary ne peut être persistant"
#: tiramisu/value.py:339 #: tiramisu/value.py:356
msgid "no value for {0} cannot change owner to {1}" msgid "no value for {0} cannot change owner to {1}"
msgstr "pas de valeur pour {0} ne peut changer d'utilisateur pour {1}" msgstr "pas de valeur pour {0} ne peut changer d'utilisateur pour {1}"
#: tiramisu/value.py:421 #: tiramisu/value.py:438
msgid "can force cache only if cache is actived in config" msgid "can force cache only if cache is actived in config"
msgstr "" msgstr ""
"peut force la mise en cache seulement si le cache est activé dans la config" "peut force la mise en cache seulement si le cache est activé dans la config"
#: tiramisu/value.py:460 #: tiramisu/value.py:477
msgid "{0} is already a Multi " msgid "{0} is already a Multi "
msgstr "{0} est déjà une Multi" msgstr "{0} est déjà une Multi"
#: tiramisu/value.py:496 tiramisu/value.py:560 #: tiramisu/value.py:513 tiramisu/value.py:577
msgid "invalid len for the slave: {0} which has {1} as master" 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" msgstr "longueur invalide pour une esclave : {0} qui a {1} comme maître"
#: tiramisu/value.py:532 #: tiramisu/value.py:549
msgid "cannot append a value on a multi option {0} which is a slave" 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" msgstr "ne peut ajouter une valeur sur l'option multi {0} qui est une esclave"
#: tiramisu/value.py:570 #: tiramisu/value.py:587
msgid "cannot sort multi option {0} if master or slave" 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" msgstr "ne peut trier une option multi {0} pour une maître ou une esclave"
#: tiramisu/value.py:574 #: tiramisu/value.py:591
msgid "cmp is not permitted in python v3 or greater" msgid "cmp is not permitted in python v3 or greater"
msgstr "cmp n'est pas permis en python v3 ou supérieure" msgstr "cmp n'est pas permis en python v3 ou supérieure"
#: tiramisu/value.py:583 #: tiramisu/value.py:600
msgid "cannot reverse multi option {0} if master or slave" 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" msgstr "ne peut inverser une option multi {0} pour une maître ou une esclave"
#: tiramisu/value.py:591 #: tiramisu/value.py:608
msgid "cannot insert multi option {0} if master or slave" 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" msgstr "ne peut insérer une option multi {0} pour une maître ou une esclave"
#: tiramisu/value.py:599 #: tiramisu/value.py:616
msgid "cannot extend multi option {0} if master or slave" 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" msgstr "ne peut étendre une option multi {0} pour une maître ou une esclave"
#: tiramisu/value.py:610 #: tiramisu/value.py:627
msgid "invalid value {0} for option {1}: {2}" msgid "invalid value {0} for option {1}: {2}"
msgstr "valeur invalide {0} pour l'option {1} : {2}" msgstr "valeur invalide {0} pour l'option {1} : {2}"
#: tiramisu/value.py:628 #: tiramisu/value.py:645
msgid "cannot pop a value on a multi option {0} which is a slave" 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" msgstr "ne peut supprimer une valeur dans l'option multi {0} qui est esclave"

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-26 20:46+CET\n" "POT-Creation-Date: 2014-03-29 19:01+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"
@ -28,7 +28,7 @@ msgid "unknown group_type: {0}"
msgstr "" msgstr ""
#: tiramisu/config.py:163 tiramisu/setting.py:334 tiramisu/value.py:55 #: tiramisu/config.py:163 tiramisu/setting.py:334 tiramisu/value.py:55
#: tiramisu/value.py:483 #: tiramisu/value.py:500
msgid "the context does not exist anymore" msgid "the context does not exist anymore"
msgstr "" msgstr ""
@ -60,27 +60,27 @@ msgstr ""
msgid "opt in getowner must be an option not {0}" msgid "opt in getowner must be an option not {0}"
msgstr "" msgstr ""
#: tiramisu/config.py:534 #: tiramisu/config.py:535
msgid "cannot serialize Config with MetaConfig" msgid "cannot serialize Config with MetaConfig"
msgstr "" msgstr ""
#: tiramisu/config.py:548 #: tiramisu/config.py:549
msgid "this storage is not serialisable, could be a none persistent storage" msgid "this storage is not serialisable, could be a none persistent storage"
msgstr "" msgstr ""
#: tiramisu/config.py:611 #: tiramisu/config.py:612
msgid "metaconfig's children must be a list" msgid "metaconfig's children must be a list"
msgstr "" msgstr ""
#: tiramisu/config.py:705 #: tiramisu/config.py:706
msgid "metaconfig's children should be config, not {0}" msgid "metaconfig's children should be config, not {0}"
msgstr "" msgstr ""
#: tiramisu/config.py:709 #: tiramisu/config.py:710
msgid "child has already a metaconfig's" msgid "child has already a metaconfig's"
msgstr "" msgstr ""
#: tiramisu/config.py:713 #: tiramisu/config.py:714
msgid "all config in metaconfig must have the same optiondescription" msgid "all config in metaconfig must have the same optiondescription"
msgstr "" msgstr ""
@ -96,7 +96,7 @@ msgstr ""
msgid "'{0}' ({1}) object attribute '{2}' is read-only" msgid "'{0}' ({1}) object attribute '{2}' is read-only"
msgstr "" msgstr ""
#: tiramisu/option.py:140 tiramisu/value.py:393 #: tiramisu/option.py:140 tiramisu/value.py:410
msgid "information's item not found: {0}" msgid "information's item not found: {0}"
msgstr "" msgstr ""
@ -396,67 +396,71 @@ msgstr ""
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:1466 #: tiramisu/option.py:1465
msgid "malformed requirements for option: {0} inverse must be boolean" msgid "malformed requirements for option: {0} action cannot be force_store_value"
msgstr "" msgstr ""
#: tiramisu/option.py:1470 #: tiramisu/option.py:1470
msgid "malformed requirements for option: {0} transitive must be boolean" msgid "malformed requirements for option: {0} inverse must be boolean"
msgstr "" msgstr ""
#: tiramisu/option.py:1474 #: tiramisu/option.py:1474
msgid "malformed requirements for option: {0} same_action must be boolean" msgid "malformed requirements for option: {0} transitive must be boolean"
msgstr "" msgstr ""
#: tiramisu/option.py:1478 #: tiramisu/option.py:1478
msgid "malformed requirements for option: {0} same_action must be boolean"
msgstr ""
#: tiramisu/option.py:1482
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:1481 #: tiramisu/option.py:1485
msgid "malformed requirements option {0} must not be a multi" msgid "malformed requirements option {0} must not be a multi"
msgstr "" msgstr ""
#: tiramisu/option.py:1487 #: tiramisu/option.py:1491
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:1492 #: tiramisu/option.py:1496
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:1517 #: tiramisu/option.py:1521
msgid "{0} must be a function" msgid "{0} must be a function"
msgstr "" msgstr ""
#: tiramisu/option.py:1520 #: tiramisu/option.py:1524
msgid "{0}_params must be a dict" msgid "{0}_params must be a dict"
msgstr "" msgstr ""
#: tiramisu/option.py:1523 #: tiramisu/option.py:1527
msgid "{0}_params with key {1} mustn't have length different to 1" msgid "{0}_params with key {1} mustn't have length different to 1"
msgstr "" msgstr ""
#: tiramisu/option.py:1527 #: tiramisu/option.py:1531
msgid "{0}_params must be tuple for key \"{1}\"" msgid "{0}_params must be tuple for key \"{1}\""
msgstr "" msgstr ""
#: tiramisu/option.py:1533 #: tiramisu/option.py:1537
msgid "{0}_params with length of tuple as 1 must only have None as first value" msgid "{0}_params with length of tuple as 1 must only have None as first value"
msgstr "" msgstr ""
#: tiramisu/option.py:1537 #: tiramisu/option.py:1541
msgid "{0}_params must only have 1 or 2 as length" msgid "{0}_params must only have 1 or 2 as length"
msgstr "" msgstr ""
#: tiramisu/option.py:1542 #: tiramisu/option.py:1546
msgid "validator not support tuple" msgid "validator not support tuple"
msgstr "" msgstr ""
#: tiramisu/option.py:1545 #: tiramisu/option.py:1549
msgid "{0}_params must 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:1549 #: tiramisu/option.py:1553
msgid "{0}_params must have a boolean not a {0} for second argument" msgid "{0}_params must have a boolean not a {0} for second argument"
msgstr "" msgstr ""
@ -476,31 +480,31 @@ msgstr ""
msgid "opt and all_properties must not be set together in reset" msgid "opt and all_properties must not be set together in reset"
msgstr "" msgstr ""
#: tiramisu/setting.py:373 #: tiramisu/setting.py:376
msgid "if opt is not None, path should not be None in _getproperties" msgid "if opt is not None, path should not be None in _getproperties"
msgstr "" msgstr ""
#: tiramisu/setting.py:482 #: tiramisu/setting.py:486
msgid "cannot change the value for option {0} this option is frozen" msgid "cannot change the value for option {0} this option is frozen"
msgstr "" msgstr ""
#: tiramisu/setting.py:488 #: tiramisu/setting.py:492
msgid "trying to access to an option named: {0} with properties {1}" msgid "trying to access to an option named: {0} with properties {1}"
msgstr "" msgstr ""
#: tiramisu/setting.py:506 #: tiramisu/setting.py:510
msgid "permissive must be a tuple" msgid "permissive must be a tuple"
msgstr "" msgstr ""
#: tiramisu/setting.py:513 tiramisu/value.py:332 #: tiramisu/setting.py:517 tiramisu/value.py:349
msgid "invalid generic owner {0}" msgid "invalid generic owner {0}"
msgstr "" msgstr ""
#: tiramisu/setting.py:601 #: tiramisu/setting.py:605
msgid "malformed requirements imbrication detected for option: '{0}' with requirement on: '{1}'" msgid "malformed requirements imbrication detected for option: '{0}' with requirement on: '{1}'"
msgstr "" msgstr ""
#: tiramisu/setting.py:612 #: tiramisu/setting.py:616
msgid "option '{0}' has requirement's property error: {1} {2}" msgid "option '{0}' has requirement's property error: {1} {2}"
msgstr "" msgstr ""
@ -524,51 +528,51 @@ msgstr ""
msgid "a dictionary cannot be persistent" msgid "a dictionary cannot be persistent"
msgstr "" msgstr ""
#: tiramisu/value.py:339 #: tiramisu/value.py:356
msgid "no value for {0} cannot change owner to {1}" msgid "no value for {0} cannot change owner to {1}"
msgstr "" msgstr ""
#: tiramisu/value.py:421 #: tiramisu/value.py:438
msgid "can force cache only if cache is actived in config" msgid "can force cache only if cache is actived in config"
msgstr "" msgstr ""
#: tiramisu/value.py:460 #: tiramisu/value.py:477
msgid "{0} is already a Multi " msgid "{0} is already a Multi "
msgstr "" msgstr ""
#: tiramisu/value.py:496 tiramisu/value.py:560 #: tiramisu/value.py:513 tiramisu/value.py:577
msgid "invalid len for the slave: {0} which has {1} as master" msgid "invalid len for the slave: {0} which has {1} as master"
msgstr "" msgstr ""
#: tiramisu/value.py:532 #: tiramisu/value.py:549
msgid "cannot append a value on a multi option {0} which is a slave" msgid "cannot append a value on a multi option {0} which is a slave"
msgstr "" msgstr ""
#: tiramisu/value.py:570 #: tiramisu/value.py:587
msgid "cannot sort multi option {0} if master or slave" msgid "cannot sort multi option {0} if master or slave"
msgstr "" msgstr ""
#: tiramisu/value.py:574 #: tiramisu/value.py:591
msgid "cmp is not permitted in python v3 or greater" msgid "cmp is not permitted in python v3 or greater"
msgstr "" msgstr ""
#: tiramisu/value.py:583 #: tiramisu/value.py:600
msgid "cannot reverse multi option {0} if master or slave" msgid "cannot reverse multi option {0} if master or slave"
msgstr "" msgstr ""
#: tiramisu/value.py:591 #: tiramisu/value.py:608
msgid "cannot insert multi option {0} if master or slave" msgid "cannot insert multi option {0} if master or slave"
msgstr "" msgstr ""
#: tiramisu/value.py:599 #: tiramisu/value.py:616
msgid "cannot extend multi option {0} if master or slave" msgid "cannot extend multi option {0} if master or slave"
msgstr "" msgstr ""
#: tiramisu/value.py:610 #: tiramisu/value.py:627
msgid "invalid value {0} for option {1}: {2}" msgid "invalid value {0} for option {1}: {2}"
msgstr "" msgstr ""
#: tiramisu/value.py:628 #: tiramisu/value.py:645
msgid "cannot pop a value on a multi option {0} which is a slave" msgid "cannot pop a value on a multi option {0} which is a slave"
msgstr "" msgstr ""