Compare commits

...

8 Commits

29 changed files with 866 additions and 709 deletions

View File

@ -1,5 +1,15 @@
Mon Aug 21 14:24:42 2019 +0200 Emmanuel Garette <egarette@cadoles.com>
* version 3.0 rc12
* prefix metaconfig_prefix with current name
Mon Aug 19 08:02:27 2019 +0200 Emmanuel Garette <egarette@cadoles.com>
* version 3.0 rc11
* Config could have multiple parents
* todict works with Metaconfig
* separate Cache from values and settings
Fri Jul 26 09:43:03 2019 +0200 Emmanuel Garette <egarette@cadoles.com> Fri Jul 26 09:43:03 2019 +0200 Emmanuel Garette <egarette@cadoles.com>
* version 3.0 rc9 * version 3.0 rc9 and rc10
* better todict support (especially for leadership * better todict support (especially for leadership
* can add display_name method to Config init to change the name a * can add display_name method to Config init to change the name a
option in errors option in errors

View File

@ -1,17 +0,0 @@
[build-system]
requires = ["flit"]
build-backend = "flit.buildapi"
[tool.flit.metadata]
module = "tiramisu"
author = "Emmanuel Garette"
author-email = "gnunux@gnunux.info"
home-page = "https://framagit.org/tiramisu/tiramisu"
classifiers = [
"License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",
"Programming Language :: Python :: 3",
"Natural Language :: English",
"Natural Language :: French",
"Operating System :: OS Independent",
]
requires-python = ">=3.5"

View File

@ -1,8 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from setuptools import setup, find_packages from setuptools import setup, find_packages
from os.path import dirname, abspath, join, normpath, isdir
from os import listdir
import os import os
from tiramisu import __version__ from tiramisu import __version__
@ -17,6 +15,7 @@ setup(
description='an options controller tool', description='an options controller tool',
url='https://framagit.org/tiramisu/tiramisu', url='https://framagit.org/tiramisu/tiramisu',
license='GNU Library or Lesser General Public License (LGPL)', license='GNU Library or Lesser General Public License (LGPL)',
provides=['tiramisu_api'],
classifiers=[ classifiers=[
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)", "License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",

View File

@ -949,8 +949,6 @@ def autocheck_default_owner_with_value_permissive(cfg, mcfg, pathread, pathwrite
else: else:
assert cfg_.forcepermissive.option(pathread, 0).owner.isdefault() is True assert cfg_.forcepermissive.option(pathread, 0).owner.isdefault() is True
assert cfg_.forcepermissive.option(pathread, 1).owner.isdefault() is False assert cfg_.forcepermissive.option(pathread, 1).owner.isdefault() is False
#FIXME else:
# raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread).owner.isdefault()")
do(confwrite) do(confwrite)
if confwrite != confread: if confwrite != confread:
do(confread) do(confread)

42
tests/config.py Normal file
View File

@ -0,0 +1,42 @@
# from json import dumps, loads
try:
from tiramisu_api import Config
class TestConfig(Config):
def __init__(self,
config):
self.test_option = config.option
json = self.test_option.dict()
# assert json == loads(dumps(json))
super().__init__(json)
def send_data(self,
updates):
return self.updates_data(self.test_option.updates(updates))
PARAMS = ['tiramisu', 'tiramisu-api']
except:
PARAMS = ['tiramisu']
import pytest
def get_config(config, type, error=False):
if type == 'tiramisu':
return config
if error:
config.property.add('demoting_error_warning')
return TestConfig(config)
def value_list(values):
if values[0] == '':
del values[0]
return tuple(values)
def global_owner(config, config_type):
return config.owner.get()
@pytest.fixture(params=PARAMS)
def config_type(request):
return request.param

View File

@ -54,16 +54,16 @@ def test_cache_config():
def test_cache(): def test_cache():
od1 = make_description() od1 = make_description()
cfg = Config(od1) cfg = Config(od1)
values = cfg._config_bag.context.cfgimpl_get_values() values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context.cfgimpl_get_settings() settings = cfg._config_bag.context._impl_properties_cache
cfg.option('u1').value.get() cfg.option('u1').value.get()
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
cfg.option('u2').value.get() cfg.option('u2').value.get()
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
assert 'u2' in values._p_.get_cached() assert 'u2' in values.get_cached()
assert 'u2' in settings._p_.get_cached() assert 'u2' in settings.get_cached()
def test_cache_importation(): def test_cache_importation():
@ -105,171 +105,173 @@ def test_cache_importation_permissive():
def test_cache_reset(): def test_cache_reset():
od1 = make_description() od1 = make_description()
cfg = Config(od1) cfg = Config(od1)
values = cfg._config_bag.context.cfgimpl_get_values() values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context.cfgimpl_get_settings() settings = cfg._config_bag.context._impl_properties_cache
#when change a value #when change a value
cfg.option('u1').value.get() cfg.option('u1').value.get()
cfg.option('u2').value.get() cfg.option('u2').value.get()
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
assert 'u2' in values._p_.get_cached() assert 'u2' in values.get_cached()
assert 'u2' in settings._p_.get_cached() assert 'u2' in settings.get_cached()
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
cfg.option('u2').value.set(1) cfg.option('u2').value.set(1)
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
assert 'u2' not in values._p_.get_cached() assert 'u2' not in values.get_cached()
assert 'u2' not in settings._p_.get_cached() assert 'u2' not in settings.get_cached()
#when remove a value #when remove a value
cfg.option('u1').value.get() cfg.option('u1').value.get()
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
cfg.option('u2').value.reset() cfg.option('u2').value.reset()
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
assert 'u2' not in values._p_.get_cached() assert 'u2' not in values.get_cached()
assert 'u2' not in settings._p_.get_cached() assert 'u2' not in settings.get_cached()
#when add/del property #when add/del property
cfg.option('u1').value.get() cfg.option('u1').value.get()
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
cfg.option('u2').property.add('test') cfg.option('u2').property.add('test')
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
assert 'u2' not in values._p_.get_cached() assert 'u2' not in values.get_cached()
assert 'u2' not in settings._p_.get_cached() assert 'u2' not in settings.get_cached()
cfg.option('u1').value.get() cfg.option('u1').value.get()
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
cfg.option('u2').property.pop('test') cfg.option('u2').property.pop('test')
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
assert 'u2' not in values._p_.get_cached() assert 'u2' not in values.get_cached()
assert 'u2' not in settings._p_.get_cached() assert 'u2' not in settings.get_cached()
#when enable/disabled property #when enable/disabled property
cfg.option('u1').value.get() cfg.option('u1').value.get()
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
cfg.property.add('test') cfg.property.add('test')
assert 'u1' not in values._p_.get_cached() assert 'u1' not in values.get_cached()
assert 'u1' not in settings._p_.get_cached() assert 'u1' not in settings.get_cached()
cfg.option('u1').value.get() cfg.option('u1').value.get()
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
cfg.property.pop('test') cfg.property.pop('test')
assert 'u1' not in values._p_.get_cached() assert 'u1' not in values.get_cached()
assert 'u1' not in settings._p_.get_cached() assert 'u1' not in settings.get_cached()
def test_cache_reset_multi(): def test_cache_reset_multi():
od1 = make_description() od1 = make_description()
cfg = Config(od1) cfg = Config(od1)
values = cfg._config_bag.context.cfgimpl_get_values() values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context.cfgimpl_get_settings() settings = cfg._config_bag.context._impl_properties_cache
cfg.option('u1').value.get() cfg.option('u1').value.get()
cfg.option('u3').value.get() cfg.option('u3').value.get()
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
assert 'u3' in values._p_.get_cached() assert 'u3' in values.get_cached()
assert 'u3' in settings._p_.get_cached() assert 'u3' in settings.get_cached()
#when change a value #when change a value
cfg.option('u3').value.set([1]) cfg.option('u3').value.set([1])
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
assert 'u3' not in values._p_.get_cached() assert 'u3' not in values.get_cached()
assert 'u3' not in settings._p_.get_cached() assert 'u3' not in settings.get_cached()
#when append value #when append value
cfg.option('u1').value.get() cfg.option('u1').value.get()
cfg.option('u3').value.get() cfg.option('u3').value.get()
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
assert 'u3' in values._p_.get_cached() assert 'u3' in values.get_cached()
assert 'u3' in settings._p_.get_cached() assert 'u3' in settings.get_cached()
cfg.option('u3').value.set([1, 1]) cfg.option('u3').value.set([1, 1])
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
assert 'u3' not in values._p_.get_cached() assert 'u3' not in values.get_cached()
assert 'u3' not in settings._p_.get_cached() assert 'u3' not in settings.get_cached()
#when pop value #when pop value
cfg.option('u1').value.get() cfg.option('u1').value.get()
cfg.option('u3').value.get() cfg.option('u3').value.get()
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
assert 'u3' in values._p_.get_cached() assert 'u3' in values.get_cached()
assert 'u3' in settings._p_.get_cached() assert 'u3' in settings.get_cached()
cfg.option('u3').value.set([1]) cfg.option('u3').value.set([1])
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
assert 'u3' not in values._p_.get_cached() assert 'u3' not in values.get_cached()
assert 'u3' not in settings._p_.get_cached() assert 'u3' not in settings.get_cached()
#when remove a value #when remove a value
cfg.option('u1').value.get() cfg.option('u1').value.get()
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
cfg.option('u3').value.reset() cfg.option('u3').value.reset()
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
assert 'u3' not in values._p_.get_cached() assert 'u3' not in values.get_cached()
assert 'u3' not in settings._p_.get_cached() assert 'u3' not in settings.get_cached()
def test_reset_cache(): def test_reset_cache():
od1 = make_description() od1 = make_description()
cfg = Config(od1) cfg = Config(od1)
values = cfg._config_bag.context.cfgimpl_get_values() values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context.cfgimpl_get_settings() settings = cfg._config_bag.context._impl_properties_cache
cfg.option('u1').value.get() cfg.option('u1').value.get()
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
cfg.cache.reset() cfg.cache.reset()
assert 'u1' not in values._p_.get_cached() assert 'u1' not in values.get_cached()
assert 'u1' not in settings._p_.get_cached() assert 'u1' not in settings.get_cached()
cfg.option('u1').value.get() cfg.option('u1').value.get()
cfg.option('u2').value.get() cfg.option('u2').value.get()
assert 'u1' in values._p_.get_cached() assert 'u1' in values.get_cached()
assert 'u1' in settings._p_.get_cached() assert 'u1' in settings.get_cached()
assert 'u2' in values._p_.get_cached() assert 'u2' in values.get_cached()
assert 'u2' in settings._p_.get_cached() assert 'u2' in settings.get_cached()
cfg.cache.reset() cfg.cache.reset()
assert 'u1' not in values._p_.get_cached() assert 'u1' not in values.get_cached()
assert 'u1' not in settings._p_.get_cached() assert 'u1' not in settings.get_cached()
assert 'u2' not in values._p_.get_cached() assert 'u2' not in values.get_cached()
assert 'u2' not in settings._p_.get_cached() assert 'u2' not in settings.get_cached()
def test_cache_not_cache(): def test_cache_not_cache():
od1 = make_description() od1 = make_description()
cfg = Config(od1) cfg = Config(od1)
values = cfg._config_bag.context.cfgimpl_get_values() values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context.cfgimpl_get_settings() settings = cfg._config_bag.context._impl_properties_cache
cfg.property.pop('cache') cfg.property.pop('cache')
cfg.option('u1').value.get() cfg.option('u1').value.get()
assert 'u1' not in values._p_.get_cached() assert 'u1' not in values.get_cached()
assert 'u1' not in settings._p_.get_cached() assert 'u1' not in settings.get_cached()
def test_cache_leadership(): def test_cache_leadership():
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True) ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
maconfig = OptionDescription('toto', '', [interface1]) od1 = OptionDescription('toto', '', [interface1])
cfg = Config(maconfig) cfg = Config(od1)
cfg.property.read_write() cfg.property.read_write()
assert cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached() == {} values = cfg._config_bag.context._impl_values_cache
#assert cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached() == {} settings = cfg._config_bag.context._impl_properties_cache
assert values.get_cached() == {}
#assert settings.get_cached() == {}
# #
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2']) cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2'])
cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()
cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()
cache = cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached() cache = values.get_cached()
assert set(cache.keys()) == set(['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0']) assert set(cache.keys()) == set(['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None]) assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
assert cache['ip_admin_eth0.ip_admin_eth0'][None][0] == ['192.168.1.2'] assert cache['ip_admin_eth0.ip_admin_eth0'][None][0] == ['192.168.1.2']
#assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([None]) #assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([None])
#assert cache['ip_admin_eth0.netmask_admin_eth0'][None][0] == [None] #assert cache['ip_admin_eth0.netmask_admin_eth0'][None][0] == [None]
#assert cache['ip_admin_eth0.netmask_admin_eth0'][0][0] is None #assert cache['ip_admin_eth0.netmask_admin_eth0'][0][0] is None
cache = cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached() cache = settings.get_cached()
assert set(cache.keys()) == set([None, 'ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0']) assert set(cache.keys()) == set([None, 'ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
assert set(cache['ip_admin_eth0'].keys()) == set([None]) assert set(cache['ip_admin_eth0'].keys()) == set([None])
assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None]) assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
@ -279,7 +281,7 @@ def test_cache_leadership():
cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()
cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()
cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get()
cache = cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached() cache = values.get_cached()
assert set(cache.keys()) == set(['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0']) assert set(cache.keys()) == set(['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None]) assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
assert cache['ip_admin_eth0.ip_admin_eth0'][None][0] == ['192.168.1.2', '192.168.1.1'] assert cache['ip_admin_eth0.ip_admin_eth0'][None][0] == ['192.168.1.2', '192.168.1.1']
@ -287,7 +289,7 @@ def test_cache_leadership():
#assert cache['ip_admin_eth0.netmask_admin_eth0'][None][0] == [None, None] #assert cache['ip_admin_eth0.netmask_admin_eth0'][None][0] == [None, None]
#assert cache['ip_admin_eth0.netmask_admin_eth0'][0][0] is None #assert cache['ip_admin_eth0.netmask_admin_eth0'][0][0] is None
#assert cache['ip_admin_eth0.netmask_admin_eth0'][1][0] is None #assert cache['ip_admin_eth0.netmask_admin_eth0'][1][0] is None
cache = cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached() cache = settings.get_cached()
assert set(cache.keys()) == set([None, 'ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0']) assert set(cache.keys()) == set([None, 'ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
assert set(cache['ip_admin_eth0'].keys()) == set([None]) assert set(cache['ip_admin_eth0'].keys()) == set([None])
assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None]) assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
@ -314,83 +316,85 @@ def test_cache_callback():
val3 = StrOption('val3', "", callback=return_value, callback_params=Params((ParamValue('yes'),))) val3 = StrOption('val3', "", callback=return_value, callback_params=Params((ParamValue('yes'),)))
val4 = StrOption('val4', "", callback=return_value, callback_params=Params(kwargs={'value': ParamOption(val1)})) val4 = StrOption('val4', "", callback=return_value, callback_params=Params(kwargs={'value': ParamOption(val1)}))
val5 = StrOption('val5', "", callback=return_value, callback_params=Params(kwargs={'value': ParamValue('yes')}), multi=True) val5 = StrOption('val5', "", callback=return_value, callback_params=Params(kwargs={'value': ParamValue('yes')}), multi=True)
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3, val4, val5]) od1 = OptionDescription('rootconfig', '', [val1, val2, val3, val4, val5])
cfg = Config(maconfig) cfg = Config(od1)
cfg.property.read_write() cfg.property.read_write()
cfg.value.dict() cfg.value.dict()
#assert cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)}, values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache
#assert settings.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
# 'val1': {None: (set([]), None)}} # 'val1': {None: (set([]), None)}}
compare(cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached(), {'val1': {None: ('val', None)}, compare(values.get_cached(), {'val1': {None: ('val', None)},
'val2': {None: ('val', None)}, 'val2': {None: ('val', None)},
'val3': {None: ('yes', None)}, 'val3': {None: ('yes', None)},
'val4': {None: ('val', None)}, 'val4': {None: ('val', None)},
'val5': {None: (['yes'], None)}}) 'val5': {None: (['yes'], None)}})
cfg.option('val1').value.set('new') cfg.option('val1').value.set('new')
#assert cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)}, #assert settings.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
# 'val1': {None: (set([]), None)}} # 'val1': {None: (set([]), None)}}
compare(cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached(), {'val3': {None: ('yes', None)}, compare(values.get_cached(), {'val3': {None: ('yes', None)},
'val5': {None: (['yes'], None)}}) 'val5': {None: (['yes'], None)}})
cfg.value.dict() cfg.value.dict()
#assert cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)}, #assert settings.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
# 'val1': {None: (set([]), None)}} # 'val1': {None: (set([]), None)}}
compare(cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached(), {'val1': {None: ('new', None)}, compare(values.get_cached(), {'val1': {None: ('new', None)},
'val2': {None: ('new', None)}, 'val2': {None: ('new', None)},
'val3': {None: ('yes', None)}, 'val3': {None: ('yes', None)},
'val4': {None: ('new', None)}, 'val4': {None: ('new', None)},
'val5': {None: (['yes'], None)}}) 'val5': {None: (['yes'], None)}})
cfg.option('val3').value.set('new2') cfg.option('val3').value.set('new2')
#assert cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)}, #assert settings.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
# 'val1': {None: (set([]), None)}, # 'val1': {None: (set([]), None)},
# 'val3': {None: (set([]), None)}} # 'val3': {None: (set([]), None)}}
compare(cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached(), {'val1': {None: ('new', None)}, compare(values.get_cached(), {'val1': {None: ('new', None)},
'val2': {None: ('new', None)}, 'val2': {None: ('new', None)},
'val4': {None: ('new', None)}, 'val4': {None: ('new', None)},
'val5': {None: (['yes'], None)}}) 'val5': {None: (['yes'], None)}})
cfg.value.dict() cfg.value.dict()
#assert cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)}, #assert settings.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
# 'val1': {None: (set([]), None)}, # 'val1': {None: (set([]), None)},
# 'val3': {None: (set([]), None)}} # 'val3': {None: (set([]), None)}}
compare(cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached(), {'val1': {None: ('new', None)}, compare(values.get_cached(), {'val1': {None: ('new', None)},
'val2': {None: ('new', None)}, 'val2': {None: ('new', None)},
'val3': {None: ('new2', None)}, 'val3': {None: ('new2', None)},
'val4': {None: ('new', None)}, 'val4': {None: ('new', None)},
'val5': {None: (['yes'], None)}}) 'val5': {None: (['yes'], None)}})
cfg.option('val4').value.set('new3') cfg.option('val4').value.set('new3')
#assert cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)}, #assert settings.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
# 'val1': {None: (set([]), None)}, # 'val1': {None: (set([]), None)},
# 'val3': {None: (set([]), None)}, # 'val3': {None: (set([]), None)},
# 'val4': {None: (set([]), None)}} # 'val4': {None: (set([]), None)}}
compare(cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached(), {'val1': {None: ('new', None)}, compare(values.get_cached(), {'val1': {None: ('new', None)},
'val2': {None: ('new', None)}, 'val2': {None: ('new', None)},
'val3': {None: ('new2', None)}, 'val3': {None: ('new2', None)},
'val5': {None: (['yes'], None)}}) 'val5': {None: (['yes'], None)}})
cfg.value.dict() cfg.value.dict()
#assert cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)}, #assert settings.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
# 'val1': {None: (set([]), None)}, # 'val1': {None: (set([]), None)},
# 'val3': {None: (set([]), None)}, # 'val3': {None: (set([]), None)},
# 'val4': {None: (set([]), None)}} # 'val4': {None: (set([]), None)}}
compare(cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached(), {'val1': {None: ('new', None)}, compare(values.get_cached(), {'val1': {None: ('new', None)},
'val2': {None: ('new', None)}, 'val2': {None: ('new', None)},
'val3': {None: ('new2', None)}, 'val3': {None: ('new2', None)},
'val4': {None: ('new3', None)}, 'val4': {None: ('new3', None)},
'val5': {None: (['yes'], None)}}) 'val5': {None: (['yes'], None)}})
cfg.option('val5').value.set([undefined, 'new4']) cfg.option('val5').value.set([undefined, 'new4'])
#assert cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)}, #assert settings.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
# 'val1': {None: (set([]), None)}, # 'val1': {None: (set([]), None)},
# 'val3': {None: (set([]), None)}, # 'val3': {None: (set([]), None)},
# 'val4': {None: (set([]), None)}, # 'val4': {None: (set([]), None)},
# 'val5': {None: (set(['empty']), None)}} # 'val5': {None: (set(['empty']), None)}}
compare(cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached(), {'val1': {None: ('new', None)}, compare(values.get_cached(), {'val1': {None: ('new', None)},
'val2': {None: ('new', None)}, 'val2': {None: ('new', None)},
'val3': {None: ('new2', None)}, 'val3': {None: ('new2', None)},
'val4': {None: ('new3', None)}}) 'val4': {None: ('new3', None)}})
cfg.value.dict() cfg.value.dict()
#assert cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)}, #assert settings.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
# 'val1': {None: (set([]), None)}, # 'val1': {None: (set([]), None)},
# 'val3': {None: (set([]), None)}, # 'val3': {None: (set([]), None)},
# 'val4': {None: (set([]), None)}, # 'val4': {None: (set([]), None)},
# 'val5': {None: (set(['empty']), None)}} # 'val5': {None: (set(['empty']), None)}}
compare(cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached(), {'val1': {None: ('new', None)}, compare(values.get_cached(), {'val1': {None: ('new', None)},
'val2': {None: ('new', None)}, 'val2': {None: ('new', None)},
'val3': {None: ('new2', None)}, 'val3': {None: ('new2', None)},
'val4': {None: ('new3', None)}, 'val4': {None: ('new3', None)},
@ -401,8 +405,8 @@ def test_cache_leader_and_followers():
val1 = StrOption('val1', "", multi=True) val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True) val2 = StrOption('val2', "", multi=True)
interface1 = Leadership('val1', '', [val1, val2]) interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1]) od1 = OptionDescription('rootconfig', '', [interface1])
cfg = Config(maconfig) cfg = Config(od1)
cfg.property.read_write() cfg.property.read_write()
cfg.value.dict() cfg.value.dict()
global_props = ['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value'] global_props = ['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']
@ -415,42 +419,44 @@ def test_cache_leader_and_followers():
val1_val2_props = frozenset(val1_val2_props) val1_val2_props = frozenset(val1_val2_props)
#None because no value #None because no value
idx_val2 = None idx_val2 = None
compare(cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached(), {None: {None: (global_props, None)}, values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache
compare(settings.get_cached(), {None: {None: (global_props, None)},
'val1': {None: (val1_props, None)}, 'val1': {None: (val1_props, None)},
'val1.val1': {None: (val1_val1_props, None)}, 'val1.val1': {None: (val1_val1_props, None)},
'val1.val2': {idx_val2: (val1_val2_props, None)}}) 'val1.val2': {idx_val2: (val1_val2_props, None)}})
# len is 0 so don't get any value # len is 0 so don't get any value
compare(cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached(), {'val1.val1': {None: ([], None)}}) compare(values.get_cached(), {'val1.val1': {None: ([], None)}})
# #
cfg.option('val1.val1').value.set([undefined]) cfg.option('val1.val1').value.set([undefined])
compare(cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached(), {None: {None: (set(global_props), None)}}) compare(settings.get_cached(), {None: {None: (set(global_props), None)}})
assert cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached() == {} assert values.get_cached() == {}
cfg.value.dict() cfg.value.dict()
#has value #has value
idx_val2 = 0 idx_val2 = 0
val_val2 = None val_val2 = None
val_val2_props = {idx_val2: (val1_val2_props, None), None: (set(), None)} val_val2_props = {idx_val2: (val1_val2_props, None), None: (set(), None)}
compare(cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached(), {None: {None: (global_props, None)}, compare(settings.get_cached(), {None: {None: (global_props, None)},
'val1': {None: (val1_props, None)}, 'val1': {None: (val1_props, None)},
'val1.val1': {None: (val1_val1_props, None)}, 'val1.val1': {None: (val1_val1_props, None)},
'val1.val2': val_val2_props}) 'val1.val2': val_val2_props})
compare(cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached(), {'val1.val1': {None: ([None], None)}, compare(values.get_cached(), {'val1.val1': {None: ([None], None)},
'val1.val2': {idx_val2: (val_val2, None)}}) 'val1.val2': {idx_val2: (val_val2, None)}})
cfg.option('val1.val1').value.set([undefined, undefined]) cfg.option('val1.val1').value.set([undefined, undefined])
cfg.value.dict() cfg.value.dict()
cfg.option('val1.val2', 1).value.set('oui') cfg.option('val1.val2', 1).value.set('oui')
compare(cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}}) compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}})
assert cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached() == {} assert values.get_cached() == {}
val1_val2_props = {0: (frozenset([]), None), 1: (frozenset([]), None)} val1_val2_props = {0: (frozenset([]), None), 1: (frozenset([]), None)}
#assert cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached() == {None: {None: (global_props, None)}, #assert settings.get_cached() == {None: {None: (global_props, None)},
# 'val1': {None: (val1_props, None)}, # 'val1': {None: (val1_props, None)},
# 'val1.val1': {None: (val1_val1_props, None)}, # 'val1.val1': {None: (val1_val1_props, None)},
# 'val1.val2': val1_val2_props} # 'val1.val2': val1_val2_props}
#if TIRAMISU_VERSION == 2: #if TIRAMISU_VERSION == 2:
# assert cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached() == {'val1.val1': {None: ([None, None], None)}, # assert values.get_cached() == {'val1.val1': {None: ([None, None], None)},
# 'val1.val2': {None: ([None, 'oui'], None)}} # 'val1.val2': {None: ([None, 'oui'], None)}}
#else: #else:
# assert cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached() == {'val1.val1': {None: ([None, None], None)}, # assert values.get_cached() == {'val1.val1': {None: ([None, None], None)},
# 'val1.val2': {0: (None, None), 1: ('oui', None)}} # 'val1.val2': {0: (None, None), 1: ('oui', None)}}
@ -458,8 +464,8 @@ def test_cache_leader_callback():
val1 = StrOption('val1', "", multi=True) val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params=Params(kwargs={'value': ParamOption(val1)})) val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params=Params(kwargs={'value': ParamOption(val1)}))
interface1 = Leadership('val1', '', [val1, val2]) interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1]) od1 = OptionDescription('rootconfig', '', [interface1])
cfg = Config(maconfig) cfg = Config(od1)
cfg.property.read_write() cfg.property.read_write()
cfg.value.dict() cfg.value.dict()
global_props = ['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value'] global_props = ['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']
@ -470,19 +476,21 @@ def test_cache_leader_callback():
val1_props = frozenset(val1_props) val1_props = frozenset(val1_props)
val1_val1_props = frozenset(val1_val1_props) val1_val1_props = frozenset(val1_val1_props)
val1_val2_props = frozenset(val1_val2_props) val1_val2_props = frozenset(val1_val2_props)
compare(cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached(), {None: {None: (global_props, None)}, values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache
compare(settings.get_cached(), {None: {None: (global_props, None)},
'val1': {None: (val1_props, None)}, 'val1': {None: (val1_props, None)},
'val1.val1': {None: (val1_val1_props, None)}, 'val1.val1': {None: (val1_val1_props, None)},
'val1.val2': {None: (val1_val2_props, None)}}) 'val1.val2': {None: (val1_val2_props, None)}})
compare(cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached(), {'val1.val1': {None: ([], None)}}) compare(values.get_cached(), {'val1.val1': {None: ([], None)}})
cfg.option('val1.val1').value.set([undefined]) cfg.option('val1.val1').value.set([undefined])
compare(cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached(), {None: {None: (set(global_props), None)}}) compare(settings.get_cached(), {None: {None: (set(global_props), None)}})
assert cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached() == {} assert values.get_cached() == {}
cfg.value.dict() cfg.value.dict()
#FIXMEassert cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)}, #FIXMEassert settings.get_cached() == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)},
# 'val1': {None: (set([]), None)}} # 'val1': {None: (set([]), None)}}
#FIXMEassert cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached() == {'val1.val1': {None: ([None], None)}, #FIXMEassert values.get_cached() == {'val1.val1': {None: ([None], None)},
# 'val1.val2': {None: ([None], None)} # 'val1.val2': {None: ([None], None)}
# } # }
@ -494,43 +502,45 @@ def test_cache_requires():
od = OptionDescription('service', '', [a, b]) od = OptionDescription('service', '', [a, b])
cfg = Config(od) cfg = Config(od)
cfg.property.read_write() cfg.property.read_write()
assert cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached() == {} values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache
assert values.get_cached() == {}
assert cfg.option('ip_address_service').value.get() == None assert cfg.option('ip_address_service').value.get() == None
compare(cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}, compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
'activate_service': {None: (set([]), None)}, 'activate_service': {None: (set([]), None)},
'ip_address_service': {None: (set([]), None)}}) 'ip_address_service': {None: (set([]), None)}})
compare(cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached(), {'ip_address_service': {None: (None, None)}, compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
'activate_service': {None: (True, None)}}) 'activate_service': {None: (True, None)}})
cfg.value.dict() cfg.value.dict()
compare(cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}, compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
'activate_service': {None: (set([]), None)}, 'activate_service': {None: (set([]), None)},
'ip_address_service': {None: (set([]), None)}}) 'ip_address_service': {None: (set([]), None)}})
compare(cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached(), {'ip_address_service': {None: (None, None)}, compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
'activate_service': {None: (True, None)}}) 'activate_service': {None: (True, None)}})
cfg.option('ip_address_service').value.set('1.1.1.1') cfg.option('ip_address_service').value.set('1.1.1.1')
compare(cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}, compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
'activate_service': {None: (set([]), None)}}) 'activate_service': {None: (set([]), None)}})
compare(cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached(), {'activate_service': {None: (True, None)}}) compare(values.get_cached(), {'activate_service': {None: (True, None)}})
cfg.value.dict() cfg.value.dict()
compare(cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}, compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
'activate_service': {None: (set([]), None)}, 'activate_service': {None: (set([]), None)},
'ip_address_service': {None: (set([]), None)}}) 'ip_address_service': {None: (set([]), None)}})
compare(cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached(), {'ip_address_service': {None: ('1.1.1.1', None)}, compare(values.get_cached(), {'ip_address_service': {None: ('1.1.1.1', None)},
'activate_service': {None: (True, None)}}) 'activate_service': {None: (True, None)}})
cfg.option('activate_service').value.set(False) cfg.option('activate_service').value.set(False)
compare(cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}}) compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}})
assert cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached() == {} assert values.get_cached() == {}
cfg.value.dict() cfg.value.dict()
compare(cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}, compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
'activate_service': {None: (set([]), None)}, 'activate_service': {None: (set([]), None)},
'ip_address_service': {None: (set(['disabled']), None)}}) 'ip_address_service': {None: (set(['disabled']), None)}})
compare(cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached(), {'activate_service': {None: (False, None)}}) compare(values.get_cached(), {'activate_service': {None: (False, None)}})
def test_cache_global_properties(): def test_cache_global_properties():
@ -540,22 +550,24 @@ def test_cache_global_properties():
od = OptionDescription('service', '', [a, b]) od = OptionDescription('service', '', [a, b])
cfg = Config(od) cfg = Config(od)
cfg.property.read_write() cfg.property.read_write()
assert cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached() == {} values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache
assert values.get_cached() == {}
assert cfg.option('ip_address_service').value.get() == None assert cfg.option('ip_address_service').value.get() == None
compare(cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}, compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
'activate_service': {None: (set([]), None)}, 'activate_service': {None: (set([]), None)},
'ip_address_service': {None: (set([]), None)}}) 'ip_address_service': {None: (set([]), None)}})
compare(cfg._config_bag.context.cfgimpl_get_values()._p_.get_cached(), {'ip_address_service': {None: (None, None)}, compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
'activate_service': {None: (True, None)}}) 'activate_service': {None: (True, None)}})
cfg.property.pop('disabled') cfg.property.pop('disabled')
assert cfg.option('ip_address_service').value.get() == None assert cfg.option('ip_address_service').value.get() == None
compare(cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached(), {None: {None: (set(['cache', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}, compare(settings.get_cached(), {None: {None: (set(['cache', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
'activate_service': {None: (set([]), None)}, 'activate_service': {None: (set([]), None)},
'ip_address_service': {None: (set([]), None)}}) 'ip_address_service': {None: (set([]), None)}})
cfg.property.add('test') cfg.property.add('test')
assert cfg.option('ip_address_service').value.get() == None assert cfg.option('ip_address_service').value.get() == None
compare(cfg._config_bag.context.cfgimpl_get_settings()._p_.get_cached(), {None: {None: (set(['cache', 'frozen', 'hidden', 'validator', 'warnings', 'test', 'force_store_value']), None)}, compare(settings.get_cached(), {None: {None: (set(['cache', 'frozen', 'hidden', 'validator', 'warnings', 'test', 'force_store_value']), None)},
'activate_service': {None: (set([]), None)}, 'activate_service': {None: (set([]), None)},
'ip_address_service': {None: (set([]), None)}}) 'ip_address_service': {None: (set([]), None)}})
@ -563,8 +575,8 @@ def test_cache_global_properties():
def test_callback_value_incr(): def test_callback_value_incr():
val1 = IntOption('val1', "", callback=return_incr, properties=('expire',)) val1 = IntOption('val1', "", callback=return_incr, properties=('expire',))
val2 = IntOption('val2', "", callback=return_value, callback_params=Params(kwargs={'value': ParamOption(val1)})) val2 = IntOption('val2', "", callback=return_value, callback_params=Params(kwargs={'value': ParamOption(val1)}))
maconfig = OptionDescription('rootconfig', '', [val1, val2]) od1 = OptionDescription('rootconfig', '', [val1, val2])
cfg = Config(maconfig) cfg = Config(od1)
assert cfg.cache.get_expiration_time() == 5 assert cfg.cache.get_expiration_time() == 5
cfg.cache.set_expiration_time(1) cfg.cache.set_expiration_time(1)
assert cfg.cache.get_expiration_time() == 1 assert cfg.cache.get_expiration_time() == 1

View File

@ -8,6 +8,7 @@ from tiramisu import IntOption, StrOption, NetworkOption, NetmaskOption, BoolOpt
Params, ParamOption, ParamValue Params, ParamOption, ParamValue
from tiramisu.error import ConfigError, ConflictError, PropertiesOptionError, LeadershipError, APIError from tiramisu.error import ConfigError, ConflictError, PropertiesOptionError, LeadershipError, APIError
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
from .config import config_type, get_config
def teardown_function(function): def teardown_function(function):
@ -76,8 +77,6 @@ def test_path():
assert meta.config('conf2').config.path() == 'meta.conf2' assert meta.config('conf2').config.path() == 'meta.conf2'
#FIXME ne pas mettre 2 meta dans une config
#FIXME ne pas mettre 2 OD differents dans un meta
def test_none(): def test_none():
meta = make_metaconfig() meta = make_metaconfig()
assert meta.option('od1.i3').value.get() is meta.config('conf1').option('od1.i3').value.get() is meta.config('conf2').option('od1.i3').value.get() is None assert meta.option('od1.i3').value.get() is meta.config('conf1').option('od1.i3').value.get() is meta.config('conf2').option('od1.i3').value.get() is None
@ -112,10 +111,13 @@ def test_none():
assert meta.config(None).config.name() == meta.config.name() assert meta.config(None).config.name() == meta.config.name()
def test_reset(): def test_metaconfig_reset(config_type):
meta = make_metaconfig() meta = make_metaconfig()
assert meta.option('od1.i2').value.get() == 1 meta_api = get_config(meta, config_type)
meta.option('od1.i2').value.set(2) assert meta_api.option('od1.i2').value.get() == 1
meta_api.option('od1.i2').value.set(2)
if config_type == 'tiramisu-api':
meta_api.send()
meta.config('conf1').option('od1.i2').value.set(3) meta.config('conf1').option('od1.i2').value.set(3)
assert meta.option('od1.i2').value.get() == 2 assert meta.option('od1.i2').value.get() == 2
assert meta.config('conf1').option('od1.i2').value.get() == 3 assert meta.config('conf1').option('od1.i2').value.get() == 3
@ -291,8 +293,8 @@ def test_meta_add_config_readd():
config = Config(od, session_id='new') config = Config(od, session_id='new')
# #
meta.config.add(config) meta.config.add(config)
# meta2.config.add(config)
raises(ConflictError, "meta2.config.add(config)") assert len(list(config.config.parents())) == 2
def test_meta_new_config_wrong_name(): def test_meta_new_config_wrong_name():
@ -427,7 +429,11 @@ def test_meta_unconsistent():
meta.owner.set(owners.meta1) meta.owner.set(owners.meta1)
raises(TypeError, 'MetaConfig("string")') raises(TypeError, 'MetaConfig("string")')
#same descr but conf1 already in meta #same descr but conf1 already in meta
raises(ValueError, "MetaConfig([conf1, conf3])") assert len(list(conf1.config.parents())) == 1
assert len(list(conf3.config.parents())) == 0
new_meta = MetaConfig([conf1, conf3])
assert len(list(conf1.config.parents())) == 2
assert len(list(conf3.config.parents())) == 1
#not same descr #not same descr
raises(ValueError, "MetaConfig([conf3, conf4])") raises(ValueError, "MetaConfig([conf3, conf4])")
@ -458,7 +464,7 @@ def test_meta_leadership():
assert conf2._config_bag.context == next(itr)._config_bag.context assert conf2._config_bag.context == next(itr)._config_bag.context
def test_meta_leadership_value2(): def test_meta_leadership_value():
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',))
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
@ -466,21 +472,28 @@ def test_meta_leadership_value2():
conf1 = Config(od, session_id='conf1') conf1 = Config(od, session_id='conf1')
conf2 = Config(od, session_id='conf2') conf2 = Config(od, session_id='conf2')
meta = MetaConfig([conf1, conf2], session_id="meta") meta = MetaConfig([conf1, conf2], session_id="meta")
meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.8']) conf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.8'])
assert meta.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None assert conf1.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
#FIXME devrait raise ! assert meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0', 0).value.get() == None raises(APIError, "conf1.option('ip_admin_eth0.ip_admin_eth0', 0).value.get()")
# #
meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.reset() conf1.option('ip_admin_eth0.ip_admin_eth0').value.reset()
# #
meta.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) meta.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1'])
assert meta.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None assert conf1.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
meta.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.255.0') meta.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.255.0')
assert meta.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.255.0' assert conf1.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.255.0'
meta.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.0.0') meta.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.0.0')
assert meta.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0' assert conf1.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0'
# #
meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) conf1.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1'])
assert meta.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None assert conf1.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0'
#
meta.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.2.1', '192.168.3.1'])
meta.option('ip_admin_eth0.netmask_admin_eth0', 1).value.set('255.255.255.0')
#
assert conf1.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1']
assert conf1.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0'
def test_meta_leadership_value_default(): def test_meta_leadership_value_default():
@ -503,7 +516,7 @@ def test_meta_leadership_value_default():
assert meta.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0' assert meta.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0'
# #
meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1'])
assert meta.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None assert meta.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0'
def test_meta_leadership_owners(): def test_meta_leadership_owners():
@ -539,7 +552,7 @@ def test_meta_leadership_owners():
# #
meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1'])
assert meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.user assert meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.user
assert meta.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.default assert meta.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.meta1
def test_meta_force_default(): def test_meta_force_default():
@ -784,39 +797,54 @@ def test_meta_callback_follower():
interface1 = Leadership('val1', '', [val1, val3, val4]) interface1 = Leadership('val1', '', [val1, val3, val4])
od = OptionDescription('root', '', [interface1]) od = OptionDescription('root', '', [interface1])
maconfig = OptionDescription('rootconfig', '', [val, interface1]) maconfig = OptionDescription('rootconfig', '', [val, interface1])
cfg = Config(maconfig, session_id='cfg1') cfg1 = Config(maconfig, session_id='cfg1')
meta = MetaConfig([cfg]) meta = MetaConfig([cfg1])
meta.property.read_write() meta.property.read_write()
assert meta.config('cfg1').value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} assert cfg1.value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
meta.config('cfg1').option('val').value.set('val1') #
assert meta.config('cfg1').value.dict() == {'val1.val2': ['val1'], 'val1.val1': ['val1'], 'val1.val3': ['val1'], 'val': 'val1'} cfg1.option('val').value.set('val1')
meta.config('cfg1').option('val').value.reset() assert cfg1.value.dict() == {'val1.val2': ['val1'], 'val1.val1': ['val1'], 'val1.val3': ['val1'], 'val': 'val1'}
#
cfg1.option('val').value.reset()
meta.option('val').value.set('val1') meta.option('val').value.set('val1')
assert meta.config('cfg1').value.dict() == {'val1.val2': ['val1'], 'val1.val1': ['val1'], 'val1.val3': ['val1'], 'val': 'val1'} assert cfg1.value.dict() == {'val1.val2': ['val1'], 'val1.val1': ['val1'], 'val1.val3': ['val1'], 'val': 'val1'}
#
meta.option('val').value.reset() meta.option('val').value.reset()
meta.config('cfg1').option('val1.val2', 0).value.set('val2') cfg1.option('val1.val2', 0).value.set('val2')
assert meta.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} assert cfg1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
meta.config('cfg1').option('val1.val2', 0).value.reset() #
assert meta.config('cfg1').value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} cfg1.option('val1.val2', 0).value.reset()
assert cfg1.value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
#
meta.option('val1.val2', 0).value.set('val2') meta.option('val1.val2', 0).value.set('val2')
assert meta.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} assert cfg1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
meta.config('cfg1').option('val1.val3', 0).value.set('val6') #
assert meta.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val6'], 'val': 'val'} meta.option('val1.val1').value.set(['val'])
assert cfg1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
#
cfg1.option('val1.val3', 0).value.set('val6')
assert cfg1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val6'], 'val': 'val'}
#
meta.option('val1.val2', 0).value.reset() meta.option('val1.val2', 0).value.reset()
meta.config('cfg1').option('val1.val3', 0).value.reset() cfg1.option('val1.val3', 0).value.reset()
meta.config('cfg1').option('val1.val1').value.set(['val3']) cfg1.option('val1.val1').value.set(['val3'])
assert meta.config('cfg1').value.dict() == {'val1.val2': ['val3'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'} assert cfg1.value.dict() == {'val1.val2': ['val3'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'}
meta.config('cfg1').option('val1.val1').value.reset() #
assert meta.config('cfg1').value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} cfg1.option('val1.val1').value.reset()
assert cfg1.value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
#
meta.option('val1.val1').value.set(['val3']) meta.option('val1.val1').value.set(['val3'])
assert meta.config('cfg1').value.dict() == {'val1.val2': ['val3'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'} assert cfg1.value.dict() == {'val1.val2': ['val3'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'}
meta.config('cfg1').option('val1.val2', 0).value.set('val2') #
assert meta.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'} cfg1.option('val1.val2', 0).value.set('val2')
assert cfg1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'}
#
meta.option('val1.val1').value.set(['val3', 'rah']) meta.option('val1.val1').value.set(['val3', 'rah'])
assert meta.config('cfg1').value.dict() == {'val1.val2': ['val2', 'rah'], 'val1.val1': ['val3', 'rah'], 'val1.val3': ['val3', 'rah'], 'val': 'val'} assert cfg1.value.dict() == {'val1.val2': ['val2', 'rah'], 'val1.val1': ['val3', 'rah'], 'val1.val3': ['val3', 'rah'], 'val': 'val'}
#
meta.option('val1.val1').value.pop(1) meta.option('val1.val1').value.pop(1)
meta.option('val1.val1').value.set(['val4']) meta.option('val1.val1').value.set(['val4'])
assert meta.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val4'], 'val1.val3': ['val4'], 'val': 'val'} assert cfg1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val4'], 'val1.val3': ['val4'], 'val': 'val'}
def test_meta_reset(): def test_meta_reset():
@ -859,8 +887,13 @@ def test_meta_properties_meta_copy():
meta.property.read_write() meta.property.read_write()
conf3 = meta.config('conf1').config.copy(session_id='conf3') conf3 = meta.config('conf1').config.copy(session_id='conf3')
# old fashion
meta2 = conf3.config.metaconfig() meta2 = conf3.config.metaconfig()
assert meta.config.name() == meta2.config.name() assert meta.config.name() == meta2.config.name()
# new method
meta2 = list(conf3.config.parents())
assert len(meta2) == 1
assert meta.config.name() == meta2[0].config.name()
assert meta.config('conf1').value.dict() == {'ip_admin_eth0': ['192.168.1.1']} assert meta.config('conf1').value.dict() == {'ip_admin_eth0': ['192.168.1.1']}
assert meta.config('conf2').value.dict() == {'ip_admin_eth0': ['192.168.1.1']} assert meta.config('conf2').value.dict() == {'ip_admin_eth0': ['192.168.1.1']}

