better cache
This commit is contained in:
parent
6bad3c6e64
commit
dadf859905
@ -1,3 +1,7 @@
|
||||
Sat Jul 8 15:57:13 2017 +0200 Emmanuel Garette <egarette@cadoles.com>
|
||||
* better cache, only remove value/property from cache for value
|
||||
modified and for all value affected by this modification
|
||||
|
||||
Sat May 20 16:27:09 2017 +0200 Emmanuel Garette <egarette@cadoles.com>
|
||||
* add 'operator' to requirement
|
||||
|
||||
|
@ -5,7 +5,7 @@ do_autopath()
|
||||
from tiramisu import setting, value
|
||||
setting.expires_time = 1
|
||||
value.expires_time = 1
|
||||
from tiramisu.option import IntOption, StrOption, OptionDescription
|
||||
from tiramisu.option import BoolOption, IPOption, IntOption, StrOption, OptionDescription
|
||||
from tiramisu.config import Config
|
||||
from tiramisu.error import ConfigError
|
||||
from tiramisu.setting import groups
|
||||
@ -77,31 +77,42 @@ def test_cache_reset():
|
||||
settings = c.cfgimpl_get_settings()
|
||||
#when change a value
|
||||
c.u1
|
||||
c.u2
|
||||
assert 'u1' in values._p_.get_cached(c)
|
||||
assert 'u1' in settings._p_.get_cached(c)
|
||||
assert 'u2' in values._p_.get_cached(c)
|
||||
assert 'u2' in settings._p_.get_cached(c)
|
||||
c.u2 = 1
|
||||
assert 'u1' not in values._p_.get_cached(c)
|
||||
assert 'u1' not in settings._p_.get_cached(c)
|
||||
assert 'u1' in values._p_.get_cached(c)
|
||||
assert 'u1' in settings._p_.get_cached(c)
|
||||
assert 'u2' not in values._p_.get_cached(c)
|
||||
assert 'u2' not in settings._p_.get_cached(c)
|
||||
#when remove a value
|
||||
c.u1
|
||||
assert 'u1' in values._p_.get_cached(c)
|
||||
assert 'u1' in settings._p_.get_cached(c)
|
||||
del(c.u2)
|
||||
assert 'u1' not in values._p_.get_cached(c)
|
||||
assert 'u1' not in settings._p_.get_cached(c)
|
||||
assert 'u1' in values._p_.get_cached(c)
|
||||
assert 'u1' in settings._p_.get_cached(c)
|
||||
assert 'u2' not in values._p_.get_cached(c)
|
||||
assert 'u2' not in settings._p_.get_cached(c)
|
||||
#when add/del property
|
||||
c.u1
|
||||
assert 'u1' in values._p_.get_cached(c)
|
||||
assert 'u1' in settings._p_.get_cached(c)
|
||||
c.cfgimpl_get_settings()[od1.u2].append('test')
|
||||
assert 'u1' not in values._p_.get_cached(c)
|
||||
assert 'u1' not in settings._p_.get_cached(c)
|
||||
assert 'u1' in values._p_.get_cached(c)
|
||||
assert 'u1' in settings._p_.get_cached(c)
|
||||
assert 'u2' not in values._p_.get_cached(c)
|
||||
assert 'u2' not in settings._p_.get_cached(c)
|
||||
c.u1
|
||||
assert 'u1' in values._p_.get_cached(c)
|
||||
assert 'u1' in settings._p_.get_cached(c)
|
||||
c.cfgimpl_get_settings()[od1.u2].remove('test')
|
||||
assert 'u1' not in values._p_.get_cached(c)
|
||||
assert 'u1' not in settings._p_.get_cached(c)
|
||||
assert 'u1' in values._p_.get_cached(c)
|
||||
assert 'u1' in settings._p_.get_cached(c)
|
||||
assert 'u2' not in values._p_.get_cached(c)
|
||||
assert 'u2' not in settings._p_.get_cached(c)
|
||||
#when enable/disabled property
|
||||
c.u1
|
||||
assert 'u1' in values._p_.get_cached(c)
|
||||
@ -122,34 +133,51 @@ def test_cache_reset_multi():
|
||||
c = Config(od1)
|
||||
values = c.cfgimpl_get_values()
|
||||
settings = c.cfgimpl_get_settings()
|
||||
#when change a value
|
||||
c.u1
|
||||
c.u3
|
||||
assert 'u1' in values._p_.get_cached(c)
|
||||
assert 'u1' in settings._p_.get_cached(c)
|
||||
assert 'u3' in values._p_.get_cached(c)
|
||||
assert 'u3' in settings._p_.get_cached(c)
|
||||
#when change a value
|
||||
c.u3 = [1]
|
||||
assert 'u1' not in values._p_.get_cached(c)
|
||||
assert 'u1' not in settings._p_.get_cached(c)
|
||||
assert 'u1' in values._p_.get_cached(c)
|
||||
assert 'u1' in settings._p_.get_cached(c)
|
||||
assert 'u3' not in values._p_.get_cached(c)
|
||||
assert 'u3' not in settings._p_.get_cached(c)
|
||||
#when append value
|
||||
c.u1
|
||||
c.u3
|
||||
assert 'u1' in values._p_.get_cached(c)
|
||||
assert 'u1' in settings._p_.get_cached(c)
|
||||
assert 'u3' in values._p_.get_cached(c)
|
||||
assert 'u3' in settings._p_.get_cached(c)
|
||||
c.u3.append(1)
|
||||
assert 'u1' not in values._p_.get_cached(c)
|
||||
assert 'u1' not in settings._p_.get_cached(c)
|
||||
assert 'u1' in values._p_.get_cached(c)
|
||||
assert 'u1' in settings._p_.get_cached(c)
|
||||
assert 'u3' not in values._p_.get_cached(c)
|
||||
assert 'u3' not in settings._p_.get_cached(c)
|
||||
#when pop value
|
||||
c.u1
|
||||
c.u3
|
||||
assert 'u1' in values._p_.get_cached(c)
|
||||
assert 'u1' in settings._p_.get_cached(c)
|
||||
assert 'u3' in values._p_.get_cached(c)
|
||||
assert 'u3' in settings._p_.get_cached(c)
|
||||
c.u3.pop(1)
|
||||
assert 'u1' not in values._p_.get_cached(c)
|
||||
assert 'u1' not in settings._p_.get_cached(c)
|
||||
assert 'u1' in values._p_.get_cached(c)
|
||||
assert 'u1' in settings._p_.get_cached(c)
|
||||
assert 'u3' not in values._p_.get_cached(c)
|
||||
assert 'u3' not in settings._p_.get_cached(c)
|
||||
#when remove a value
|
||||
c.u1
|
||||
assert 'u1' in values._p_.get_cached(c)
|
||||
assert 'u1' in settings._p_.get_cached(c)
|
||||
del(c.u3)
|
||||
assert 'u1' not in values._p_.get_cached(c)
|
||||
assert 'u1' not in settings._p_.get_cached(c)
|
||||
assert 'u1' in values._p_.get_cached(c)
|
||||
assert 'u1' in settings._p_.get_cached(c)
|
||||
assert 'u3' not in values._p_.get_cached(c)
|
||||
assert 'u3' not in settings._p_.get_cached(c)
|
||||
|
||||
|
||||
def test_reset_cache():
|
||||
@ -348,3 +376,210 @@ def test_cache_master_slave():
|
||||
assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
|
||||
assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([None, 0, 1])
|
||||
#DEL, insert, ...
|
||||
|
||||
|
||||
def return_value(value=None):
|
||||
return value
|
||||
|
||||
|
||||
def test_cache_callback():
|
||||
val1 = StrOption('val1', "", 'val')
|
||||
val2 = StrOption('val2', "", callback=return_value, callback_params={'': ((val1, False),)}, properties=('mandatory',))
|
||||
val3 = StrOption('val3', "", callback=return_value, callback_params={'': ('yes',)})
|
||||
val4 = StrOption('val4', "", callback=return_value, callback_params={'value': ((val1, False),)})
|
||||
val5 = StrOption('val5', "", callback=return_value, callback_params={'value': ('yes',)}, multi=True)
|
||||
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3, val4, val5])
|
||||
cfg = Config(maconfig)
|
||||
cfg.cfgimpl_get_settings().remove('expire')
|
||||
cfg.read_write()
|
||||
cfg.cfgimpl_get_values().force_cache()
|
||||
assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
|
||||
'val2': {None: (set(['mandatory']), None)},
|
||||
'val3': {None: (set([]), None)},
|
||||
'val4': {None: (set([]), None)},
|
||||
'val5': {None: (set(['empty']), None)}}
|
||||
assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1': {None: ('val', None)},
|
||||
'val2': {None: ('val', None)},
|
||||
'val3': {None: ('yes', None)},
|
||||
'val4': {None: ('val', None)},
|
||||
'val5': {None: (['yes'], None)}}
|
||||
cfg.val1 = 'new'
|
||||
assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val3': {None: (set([]), None)},
|
||||
'val5': {None: (set(['empty']), None)}}
|
||||
assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val3': {None: ('yes', None)},
|
||||
'val5': {None: (['yes'], None)}}
|
||||
cfg.cfgimpl_get_values().force_cache()
|
||||
assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
|
||||
'val2': {None: (set(['mandatory']), None)},
|
||||
'val3': {None: (set([]), None)},
|
||||
'val4': {None: (set([]), None)},
|
||||
'val5': {None: (set(['empty']), None)}}
|
||||
assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1': {None: ('new', None)},
|
||||
'val2': {None: ('new', None)},
|
||||
'val3': {None: ('yes', None)},
|
||||
'val4': {None: ('new', None)},
|
||||
'val5': {None: (['yes'], None)}}
|
||||
cfg.val3 = 'new2'
|
||||
assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
|
||||
'val2': {None: (set(['mandatory']), None)},
|
||||
'val4': {None: (set([]), None)},
|
||||
'val5': {None: (set(['empty']), None)}}
|
||||
assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1': {None: ('new', None)},
|
||||
'val2': {None: ('new', None)},
|
||||
'val4': {None: ('new', None)},
|
||||
'val5': {None: (['yes'], None)}}
|
||||
cfg.cfgimpl_get_values().force_cache()
|
||||
assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
|
||||
'val2': {None: (set(['mandatory']), None)},
|
||||
'val3': {None: (set([]), None)},
|
||||
'val4': {None: (set([]), None)},
|
||||
'val5': {None: (set(['empty']), None)}}
|
||||
assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1': {None: ('new', None)},
|
||||
'val2': {None: ('new', None)},
|
||||
'val3': {None: ('new2', None)},
|
||||
'val4': {None: ('new', None)},
|
||||
'val5': {None: (['yes'], None)}}
|
||||
cfg.val4 = 'new3'
|
||||
assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
|
||||
'val2': {None: (set(['mandatory']), None)},
|
||||
'val3': {None: (set([]), None)},
|
||||
'val5': {None: (set(['empty']), None)}}
|
||||
assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1': {None: ('new', None)},
|
||||
'val2': {None: ('new', None)},
|
||||
'val3': {None: ('new2', None)},
|
||||
'val5': {None: (['yes'], None)}}
|
||||
cfg.cfgimpl_get_values().force_cache()
|
||||
assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
|
||||
'val2': {None: (set(['mandatory']), None)},
|
||||
'val3': {None: (set([]), None)},
|
||||
'val4': {None: (set([]), None)},
|
||||
'val5': {None: (set(['empty']), None)}}
|
||||
assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1': {None: ('new', None)},
|
||||
'val2': {None: ('new', None)},
|
||||
'val3': {None: ('new2', None)},
|
||||
'val4': {None: ('new3', None)},
|
||||
'val5': {None: (['yes'], None)}}
|
||||
cfg.val5.append('new4')
|
||||
assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
|
||||
'val2': {None: (set(['mandatory']), None)},
|
||||
'val3': {None: (set([]), None)},
|
||||
'val4': {None: (set([]), None)}}
|
||||
assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1': {None: ('new', None)},
|
||||
'val2': {None: ('new', None)},
|
||||
'val3': {None: ('new2', None)},
|
||||
'val4': {None: ('new3', None)}}
|
||||
cfg.cfgimpl_get_values().force_cache()
|
||||
assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
|
||||
'val2': {None: (set(['mandatory']), None)},
|
||||
'val3': {None: (set([]), None)},
|
||||
'val4': {None: (set([]), None)},
|
||||
'val5': {None: (set(['empty']), None)}}
|
||||
assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1': {None: ('new', None)},
|
||||
'val2': {None: ('new', None)},
|
||||
'val3': {None: ('new2', None)},
|
||||
'val4': {None: ('new3', None)},
|
||||
'val5': {None: (['yes', 'new4'], None)}}
|
||||
|
||||
|
||||
def test_cache_master_and_slaves_master():
|
||||
val1 = StrOption('val1', "", multi=True)
|
||||
val2 = StrOption('val2', "", multi=True)
|
||||
interface1 = OptionDescription('val1', '', [val1, val2])
|
||||
interface1.impl_set_group_type(groups.master)
|
||||
maconfig = OptionDescription('rootconfig', '', [interface1])
|
||||
cfg = Config(maconfig)
|
||||
cfg.cfgimpl_get_settings().remove('expire')
|
||||
cfg.read_write()
|
||||
cfg.cfgimpl_get_values().force_cache()
|
||||
assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
|
||||
'val1.val1': {None: (set(['empty']), None)},
|
||||
'val1.val2': {None: (set([]), None)}}
|
||||
assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1.val1': {None: ([], None)}, 'val1.val2': {None: ([], None)}}
|
||||
cfg.val1.val1.append()
|
||||
assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)}}
|
||||
assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {}
|
||||
cfg.cfgimpl_get_values().force_cache()
|
||||
assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
|
||||
'val1.val1': {None: (set(['empty']), None)},
|
||||
'val1.val2': {None: (set([]), None), 0: (set([]), None)}}
|
||||
assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1.val1': {None: ([None], None)},
|
||||
'val1.val2': {None: ([None], None), 0: (None, None)}}
|
||||
cfg.val1.val1.append()
|
||||
cfg.cfgimpl_get_values().force_cache()
|
||||
cfg.val1.val2[1] = 'oui'
|
||||
assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
|
||||
'val1.val1': {None: (set(['empty']), None)}}
|
||||
assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1.val1': {None: ([None, None], None)}}
|
||||
cfg.cfgimpl_get_values().force_cache()
|
||||
assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
|
||||
'val1.val1': {None: (set(['empty']), None)},
|
||||
'val1.val2': {None: (set([]), None), 0: (set([]), None), 1: (set([]), None)}}
|
||||
assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1.val1': {None: ([None, None], None)},
|
||||
'val1.val2': {None: ([None, 'oui'], None), 0: (None, None), 1: ('oui', None)}}
|
||||
|
||||
|
||||
def test_cache_master_callback():
|
||||
val1 = StrOption('val1', "", multi=True)
|
||||
val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params={'value': ((val1, False),)})
|
||||
interface1 = OptionDescription('val1', '', [val1, val2])
|
||||
interface1.impl_set_group_type(groups.master)
|
||||
maconfig = OptionDescription('rootconfig', '', [interface1])
|
||||
cfg = Config(maconfig)
|
||||
cfg.cfgimpl_get_settings().remove('expire')
|
||||
cfg.read_write()
|
||||
cfg.cfgimpl_get_values().force_cache()
|
||||
assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
|
||||
'val1.val1': {None: (set(['empty']), None)},
|
||||
'val1.val2': {None: (set([]), None)}}
|
||||
assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1.val1': {None: ([], None)}, 'val1.val2': {None: ([], None)}}
|
||||
cfg.val1.val1.append()
|
||||
assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)}}
|
||||
assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {}
|
||||
cfg.cfgimpl_get_values().force_cache()
|
||||
assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {'val1': {None: (set([]), None)},
|
||||
'val1.val1': {None: (set(['empty']), None)},
|
||||
'val1.val2': {None: (set([]), None), 0: (set([]), None)}}
|
||||
assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {'val1.val1': {None: ([None], None)},
|
||||
'val1.val2': {None: ([None], None), 0: (None, None)}}
|
||||
|
||||
|
||||
def test_cache_requires():
|
||||
a = BoolOption('activate_service', '', True)
|
||||
b = IPOption('ip_address_service', '',
|
||||
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
|
||||
od = OptionDescription('service', '', [a, b])
|
||||
c = Config(od)
|
||||
c.cfgimpl_get_settings().remove('expire')
|
||||
c.read_write()
|
||||
assert c.cfgimpl_get_settings()._p_.get_cached(c) == {}
|
||||
assert c.cfgimpl_get_values()._p_.get_cached(c) == {}
|
||||
assert c.ip_address_service == None
|
||||
assert c.cfgimpl_get_settings()._p_.get_cached(c) == {'activate_service': {None: (set([]), None)},
|
||||
'ip_address_service': {None: (set([]), None)}}
|
||||
|
||||
assert c.cfgimpl_get_values()._p_.get_cached(c) == {'ip_address_service': {None: (None, None)}}
|
||||
c.cfgimpl_get_values().force_cache()
|
||||
assert c.cfgimpl_get_settings()._p_.get_cached(c) == {'activate_service': {None: (set([]), None)},
|
||||
'ip_address_service': {None: (set([]), None)}}
|
||||
|
||||
assert c.cfgimpl_get_values()._p_.get_cached(c) == {'ip_address_service': {None: (None, None)},
|
||||
'activate_service': {None: (True, None)}}
|
||||
c.ip_address_service = '1.1.1.1'
|
||||
assert c.cfgimpl_get_settings()._p_.get_cached(c) == {'activate_service': {None: (set([]), None)}}
|
||||
|
||||
assert c.cfgimpl_get_values()._p_.get_cached(c) == {'activate_service': {None: (True, None)}}
|
||||
c.cfgimpl_get_values().force_cache()
|
||||
assert c.cfgimpl_get_settings()._p_.get_cached(c) == {'activate_service': {None: (set([]), None)},
|
||||
'ip_address_service': {None: (set([]), None)}}
|
||||
|
||||
assert c.cfgimpl_get_values()._p_.get_cached(c) == {'ip_address_service': {None: ('1.1.1.1', None)},
|
||||
'activate_service': {None: (True, None)}}
|
||||
c.activate_service = False
|
||||
assert c.cfgimpl_get_settings()._p_.get_cached(c) == {}
|
||||
|
||||
assert c.cfgimpl_get_values()._p_.get_cached(c) == {}
|
||||
c.cfgimpl_get_values().force_cache()
|
||||
assert c.cfgimpl_get_settings()._p_.get_cached(c) == {'activate_service': {None: (set([]), None)},
|
||||
'ip_address_service': {None: (set(['disabled']), None)}}
|
||||
|
||||
assert c.cfgimpl_get_values()._p_.get_cached(c) == {'activate_service': {None: (False, None)}}
|
||||
|
@ -3,7 +3,7 @@ do_autopath()
|
||||
|
||||
from tiramisu.option import BoolOption, UnicodeOption, SymLinkOption, \
|
||||
IntOption, IPOption, NetmaskOption, StrOption, OptionDescription, \
|
||||
DynOptionDescription
|
||||
DynOptionDescription, MasterSlaves
|
||||
from tiramisu.config import Config, GroupConfig, MetaConfig
|
||||
from tiramisu.setting import groups, owners
|
||||
from tiramisu.storage import delete_session
|
||||
@ -118,8 +118,15 @@ def _diff_opt(opt1, opt2):
|
||||
assert val1.impl_getname() == val2.impl_getname()
|
||||
except AttributeError:
|
||||
assert val1 == val2
|
||||
elif attr == '_dependencies':
|
||||
assert len(val1) == len(val2)
|
||||
for idx, val in enumerate(val1):
|
||||
if isinstance(val, MasterSlaves):
|
||||
assert val._p_.master.impl_getname() == val2[idx]._p_.master.impl_getname()
|
||||
else:
|
||||
assert val.impl_getname() == val2[idx].impl_getname()
|
||||
else:
|
||||
assert val1 == val2
|
||||
assert val1 == val2, "error for {}".format(attr)
|
||||
|
||||
|
||||
def _diff_opts(opt1, opt2):
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2012-2013 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2012-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2012-2013 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2012-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
|
@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2012-2013 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2012-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
@ -21,6 +21,7 @@
|
||||
"options handler global entry point"
|
||||
import weakref
|
||||
import sys
|
||||
from time import time
|
||||
|
||||
|
||||
from .error import PropertiesOptionError, ConfigError, ConflictError
|
||||
@ -70,10 +71,78 @@ class SubConfig(object):
|
||||
self._impl_context = context
|
||||
self._impl_path = subpath
|
||||
|
||||
def cfgimpl_reset_cache(self, only_expired=False, only=('values',
|
||||
'settings')):
|
||||
"remove cache (in context)"
|
||||
self._cfgimpl_get_context().cfgimpl_reset_cache(only_expired, only) # pragma: optional cover
|
||||
def cfgimpl_reset_cache(self,
|
||||
only_expired=False,
|
||||
only=('values', 'settings'),
|
||||
opt=None,
|
||||
path=None):
|
||||
"""reset all settings in cache
|
||||
|
||||
:param only_expired: if True reset only expired cached values
|
||||
:type only_expired: boolean
|
||||
"""
|
||||
context = self._cfgimpl_get_context()
|
||||
if 'values' in only:
|
||||
values = context.cfgimpl_get_values()
|
||||
if 'settings' in only:
|
||||
settings = context.cfgimpl_get_settings()
|
||||
if only_expired:
|
||||
if 'values' in only:
|
||||
values._p_.reset_expired_cache(int(time()))
|
||||
if 'settings' in only:
|
||||
settings._p_.reset_expired_cache(int(time()))
|
||||
elif not None in (opt, path):
|
||||
if opt.__class__.__name__ == 'DynOptionDescription':
|
||||
descr = context.cfgimpl_get_description()
|
||||
spath = path.split('.')
|
||||
subpath = '.'.join(spath[:-1])
|
||||
dynopt = getattr(descr, subpath)._getattr(spath[-1], context=context,
|
||||
dyn=False)
|
||||
for suffix in dynopt._impl_get_suffixes(context):
|
||||
path = subpath + '.' + spath[-1] + suffix
|
||||
if 'values' in only:
|
||||
values._p_.delcache(path)
|
||||
if 'settings' in only:
|
||||
settings._p_.delcache(path)
|
||||
elif not isinstance(opt, DynSymLinkOption) and opt._is_subdyn():
|
||||
descr = context.cfgimpl_get_description()
|
||||
spath = path.split('.')
|
||||
try:
|
||||
subpath = '.'.join(spath[:-2])
|
||||
dynsubopt = getattr(descr, subpath)
|
||||
spath1 = spath[-2]
|
||||
spath2 = spath[-1]
|
||||
spath3 = None
|
||||
except AttributeError:
|
||||
subpath = '.'.join(spath[:-3])
|
||||
dynsubopt = getattr(descr, subpath)
|
||||
spath1 = spath[-3]
|
||||
spath2 = spath[-2]
|
||||
spath3 = spath[-1]
|
||||
dynopt = dynsubopt._getattr(spath1, context=context, dyn=False)
|
||||
for suffix in dynopt._impl_get_suffixes(context):
|
||||
path = subpath + '.' + spath1 + suffix + '.' + spath2 + suffix
|
||||
if spath3:
|
||||
path += '.' + spath3 + suffix
|
||||
if 'values' in only:
|
||||
values._p_.delcache(path)
|
||||
if 'settings' in only:
|
||||
settings._p_.delcache(path)
|
||||
else:
|
||||
if 'values' in only:
|
||||
values._p_.delcache(path)
|
||||
if 'settings' in only:
|
||||
settings._p_.delcache(path)
|
||||
for option in getattr(opt, '_dependencies', []):
|
||||
if 'values' in only:
|
||||
option.reset_cache(opt, values, 'values')
|
||||
if 'settings' in only:
|
||||
option.reset_cache(opt, settings, 'settings')
|
||||
else:
|
||||
if 'values' in only:
|
||||
values._p_.reset_all_cache()
|
||||
if 'settings' in only:
|
||||
settings._p_.reset_all_cache()
|
||||
|
||||
def cfgimpl_get_home_by_path(self, path, force_permissive=False,
|
||||
returns_raise=False):
|
||||
@ -678,7 +747,7 @@ class Config(_CommonConfig):
|
||||
|
||||
def __init__(self, descr, session_id=None, persistent=False,
|
||||
name=undefined, force_values=None, force_settings=None,
|
||||
_duplicate=False):
|
||||
_duplicate=False, mandatory_name=False):
|
||||
""" Configuration option management master class
|
||||
|
||||
:param descr: describes the configuration schema
|
||||
@ -700,6 +769,8 @@ class Config(_CommonConfig):
|
||||
name = 'config'
|
||||
if session_id is not None:
|
||||
name += session_id
|
||||
if mandatory_name and name is None:
|
||||
raise ValueError(_("name is mandatory for the config").format(name))
|
||||
if name is not None and not valid_name(name): # pragma: optional cover
|
||||
raise ValueError(_("invalid name: {0} for config").format(name))
|
||||
self._impl_settings = Settings(self, settings)
|
||||
@ -712,14 +783,6 @@ class Config(_CommonConfig):
|
||||
self._impl_build_all_caches()
|
||||
self._impl_name = name
|
||||
|
||||
def cfgimpl_reset_cache(self,
|
||||
only_expired=False,
|
||||
only=('values', 'settings')):
|
||||
if 'values' in only:
|
||||
self.cfgimpl_get_values().reset_cache(only_expired=only_expired)
|
||||
if 'settings' in only:
|
||||
self.cfgimpl_get_settings().reset_cache(only_expired=only_expired)
|
||||
|
||||
def impl_getname(self):
|
||||
return self._impl_name
|
||||
|
||||
@ -763,19 +826,15 @@ class GroupConfig(_CommonConfig):
|
||||
def cfgimpl_get_children(self):
|
||||
return self._impl_children
|
||||
|
||||
#def cfgimpl_get_context(self):
|
||||
# "a meta config is a config which has a setting, that is itself"
|
||||
# return self
|
||||
|
||||
def cfgimpl_reset_cache(self,
|
||||
only_expired=False,
|
||||
only=('values', 'settings')):
|
||||
if 'values' in only:
|
||||
self.cfgimpl_get_values().reset_cache(only_expired=only_expired)
|
||||
if 'settings' in only:
|
||||
self.cfgimpl_get_settings().reset_cache(only_expired=only_expired)
|
||||
only=('values', 'settings'),
|
||||
opt=None,
|
||||
path=None):
|
||||
if isinstance(self, MetaConfig):
|
||||
super(GroupConfig, self).cfgimpl_reset_cache(only_expired=only_expired, only=only, opt=opt, path=path)
|
||||
for child in self._impl_children:
|
||||
child.cfgimpl_reset_cache(only_expired=only_expired, only=only)
|
||||
child.cfgimpl_reset_cache(only_expired=only_expired, only=only, opt=opt, path=path)
|
||||
|
||||
def set_value(self, path, value):
|
||||
"""Setattr not in current GroupConfig, but in each children
|
||||
@ -906,3 +965,7 @@ class MetaConfig(GroupConfig):
|
||||
setattr(child, path, child_value)
|
||||
|
||||
setattr(self, path, value)
|
||||
|
||||
def new_config(self, session_id=None, name=undefined):
|
||||
return Config(self._impl_descr, _duplicate=True, session_id=session_id, name=name,
|
||||
mandatory_name=True)
|
||||
|
@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2012-2013 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2012-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
|
@ -1,5 +1,5 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
# Copyright (C) 2012-2013 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2012-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
|
@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2014-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
@ -25,7 +25,7 @@ import sys
|
||||
from inspect import getargspec
|
||||
|
||||
from ..i18n import _
|
||||
from ..setting import log, undefined, debug
|
||||
from ..setting import log, undefined, debug, groups
|
||||
from ..autolib import carry_out_calculation
|
||||
from ..error import (ConfigError, ValueWarning, PropertiesOptionError,
|
||||
display_list)
|
||||
@ -58,7 +58,7 @@ def valid_name(name):
|
||||
return False
|
||||
|
||||
|
||||
def validate_callback(callback, callback_params, type_):
|
||||
def validate_callback(callback, callback_params, type_, callbackoption):
|
||||
if not isinstance(callback, FunctionType):
|
||||
raise ValueError(_('{0} must be a function').format(type_))
|
||||
if callback_params is not None:
|
||||
@ -94,6 +94,17 @@ def validate_callback(callback, callback_params, type_):
|
||||
' not a {} for second argument'
|
||||
).format(type_, type(
|
||||
force_permissive)))
|
||||
if isinstance(option, SymLinkOption):
|
||||
cur_opt = option._impl_getopt()
|
||||
else:
|
||||
cur_opt = option
|
||||
if cur_opt != callbackoption:
|
||||
if not getattr(cur_opt, '_dependencies', None):
|
||||
options = []
|
||||
else:
|
||||
options = list(cur_opt._dependencies)
|
||||
options.append(callbackoption)
|
||||
cur_opt._dependencies = tuple(options)
|
||||
#____________________________________________________________
|
||||
#
|
||||
|
||||
@ -127,7 +138,7 @@ class Base(StorageBase):
|
||||
if not is_multi and unique is True:
|
||||
raise ValueError(_('unique must be set only with multi value'))
|
||||
if requires is not None:
|
||||
calc_properties, requires = validate_requires_arg(is_multi,
|
||||
calc_properties, requires = validate_requires_arg(self, is_multi,
|
||||
requires, name)
|
||||
else:
|
||||
calc_properties = frozenset()
|
||||
@ -143,7 +154,7 @@ class Base(StorageBase):
|
||||
if multi: # and validator_params is None:
|
||||
validator_params = self._build_validator_params(validator, validator_params)
|
||||
|
||||
validate_callback(validator, validator_params, 'validator')
|
||||
validate_callback(validator, validator_params, 'validator', self)
|
||||
self._set_validator(validator, validator_params)
|
||||
self._set_has_dependency()
|
||||
if calc_properties != frozenset([]) and properties is not tuple():
|
||||
@ -217,7 +228,7 @@ class Base(StorageBase):
|
||||
"cannot set another one's").format(self.impl_getname()))
|
||||
self._validate_callback(callback, callback_params)
|
||||
if callback is not None:
|
||||
validate_callback(callback, callback_params, 'callback')
|
||||
validate_callback(callback, callback_params, 'callback', self)
|
||||
self._set_callback(callback, callback_params)
|
||||
|
||||
def impl_is_optiondescription(self):
|
||||
@ -239,6 +250,36 @@ class BaseOption(Base):
|
||||
|
||||
# ____________________________________________________________
|
||||
# serialize object
|
||||
def _impl_convert_dependencies(self, descr, load=False):
|
||||
"""export of the requires during the serialization process
|
||||
|
||||
:type descr: :class:`tiramisu.option.OptionDescription`
|
||||
:param load: `True` if we are at the init of the option description
|
||||
:type load: bool
|
||||
"""
|
||||
if not load and getattr(self, '_dependencies', None) is None:
|
||||
self._state_dependencies = None
|
||||
elif load and self._state_dependencies is None:
|
||||
del(self._state_dependencies)
|
||||
else:
|
||||
if load:
|
||||
self._dependencies = []
|
||||
for dependency in self._state_dependencies:
|
||||
option = descr.impl_get_opt_by_path(dependency)
|
||||
if option.impl_is_optiondescription() and \
|
||||
option.impl_get_group_type() == groups.master:
|
||||
master_path = dependency + '.' + dependency.split('.')[-1]
|
||||
option = descr.impl_get_opt_by_path(master_path).impl_get_master_slaves()
|
||||
self._dependencies.append(option)
|
||||
del(self._state_dependencies)
|
||||
else:
|
||||
self._state_dependencies = []
|
||||
for dependency in self._dependencies:
|
||||
if isinstance(dependency, MasterSlaves):
|
||||
self._state_dependencies.append('.'.join(descr.impl_get_path_by_opt(dependency._p_.master).split('.')[:-1]))
|
||||
else:
|
||||
self._state_dependencies.append(descr.impl_get_path_by_opt(dependency))
|
||||
|
||||
def _impl_convert_requires(self, descr, load=False):
|
||||
"""export of the requires during the serialization process
|
||||
|
||||
@ -417,6 +458,14 @@ class BaseOption(Base):
|
||||
name = name.encode('utf8')
|
||||
return name
|
||||
|
||||
def reset_cache(self, opt, obj, type_):
|
||||
context = obj._getcontext()
|
||||
path = self.impl_getpath(context)
|
||||
obj._p_.delcache(path)
|
||||
context.cfgimpl_reset_cache(only=(type_,),
|
||||
opt=self,
|
||||
path=path)
|
||||
|
||||
|
||||
class OnlyOption(BaseOption):
|
||||
__slots__ = tuple()
|
||||
@ -927,7 +976,7 @@ class Option(OnlyOption):
|
||||
"is calculated").format(self.impl_getname()))
|
||||
|
||||
|
||||
def validate_requires_arg(multi, requires, name):
|
||||
def validate_requires_arg(new_option, multi, requires, name):
|
||||
"""check malformed requirements
|
||||
and tranform dict to internal tuple
|
||||
|
||||
@ -936,6 +985,14 @@ def validate_requires_arg(multi, requires, name):
|
||||
know more about
|
||||
the description of the requires dictionary
|
||||
"""
|
||||
def set_dependency(option):
|
||||
if not getattr(option, '_dependencies', None):
|
||||
options = []
|
||||
else:
|
||||
options = list(option._dependencies)
|
||||
options.append(new_option)
|
||||
option._dependencies = tuple(options)
|
||||
|
||||
def get_option(require):
|
||||
option = require['option']
|
||||
if not isinstance(option, Option):
|
||||
@ -945,6 +1002,7 @@ def validate_requires_arg(multi, requires, name):
|
||||
raise ValueError(_('malformed requirements '
|
||||
'multi option must not set '
|
||||
'as requires of non multi option {0}').format(name))
|
||||
set_dependency(option)
|
||||
return option
|
||||
|
||||
def _set_expected(action, inverse, transitive, same_action, option, expected, operator):
|
||||
@ -970,6 +1028,7 @@ def validate_requires_arg(multi, requires, name):
|
||||
raise ValueError(_('malformed requirements expected must have '
|
||||
'option and value for option {0}').format(name))
|
||||
option = exp['option']
|
||||
set_dependency(option)
|
||||
if option is not None:
|
||||
err = option._validate(exp['value'])
|
||||
if err:
|
||||
|
@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"master slave support"
|
||||
# Copyright (C) 2014 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2014-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
@ -275,3 +275,8 @@ class MasterSlaves(object):
|
||||
raise SlaveError(_("invalid len for the slave: {0}"
|
||||
" which has {1} as master").format(
|
||||
name, self.getmaster(opt).impl_getname()))
|
||||
|
||||
def reset_cache(self, opt, values, type_):
|
||||
for slave in self.getslaves(opt):
|
||||
slave_path = slave.impl_getpath(values._getcontext())
|
||||
values._p_.delcache(slave_path)
|
||||
|
@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"option types and option description"
|
||||
# Copyright (C) 2012-2013 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2012-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
@ -49,7 +49,7 @@ class ChoiceOption(Option):
|
||||
:param values: is a list of values the option can possibly take
|
||||
"""
|
||||
if isinstance(values, FunctionType):
|
||||
validate_callback(values, values_params, 'values')
|
||||
validate_callback(values, values_params, 'values', self)
|
||||
else:
|
||||
if values_params is not None:
|
||||
raise ValueError(_('values is not a function, so values_params must be None'))
|
||||
|
@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2014-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
@ -125,6 +125,13 @@ class OptionDescription(BaseOption, StorageOptionDescription):
|
||||
cache_option, force_store_values)
|
||||
#cannot set multi option as OptionDescription requires
|
||||
else:
|
||||
if option.impl_is_master_slaves('master'):
|
||||
if not getattr(option, '_dependencies', None):
|
||||
options = []
|
||||
else:
|
||||
options = list(option._dependencies)
|
||||
options.append(option.impl_get_master_slaves())
|
||||
option._dependencies = tuple(options)
|
||||
option._set_readonly(True)
|
||||
is_multi = option.impl_is_multi()
|
||||
if not isinstance(option, SymLinkOption) and 'force_store_value' in option.impl_getproperties():
|
||||
@ -132,8 +139,8 @@ class OptionDescription(BaseOption, StorageOptionDescription):
|
||||
for func, all_cons_opts, params in option._get_consistencies():
|
||||
option._valid_consistencies(all_cons_opts[1:], init=False)
|
||||
if func not in allowed_const_list and is_multi:
|
||||
is_slave = option.impl_is_master_slaves()
|
||||
if not is_slave:
|
||||
is_masterslaves = option.impl_is_master_slaves()
|
||||
if not is_masterslaves:
|
||||
raise ValueError(_('malformed consistency option "{0}" '
|
||||
'must be a master/slaves').format(
|
||||
option.impl_getname()))
|
||||
@ -178,7 +185,6 @@ class OptionDescription(BaseOption, StorageOptionDescription):
|
||||
'must not be a multi for {1}').format(
|
||||
require_opt.impl_getname(), option.impl_getname()))
|
||||
if init:
|
||||
session = config._impl_values._p_.getsession()
|
||||
if len(cache_option) != len(set(cache_option)):
|
||||
for idx in xrange(1, len(cache_option) + 1):
|
||||
opt = cache_option.pop(0)
|
||||
@ -194,7 +200,6 @@ class OptionDescription(BaseOption, StorageOptionDescription):
|
||||
self._cache_consistencies[opt] = tuple(cons)
|
||||
self._cache_force_store_values = force_store_values
|
||||
self._set_readonly(False)
|
||||
del(session)
|
||||
|
||||
|
||||
def impl_build_force_store_values(self, config):
|
||||
@ -408,8 +413,7 @@ class SynDynOptionDescription(object):
|
||||
def _impl_getchildren(self, dyn=True, context=undefined):
|
||||
children = []
|
||||
for child in self._opt._impl_getchildren():
|
||||
children.append(self._opt._impl_get_dynchild(child, self._suffix))
|
||||
return children
|
||||
yield(self._opt._impl_get_dynchild(child, self._suffix))
|
||||
|
||||
def impl_getchildren(self):
|
||||
return self._impl_getchildren()
|
||||
|
@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"sets the options of the configuration objects Config object itself"
|
||||
# Copyright (C) 2012-2013 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2012-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
@ -269,7 +269,7 @@ class Property(object):
|
||||
raise ConfigError(_('cannot add those properties: {0}').format(propname))
|
||||
self._properties.add(propname)
|
||||
if save:
|
||||
self._setting._setproperties(self._properties, self._path, force=True)
|
||||
self._setting._setproperties(self._properties, self._opt, self._path, force=True)
|
||||
|
||||
def remove(self, propname):
|
||||
"""Removes a property named propname
|
||||
@ -279,7 +279,7 @@ class Property(object):
|
||||
"""
|
||||
if propname in self._properties:
|
||||
self._properties.remove(propname)
|
||||
self._setting._setproperties(self._properties, self._path)
|
||||
self._setting._setproperties(self._properties, self._opt, self._path)
|
||||
|
||||
def extend(self, propnames):
|
||||
"""Extends properties to the existing properties
|
||||
@ -289,7 +289,7 @@ class Property(object):
|
||||
"""
|
||||
for propname in propnames:
|
||||
self._append(propname, save=False)
|
||||
self._setting._setproperties(self._properties, self._path)
|
||||
self._setting._setproperties(self._properties, self._opt, self._path)
|
||||
|
||||
def reset(self):
|
||||
"""resets the properties (does not **clear** the properties,
|
||||
@ -370,7 +370,7 @@ class Settings(object):
|
||||
if opt is not None and _path is None:
|
||||
_path = opt.impl_getpath(self._getcontext())
|
||||
self._p_.delproperties(_path)
|
||||
self._getcontext().cfgimpl_reset_cache()
|
||||
self._getcontext().cfgimpl_reset_cache(opt=opt, path=_path)
|
||||
|
||||
def _getproperties(self, opt=None, path=None,
|
||||
setting_properties=undefined, read_write=True,
|
||||
@ -415,20 +415,20 @@ class Settings(object):
|
||||
props = self._p_.getproperties(None, default_properties)
|
||||
if propname not in props:
|
||||
props.add(propname)
|
||||
self._setproperties(props, None)
|
||||
self._setproperties(props, None, None)
|
||||
|
||||
def remove(self, propname):
|
||||
"deletes property propname in the Config's properties attribute"
|
||||
props = self._p_.getproperties(None, default_properties)
|
||||
if propname in props:
|
||||
props.remove(propname)
|
||||
self._setproperties(props, None)
|
||||
self._setproperties(props, None, None)
|
||||
|
||||
def extend(self, propnames):
|
||||
for propname in propnames:
|
||||
self.append(propname)
|
||||
|
||||
def _setproperties(self, properties, path, force=False):
|
||||
def _setproperties(self, properties, opt, path, force=False):
|
||||
"""save properties for specified path
|
||||
(never save properties if same has option properties)
|
||||
"""
|
||||
@ -438,7 +438,7 @@ class Settings(object):
|
||||
raise ConfigError(_('cannot add those properties: {0}').format(
|
||||
' '.join(forbidden_properties)))
|
||||
self._p_.setproperties(path, properties)
|
||||
self._getcontext().cfgimpl_reset_cache()
|
||||
self._getcontext().cfgimpl_reset_cache(opt=opt, path=path)
|
||||
|
||||
#____________________________________________________________
|
||||
def validate_properties(self, opt_or_descr, is_descr, check_frozen, path,
|
||||
@ -541,7 +541,7 @@ class Settings(object):
|
||||
if not isinstance(permissive, tuple): # pragma: optional cover
|
||||
raise TypeError(_('permissive must be a tuple'))
|
||||
self._p_.setpermissive(path, permissive)
|
||||
self._getcontext().cfgimpl_reset_cache()
|
||||
self._getcontext().cfgimpl_reset_cache(opt=opt, path=path)
|
||||
|
||||
#____________________________________________________________
|
||||
def setowner(self, owner):
|
||||
@ -564,7 +564,7 @@ class Settings(object):
|
||||
props = props | append
|
||||
modified = True
|
||||
if modified:
|
||||
self._setproperties(props, None)
|
||||
self._setproperties(props, None, None)
|
||||
|
||||
def read_only(self):
|
||||
"convenience method to freeze, hide and disable"
|
||||
@ -574,17 +574,6 @@ class Settings(object):
|
||||
"convenience method to freeze, hide and disable"
|
||||
self._read(rw_remove, rw_append)
|
||||
|
||||
def reset_cache(self, only_expired):
|
||||
"""reset all settings in cache
|
||||
|
||||
:param only_expired: if True reset only expired cached values
|
||||
:type only_expired: boolean
|
||||
"""
|
||||
if only_expired:
|
||||
self._p_.reset_expired_cache(int(time()))
|
||||
else:
|
||||
self._p_.reset_all_cache()
|
||||
|
||||
def apply_requires(self, opt, path, setting_properties, index, debug):
|
||||
"""carries out the jit (just in time) requirements between options
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2013-2014 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2013-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
|
@ -56,6 +56,7 @@ class StorageBase(object):
|
||||
'_choice_values_params',
|
||||
#other
|
||||
'_has_dependency',
|
||||
'_dependencies',
|
||||
'_state_master_slaves',
|
||||
'_state_val_call',
|
||||
'_state_requires',
|
||||
@ -64,8 +65,9 @@ class StorageBase(object):
|
||||
'_state_informations',
|
||||
'_state_extra',
|
||||
'_state_readonly',
|
||||
'_state_dependencies',
|
||||
'__weakref__'
|
||||
)
|
||||
)
|
||||
|
||||
def __init__(self, name, multi, warnings_only, doc, extra, calc_properties,
|
||||
requires, properties, allow_empty_list, unique, opt=undefined,
|
||||
@ -588,10 +590,10 @@ class StorageMasterSlaves(object):
|
||||
|
||||
def __init__(self, master, slaves):
|
||||
self.master = master
|
||||
self.slaves = slaves
|
||||
self.slaves = tuple(slaves)
|
||||
|
||||
def _sm_getmaster(self):
|
||||
return self.master
|
||||
|
||||
def _sm_getslaves(self):
|
||||
return tuple(self.slaves)
|
||||
return self.slaves
|
||||
|
@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"default plugin for setting: set it in a simple dictionary"
|
||||
# Copyright (C) 2013 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2013-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
|
@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2013 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2013-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
|
@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"default plugin for value: set it in a simple dictionary"
|
||||
# Copyright (C) 2013-2014 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2013-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
|
@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2013 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2013-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
|
@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"utils used by storage"
|
||||
# Copyright (C) 2013 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2013-2017 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
@ -98,6 +98,9 @@ class Cache(object):
|
||||
setattr(self, key, value)
|
||||
|
||||
def setcache(self, path, val, time, index):
|
||||
"""add val in cache for a specified path
|
||||
if slave, add index
|
||||
"""
|
||||
self._cache.setdefault(path, {})[index] = (val, time)
|
||||
|
||||
def getcache(self, path, exp, index):
|
||||
@ -106,6 +109,12 @@ class Cache(object):
|
||||
return True, value
|
||||
return False, None # pragma: no cover
|
||||
|
||||
def delcache(self, path):
|
||||
"""remove cache for a specified path
|
||||
"""
|
||||
if path in self._cache:
|
||||
del self._cache[path]
|
||||
|
||||
def hascache(self, path, index):
|
||||
""" path is in the cache
|
||||
|
||||
|
@ -201,7 +201,7 @@ class Values(object):
|
||||
self._setvalue(opt, path, value, force_owner=owners.forced)
|
||||
else:
|
||||
self._p_.resetvalue(path, session)
|
||||
context.cfgimpl_reset_cache()
|
||||
context.cfgimpl_reset_cache(opt=opt, path=path)
|
||||
|
||||
def _isempty(self, opt, value, force_allow_empty_list=False, index=None):
|
||||
"convenience method to know if an option is empty"
|
||||
@ -427,7 +427,7 @@ class Values(object):
|
||||
|
||||
def _setvalue(self, opt, path, value, force_owner=undefined, index=None):
|
||||
context = self._getcontext()
|
||||
context.cfgimpl_reset_cache()
|
||||
context.cfgimpl_reset_cache(opt=opt, path=path)
|
||||
if force_owner is undefined:
|
||||
owner = context.cfgimpl_get_settings().getowner()
|
||||
else:
|
||||
@ -599,15 +599,6 @@ class Values(object):
|
||||
index=index, force_permissive=force_permissive)
|
||||
return d == owners.default
|
||||
|
||||
def reset_cache(self, only_expired):
|
||||
"""
|
||||
clears the cache if necessary
|
||||
"""
|
||||
if only_expired:
|
||||
self._p_.reset_expired_cache(int(time()))
|
||||
else:
|
||||
self._p_.reset_all_cache()
|
||||
|
||||
# information
|
||||
def set_information(self, key, value):
|
||||
"""updates the information's attribute
|
||||
@ -699,8 +690,7 @@ class Values(object):
|
||||
if not 'cache' in context.cfgimpl_get_settings():
|
||||
raise ConfigError(_('can force cache only if cache '
|
||||
'is actived in config'))
|
||||
#remove all cached properties and value to update "expired" time
|
||||
context.cfgimpl_reset_cache()
|
||||
#FIXME properties and value should update "expired" time
|
||||
for path in context.cfgimpl_get_description().impl_getpaths(
|
||||
include_groups=True):
|
||||
err = context.getattr(path, returns_raise=True)
|
||||
|
Loading…
Reference in New Issue
Block a user