View File

@ -306,7 +306,11 @@ def test_mix_unconsistent():
mix.owner.set(owners.mix1) mix.owner.set(owners.mix1)
raises(TypeError, 'MixConfig(od2, "string")') raises(TypeError, 'MixConfig(od2, "string")')
# same descr but conf1 already in mix # same descr but conf1 already in mix
raises(ValueError, "MixConfig(od2, [conf1, conf3])") assert len(list(conf1.config.parents())) == 1
assert len(list(conf3.config.parents())) == 0
new_mix = MixConfig(od2, [conf1, conf3])
assert len(list(conf1.config.parents())) == 2
assert len(list(conf3.config.parents())) == 1
# not same descr # not same descr
MixConfig(od2, [conf3, conf4]) MixConfig(od2, [conf3, conf4])
@ -359,7 +363,7 @@ def test_mix_leadership_value2():
assert mix.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0' assert mix.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0'
# #
mix.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) mix.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1'])
assert mix.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None assert mix.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0'
def test_mix_leadership_value_default(): def test_mix_leadership_value_default():
@ -382,7 +386,7 @@ def test_mix_leadership_value_default():
assert mix.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0' assert mix.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0'
# #
mix.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) mix.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1'])
assert mix.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None assert mix.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0'
def test_mix_leadership_owners(): def test_mix_leadership_owners():
@ -418,7 +422,7 @@ def test_mix_leadership_owners():
# #
mix.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) mix.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1'])
assert mix.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.user assert mix.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.user
assert mix.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.default assert mix.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.mix1
def test_mix_force_default(): def test_mix_force_default():
@ -647,32 +651,47 @@ def test_mix_callback_follower():
mix = MixConfig(maconfig, [cfg]) mix = MixConfig(maconfig, [cfg])
mix.property.read_write() mix.property.read_write()
assert mix.config('cfg1').value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} assert mix.config('cfg1').value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
#
mix.config('cfg1').option('val').value.set('val1') mix.config('cfg1').option('val').value.set('val1')
assert mix.config('cfg1').value.dict() == {'val1.val2': ['val1'], 'val1.val1': ['val1'], 'val1.val3': ['val1'], 'val': 'val1'} assert mix.config('cfg1').value.dict() == {'val1.val2': ['val1'], 'val1.val1': ['val1'], 'val1.val3': ['val1'], 'val': 'val1'}
#
mix.config('cfg1').option('val').value.reset() mix.config('cfg1').option('val').value.reset()
mix.option('val').value.set('val1') mix.option('val').value.set('val1')
assert mix.config('cfg1').value.dict() == {'val1.val2': ['val1'], 'val1.val1': ['val1'], 'val1.val3': ['val1'], 'val': 'val1'} assert mix.config('cfg1').value.dict() == {'val1.val2': ['val1'], 'val1.val1': ['val1'], 'val1.val3': ['val1'], 'val': 'val1'}
#
mix.option('val').value.reset() mix.option('val').value.reset()
mix.config('cfg1').option('val1.val2', 0).value.set('val2') mix.config('cfg1').option('val1.val2', 0).value.set('val2')
assert mix.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} assert mix.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
#
mix.config('cfg1').option('val1.val2', 0).value.reset() mix.config('cfg1').option('val1.val2', 0).value.reset()
assert mix.config('cfg1').value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} assert mix.config('cfg1').value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
#
mix.option('val1.val2', 0).value.set('val2') mix.option('val1.val2', 0).value.set('val2')
assert mix.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} assert mix.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
#
mix.option('val1.val1').value.set(['val'])
assert mix.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
#
mix.config('cfg1').option('val1.val3', 0).value.set('val6') mix.config('cfg1').option('val1.val3', 0).value.set('val6')
assert mix.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val6'], 'val': 'val'} assert mix.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val6'], 'val': 'val'}
#
mix.option('val1.val2', 0).value.reset() mix.option('val1.val2', 0).value.reset()
mix.config('cfg1').option('val1.val3', 0).value.reset() mix.config('cfg1').option('val1.val3', 0).value.reset()
mix.config('cfg1').option('val1.val1').value.set(['val3']) mix.config('cfg1').option('val1.val1').value.set(['val3'])
assert mix.config('cfg1').value.dict() == {'val1.val2': ['val3'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'} assert mix.config('cfg1').value.dict() == {'val1.val2': ['val3'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'}
#
mix.config('cfg1').option('val1.val1').value.reset() mix.config('cfg1').option('val1.val1').value.reset()
assert mix.config('cfg1').value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} assert mix.config('cfg1').value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
#
mix.option('val1.val1').value.set(['val3']) mix.option('val1.val1').value.set(['val3'])
assert mix.config('cfg1').value.dict() == {'val1.val2': ['val3'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'} assert mix.config('cfg1').value.dict() == {'val1.val2': ['val3'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'}
#
mix.config('cfg1').option('val1.val2', 0).value.set('val2') mix.config('cfg1').option('val1.val2', 0).value.set('val2')
assert mix.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'} assert mix.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'}
#
mix.option('val1.val1').value.set(['val3', 'rah']) mix.option('val1.val1').value.set(['val3', 'rah'])
assert mix.config('cfg1').value.dict() == {'val1.val2': ['val2', 'rah'], 'val1.val1': ['val3', 'rah'], 'val1.val3': ['val3', 'rah'], 'val': 'val'} assert mix.config('cfg1').value.dict() == {'val1.val2': ['val2', 'rah'], 'val1.val1': ['val3', 'rah'], 'val1.val3': ['val3', 'rah'], 'val': 'val'}
#
mix.option('val1.val1').value.pop(1) mix.option('val1.val1').value.pop(1)
mix.option('val1.val1').value.set(['val4']) mix.option('val1.val1').value.set(['val4'])
assert mix.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val4'], 'val1.val3': ['val4'], 'val': 'val'} assert mix.config('cfg1').value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val4'], 'val1.val3': ['val4'], 'val': 'val'}
@ -732,8 +751,13 @@ def test_mix_properties_mix_copy():
mix.property.read_write() mix.property.read_write()
conf3 = mix.config('conf1').config.copy(session_id='conf3') conf3 = mix.config('conf1').config.copy(session_id='conf3')
# old fashion
mix2 = conf3.config.metaconfig() mix2 = conf3.config.metaconfig()
assert mix.config.name() == mix2.config.name() assert mix.config.name() == mix2.config.name()
# new method
mix2 = list(conf3.config.parents())
assert len(mix2) == 1
assert mix.config.name() == mix2[0].config.name()
assert mix.config('conf1').value.dict() == {'ip_admin_eth0': ['192.168.1.1']} assert mix.config('conf1').value.dict() == {'ip_admin_eth0': ['192.168.1.1']}
assert mix.config('conf2').value.dict() == {'ip_admin_eth0': ['192.168.1.1']} assert mix.config('conf2').value.dict() == {'ip_admin_eth0': ['192.168.1.1']}
@ -1121,7 +1145,8 @@ def test_mix_add_config_readd():
# #
config = Config(od, session_id='new') config = Config(od, session_id='new')
mix.config.add(config) mix.config.add(config)
raises(ConflictError, "mix2.config.add(config)") mix2.config.add(config)
assert len(list(config.config.parents())) == 2
def test_meta_new_mixconfig(): def test_meta_new_mixconfig():

View File

@ -0,0 +1,56 @@
from tiramisu import IntOption, OptionDescription, MetaConfig
def make_metaconfig():
i1 = IntOption('i1', '')
i2 = IntOption('i2', '', default=1)
i3 = IntOption('i3', '')
i4 = IntOption('i4', '', default=2)
i5 = IntOption('i5', '', default=[2], multi=True)
i6 = IntOption('i6', '', properties=('disabled',))
od1 = OptionDescription('od1', '', [i1, i2, i3, i4, i5, i6])
od2 = OptionDescription('od2', '', [od1])
return MetaConfig([], optiondescription=od2, session_id='metacfg1')
def test_multi_parents_path():
"""
metacfg1 (1) ---
| -- cfg1
metacfg2 (2) ---
"""
metacfg1 = make_metaconfig()
cfg1 = metacfg1.config.new(type='config', session_id="cfg1")
metacfg2 = MetaConfig([cfg1], session_id='metacfg2')
#
assert metacfg1.config.path() == 'metacfg1'
assert metacfg2.config.path() == 'metacfg2'
assert cfg1.config.path() == 'metacfg2.metacfg1.cfg1'
def test_multi_parents_value():
metacfg1 = make_metaconfig()
cfg1 = metacfg1.config.new(type='config', session_id="cfg1")
metacfg2 = MetaConfig([cfg1], session_id='metacfg2')
#
assert cfg1.option('od1.i1').value.get() == None
assert cfg1.option('od1.i2').value.get() == 1
assert cfg1.option('od1.i3').value.get() == None
#
assert metacfg1.option('od1.i1').value.get() == None
assert metacfg1.option('od1.i2').value.get() == 1
assert metacfg1.option('od1.i3').value.get() == None
#
assert metacfg2.option('od1.i1').value.get() == None
assert metacfg2.option('od1.i2').value.get() == 1
assert metacfg2.option('od1.i3').value.get() == None
#
metacfg1.option('od1.i3').value.set(3)
assert metacfg1.option('od1.i3').value.get() == 3
assert cfg1.option('od1.i3').value.get() == 3
assert metacfg2.option('od1.i2').value.get() == 1
#
metacfg2.option('od1.i2').value.set(4)
assert metacfg2.option('od1.i2').value.get() == 4
assert metacfg1.option('od1.i2').value.get() == 1
assert cfg1.option('od1.i2').value.get() == 4

View File

@ -45,4 +45,4 @@ allfuncs.extend(all_options)
del(all_options) del(all_options)
__all__ = tuple(allfuncs) __all__ = tuple(allfuncs)
del(allfuncs) del(allfuncs)
__version__ = "3.0rc9" __version__ = "3.0rc12"

View File

@ -171,6 +171,11 @@ class _TiramisuOptionOptionDescription(CommonTiramisuOption):
option = self._option_bag.option option = self._option_bag.option
return option.impl_get_display_name() return option.impl_get_display_name()
def description(self):
"""Get option description"""
option = self._option_bag.option
return option.impl_get_information('doc', None)
def name(self, def name(self,
follow_symlink: bool=False) -> str: follow_symlink: bool=False) -> str:
"""Get option name""" """Get option name"""
@ -340,17 +345,17 @@ class TiramisuOptionOwner(CommonTiramisuOption):
def get(self): def get(self):
"""Get owner for a specified option""" """Get owner for a specified option"""
option = self._option_bag.option self._option_bag.option
return self._values.getowner(self._option_bag) return self._values.getowner(self._option_bag)
def isdefault(self): def isdefault(self):
"""Is option has defaut value""" """Is option has defaut value"""
option = self._option_bag.option self._option_bag.option
return self._values.is_default_owner(self._option_bag) return self._values.is_default_owner(self._option_bag)
def set(self, owner): def set(self, owner):
"""Get owner for a specified option""" """Get owner for a specified option"""
option = self._option_bag.option self._option_bag.option
try: try:
obj_owner = getattr(owners, owner) obj_owner = getattr(owners, owner)
except AttributeError: except AttributeError:
@ -707,9 +712,29 @@ class _TiramisuOption(CommonTiramisu):
self._option_bag, self._option_bag,
config) config)
raise APIError(_('please specify a valid sub function ({})').format(subfunc)) # pragma: no cover raise APIError(_('please specify a valid sub function ({})').format(subfunc)) # pragma: no cover
#__________________________________________________________________________________________________
#
class _TiramisuOptionDescription(_TiramisuOption): class TiramisuConfig(TiramisuHelp):
def __init__(self,
config_bag: Optional[ConfigBag]) -> None:
self._config_bag = config_bag
def _return_config(self,
config):
if isinstance(config, KernelConfig):
return Config(config)
if isinstance(config, KernelMetaConfig):
return MetaConfig(config)
if isinstance(config, KernelMixConfig):
return MixConfig([], config)
if isinstance(config, KernelGroupConfig):
return GroupConfig(config)
raise Exception(_('unknown config type {}').format(type(config)))
class _TiramisuOptionDescription(_TiramisuOption, TiramisuConfig):
def find(self, def find(self,
name: str, name: str,
value=undefined, value=undefined,
@ -755,7 +780,7 @@ class _TiramisuOptionDescription(_TiramisuOption):
option_bag = OptionBag() option_bag = OptionBag()
option_bag.set_option(opt, option_bag.set_option(opt,
opt.impl_getpath(), opt.impl_getpath(),
None, None,
config_bag) config_bag)
if opt.impl_is_optiondescription(): if opt.impl_is_optiondescription():
config_bag.context.cfgimpl_get_settings().validate_properties(option_bag) config_bag.context.cfgimpl_get_settings().validate_properties(option_bag)
@ -802,6 +827,15 @@ class _TiramisuOptionDescription(_TiramisuOption):
subconfig, subconfig,
self._config_bag) self._config_bag)
def _load_dict(self,
clearable: str="all",
remotable: str="minimum"):
root = self._get_option().impl_getpath()
self._tiramisu_dict = TiramisuDict(self._return_config(self._config_bag.context),
root=root,
clearable=clearable,
remotable=remotable)
def dict(self, def dict(self,
clearable: str="all", clearable: str="all",
remotable: str="minimum", remotable: str="minimum",
@ -809,21 +843,14 @@ class _TiramisuOptionDescription(_TiramisuOption):
force: bool=False) -> Dict: force: bool=False) -> Dict:
"""convert config and option to tiramisu format""" """convert config and option to tiramisu format"""
if force or self._tiramisu_dict is None: if force or self._tiramisu_dict is None:
option = self._get_option() self._load_dict(clearable, remotable)
name = option.impl_getname()
root = self._subconfig._get_subpath(name)
config = self._config_bag.context
self._tiramisu_dict = TiramisuDict(Config(self._config_bag.context),
root=root,
clearable=clearable,
remotable=remotable)
return self._tiramisu_dict.todict(form) return self._tiramisu_dict.todict(form)
def updates(self, def updates(self,
body: List) -> Dict: body: List) -> Dict:
"""updates value with tiramisu format""" """updates value with tiramisu format"""
if self._tiramisu_dict is None: if self._tiramisu_dict is None:
raise APIError(_('please use .dict() before .updates()')) self._load_dict()
return self._tiramisu_dict.set_updates(body) return self._tiramisu_dict.set_updates(body)
@ -856,29 +883,9 @@ class TiramisuOption(CommonTiramisuOption):
config_bag=config_bag) config_bag=config_bag)
#__________________________________________________________________________________________________
#
class TiramisuContext(TiramisuHelp): class TiramisuContextInformation(TiramisuConfig):
def __init__(self,
config_bag: Optional[ConfigBag]) -> None:
self._config_bag = config_bag
def _return_config(self,
config):
if isinstance(config, KernelConfig):
return Config(config)
if isinstance(config, KernelMetaConfig):
return MetaConfig(config)
if isinstance(config, KernelMixConfig):
return MixConfig([], config)
if isinstance(config, KernelGroupConfig):
return GroupConfig(config)
raise Exception(_('unknown config type {}').format(type(config)))
class TiramisuContextInformation(TiramisuContext):
"""Manage config informations""" """Manage config informations"""
def get(self, name, default=undefined): def get(self, name, default=undefined):
"""Get an information""" """Get an information"""
@ -897,7 +904,7 @@ class TiramisuContextInformation(TiramisuContext):
return self._config_bag.context.impl_list_information() return self._config_bag.context.impl_list_information()
class TiramisuContextValue(TiramisuContext): class TiramisuContextValue(TiramisuConfig):
"""Manage config value""" """Manage config value"""
def mandatory(self): def mandatory(self):
"""Return path of options with mandatory property without any value""" """Return path of options with mandatory property without any value"""
@ -981,7 +988,7 @@ class TiramisuContextValue(TiramisuContext):
True) True)
class TiramisuContextOwner(TiramisuContext): class TiramisuContextOwner(TiramisuConfig):
"""Global owner""" """Global owner"""
def get(self): def get(self):
@ -998,7 +1005,7 @@ class TiramisuContextOwner(TiramisuContext):
self._config_bag.context.cfgimpl_get_values().set_context_owner(obj_owner) self._config_bag.context.cfgimpl_get_values().set_context_owner(obj_owner)
class TiramisuContextProperty(TiramisuContext): class TiramisuContextProperty(TiramisuConfig):
"""Manage config properties""" """Manage config properties"""
def read_only(self): def read_only(self):
@ -1129,7 +1136,7 @@ class TiramisuContextProperty(TiramisuContext):
raise ValueError(_('unknown type {}').format(type)) raise ValueError(_('unknown type {}').format(type))
class TiramisuContextPermissive(TiramisuContext): class TiramisuContextPermissive(TiramisuConfig):
"""Manage config permissives""" """Manage config permissives"""
def get(self): def get(self):
@ -1173,7 +1180,7 @@ class TiramisuContextPermissive(TiramisuContext):
self.set(frozenset(props)) self.set(frozenset(props))
class TiramisuContextOption(TiramisuContext): class TiramisuContextOption(TiramisuConfig):
def __init__(self, def __init__(self,
*args, *args,
**kwargs) -> None: **kwargs) -> None:
@ -1276,6 +1283,14 @@ class TiramisuContextOption(TiramisuContext):
config_bag, config_bag,
config_bag.context) config_bag.context)
def _load_dict(self,
clearable="all",
remotable="minimum"):
self._tiramisu_dict = TiramisuDict(self._return_config(self._config_bag.context),
root=None,
clearable=clearable,
remotable=remotable)
def dict(self, def dict(self,
clearable="all", clearable="all",
remotable="minimum", remotable="minimum",
@ -1283,17 +1298,14 @@ class TiramisuContextOption(TiramisuContext):
force=False): force=False):
"""convert config and option to tiramisu format""" """convert config and option to tiramisu format"""
if force or self._tiramisu_dict is None: if force or self._tiramisu_dict is None:
self._tiramisu_dict = TiramisuDict(Config(self._config_bag.context), self._load_dict(clearable, remotable)
root=None,
clearable=clearable,
remotable=remotable)
return self._tiramisu_dict.todict(form) return self._tiramisu_dict.todict(form)
def updates(self, def updates(self,
body: List) -> Dict: body: List) -> Dict:
"""updates value with tiramisu format""" """updates value with tiramisu format"""
if self._tiramisu_dict is None: if self._tiramisu_dict is None:
raise APIError(_('please use .dict() before .updates()')) self._load_dict()
return self._tiramisu_dict.set_updates(body) return self._tiramisu_dict.set_updates(body)
@ -1318,7 +1330,7 @@ class _TiramisuContextConfigReset():
self._config_bag.context.cfgimpl_reset_cache(None, None) self._config_bag.context.cfgimpl_reset_cache(None, None)
class _TiramisuContextConfig(TiramisuContext, _TiramisuContextConfigReset): class _TiramisuContextConfig(TiramisuConfig, _TiramisuContextConfigReset):
"""Actions to Config""" """Actions to Config"""
def name(self): def name(self):
return self._config_bag.context.impl_getname() return self._config_bag.context.impl_getname()
@ -1327,6 +1339,7 @@ class _TiramisuContextConfig(TiramisuContext, _TiramisuContextConfigReset):
session_id=None, session_id=None,
persistent=False, persistent=False,
storage=None): storage=None):
"""Copy current config"""
return self._return_config(self._config_bag.context.duplicate(session_id, return self._return_config(self._config_bag.context.duplicate(session_id,
persistent=persistent, persistent=persistent,
storage=storage)) storage=storage))
@ -1336,6 +1349,7 @@ class _TiramisuContextConfig(TiramisuContext, _TiramisuContextConfigReset):
persistent=False, persistent=False,
storage=None, storage=None,
metaconfig_prefix=None): metaconfig_prefix=None):
"""Copy current config with all parents"""
return self._return_config(self._config_bag.context.duplicate(session_id, return self._return_config(self._config_bag.context.duplicate(session_id,
persistent=persistent, persistent=persistent,
storage=storage, storage=storage,
@ -1343,13 +1357,23 @@ class _TiramisuContextConfig(TiramisuContext, _TiramisuContextConfigReset):
deep=True)) deep=True))
def metaconfig(self): def metaconfig(self):
return self._return_config(self._config_bag.context.cfgimpl_get_meta()) """Get first meta configuration (obsolete please use parents)"""
try:
return next(self.parents())
except StopIteration:
return None
def parents(self):
"""Get all parents of current config"""
for parent in self._config_bag.context.get_parents():
yield self._return_config(parent)
def path(self): def path(self):
"""Get path from config (all parents name)"""
return self._config_bag.context.cfgimpl_get_config_path() return self._config_bag.context.cfgimpl_get_config_path()
class _TiramisuContextGroupConfig(TiramisuContext): class _TiramisuContextGroupConfig(TiramisuConfig):
"""Actions to GroupConfig""" """Actions to GroupConfig"""
def name(self): def name(self):
"""Get config name""" """Get config name"""
@ -1409,9 +1433,12 @@ class _TiramisuContextGroupConfig(TiramisuContext):
class _TiramisuContextMixConfig(_TiramisuContextGroupConfig, _TiramisuContextConfigReset): class _TiramisuContextMixConfig(_TiramisuContextGroupConfig, _TiramisuContextConfigReset):
"""Actions to MixConfig""" """Actions to MixConfig"""
def pop(self, def pop(self,
session_id): session_id=None,
config=None):
"""Remove config from MetaConfig""" """Remove config from MetaConfig"""
return self._return_config(self._config_bag.context.pop_config(session_id=session_id)) if __debug__ and None not in [session_id, config]:
raise APIError(_('cannot set session_id and config together'))
return self._return_config(self._config_bag.context.pop_config(session_id=session_id, config=config))
def add(self, def add(self,
config): config):
@ -1427,12 +1454,13 @@ class _TiramisuContextMetaConfig(_TiramisuContextMixConfig):
type='config'): type='config'):
"""Create and add a new config""" """Create and add a new config"""
new_config = self._config_bag.context.new_config(session_id=session_id, new_config = self._config_bag.context.new_config(session_id=session_id,
persistent=persistent, persistent=persistent,
type_=type) type_=type)
return self._return_config(new_config) return self._return_config(new_config)
class TiramisuContextCache(TiramisuContext):
class TiramisuContextCache(TiramisuConfig):
def reset(self): def reset(self):
self._config_bag.context.cfgimpl_reset_cache(None, None) self._config_bag.context.cfgimpl_reset_cache(None, None)
@ -1509,7 +1537,6 @@ class TiramisuDispatcherOption(TiramisuDispatcher, TiramisuContextOption):
self._config_bag) self._config_bag)
#__________________________________________________________________________________________________
class Config(TiramisuAPI): class Config(TiramisuAPI):
"""Root config object that enables us to handle the configuration options""" """Root config object that enables us to handle the configuration options"""
def __init__(self, def __init__(self,

View File

@ -28,7 +28,7 @@ from .error import PropertiesOptionError, ConfigError, ConflictError, \
from .option import SynDynOptionDescription, DynOptionDescription, Leadership from .option import SynDynOptionDescription, DynOptionDescription, Leadership
from .option.baseoption import BaseOption, valid_name from .option.baseoption import BaseOption, valid_name
from .setting import OptionBag, ConfigBag, Settings, undefined from .setting import OptionBag, ConfigBag, Settings, undefined
from .storage import get_storages, gen_storage_id, get_default_values_storages, list_sessions from .storage import get_storages, gen_storage_id, get_default_values_storages, list_sessions, Cache
from .value import Values from .value import Values
from .i18n import _ from .i18n import _
@ -104,8 +104,6 @@ class SubConfig(object):
def reset_one_option_cache(self, def reset_one_option_cache(self,
desc, desc,
values,
settings,
resetted_opts, resetted_opts,
option_bag): option_bag):
@ -127,8 +125,6 @@ class SubConfig(object):
option_bag.index, option_bag.index,
option_bag.config_bag) option_bag.config_bag)
self.reset_one_option_cache(desc, self.reset_one_option_cache(desc,
values,
settings,
resetted_opts, resetted_opts,
doption_bag) doption_bag)
elif option.issubdyn(): elif option.issubdyn():
@ -146,8 +142,6 @@ class SubConfig(object):
option_bag.index, option_bag.index,
option_bag.config_bag) option_bag.config_bag)
self.reset_one_option_cache(desc, self.reset_one_option_cache(desc,
values,
settings,
resetted_opts, resetted_opts,
doption_bag) doption_bag)
else: else:
@ -158,14 +152,11 @@ class SubConfig(object):
option_bag.index, option_bag.index,
option_bag.config_bag) option_bag.config_bag)
self.reset_one_option_cache(desc, self.reset_one_option_cache(desc,
values,
settings,
resetted_opts, resetted_opts,
doption_bag) doption_bag)
del option del option
option_bag.option.reset_cache(option_bag.path, option_bag.option.reset_cache(option_bag.path,
values, option_bag.config_bag,
settings,
resetted_opts) resetted_opts)
def cfgimpl_reset_cache(self, def cfgimpl_reset_cache(self,
@ -178,18 +169,14 @@ class SubConfig(object):
context = self.cfgimpl_get_context() context = self.cfgimpl_get_context()
desc = context.cfgimpl_get_description() desc = context.cfgimpl_get_description()
values = context.cfgimpl_get_values()
settings = context.cfgimpl_get_settings()
if option_bag is not None: if option_bag is not None:
self.reset_one_option_cache(desc, self.reset_one_option_cache(desc,
values,
settings,
resetted_opts, resetted_opts,
option_bag) option_bag)
else: else:
values._p_.reset_all_cache() context._impl_values_cache.reset_all_cache()
settings._p_.reset_all_cache() context._impl_properties_cache.reset_all_cache()
def cfgimpl_get_home_by_path(self, def cfgimpl_get_home_by_path(self,
path, path,
@ -238,7 +225,7 @@ class SubConfig(object):
context = option_bag.config_bag.context context = option_bag.config_bag.context
context.cfgimpl_get_settings().validate_properties(option_bag) context.cfgimpl_get_settings().validate_properties(option_bag)
if option_bag.option.impl_is_leader() and len(value) < self._impl_length: if option_bag.option.impl_is_leader() and len(value) < self._impl_length:
raise LeadershipError(_('cannot reduce length of a leader "{}"' raise LeadershipError(_('cannot reduce length of the leader "{}"'
'').format(option_bag.option.impl_get_display_name())) '').format(option_bag.option.impl_get_display_name()))
return context.cfgimpl_get_values().setvalue(value, return context.cfgimpl_get_values().setvalue(value,
option_bag, option_bag,
@ -608,8 +595,11 @@ class SubConfig(object):
class _CommonConfig(SubConfig): class _CommonConfig(SubConfig):
"abstract base class for the Config, KernelGroupConfig and the KernelMetaConfig" "abstract base class for the Config, KernelGroupConfig and the KernelMetaConfig"
__slots__ = ('_impl_values', __slots__ = ('_impl_values',
'_impl_values_cache',
'_impl_settings', '_impl_settings',
'_impl_meta', '_impl_properties_cache',
'_impl_permissives_cache',
'parents',
'impl_type') 'impl_type')
def _impl_build_all_caches(self): def _impl_build_all_caches(self):
@ -619,9 +609,9 @@ class _CommonConfig(SubConfig):
config_bag = ConfigBag(context=self) config_bag = ConfigBag(context=self)
descr.impl_build_force_store_values(config_bag) descr.impl_build_force_store_values(config_bag)
def cfgimpl_get_meta(self): def get_parents(self):
if self._impl_meta is not None: for parent in self.parents:
return self._impl_meta() yield parent()
# information # information
def impl_set_information(self, key, value): def impl_set_information(self, key, value):
@ -699,26 +689,37 @@ class _CommonConfig(SubConfig):
duplicated_config.cfgimpl_reset_cache(None, None) duplicated_config.cfgimpl_reset_cache(None, None)
if child is not None: if child is not None:
duplicated_config._impl_children.append(child) duplicated_config._impl_children.append(child)
child._impl_meta = weakref.ref(duplicated_config) child.parents.append(weakref.ref(duplicated_config))
if self._impl_meta: if self.parents:
if deep: if deep:
duplicated_config = self._impl_meta().duplicate(deep=deep, if metaconfig_prefix is not None and self._impl_path is not None:
storage=storage, metaconfig_prefix += self._impl_path
metaconfig_prefix=metaconfig_prefix, for parent in self.parents:
child=duplicated_config, duplicated_config = parent().duplicate(deep=deep,
persistent=persistent) storage=storage,
metaconfig_prefix=metaconfig_prefix,
child=duplicated_config,
persistent=persistent)
else: else:
duplicated_config._impl_meta = self._impl_meta duplicated_config.parents = self.parents
self._impl_meta()._impl_children.append(duplicated_config) for parent in self.parents:
parent()._impl_children.append(duplicated_config)
return duplicated_config return duplicated_config
def cfgimpl_get_config_path(self):
path = self._impl_name
for parent in self.parents:
path = parent().cfgimpl_get_config_path() + '.' + path
return path
# ____________________________________________________________ # ____________________________________________________________
class KernelConfig(_CommonConfig): class KernelConfig(_CommonConfig):
"main configuration management entry" "main configuration management entry"
__slots__ = ('__weakref__', __slots__ = ('__weakref__',
'_impl_name', '_impl_name',
'_display_name') '_display_name',
'_impl_symlink')
impl_type = 'config' impl_type = 'config'
def __init__(self, def __init__(self,
@ -742,7 +743,8 @@ class KernelConfig(_CommonConfig):
:param persistent: if persistent, don't delete storage when leaving :param persistent: if persistent, don't delete storage when leaving
:type persistent: `boolean` :type persistent: `boolean`
""" """
self._impl_meta = None self.parents = []
self._impl_symlink = []
self._display_name = display_name self._display_name = display_name
if isinstance(descr, Leadership): if isinstance(descr, Leadership):
raise ConfigError(_('cannot set leadership object has root optiondescription')) raise ConfigError(_('cannot set leadership object has root optiondescription'))
@ -754,7 +756,10 @@ class KernelConfig(_CommonConfig):
force_settings[1]) force_settings[1])
else: else:
self._impl_settings = force_settings self._impl_settings = force_settings
self._impl_permissives_cache = Cache()
self._impl_properties_cache = Cache()
self._impl_values = Values(force_values) self._impl_values = Values(force_values)
self._impl_values_cache = Cache()
else: else:
properties, permissives, values, session_id = get_storages(self, properties, permissives, values, session_id = get_storages(self,
session_id, session_id,
@ -764,7 +769,10 @@ class KernelConfig(_CommonConfig):
raise ValueError(_("invalid session ID: {0} for config").format(session_id)) raise ValueError(_("invalid session ID: {0} for config").format(session_id))
self._impl_settings = Settings(properties, self._impl_settings = Settings(properties,
permissives) permissives)
self._impl_permissives_cache = Cache()
self._impl_properties_cache = Cache()
self._impl_values = Values(values) self._impl_values = Values(values)
self._impl_values_cache = Cache()
super().__init__(descr, super().__init__(descr,
weakref.ref(self), weakref.ref(self),
ConfigBag(self), ConfigBag(self),
@ -776,11 +784,6 @@ class KernelConfig(_CommonConfig):
def impl_getname(self): def impl_getname(self):
return self._impl_name return self._impl_name
def cfgimpl_get_config_path(self):
if self._impl_meta is None or self._impl_meta() is None:
return self._impl_name
return self._impl_meta().cfgimpl_get_config_path() + '.' + self._impl_name
class KernelGroupConfig(_CommonConfig): class KernelGroupConfig(_CommonConfig):
__slots__ = ('__weakref__', __slots__ = ('__weakref__',
@ -806,7 +809,7 @@ class KernelGroupConfig(_CommonConfig):
raise ConflictError(_('config name must be uniq in ' raise ConflictError(_('config name must be uniq in '
'groupconfig for "{0}"').format(name)) 'groupconfig for "{0}"').format(name))
self._impl_children = children self._impl_children = children
self._impl_meta = None self.parents = []
session_id = gen_storage_id(session_id, self) session_id = gen_storage_id(session_id, self)
assert valid_name(session_id), _("invalid session ID: {0} for config").format(session_id) assert valid_name(session_id), _("invalid session ID: {0} for config").format(session_id)
super().__init__(_descr, super().__init__(_descr,
@ -975,14 +978,10 @@ class KernelGroupConfig(_CommonConfig):
return child return child
raise ConfigError(_('unknown config "{}"').format(name)) raise ConfigError(_('unknown config "{}"').format(name))
def cfgimpl_get_config_path(self):
if self._impl_meta is None or self._impl_meta() is None:
return self._impl_name
return self._impl_meta().cfgimpl_get_config_path() + '.' + self._impl_name
class KernelMixConfig(KernelGroupConfig): class KernelMixConfig(KernelGroupConfig):
__slots__ = ('_display_name',) __slots__ = ('_display_name',
'_impl_symlink')
impl_type = 'mix' impl_type = 'mix'
def __init__(self, def __init__(self,
@ -995,27 +994,21 @@ class KernelMixConfig(KernelGroupConfig):
_duplicate=False): _duplicate=False):
# FIXME _duplicate # FIXME _duplicate
self._display_name = display_name self._display_name = display_name
self._impl_symlink = []
for child in children: for child in children:
if not isinstance(child, _CommonConfig):
try:
child = child._config
except:
raise TypeError(_("{}config's children "
"should be config, not {}"
).format(self.impl_type,
type(child)))
if not isinstance(child, (KernelConfig, KernelMixConfig)): if not isinstance(child, (KernelConfig, KernelMixConfig)):
raise TypeError(_("child must be a Config, MixConfig or MetaConfig")) raise TypeError(_("child must be a Config, MixConfig or MetaConfig"))
if child.cfgimpl_get_meta() is not None: child.parents.append(weakref.ref(self))
raise ValueError(_("child has already a {}config's").format(self.impl_type))
child._impl_meta = weakref.ref(self)
properties, permissives, values, session_id = get_storages(self, properties, permissives, values, session_id = get_storages(self,
session_id, session_id,
persistent, persistent,
storage=storage) storage=storage)
self._impl_settings = Settings(properties, self._impl_settings = Settings(properties,
permissives) permissives)
self._impl_permissives_cache = Cache()
self._impl_properties_cache = Cache()
self._impl_values = Values(values) self._impl_values = Values(values)
self._impl_values_cache = Cache()
super().__init__(children, super().__init__(children,
session_id=session_id, session_id=session_id,
_descr=optiondescription) _descr=optiondescription)
@ -1188,24 +1181,35 @@ class KernelMixConfig(KernelGroupConfig):
def add_config(self, def add_config(self,
apiconfig): apiconfig):
config = apiconfig._config_bag.context config = apiconfig._config_bag.context
if config._impl_meta is not None:
raise ConflictError(_('config is already in a metaconfig'))
if config.impl_getname() in [child.impl_getname() for child in self._impl_children]: if config.impl_getname() in [child.impl_getname() for child in self._impl_children]:
raise ConflictError(_('config name must be uniq in ' raise ConflictError(_('config name must be uniq in '
'groupconfig for {0}').format(config.impl_getname())) 'groupconfig for {0}').format(config.impl_getname()))
config._impl_meta = weakref.ref(self) config.parents.append(weakref.ref(self))
self._impl_children.append(config) self._impl_children.append(config)
config.cfgimpl_reset_cache(None, None) config.cfgimpl_reset_cache(None, None)
def pop_config(self, def pop_config(self,
session_id): session_id,
for idx, child in enumerate(self._impl_children): config):
if session_id == child.impl_getname(): if session_id is not None:
child._impl_meta = None for idx, child in enumerate(self._impl_children):
child.cfgimpl_reset_cache(None, None) if session_id == child.impl_getname():
return self._impl_children.pop(idx) child.cfgimpl_reset_cache(None, None)
raise ConfigError(_('cannot find the config {}').format(session_id)) self._impl_children.pop(idx)
break
else:
raise ConfigError(_('cannot find the config {}').format(session_id))
if config is not None:
self._impl_children.remove(config)
child = config
for index, parent in enumerate(child.parents):
if parent() == self:
child.parents.pop(index)
break
else:
raise ConfigError(_('cannot find the config {}').format(self.session_id))
return child
class KernelMetaConfig(KernelMixConfig): class KernelMetaConfig(KernelMixConfig):
@ -1236,14 +1240,6 @@ class KernelMetaConfig(KernelMixConfig):
children = new_children children = new_children
descr = optiondescription descr = optiondescription
for child in children: for child in children:
if not isinstance(child, _CommonConfig):
try:
child = child._config
except Exception:
raise TypeError(_("{}config's children "
"should be config, not {}"
).format(self.impl_type,
type(child)))
if __debug__ and not isinstance(child, (KernelConfig, if __debug__ and not isinstance(child, (KernelConfig,
KernelMetaConfig)): KernelMetaConfig)):
raise TypeError(_("child must be a Config or MetaConfig")) raise TypeError(_("child must be a Config or MetaConfig"))
@ -1286,7 +1282,7 @@ class KernelMetaConfig(KernelMixConfig):
display_name=self._display_name) display_name=self._display_name)
# Copy context properties/permissives # Copy context properties/permissives
if new: if new:
config.cfgimpl_get_settings().set_context_properties(self.cfgimpl_get_settings().get_context_properties(), config) config.cfgimpl_get_settings().set_context_properties(self.cfgimpl_get_settings().get_context_properties(config._impl_properties_cache), config)
config.cfgimpl_get_settings().set_context_permissives(self.cfgimpl_get_settings().get_context_permissives()) config.cfgimpl_get_settings().set_context_permissives(self.cfgimpl_get_settings().get_context_permissives())
config.cfgimpl_get_settings().ro_append = self.cfgimpl_get_settings().ro_append config.cfgimpl_get_settings().ro_append = self.cfgimpl_get_settings().ro_append
config.cfgimpl_get_settings().rw_append = self.cfgimpl_get_settings().rw_append config.cfgimpl_get_settings().rw_append = self.cfgimpl_get_settings().rw_append
@ -1294,7 +1290,7 @@ class KernelMetaConfig(KernelMixConfig):
config.cfgimpl_get_settings().rw_remove = self.cfgimpl_get_settings().rw_remove config.cfgimpl_get_settings().rw_remove = self.cfgimpl_get_settings().rw_remove
config.cfgimpl_get_settings().default_properties = self.cfgimpl_get_settings().default_properties config.cfgimpl_get_settings().default_properties = self.cfgimpl_get_settings().default_properties
config._impl_meta = weakref.ref(self) config.parents.append(weakref.ref(self))
self._impl_children.append(config) self._impl_children.append(config)
return config return config

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: 2019-07-26 09:35+CEST\n" "POT-Creation-Date: 2019-08-19 14:10+CEST\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"
@ -53,46 +53,46 @@ msgstr "l'index est obligatoire pour l'option suiveuse \"{}\""
msgid "unknown method {} in {}" msgid "unknown method {} in {}"
msgstr "méthode {} inconnue dans {}" msgstr "méthode {} inconnue dans {}"
#: tiramisu/api.py:393 #: tiramisu/api.py:398
msgid "cannot add this property: \"{0}\"" msgid "cannot add this property: \"{0}\""
msgstr "ne peut pas ajouter cette propriété : \"{0}\"" msgstr "ne peut pas ajouter cette propriété : \"{0}\""
#: tiramisu/api.py:549 tiramisu/config.py:252 #: tiramisu/api.py:554 tiramisu/config.py:239
msgid "can't delete a SymLinkOption" msgid "can't delete a SymLinkOption"
msgstr "ne peut supprimer une valeur à une SymLinkOption" msgstr "ne peut supprimer une valeur à une SymLinkOption"
#: tiramisu/api.py:709 tiramisu/api.py:1487 #: tiramisu/api.py:714 tiramisu/api.py:1515
msgid "please specify a valid sub function ({})" msgid "please specify a valid sub function ({})"
msgstr "veuillez spécifier une sous fonction valide ({})" msgstr "veuillez spécifier une sous fonction valide ({})"
#: tiramisu/api.py:770 tiramisu/api.py:1264 #: tiramisu/api.py:734
msgid "unknown list type {}"
msgstr "type de liste inconnue {}"
#: tiramisu/api.py:772 tiramisu/api.py:1266
msgid "unknown group_type: {0}"
msgstr "group_type inconnu: {0}"
#: tiramisu/api.py:826 tiramisu/api.py:1296
msgid "please use .dict() before .updates()"
msgstr "faire .dict() avant .updates()"
#: tiramisu/api.py:878
msgid "unknown config type {}" msgid "unknown config type {}"
msgstr "type de config {} inconnue" msgstr "type de config {} inconnue"
#: tiramisu/api.py:1089 #: tiramisu/api.py:795 tiramisu/api.py:1271
msgid "unknown list type {}"
msgstr "type de liste inconnue {}"
#: tiramisu/api.py:797 tiramisu/api.py:1273
msgid "unknown group_type: {0}"
msgstr "group_type inconnu: {0}"
#: tiramisu/api.py:1096
msgid "properties must be a frozenset" msgid "properties must be a frozenset"
msgstr "une propriété doit être de type frozenset" msgstr "une propriété doit être de type frozenset"
#: tiramisu/api.py:1095 tiramisu/api.py:1117 #: tiramisu/api.py:1102 tiramisu/api.py:1124
msgid "unknown when {} (must be in append or remove)" msgid "unknown when {} (must be in append or remove)"
msgstr "value {} inconsistent (doit être append ou remove)" msgstr "value {} inconsistent (doit être append ou remove)"
#: tiramisu/api.py:1107 tiramisu/api.py:1129 tiramisu/config.py:1268 #: tiramisu/api.py:1114 tiramisu/api.py:1136 tiramisu/config.py:1262
msgid "unknown type {}" msgid "unknown type {}"
msgstr "type inconnu {}" msgstr "type inconnu {}"
#: tiramisu/api.py:1440
msgid "cannot set session_id and config together"
msgstr "session_id et config ne peut être mis ensemble"
#: tiramisu/autolib.py:96 #: tiramisu/autolib.py:96
msgid "unable to carry out a calculation for \"{}\", {}" msgid "unable to carry out a calculation for \"{}\", {}"
msgstr "impossible d'effectuer le calcul pour \"{}\", {}" msgstr "impossible d'effectuer le calcul pour \"{}\", {}"
@ -131,25 +131,25 @@ msgstr ""
msgid "\"{0}\" must be an optiondescription, not an {1}" msgid "\"{0}\" must be an optiondescription, not an {1}"
msgstr "\"{0}\" doit être une optiondescription, et non {1}" msgstr "\"{0}\" doit être une optiondescription, et non {1}"
#: tiramisu/config.py:213 #: tiramisu/config.py:200
msgid "unknown option {}" msgid "unknown option {}"
msgstr "option {} inconnue" msgstr "option {} inconnue"
#: tiramisu/config.py:221 #: tiramisu/config.py:208
msgid "there is no option description for this config (may be GroupConfig)" msgid "there is no option description for this config (may be GroupConfig)"
msgstr "" msgstr ""
"il n'y a pas d'option description trouvé pour cette config (peut être un " "il n'y a pas d'option description trouvé pour cette config (peut être un "
"GroupConfig)" "GroupConfig)"
#: tiramisu/config.py:237 #: tiramisu/config.py:224
msgid "can't assign to a SymLinkOption" msgid "can't assign to a SymLinkOption"
msgstr "ne peut assigner une valeur à une SymLinkOption" msgstr "ne peut assigner une valeur à une SymLinkOption"
#: tiramisu/config.py:241 #: tiramisu/config.py:228
msgid "cannot reduce length of a leader \"{}\"" msgid "cannot reduce length of the leader \"{}\""
msgstr "il est impossible de réduire la longueur de l'option leader \"{}\"" msgstr "il est impossible de réduire la longueur du leader \"{}\""
#: tiramisu/config.py:321 #: tiramisu/config.py:308
msgid "" msgid ""
"the follower option \"{}\" has greater length ({}) than the leader length " "the follower option \"{}\" has greater length ({}) than the leader length "
"({})" "({})"
@ -157,19 +157,19 @@ msgstr ""
"l'option suiveuse \"{}\" a une longueur supérieur ({}) à la longueur de " "l'option suiveuse \"{}\" a une longueur supérieur ({}) à la longueur de "
"l'option leader ({})" "l'option leader ({})"
#: tiramisu/config.py:418 #: tiramisu/config.py:405
msgid "no option found in config with these criteria" msgid "no option found in config with these criteria"
msgstr "aucune option trouvée dans la config avec ces critères" msgstr "aucune option trouvée dans la config avec ces critères"
#: tiramisu/config.py:468 #: tiramisu/config.py:455
msgid "make_dict can't filtering with value without option" msgid "make_dict can't filtering with value without option"
msgstr "make_dict ne peut filtrer sur une valeur mais sans option" msgstr "make_dict ne peut filtrer sur une valeur mais sans option"
#: tiramisu/config.py:521 #: tiramisu/config.py:508
msgid "unexpected path \"{0}\", should start with \"{1}\"" msgid "unexpected path \"{0}\", should start with \"{1}\""
msgstr "chemin inconsistant \"{0}\", devrait commencé par \"{1}\"" msgstr "chemin inconsistant \"{0}\", devrait commencé par \"{1}\""
#: tiramisu/config.py:669 #: tiramisu/config.py:659
msgid "cannot duplicate {}" msgid "cannot duplicate {}"
msgstr "ne peut dupliquer : {0}" msgstr "ne peut dupliquer : {0}"
@ -182,41 +182,33 @@ msgid "cannot set dynoptiondescription object has root optiondescription"
msgstr "" msgstr ""
"ne peut assigner un objet dynoptiondescription comme optiondescription racine" "ne peut assigner un objet dynoptiondescription comme optiondescription racine"
#: tiramisu/config.py:764 tiramisu/config.py:811 #: tiramisu/config.py:767 tiramisu/config.py:812
msgid "invalid session ID: {0} for config" msgid "invalid session ID: {0} for config"
msgstr "ID de session invalide : {0} pour une config" msgstr "ID de session invalide : {0} pour une config"
#: tiramisu/config.py:795 #: tiramisu/config.py:796
msgid "groupconfig's children must be a list" msgid "groupconfig's children must be a list"
msgstr "enfants d'une groupconfig doit être une liste" msgstr "enfants d'une groupconfig doit être une liste"
#: tiramisu/config.py:799 #: tiramisu/config.py:800
msgid "groupconfig's children must be Config, MetaConfig or GroupConfig" msgid "groupconfig's children must be Config, MetaConfig or GroupConfig"
msgstr "" msgstr ""
"les enfants d'un groupconfig doivent être des Config, MetaConfig ou " "les enfants d'un groupconfig doivent être des Config, MetaConfig ou "
"GroupConfig" "GroupConfig"
#: tiramisu/config.py:806 #: tiramisu/config.py:807
msgid "config name must be uniq in groupconfig for \"{0}\"" msgid "config name must be uniq in groupconfig for \"{0}\""
msgstr "le nom d'un config doit être unique dans un groupconfig pour \"{0}\"" msgstr "le nom d'un config doit être unique dans un groupconfig pour \"{0}\""
#: tiramisu/config.py:976 #: tiramisu/config.py:977
msgid "unknown config \"{}\"" msgid "unknown config \"{}\""
msgstr "config \"{}\" inconnue" msgstr "config \"{}\" inconnue"
#: tiramisu/config.py:1003 tiramisu/config.py:1243 #: tiramisu/config.py:998
msgid "{}config's children should be config, not {}"
msgstr "enfants d'un {}config doit être une config, pas {}"
#: tiramisu/config.py:1008
msgid "child must be a Config, MixConfig or MetaConfig" msgid "child must be a Config, MixConfig or MetaConfig"
msgstr "l'enfant doit être une Config, MixConfig ou MetaConfig" msgstr "l'enfant doit être une Config, MixConfig ou MetaConfig"
#: tiramisu/config.py:1010 #: tiramisu/config.py:1030
msgid "child has already a {}config's"
msgstr "enfant a déjà un {}config"
#: tiramisu/config.py:1039
msgid "" msgid ""
"force_default, force_default_if_same or force_dont_change_value cannot be " "force_default, force_default_if_same or force_dont_change_value cannot be "
"set with only_config" "set with only_config"
@ -224,38 +216,34 @@ msgstr ""
"force_default, force_default_if_same ou force_dont_change_value ne peuvent " "force_default, force_default_if_same ou force_dont_change_value ne peuvent "
"pas être spécifié avec only_config" "pas être spécifié avec only_config"
#: tiramisu/config.py:1061 #: tiramisu/config.py:1052
msgid "force_default and force_dont_change_value cannot be set together" msgid "force_default and force_dont_change_value cannot be set together"
msgstr "" msgstr ""
"force_default et force_dont_change_value ne peuvent pas être mis ensemble" "force_default et force_dont_change_value ne peuvent pas être mis ensemble"
#: tiramisu/config.py:1192 #: tiramisu/config.py:1183 tiramisu/config.py:1260
msgid "config is already in a metaconfig"
msgstr "la config est déjà dans une metaconfig"
#: tiramisu/config.py:1194 tiramisu/config.py:1266
msgid "config name must be uniq in groupconfig for {0}" msgid "config name must be uniq in groupconfig for {0}"
msgstr "le nom de la config doit être unique dans un groupconfig pour {0}" msgstr "le nom de la config doit être unique dans un groupconfig pour {0}"
#: tiramisu/config.py:1208 #: tiramisu/config.py:1200 tiramisu/config.py:1209
msgid "cannot find the config {}" msgid "cannot find the config {}"
msgstr "ne peut pas trouver la config {0}" msgstr "ne peut pas trouver la config {0}"
#: tiramisu/config.py:1229 #: tiramisu/config.py:1231
msgid "MetaConfig with optiondescription must have string has child, not {}" msgid "MetaConfig with optiondescription must have string has child, not {}"
msgstr "" msgstr ""
"MetaConfig avec une optiondescription doit avoir un nom comme enfant, pas {}" "MetaConfig avec une optiondescription doit avoir un nom comme enfant, pas {}"
#: tiramisu/config.py:1249 #: tiramisu/config.py:1243
msgid "child must be a Config or MetaConfig" msgid "child must be a Config or MetaConfig"
msgstr "enfant doit être une une Config ou une MetaConfig" msgstr "enfant doit être une une Config ou une MetaConfig"
#: tiramisu/config.py:1253 #: tiramisu/config.py:1247
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"
#: tiramisu/config.py:1304 #: tiramisu/config.py:1298
msgid "metaconfig must have the same optiondescription" msgid "metaconfig must have the same optiondescription"
msgstr "metaconfig doivent avoir la même optiondescription" msgstr "metaconfig doivent avoir la même optiondescription"
@ -271,11 +259,11 @@ msgstr "ou"
msgid " {} " msgid " {} "
msgstr " {} " msgstr " {} "
#: tiramisu/error.py:105 tiramisu/setting.py:599 #: tiramisu/error.py:105 tiramisu/setting.py:601
msgid "property" msgid "property"
msgstr "de la propriété" msgstr "de la propriété"
#: tiramisu/error.py:107 tiramisu/setting.py:601 #: tiramisu/error.py:107 tiramisu/setting.py:603
msgid "properties" msgid "properties"
msgstr "des propriétés" msgstr "des propriétés"
@ -361,7 +349,7 @@ msgstr ""
"paramètres définis pour la fonction de callback mais aucun callback défini " "paramètres définis pour la fonction de callback mais aucun callback défini "
"pour l'option \"{0}\"" "pour l'option \"{0}\""
#: tiramisu/option/baseoption.py:350 tiramisu/storage/dictionary/value.py:258 #: tiramisu/option/baseoption.py:350 tiramisu/storage/dictionary/value.py:256
#: tiramisu/storage/sqlite3/value.py:201 #: tiramisu/storage/sqlite3/value.py:201
msgid "information's item not found: {0}" msgid "information's item not found: {0}"
msgstr "item '{0}' dans les informations non trouvée" msgstr "item '{0}' dans les informations non trouvée"
@ -673,21 +661,21 @@ msgstr ""
"le masque de réseau ne correspond pas à l'IP \"{0}\" (\"{1}\") et au " "le masque de réseau ne correspond pas à l'IP \"{0}\" (\"{1}\") et au "
"broadcast \"{2}\" (\"{3}\")" "broadcast \"{2}\" (\"{3}\")"
#: tiramisu/option/leadership.py:57 #: tiramisu/option/leadership.py:56
msgid "a leader and a follower are mandatories in leadership \"{}\"" msgid "a leader and a follower are mandatories in leadership \"{}\""
msgstr "" msgstr ""
"une option leader et une option suiveuse sont obligatoires dans une option " "une option leader et une option suiveuse sont obligatoires dans une option "
"leadership \"{}\"" "leadership \"{}\""
#: tiramisu/option/leadership.py:63 #: tiramisu/option/leadership.py:62
msgid "leadership \"{0}\" shall not have a symlinkoption" msgid "leadership \"{0}\" shall not have a symlinkoption"
msgstr "une option leadership \"{0}\" ne devrait pas avoir de symlinkoption" msgstr "une option leadership \"{0}\" ne devrait pas avoir de symlinkoption"
#: tiramisu/option/leadership.py:66 #: tiramisu/option/leadership.py:65
msgid "leadership \"{0}\" shall not have a subgroup" msgid "leadership \"{0}\" shall not have a subgroup"
msgstr "une option leadership \"{0}\" ne devrait pas avoir de sous-groupe" msgstr "une option leadership \"{0}\" ne devrait pas avoir de sous-groupe"
#: tiramisu/option/leadership.py:69 #: tiramisu/option/leadership.py:68
msgid "" msgid ""
"only multi option allowed in leadership \"{0}\" but option \"{1}\" is not a " "only multi option allowed in leadership \"{0}\" but option \"{1}\" is not a "
"multi" "multi"
@ -695,25 +683,25 @@ msgstr ""
"seules des options multiples sont autorisés dans l'option leadership \"{0}\" " "seules des options multiples sont autorisés dans l'option leadership \"{0}\" "
"alors que l'option \"{1}\" n'est pas une option multiple" "alors que l'option \"{1}\" n'est pas une option multiple"
#: tiramisu/option/leadership.py:74 #: tiramisu/option/leadership.py:73
msgid "" msgid ""
"not allowed default value for follower option \"{0}\" in leadership \"{1}\"" "not allowed default value for follower option \"{0}\" in leadership \"{1}\""
msgstr "" msgstr ""
"valeur par défaut non autorisée pour l'option suiveuse \"{0}\" dans l'option " "valeur par défaut non autorisée pour l'option suiveuse \"{0}\" dans l'option "
"leadership \"{1}\"" "leadership \"{1}\""
#: tiramisu/option/leadership.py:90 #: tiramisu/option/leadership.py:89
msgid "callback of leader's option shall not refered to a follower's ones" msgid "callback of leader's option shall not refered to a follower's ones"
msgstr "" msgstr ""
"callback d'une variable leader ne devrait pas référencer une variable " "callback d'une variable leader ne devrait pas référencer une variable "
"suiveuse" "suiveuse"
#: tiramisu/option/leadership.py:98 #: tiramisu/option/leadership.py:97
msgid "leader {} have requirement, but Leadership {} too" msgid "leader {} have requirement, but Leadership {} too"
msgstr "" msgstr ""
"l'option leader {} a des requirements mais l'option leadership {} également" "l'option leader {} a des requirements mais l'option leadership {} également"
#: tiramisu/option/leadership.py:113 #: tiramisu/option/leadership.py:112
msgid "" msgid ""
"malformed requirements option \"{0}\" must not be in follower for \"{1}\"" "malformed requirements option \"{0}\" must not be in follower for \"{1}\""
msgstr "" msgstr ""
@ -898,7 +886,7 @@ msgstr ""
msgid "the dynoption \"{0}\" cannot have \"force_store_value\" property" msgid "the dynoption \"{0}\" cannot have \"force_store_value\" property"
msgstr "la dynoption \"{0}\" ne peut avoir la propriété \"force_store_value\"" msgstr "la dynoption \"{0}\" ne peut avoir la propriété \"force_store_value\""
#: tiramisu/option/optiondescription.py:99 tiramisu/setting.py:687 #: tiramisu/option/optiondescription.py:99 tiramisu/setting.py:689
msgid "" msgid ""
"a leader ({0}) cannot have \"force_default_on_freeze\" or " "a leader ({0}) cannot have \"force_default_on_freeze\" or "
"\"force_metaconfig_on_freeze\" property without \"frozen\"" "\"force_metaconfig_on_freeze\" property without \"frozen\""
@ -1041,7 +1029,7 @@ msgstr "ne peut redéfinir ({0})"
msgid "can't unbind {0}" msgid "can't unbind {0}"
msgstr "ne peut supprimer ({0})" msgstr "ne peut supprimer ({0})"
#: tiramisu/setting.py:539 #: tiramisu/setting.py:541
msgid "" msgid ""
"malformed requirements imbrication detected for option: '{0}' with " "malformed requirements imbrication detected for option: '{0}' with "
"requirement on: '{1}'" "requirement on: '{1}'"
@ -1049,82 +1037,82 @@ 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:602 #: tiramisu/setting.py:604
msgid "" msgid ""
"cannot access to option \"{0}\" because required option \"{1}\" has {2} {3}" "cannot access to option \"{0}\" because required option \"{1}\" has {2} {3}"
msgstr "" msgstr ""
"ne peut accéder à l'option \"{0}\" parce que l'option requise \"{1}\" a {2} " "ne peut accéder à l'option \"{0}\" parce que l'option requise \"{1}\" a {2} "
"{3}" "{3}"
#: tiramisu/setting.py:630 #: tiramisu/setting.py:632
msgid "the calculated value is {0}" msgid "the calculated value is {0}"
msgstr "valeurs calculées est {0}" msgstr "valeurs calculées est {0}"
#: tiramisu/setting.py:632 #: tiramisu/setting.py:634
msgid "the calculated value is not {0}" msgid "the calculated value is not {0}"
msgstr "valeurs calculées n'est pas {0}" msgstr "valeurs calculées n'est pas {0}"
#: tiramisu/setting.py:636 #: tiramisu/setting.py:638
msgid "the value of \"{0}\" is {1}" msgid "the value of \"{0}\" is {1}"
msgstr "la valeur de \"{0}\" est {1}" msgstr "la valeur de \"{0}\" est {1}"
#: tiramisu/setting.py:638 #: tiramisu/setting.py:640
msgid "the value of \"{0}\" is not {1}" msgid "the value of \"{0}\" is not {1}"
msgstr "la valeur de \"{0}\" n'est pas {1}" msgstr "la valeur de \"{0}\" n'est pas {1}"
#: tiramisu/setting.py:677 #: tiramisu/setting.py:679
msgid "cannot set property {} for option \"{}\" this property is calculated" msgid "cannot set property {} for option \"{}\" this property is calculated"
msgstr "" msgstr ""
"ne peut ajouter la propriété {} pour l'option \"{}\" cette propriété est " "ne peut ajouter la propriété {} pour l'option \"{}\" cette propriété est "
"calculée" "calculée"
#: tiramisu/setting.py:682 #: tiramisu/setting.py:684
msgid "can't assign property to the symlinkoption \"{}\"" msgid "can't assign property to the symlinkoption \"{}\""
msgstr "ne peut assigner une propriété à une symlinkoption \"{}\"" msgstr "ne peut assigner une propriété à une symlinkoption \"{}\""
#: tiramisu/setting.py:714 #: tiramisu/setting.py:716
msgid "permissive must be a frozenset" msgid "permissive must be a frozenset"
msgstr "une permissive doit être de type frozenset" msgstr "une permissive doit être de type frozenset"
#: tiramisu/setting.py:718 #: tiramisu/setting.py:720
msgid "can't assign permissive to the symlinkoption \"{}\"" msgid "can't assign permissive to the symlinkoption \"{}\""
msgstr "ne peut assigner une permissive à la symlinkoption \"{}\"" msgstr "ne peut assigner une permissive à la symlinkoption \"{}\""
#: tiramisu/setting.py:725 #: tiramisu/setting.py:727
msgid "cannot add those permissives: {0}" msgid "cannot add those permissives: {0}"
msgstr "ne peut ajouter ces permissives : {0}" msgstr "ne peut ajouter ces permissives : {0}"
#: tiramisu/setting.py:742 #: tiramisu/setting.py:744
msgid "can't reset properties to the symlinkoption \"{}\"" msgid "can't reset properties to the symlinkoption \"{}\""
msgstr "ne peut réinitialiser les propriétés de la symlinkoption \"{}\"" msgstr "ne peut réinitialiser les propriétés de la symlinkoption \"{}\""
#: tiramisu/setting.py:757 #: tiramisu/setting.py:759
msgid "can't reset permissives to the symlinkoption \"{}\"" msgid "can't reset permissives to the symlinkoption \"{}\""
msgstr "ne peut réinitialiser les permissive de la symlinkoption \"{}\"" msgstr "ne peut réinitialiser les permissive de la symlinkoption \"{}\""
#: tiramisu/storage/__init__.py:60 #: tiramisu/storage/__init__.py:61
msgid "cannot import the storage {0}" msgid "cannot import the storage {0}"
msgstr "ne peut pas importer le stockage {0}" msgstr "ne peut pas importer le stockage {0}"
#: tiramisu/storage/__init__.py:72 #: tiramisu/storage/__init__.py:73
msgid "storage_type is already set, cannot rebind it" msgid "storage_type is already set, cannot rebind it"
msgstr "storage_type est déjà défini, impossible de le redéfinir" msgstr "storage_type est déjà défini, impossible de le redéfinir"
#: tiramisu/storage/dictionary/storage.py:44 #: tiramisu/storage/dictionary/storage.py:44
#: tiramisu/storage/sqlite3/storage.py:129 #: tiramisu/storage/sqlite3/storage.py:129
msgid "session \"{}\" already used" msgid "session \"{}\" already exists"
msgstr "session \"{}\" en court d'utilisation" msgstr "la session \"{}\" existe déjà"
#: tiramisu/storage/dictionary/storage.py:46 #: tiramisu/storage/dictionary/storage.py:46
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/storage/dictionary/value.py:267 #: tiramisu/storage/dictionary/value.py:265
#: tiramisu/storage/sqlite3/value.py:213 #: tiramisu/storage/sqlite3/value.py:213
msgid "information's item not found {0}" msgid "information's item not found {0}"
msgstr "l'information de l'objet ne sont pas trouvé {0}" msgstr "l'information de l'objet ne sont pas trouvé {0}"
#: tiramisu/storage/dictionary/value.py:286 #: tiramisu/storage/dictionary/value.py:284
msgid "cannot delete none persistent session" msgid "cannot delete none persistent session"
msgstr "ne peut supprimer une session non persistante" msgstr "ne peut supprimer une session non persistante"
@ -1144,40 +1132,52 @@ msgstr "l'option {} ne fonctionne que si remotable n'est pas \"none\""
msgid "unable to transform tiramisu object to dict: {}" msgid "unable to transform tiramisu object to dict: {}"
msgstr "impossible de transformer l'objet tiramisu en dict : {}" msgstr "impossible de transformer l'objet tiramisu en dict : {}"
#: tiramisu/todict.py:794 tiramisu/todict.py:926 #: tiramisu/todict.py:795 tiramisu/todict.py:927
msgid "unknown form {}" msgid "unknown form {}"
msgstr "form {} inconnu" msgstr "form {} inconnu"
#: tiramisu/todict.py:839 #: tiramisu/todict.py:840
msgid "not in current area" msgid "not in current area"
msgstr "n'est pas dans l'espace courant" msgstr "n'est pas dans l'espace courant"
#: tiramisu/todict.py:859 #: tiramisu/todict.py:860
msgid "only multi option can have action \"add\", but \"{}\" is not a multi" msgid "only multi option can have action \"add\", but \"{}\" is not a multi"
msgstr "" msgstr ""
"seules des options multiples peuvent avoir l'action \"add\", mais \"{}\" " "seules des options multiples peuvent avoir l'action \"add\", mais \"{}\" "
"n'est pas une valeur multiple" "n'est pas une valeur multiple"
#: tiramisu/todict.py:861 #: tiramisu/todict.py:862
msgid "unknown action" msgid "unknown action"
msgstr "action inconnue" msgstr "action inconnue"
#: tiramisu/value.py:428 #: tiramisu/value.py:425
msgid "can't set owner for the symlinkoption \"{}\"" msgid "can't set owner for the symlinkoption \"{}\""
msgstr "ne peut spécifier d'utilisateur à la symlinkoption \"{}\"" msgstr "ne peut spécifier d'utilisateur à la symlinkoption \"{}\""
#: tiramisu/value.py:431 tiramisu/value.py:641 #: tiramisu/value.py:428 tiramisu/value.py:638
msgid "set owner \"{0}\" is forbidden" msgid "set owner \"{0}\" is forbidden"
msgstr "assigner l'utilisateur \"{0}\" est interdit" msgstr "assigner l'utilisateur \"{0}\" est interdit"
#: tiramisu/value.py:434 #: tiramisu/value.py:431
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:512 #: tiramisu/value.py:509
msgid "index {} is greater than the length {} for option \"{}\"" msgid "index {} is greater than the length {} for option \"{}\""
msgstr "l'index {} est supérieur à la longueur \"{}\" pour l'option \"{}\"" msgstr "l'index {} est supérieur à la longueur \"{}\" pour l'option \"{}\""
#~ msgid "please use .dict() before .updates()"
#~ msgstr "faire .dict() avant .updates()"
#~ msgid "{}config's children should be config, not {}"
#~ msgstr "enfants d'un {}config doit être une config, pas {}"
#~ msgid "child has already a {}config's"
#~ msgstr "enfant a déjà un {}config"
#~ msgid "config is already in a metaconfig"
#~ msgstr "la config est déjà dans une metaconfig"
#~ msgid "some characters may cause problems" #~ msgid "some characters may cause problems"
#~ msgstr "des caractères peuvent poser problèmes" #~ msgstr "des caractères peuvent poser problèmes"

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: 2019-07-26 09:35+CEST\n" "POT-Creation-Date: 2019-08-19 14:10+CEST\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"
@ -51,46 +51,46 @@ msgstr ""
msgid "unknown method {} in {}" msgid "unknown method {} in {}"
msgstr "" msgstr ""
#: tiramisu/api.py:393 #: tiramisu/api.py:398
msgid "cannot add this property: \"{0}\"" msgid "cannot add this property: \"{0}\""
msgstr "" msgstr ""
#: tiramisu/api.py:549 tiramisu/config.py:252 #: tiramisu/api.py:554 tiramisu/config.py:239
msgid "can't delete a SymLinkOption" msgid "can't delete a SymLinkOption"
msgstr "" msgstr ""
#: tiramisu/api.py:709 tiramisu/api.py:1487 #: tiramisu/api.py:714 tiramisu/api.py:1515
msgid "please specify a valid sub function ({})" msgid "please specify a valid sub function ({})"
msgstr "" msgstr ""
#: tiramisu/api.py:770 tiramisu/api.py:1264 #: tiramisu/api.py:734
msgid "unknown list type {}"
msgstr ""
#: tiramisu/api.py:772 tiramisu/api.py:1266
msgid "unknown group_type: {0}"
msgstr ""
#: tiramisu/api.py:826 tiramisu/api.py:1296
msgid "please use .dict() before .updates()"
msgstr ""
#: tiramisu/api.py:878
msgid "unknown config type {}" msgid "unknown config type {}"
msgstr "" msgstr ""
#: tiramisu/api.py:1089 #: tiramisu/api.py:795 tiramisu/api.py:1271
msgid "unknown list type {}"
msgstr ""
#: tiramisu/api.py:797 tiramisu/api.py:1273
msgid "unknown group_type: {0}"
msgstr ""
#: tiramisu/api.py:1096
msgid "properties must be a frozenset" msgid "properties must be a frozenset"
msgstr "" msgstr ""
#: tiramisu/api.py:1095 tiramisu/api.py:1117 #: tiramisu/api.py:1102 tiramisu/api.py:1124
msgid "unknown when {} (must be in append or remove)" msgid "unknown when {} (must be in append or remove)"
msgstr "" msgstr ""
#: tiramisu/api.py:1107 tiramisu/api.py:1129 tiramisu/config.py:1268 #: tiramisu/api.py:1114 tiramisu/api.py:1136 tiramisu/config.py:1262
msgid "unknown type {}" msgid "unknown type {}"
msgstr "" msgstr ""
#: tiramisu/api.py:1440
msgid "cannot set session_id and config together"
msgstr ""
#: tiramisu/autolib.py:96 #: tiramisu/autolib.py:96
msgid "unable to carry out a calculation for \"{}\", {}" msgid "unable to carry out a calculation for \"{}\", {}"
msgstr "" msgstr ""
@ -115,39 +115,39 @@ msgstr ""
msgid "\"{0}\" must be an optiondescription, not an {1}" msgid "\"{0}\" must be an optiondescription, not an {1}"
msgstr "" msgstr ""
#: tiramisu/config.py:213 #: tiramisu/config.py:200
msgid "unknown option {}" msgid "unknown option {}"
msgstr "" msgstr ""
#: tiramisu/config.py:221 #: tiramisu/config.py:208
msgid "there is no option description for this config (may be GroupConfig)" msgid "there is no option description for this config (may be GroupConfig)"
msgstr "" msgstr ""
#: tiramisu/config.py:237 #: tiramisu/config.py:224
msgid "can't assign to a SymLinkOption" msgid "can't assign to a SymLinkOption"
msgstr "" msgstr ""
#: tiramisu/config.py:241 #: tiramisu/config.py:228
msgid "cannot reduce length of a leader \"{}\"" msgid "cannot reduce length of the leader \"{}\""
msgstr "" msgstr ""
#: tiramisu/config.py:321 #: tiramisu/config.py:308
msgid "the follower option \"{}\" has greater length ({}) than the leader length ({})" msgid "the follower option \"{}\" has greater length ({}) than the leader length ({})"
msgstr "" msgstr ""
#: tiramisu/config.py:418 #: tiramisu/config.py:405
msgid "no option found in config with these criteria" msgid "no option found in config with these criteria"
msgstr "" msgstr ""
#: tiramisu/config.py:468 #: tiramisu/config.py:455
msgid "make_dict can't filtering with value without option" msgid "make_dict can't filtering with value without option"
msgstr "" msgstr ""
#: tiramisu/config.py:521 #: tiramisu/config.py:508
msgid "unexpected path \"{0}\", should start with \"{1}\"" msgid "unexpected path \"{0}\", should start with \"{1}\""
msgstr "" msgstr ""
#: tiramisu/config.py:669 #: tiramisu/config.py:659
msgid "cannot duplicate {}" msgid "cannot duplicate {}"
msgstr "" msgstr ""
@ -159,71 +159,59 @@ msgstr ""
msgid "cannot set dynoptiondescription object has root optiondescription" msgid "cannot set dynoptiondescription object has root optiondescription"
msgstr "" msgstr ""
#: tiramisu/config.py:764 tiramisu/config.py:811 #: tiramisu/config.py:767 tiramisu/config.py:812
msgid "invalid session ID: {0} for config" msgid "invalid session ID: {0} for config"
msgstr "" msgstr ""
#: tiramisu/config.py:795 #: tiramisu/config.py:796
msgid "groupconfig's children must be a list" msgid "groupconfig's children must be a list"
msgstr "" msgstr ""
#: tiramisu/config.py:799 #: tiramisu/config.py:800
msgid "groupconfig's children must be Config, MetaConfig or GroupConfig" msgid "groupconfig's children must be Config, MetaConfig or GroupConfig"
msgstr "" msgstr ""
#: tiramisu/config.py:806 #: tiramisu/config.py:807
msgid "config name must be uniq in groupconfig for \"{0}\"" msgid "config name must be uniq in groupconfig for \"{0}\""
msgstr "" msgstr ""
#: tiramisu/config.py:976 #: tiramisu/config.py:977
msgid "unknown config \"{}\"" msgid "unknown config \"{}\""
msgstr "" msgstr ""
#: tiramisu/config.py:1003 tiramisu/config.py:1243 #: tiramisu/config.py:998
msgid "{}config's children should be config, not {}"
msgstr ""
#: tiramisu/config.py:1008
msgid "child must be a Config, MixConfig or MetaConfig" msgid "child must be a Config, MixConfig or MetaConfig"
msgstr "" msgstr ""
#: tiramisu/config.py:1010 #: tiramisu/config.py:1030
msgid "child has already a {}config's"
msgstr ""
#: tiramisu/config.py:1039
msgid "force_default, force_default_if_same or force_dont_change_value cannot be set with only_config" msgid "force_default, force_default_if_same or force_dont_change_value cannot be set with only_config"
msgstr "" msgstr ""
#: tiramisu/config.py:1061 #: tiramisu/config.py:1052
msgid "force_default and force_dont_change_value cannot be set together" msgid "force_default and force_dont_change_value cannot be set together"
msgstr "" msgstr ""
#: tiramisu/config.py:1192 #: tiramisu/config.py:1183 tiramisu/config.py:1260
msgid "config is already in a metaconfig"
msgstr ""
#: tiramisu/config.py:1194 tiramisu/config.py:1266
msgid "config name must be uniq in groupconfig for {0}" msgid "config name must be uniq in groupconfig for {0}"
msgstr "" msgstr ""
#: tiramisu/config.py:1208 #: tiramisu/config.py:1200 tiramisu/config.py:1209
msgid "cannot find the config {}" msgid "cannot find the config {}"
msgstr "" msgstr ""
#: tiramisu/config.py:1229 #: tiramisu/config.py:1231
msgid "MetaConfig with optiondescription must have string has child, not {}" msgid "MetaConfig with optiondescription must have string has child, not {}"
msgstr "" msgstr ""
#: tiramisu/config.py:1249 #: tiramisu/config.py:1243
msgid "child must be a Config or MetaConfig" msgid "child must be a Config or MetaConfig"
msgstr "" msgstr ""
#: tiramisu/config.py:1253 #: tiramisu/config.py:1247
msgid "all config in metaconfig must have the same optiondescription" msgid "all config in metaconfig must have the same optiondescription"
msgstr "" msgstr ""
#: tiramisu/config.py:1304 #: tiramisu/config.py:1298
msgid "metaconfig must have the same optiondescription" msgid "metaconfig must have the same optiondescription"
msgstr "" msgstr ""
@ -239,11 +227,11 @@ msgstr ""
msgid " {} " msgid " {} "
msgstr "" msgstr ""
#: tiramisu/error.py:105 tiramisu/setting.py:599 #: tiramisu/error.py:105 tiramisu/setting.py:601
msgid "property" msgid "property"
msgstr "" msgstr ""
#: tiramisu/error.py:107 tiramisu/setting.py:601 #: tiramisu/error.py:107 tiramisu/setting.py:603
msgid "properties" msgid "properties"
msgstr "" msgstr ""
@ -323,7 +311,7 @@ msgstr ""
msgid "params defined for a callback function but no callback defined yet for option \"{0}\"" msgid "params defined for a callback function but no callback defined yet for option \"{0}\""
msgstr "" msgstr ""
#: tiramisu/option/baseoption.py:350 tiramisu/storage/dictionary/value.py:258 #: tiramisu/option/baseoption.py:350 tiramisu/storage/dictionary/value.py:256
#: tiramisu/storage/sqlite3/value.py:201 #: tiramisu/storage/sqlite3/value.py:201
msgid "information's item not found: {0}" msgid "information's item not found: {0}"
msgstr "" msgstr ""
@ -593,35 +581,35 @@ msgstr ""
msgid "the netmask does not match with IP \"{0}\" (\"{1}\") and broadcast \"{2}\" (\"{3}\")" msgid "the netmask does not match with IP \"{0}\" (\"{1}\") and broadcast \"{2}\" (\"{3}\")"
msgstr "" msgstr ""
#: tiramisu/option/leadership.py:57 #: tiramisu/option/leadership.py:56
msgid "a leader and a follower are mandatories in leadership \"{}\"" msgid "a leader and a follower are mandatories in leadership \"{}\""
msgstr "" msgstr ""
#: tiramisu/option/leadership.py:63 #: tiramisu/option/leadership.py:62
msgid "leadership \"{0}\" shall not have a symlinkoption" msgid "leadership \"{0}\" shall not have a symlinkoption"
msgstr "" msgstr ""
#: tiramisu/option/leadership.py:66 #: tiramisu/option/leadership.py:65
msgid "leadership \"{0}\" shall not have a subgroup" msgid "leadership \"{0}\" shall not have a subgroup"
msgstr "" msgstr ""
#: tiramisu/option/leadership.py:69 #: tiramisu/option/leadership.py:68
msgid "only multi option allowed in leadership \"{0}\" but option \"{1}\" is not a multi" msgid "only multi option allowed in leadership \"{0}\" but option \"{1}\" is not a multi"
msgstr "" msgstr ""
#: tiramisu/option/leadership.py:74 #: tiramisu/option/leadership.py:73
msgid "not allowed default value for follower option \"{0}\" in leadership \"{1}\"" msgid "not allowed default value for follower option \"{0}\" in leadership \"{1}\""
msgstr "" msgstr ""
#: tiramisu/option/leadership.py:90 #: tiramisu/option/leadership.py:89
msgid "callback of leader's option shall not refered to a follower's ones" msgid "callback of leader's option shall not refered to a follower's ones"
msgstr "" msgstr ""
#: tiramisu/option/leadership.py:98 #: tiramisu/option/leadership.py:97
msgid "leader {} have requirement, but Leadership {} too" msgid "leader {} have requirement, but Leadership {} too"
msgstr "" msgstr ""
#: tiramisu/option/leadership.py:113 #: tiramisu/option/leadership.py:112
msgid "malformed requirements option \"{0}\" must not be in follower for \"{1}\"" msgid "malformed requirements option \"{0}\" must not be in follower for \"{1}\""
msgstr "" msgstr ""
@ -786,7 +774,7 @@ msgstr ""
msgid "the dynoption \"{0}\" cannot have \"force_store_value\" property" msgid "the dynoption \"{0}\" cannot have \"force_store_value\" property"
msgstr "" msgstr ""
#: tiramisu/option/optiondescription.py:99 tiramisu/setting.py:687 #: tiramisu/option/optiondescription.py:99 tiramisu/setting.py:689
msgid "a leader ({0}) cannot have \"force_default_on_freeze\" or \"force_metaconfig_on_freeze\" property without \"frozen\"" msgid "a leader ({0}) cannot have \"force_default_on_freeze\" or \"force_metaconfig_on_freeze\" property without \"frozen\""
msgstr "" msgstr ""
@ -910,63 +898,63 @@ msgstr ""
msgid "can't unbind {0}" msgid "can't unbind {0}"
msgstr "" msgstr ""
#: tiramisu/setting.py:539 #: tiramisu/setting.py:541
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:602 #: tiramisu/setting.py:604
msgid "cannot access to option \"{0}\" because required option \"{1}\" has {2} {3}" msgid "cannot access to option \"{0}\" because required option \"{1}\" has {2} {3}"
msgstr "" msgstr ""
#: tiramisu/setting.py:630 #: tiramisu/setting.py:632
msgid "the calculated value is {0}" msgid "the calculated value is {0}"
msgstr "" msgstr ""
#: tiramisu/setting.py:632 #: tiramisu/setting.py:634
msgid "the calculated value is not {0}" msgid "the calculated value is not {0}"
msgstr "" msgstr ""
#: tiramisu/setting.py:636 #: tiramisu/setting.py:638
msgid "the value of \"{0}\" is {1}" msgid "the value of \"{0}\" is {1}"
msgstr "" msgstr ""
#: tiramisu/setting.py:638 #: tiramisu/setting.py:640
msgid "the value of \"{0}\" is not {1}" msgid "the value of \"{0}\" is not {1}"
msgstr "" msgstr ""
#: tiramisu/setting.py:677 #: tiramisu/setting.py:679
msgid "cannot set property {} for option \"{}\" this property is calculated" msgid "cannot set property {} for option \"{}\" this property is calculated"
msgstr "" msgstr ""
#: tiramisu/setting.py:682 #: tiramisu/setting.py:684
msgid "can't assign property to the symlinkoption \"{}\"" msgid "can't assign property to the symlinkoption \"{}\""
msgstr "" msgstr ""
#: tiramisu/setting.py:714 #: tiramisu/setting.py:716
msgid "permissive must be a frozenset" msgid "permissive must be a frozenset"
msgstr "" msgstr ""
#: tiramisu/setting.py:718 #: tiramisu/setting.py:720
msgid "can't assign permissive to the symlinkoption \"{}\"" msgid "can't assign permissive to the symlinkoption \"{}\""
msgstr "" msgstr ""
#: tiramisu/setting.py:725 #: tiramisu/setting.py:727
msgid "cannot add those permissives: {0}" msgid "cannot add those permissives: {0}"
msgstr "" msgstr ""
#: tiramisu/setting.py:742 #: tiramisu/setting.py:744
msgid "can't reset properties to the symlinkoption \"{}\"" msgid "can't reset properties to the symlinkoption \"{}\""
msgstr "" msgstr ""
#: tiramisu/setting.py:757 #: tiramisu/setting.py:759
msgid "can't reset permissives to the symlinkoption \"{}\"" msgid "can't reset permissives to the symlinkoption \"{}\""
msgstr "" msgstr ""
#: tiramisu/storage/__init__.py:60 #: tiramisu/storage/__init__.py:61
msgid "cannot import the storage {0}" msgid "cannot import the storage {0}"
msgstr "" msgstr ""
#: tiramisu/storage/__init__.py:72 #: tiramisu/storage/__init__.py:73
msgid "storage_type is already set, cannot rebind it" msgid "storage_type is already set, cannot rebind it"
msgstr "" msgstr ""
@ -979,12 +967,12 @@ msgstr ""
msgid "a dictionary cannot be persistent" msgid "a dictionary cannot be persistent"
msgstr "" msgstr ""
#: tiramisu/storage/dictionary/value.py:267 #: tiramisu/storage/dictionary/value.py:265
#: tiramisu/storage/sqlite3/value.py:213 #: tiramisu/storage/sqlite3/value.py:213
msgid "information's item not found {0}" msgid "information's item not found {0}"
msgstr "" msgstr ""
#: tiramisu/storage/dictionary/value.py:286 #: tiramisu/storage/dictionary/value.py:284
msgid "cannot delete none persistent session" msgid "cannot delete none persistent session"
msgstr "" msgstr ""
@ -1004,35 +992,35 @@ msgstr ""
msgid "unable to transform tiramisu object to dict: {}" msgid "unable to transform tiramisu object to dict: {}"
msgstr "" msgstr ""
#: tiramisu/todict.py:794 tiramisu/todict.py:926 #: tiramisu/todict.py:795 tiramisu/todict.py:927
msgid "unknown form {}" msgid "unknown form {}"
msgstr "" msgstr ""
#: tiramisu/todict.py:839 #: tiramisu/todict.py:840
msgid "not in current area" msgid "not in current area"
msgstr "" msgstr ""
#: tiramisu/todict.py:859 #: tiramisu/todict.py:860
msgid "only multi option can have action \"add\", but \"{}\" is not a multi" msgid "only multi option can have action \"add\", but \"{}\" is not a multi"
msgstr "" msgstr ""
#: tiramisu/todict.py:861 #: tiramisu/todict.py:862
msgid "unknown action" msgid "unknown action"
msgstr "" msgstr ""
#: tiramisu/value.py:428 #: tiramisu/value.py:425
msgid "can't set owner for the symlinkoption \"{}\"" msgid "can't set owner for the symlinkoption \"{}\""
msgstr "" msgstr ""
#: tiramisu/value.py:431 tiramisu/value.py:641 #: tiramisu/value.py:428 tiramisu/value.py:638
msgid "set owner \"{0}\" is forbidden" msgid "set owner \"{0}\" is forbidden"
msgstr "" msgstr ""
#: tiramisu/value.py:434 #: tiramisu/value.py:431
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:512 #: tiramisu/value.py:509
msgid "index {} is greater than the length {} for option \"{}\"" msgid "index {} is greater than the length {} for option \"{}\""
msgstr "" msgstr ""

View File

@ -409,7 +409,7 @@ class BaseOption(Base):
def _impl_get_display_name(self, def _impl_get_display_name(self,
dyn_name: Base=None) -> str: dyn_name: Base=None) -> str:
name = self.impl_get_information('doc') name = self.impl_get_information('doc', None)
if name is None or name == '': if name is None or name == '':
if dyn_name is not None: if dyn_name is not None:
name = dyn_name name = dyn_name
@ -425,13 +425,13 @@ class BaseOption(Base):
def reset_cache(self, def reset_cache(self,
path: str, path: str,
values: Values, config_bag: 'OptionBag',
settings: Settings,
resetted_opts: List[Base]) -> None: resetted_opts: List[Base]) -> None:
settings._p_.delcache(path) context = config_bag.context
settings._pp_.delcache(path) context._impl_properties_cache.delcache(path)
context._impl_permissives_cache.delcache(path)
if not self.impl_is_optiondescription(): if not self.impl_is_optiondescription():
values._p_.delcache(path) context._impl_values_cache.delcache(path)
def impl_is_symlinkoption(self) -> bool: def impl_is_symlinkoption(self) -> bool:
return False return False

View File

@ -45,7 +45,6 @@ class Leadership(OptionDescription):
children: List[BaseOption], children: List[BaseOption],
requires=None, requires=None,
properties=None) -> None: properties=None) -> None:
super().__init__(name, super().__init__(name,
doc, doc,
children, children,
@ -182,36 +181,30 @@ class Leadership(OptionDescription):
def reset_cache(self, def reset_cache(self,
path: str, path: str,
values: Values, config_bag: 'ConfigBag',
settings: Settings,
resetted_opts: List[Option]) -> None: resetted_opts: List[Option]) -> None:
self._reset_cache(path, self._reset_cache(path,
self.get_leader(), self.get_leader(),
self.get_followers(), self.get_followers(),
values, config_bag,
settings,
resetted_opts) resetted_opts)
def _reset_cache(self, def _reset_cache(self,
path: str, path: str,
leader: Option, leader: Option,
followers: List[Option], followers: List[Option],
values: Values, config_bag: 'ConfigBag',
settings: Settings,
resetted_opts: List[Option]) -> None: resetted_opts: List[Option]) -> None:
super().reset_cache(path, super().reset_cache(path,
values, config_bag,
settings,
resetted_opts) resetted_opts)
leader.reset_cache(leader.impl_getpath(), leader.reset_cache(leader.impl_getpath(),
values, config_bag,
settings,
None) None)
for follower in followers: for follower in followers:
spath = follower.impl_getpath() spath = follower.impl_getpath()
follower.reset_cache(spath, follower.reset_cache(spath,
values, config_bag,
settings,
None) None)
resetted_opts.append(spath) resetted_opts.append(spath)

View File

@ -81,3 +81,7 @@ class SynDynOption:
def impl_is_dynsymlinkoption(self) -> bool: def impl_is_dynsymlinkoption(self) -> bool:
return True return True
def impl_get_leadership(self):
return self.opt.impl_get_leadership().to_dynoption(self.rootpath,
self.suffix)

View File

@ -117,16 +117,14 @@ class SynDynLeadership(SynDynOptionDescription):
def reset_cache(self, def reset_cache(self,
path: str, path: str,
values: Values, config_bag: 'ConfigBag',
settings: Settings,
resetted_opts: List[str]) -> None: resetted_opts: List[str]) -> None:
leader = self.get_leader() leader = self.get_leader()
followers = self.get_followers() followers = self.get_followers()
self._reset_cache(path, self._reset_cache(path,
leader, leader,
followers, followers,
values, config_bag,
settings,
resetted_opts) resetted_opts)
def pop(self, def pop(self,

View File

@ -196,7 +196,7 @@ class ConfigBag:
def __getattr__(self, key): def __getattr__(self, key):
if key == 'properties': if key == 'properties':
settings = self.context.cfgimpl_get_settings() settings = self.context.cfgimpl_get_settings()
self.properties = settings.get_context_properties() self.properties = settings.get_context_properties(self.context._impl_properties_cache)
return self.properties return self.properties
if key == 'permissives': if key == 'permissives':
settings = self.context.cfgimpl_get_settings() settings = self.context.cfgimpl_get_settings()
@ -390,22 +390,23 @@ class Settings(object):
# ____________________________________________________________ # ____________________________________________________________
# get properties and permissive methods # get properties and permissive methods
def get_context_properties(self): def get_context_properties(self,
is_cached, props, validated = self._p_.getcache(None, cache):
None, is_cached, props, validated = cache.getcache(None,
None, None,
{}, None,
{}, {},
'context_props') {},
'context_props')
if not is_cached: if not is_cached:
props = self._p_.getproperties(None, props = self._p_.getproperties(None,
self.default_properties) self.default_properties)
self._p_.setcache(None, cache.setcache(None,
None, None,
props, props,
{}, {},
props, props,
True) True)
return props return props
def getproperties(self, def getproperties(self,
@ -423,13 +424,14 @@ class Settings(object):
path = opt.impl_getpath() path = opt.impl_getpath()
if apply_requires: if apply_requires:
cache = config_bag.context._impl_properties_cache
props = config_bag.properties props = config_bag.properties
is_cached, props, validated = self._p_.getcache(path, is_cached, props, validated = cache.getcache(path,
config_bag.expiration_time, config_bag.expiration_time,
index, index,
props, props,
{}, {},
'self_props') 'self_props')
else: else:
is_cached = False is_cached = False
if not is_cached: if not is_cached:
@ -443,12 +445,12 @@ class Settings(object):
path) path)
#if apply_requires and config_bag.properties == config_bag.true_properties: #if apply_requires and config_bag.properties == config_bag.true_properties:
if apply_requires and not config_bag.is_unrestraint: if apply_requires and not config_bag.is_unrestraint:
self._p_.setcache(path, cache.setcache(path,
index, index,
props, props,
props, props,
config_bag.properties, config_bag.properties,
True) True)
return props return props
def get_context_permissives(self): def get_context_permissives(self):

View File

@ -31,6 +31,7 @@ from os.path import split
from typing import Dict from typing import Dict
from ..error import ConfigError from ..error import ConfigError
from ..i18n import _ from ..i18n import _
from .util import Cache
DEFAULT_STORAGE = MEMORY_STORAGE = 'dictionary' DEFAULT_STORAGE = MEMORY_STORAGE = 'dictionary'

View File

@ -16,26 +16,27 @@
# ____________________________________________________________ # ____________________________________________________________
class Cache(object): class Cache:
__slots__ = ('_cache',) __slots__ = ('_cache',)
def __init__(self): def __init__(self):
self._cache = {} self._cache = {}
def _setcache(self, path, index, val, time, validated): def setcache(self, path, index, val, time, validated):
self._cache.setdefault(path, {})[index] = (val, int(time), validated) self._cache.setdefault(path, {})[index] = (val, int(time), validated)
def _getcache(self, path, index): def getcache(self, path, index):
values = self._cache.get(path) values = self._cache.get(path)
if values is None: if values is None:
return return
return values.get(index) return values.get(index)
def _delcache(self, path): def delcache(self, path):
del self._cache[path] if path in self._cache:
del self._cache[path]
def _get_cached(self): def get_cached(self):
return self._cache return self._cache
def _reset_all_cache(self): def reset_all_cache(self):
self._cache.clear() self._cache.clear()

View File

@ -16,19 +16,18 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# ____________________________________________________________ # ____________________________________________________________
from copy import copy from copy import copy
from ..util import Cache
from ...log import log from ...log import log
class Properties(Cache): class Properties:
__slots__ = ('_properties',) __slots__ = ('_properties',
'_storage')
def __init__(self, storage): def __init__(self, storage):
# properties attribute: the name of a property enables this property # properties attribute: the name of a property enables this property
# key is None for global properties # key is None for global properties
self._properties = {} self._properties = {}
# permissive properties self._storage = storage
super(Properties, self).__init__(storage)
# properties # properties
def setproperties(self, path, properties): def setproperties(self, path, properties):
@ -55,13 +54,14 @@ class Properties(Cache):
self._properties = properties self._properties = properties
class Permissives(Cache): class Permissives:
__slots__ = ('_permissives',) __slots__ = ('_permissives',
'_storage')
def __init__(self, storage): def __init__(self, storage):
# permissive properties # permissive properties
self._permissives = {} self._permissives = {}
super(Permissives, self).__init__(storage) self._storage = storage
def setpermissives(self, path, permissives): def setpermissives(self, path, permissives):
log.debug('setpermissives %s %s', path, permissives) log.debug('setpermissives %s %s', path, permissives)

View File

@ -33,7 +33,7 @@ def list_sessions():
return _list_sessions return _list_sessions
class Storage(object): class Storage:
__slots__ = ('session_id', 'persistent') __slots__ = ('session_id', 'persistent')
storage = 'dictionary' storage = 'dictionary'
# if object could be serializable # if object could be serializable
@ -41,7 +41,7 @@ class Storage(object):
def __init__(self, session_id, persistent, test=False): def __init__(self, session_id, persistent, test=False):
if not test and session_id in _list_sessions: if not test and session_id in _list_sessions:
raise ConflictError(_('session "{}" already used').format(session_id)) raise ConflictError(_('session "{}" already exists').format(session_id))
if persistent: if persistent:
raise ValueError(_('a dictionary cannot be persistent')) raise ValueError(_('a dictionary cannot be persistent'))
self.session_id = session_id self.session_id = session_id

View File

@ -15,7 +15,6 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# ____________________________________________________________ # ____________________________________________________________
from ..util import Cache
from ...setting import undefined from ...setting import undefined
from ...i18n import _ from ...i18n import _
from ...log import log from ...log import log
@ -23,19 +22,18 @@ from ...log import log
from copy import deepcopy from copy import deepcopy
class Values(Cache): class Values:
__slots__ = ('_values', __slots__ = ('_values',
'_informations', '_informations',
'_storage',
'__weakref__') '__weakref__')
def __init__(self, storage): def __init__(self, storage):
"""init plugin means create values storage """init plugin means create values storage
""" """
#(('path1',), (index1,), (value1,), ('owner1')) #(('path1',), (index1,), (value1,), ('owner1'))
self._values = ([], [], [], []) self._values = ([], [], [], [])
self._informations = {} self._informations = {}
# should init cache too self._storage = storage
super(Values, self).__init__(storage)
def commit(self): def commit(self):
pass pass

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"sqlite3 cache" "sqlite3"
# Copyright (C) 2013-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2013-2019 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
@ -19,14 +19,14 @@ try:
from cPickle import loads, dumps from cPickle import loads, dumps
except ImportError: except ImportError:
from pickle import loads, dumps from pickle import loads, dumps
from ..util import Cache
class Sqlite3DB(Cache): class Sqlite3DB:
__slots__ = ('_session_id',) __slots__ = ('_session_id',
'_storage')
def __init__(self, storage): def __init__(self, storage):
self._session_id = storage.session_id self._session_id = storage.session_id
super(Sqlite3DB, self).__init__(storage) self._storage = storage
def _sqlite_decode_path(self, path): def _sqlite_decode_path(self, path):
if path == '_none': if path == '_none':

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"default plugin for cache: set it in a simple dictionary" " with sqlite3 engine"
# Copyright (C) 2013-2019 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2013-2019 Team tiramisu (see AUTHORS for all contributors)
# #
# This program is free software: you can redistribute it and/or modify it # This program is free software: you can redistribute it and/or modify it
@ -126,7 +126,7 @@ class Storage(object):
self.execute('INSERT INTO session(session, persistent) VALUES (?, ?)', self.execute('INSERT INTO session(session, persistent) VALUES (?, ?)',
(session_id, persistent)) (session_id, persistent))
except sqlite3.IntegrityError: # pragma: no cover except sqlite3.IntegrityError: # pragma: no cover
raise ConflictError(_('session "{}" already used').format(session_id)) raise ConflictError(_('session "{}" already exists').format(session_id))
self.session_id = self._cursor.lastrowid self.session_id = self._cursor.lastrowid
self.created = True self.created = True

View File

@ -25,12 +25,6 @@ def _display_classname(obj): # pragma: no cover
class Cache(DictCache): class Cache(DictCache):
__slots__ = ('_storage',)
def __init__(self, storage):
self._storage = storage
super().__init__()
def setcache(self, path, index, val, self_props, props, validated): def setcache(self, path, index, val, self_props, props, validated):
"""add val in cache for a specified path """add val in cache for a specified path
if follower, add index if follower, add index
@ -38,7 +32,7 @@ class Cache(DictCache):
if 'cache' in props or 'cache' in self_props: if 'cache' in props or 'cache' in self_props:
log.debug('setcache %s with index %s and value %s in %s (%s)', log.debug('setcache %s with index %s and value %s in %s (%s)',
path, index, val, _display_classname(self), id(self)) path, index, val, _display_classname(self), id(self))
self._setcache(path, index, val, time(), validated) super().setcache(path, index, val, time(), validated)
log.debug('not setcache %s with index %s and value %s and props %s and %s in %s (%s)', log.debug('not setcache %s with index %s and value %s and props %s and %s in %s (%s)',
path, index, val, props, self_props, _display_classname(self), id(self)) path, index, val, props, self_props, _display_classname(self), id(self))
@ -51,7 +45,7 @@ class Cache(DictCache):
type_): type_):
no_cache = False, None, False no_cache = False, None, False
if 'cache' in props or type_ == 'context_props': if 'cache' in props or type_ == 'context_props':
indexed = self._getcache(path, index) indexed = super().getcache(path, index)
if indexed is None: if indexed is None:
return no_cache return no_cache
value, timestamp, validated = indexed value, timestamp, validated = indexed
@ -89,18 +83,18 @@ class Cache(DictCache):
"""remove cache for a specified path """remove cache for a specified path
""" """
log.debug('delcache %s %s %s', path, _display_classname(self), id(self)) log.debug('delcache %s %s %s', path, _display_classname(self), id(self))
if path in self._cache: super().delcache(path)
self._delcache(path)
def reset_all_cache(self): def reset_all_cache(self):
"empty the cache" "empty the cache"
log.debug('reset_all_cache %s %s', _display_classname(self), id(self)) log.debug('reset_all_cache %s %s', _display_classname(self), id(self))
self._reset_all_cache() super().reset_all_cache()
def get_cached(self): def get_cached(self):
"""return all values in a dictionary """return all values in a dictionary
please only use it in test purpose please only use it in test purpose
example: {'path1': {'index1': ('value1', 'time1')}, 'path2': {'index2': ('value2', 'time2', )}} example: {'path1': {'index1': ('value1', 'time1')}, 'path2': {'index2': ('value2', 'time2', )}}
""" """
log.debug('get_chached %s for %s (%s)', self._cache, _display_classname(self), id(self)) cache = super().get_cached()
return self._get_cached() log.debug('get_chached %s for %s (%s)', cache, _display_classname(self), id(self))
return cache

View File

@ -467,7 +467,7 @@ class TiramisuDict:
childtype) childtype)
if schema is not None: if schema is not None:
if web_type != 'symlink': if web_type != 'symlink':
schema[path]['title'] = childapi_option.doc() schema[path]['title'] = childapi_option.description()
self.add_help(schema[path], self.add_help(schema[path],
childapi) childapi)
except Exception as err: except Exception as err:

View File

@ -62,12 +62,13 @@ class Values(object):
""" """
# try to retrive value in cache # try to retrive value in cache
setting_properties = option_bag.config_bag.properties setting_properties = option_bag.config_bag.properties
is_cached, value, validated = self._p_.getcache(option_bag.path, cache = option_bag.config_bag.context._impl_values_cache
option_bag.config_bag.expiration_time, is_cached, value, validated = cache.getcache(option_bag.path,
option_bag.index, option_bag.config_bag.expiration_time,
setting_properties, option_bag.index,
option_bag.properties, setting_properties,
'value') option_bag.properties,
'value')
if not validated: if not validated:
# no cached value so get value # no cached value so get value
value = self.getvalue(option_bag) value = self.getvalue(option_bag)
@ -79,12 +80,12 @@ class Values(object):
properties = option_bag.config_bag.properties properties = option_bag.config_bag.properties
validator = 'validator' in properties and 'demoting_error_warning' not in properties validator = 'validator' in properties and 'demoting_error_warning' not in properties
if not option_bag.fromconsistency and (not is_cached or validator): if not option_bag.fromconsistency and (not is_cached or validator):
self._p_.setcache(option_bag.path, cache.setcache(option_bag.path,
option_bag.index, option_bag.index,
value, value,
option_bag.properties, option_bag.properties,
setting_properties, setting_properties,
validator) validator)
if 'warnings' in setting_properties: if 'warnings' in setting_properties:
option_bag.option.impl_validate(value, option_bag.option.impl_validate(value,
option_bag, option_bag,
@ -139,13 +140,13 @@ class Values(object):
def getdefaultvalue(self, def getdefaultvalue(self,
option_bag): option_bag):
"""get default value: """get default value:
- get meta config value or - get parents config value or
- get calculated value or - get calculated value or
- get default value - get default value
""" """
moption_bag = self._get_meta(option_bag) moption_bag = self._get_modified_parent(option_bag)
if moption_bag: if moption_bag is not None:
# retrieved value from meta config # retrieved value from parent config
return moption_bag.config_bag.context.cfgimpl_get_values().get_cached_value(moption_bag) return moption_bag.config_bag.context.cfgimpl_get_values().get_cached_value(moption_bag)
if option_bag.option.impl_has_callback(): if option_bag.option.impl_has_callback():
@ -175,12 +176,13 @@ class Values(object):
def _reset_cache(_value): def _reset_cache(_value):
if not 'expire' in option_bag.properties: if not 'expire' in option_bag.properties:
return return
is_cache, cache_value, validated = self._p_.getcache(option_bag.path, cache = option_bag.config_bag.context._impl_values_cache
None, is_cache, cache_value, validated = cache.getcache(option_bag.path,
option_bag.index, None,
option_bag.config_bag.properties, option_bag.index,
option_bag.properties, option_bag.config_bag.properties,
'value') option_bag.properties,
'value')
if not is_cache or cache_value == _value: if not is_cache or cache_value == _value:
# calculation return same value as previous value, # calculation return same value as previous value,
# so do not invalidate cache # so do not invalidate cache
@ -257,12 +259,10 @@ class Values(object):
#______________________________________________________________________ #______________________________________________________________________
# set value # set value
def setvalue(self, def setvalue(self,
value, value,
option_bag, option_bag,
_commit): _commit):
context = option_bag.config_bag.context context = option_bag.config_bag.context
owner = self.get_context_owner() owner = self.get_context_owner()
if 'validator' in option_bag.config_bag.properties: if 'validator' in option_bag.config_bag.properties:
@ -293,7 +293,6 @@ class Values(object):
def setvalue_validation(self, def setvalue_validation(self,
value, value,
option_bag): option_bag):
settings = option_bag.config_bag.context.cfgimpl_get_settings() settings = option_bag.config_bag.context.cfgimpl_get_settings()
# First validate properties with this value # First validate properties with this value
opt = option_bag.option opt = option_bag.option
@ -315,7 +314,6 @@ class Values(object):
value, value,
owner, owner,
commit=True): commit=True):
option_bag.config_bag.context.cfgimpl_reset_cache(option_bag) option_bag.config_bag.context.cfgimpl_reset_cache(option_bag)
if isinstance(value, list): if isinstance(value, list):
# copy # copy
@ -326,38 +324,37 @@ class Values(object):
option_bag.index, option_bag.index,
commit) commit)
def _get_meta(self, def _get_modified_parent(self,
option_bag): option_bag: OptionBag) -> Optional[OptionBag]:
context = option_bag.config_bag.context """ Search in differents parents a Config with a modified value
meta = context.cfgimpl_get_meta() If not found, return None
if meta is None: For follower option, return the Config where leader is modified
return None """
if option_bag.option.impl_is_follower(): def build_option_bag(option_bag, parent):
leader = option_bag.option.impl_get_leadership().get_leader() doption_bag = option_bag.copy()
leaderpath = leader.impl_getpath() config_bag = option_bag.config_bag.copy()
# follower could be a "meta" only if leader hasn't value config_bag.context = parent
if self._p_.hasvalue(leaderpath, config_bag.unrestraint()
index=None): doption_bag.config_bag = config_bag
return None return doption_bag
doption_bag = option_bag.copy()
config_bag = option_bag.config_bag.copy() for parent in option_bag.config_bag.context.get_parents():
config_bag.context = meta doption_bag = build_option_bag(option_bag, parent)
doption_bag.config_bag = config_bag if 'force_metaconfig_on_freeze' in option_bag.properties:
if 'force_metaconfig_on_freeze' in option_bag.properties: # remove force_metaconfig_on_freeze only if option in metaconfig
# remove force_metaconfig_on_freeze only if option in metaconfig # hasn't force_metaconfig_on_freeze properties
# hasn't force_metaconfig_on_freeze properties ori_properties = doption_bag.properties
ori_properties = doption_bag.properties del doption_bag.properties
del doption_bag.properties if not self.force_to_metaconfig(doption_bag):
if not self.force_to_metaconfig(doption_bag): doption_bag.properties = ori_properties - {'force_metaconfig_on_freeze'}
doption_bag.properties = ori_properties - {'force_metaconfig_on_freeze'} else:
else: doption_bag.properties = ori_properties
doption_bag.properties = ori_properties parent_owner = parent.cfgimpl_get_values().getowner(doption_bag,
config_bag.unrestraint() only_default=True)
meta_option_bag = meta.cfgimpl_get_values().getowner(doption_bag, if parent_owner != owners.default:
only_default=True) return doption_bag
if meta_option_bag == owners.default:
return None return None
return meta_option_bag
#______________________________________________________________________ #______________________________________________________________________
@ -397,7 +394,7 @@ class Values(object):
if only_default: if only_default:
if self._p_.hasvalue(option_bag.path, if self._p_.hasvalue(option_bag.path,
option_bag.index): option_bag.index):
owner = option_bag owner = 'not_default'
else: else:
owner = owners.default owner = owners.default
else: else:
@ -406,8 +403,8 @@ class Values(object):
index=option_bag.index) index=option_bag.index)
if validate_meta is not False and (owner is owners.default or \ if validate_meta is not False and (owner is owners.default or \
'frozen' in option_bag.properties and 'force_metaconfig_on_freeze' in option_bag.properties): 'frozen' in option_bag.properties and 'force_metaconfig_on_freeze' in option_bag.properties):
moption_bag = self._get_meta(option_bag) moption_bag = self._get_modified_parent(option_bag)
if moption_bag: if moption_bag is not None:
owner = moption_bag.config_bag.context.cfgimpl_get_values().getowner(moption_bag, owner = moption_bag.config_bag.context.cfgimpl_get_values().getowner(moption_bag,
only_default=only_default) only_default=only_default)
elif 'force_metaconfig_on_freeze' in option_bag.properties: elif 'force_metaconfig_on_freeze' in option_bag.properties: