From 3567e182563caec56282c6c0862f066f0a7372be Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Sun, 17 Sep 2017 15:55:32 +0200 Subject: [PATCH] several corrections about dependency --- test/test_cache.py | 38 +++++++++++---- test/test_option_calculation.py | 17 +++++++ test/test_option_consistency.py | 24 ++++++++++ test/test_option_validator.py | 34 ++++++++++++++ test/test_symlink.py | 13 ++++++ tiramisu/config.py | 47 ++++++++++++------- tiramisu/option/baseoption.py | 65 ++++++++++++++++---------- tiramisu/option/masterslave.py | 7 ++- tiramisu/option/option.py | 15 +++--- tiramisu/option/optiondescription.py | 37 ++++++++------- tiramisu/storage/sqlalchemy/setting.py | 2 - tiramisu/storage/sqlite3/storage.py | 4 +- 12 files changed, 225 insertions(+), 78 deletions(-) diff --git a/test/test_cache.py b/test/test_cache.py index 493029d..17dc30b 100644 --- a/test/test_cache.py +++ b/test/test_cache.py @@ -15,6 +15,18 @@ from time import sleep, time from py.test import raises +global incr +incr = 0 +def return_incr(): + global incr + incr += 1 + return incr + + +def return_value(val): + return val + + def make_description(): u1 = IntOption('u1', '', multi=True) u2 = IntOption('u2', '') @@ -513,8 +525,7 @@ def test_cache_master_and_slaves_master(): 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) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)}, - 'val1': {None: (set([]), None)}, - 'val1.val1': {None: (set(['empty']), None)}} + '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) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)}, @@ -527,10 +538,8 @@ def test_cache_master_and_slaves_master(): cfg.cfgimpl_get_values().force_cache() cfg.val1.val2[1] = 'oui' assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)}, - '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': {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) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)}, 'val1': {None: (set([]), None)}, @@ -557,8 +566,7 @@ def test_cache_master_callback(): 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) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)}, - 'val1': {None: (set([]), None)}, - 'val1.val1': {None: (set(['empty']), None)}} + '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) == {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings']), None)}, @@ -644,3 +652,17 @@ def test_cache_global_properties(): assert c.cfgimpl_get_settings()._p_.get_cached(c) == {None: {None: (set(['cache', 'frozen', 'hidden', 'validator', 'warnings', 'test']), None)}, 'activate_service': {None: (set([]), None)}, 'ip_address_service': {None: (set([]), None)}} + + +def test_callback_value_incr(): + val1 = IntOption('val1', "", callback=return_incr) + val2 = IntOption('val2', "", callback=return_value, callback_params={'value': ((val1, False),)}) + maconfig = OptionDescription('rootconfig', '', [val1, val2]) + cfg = Config(maconfig) + cfg.read_write() + assert cfg.val1 == 1 + sleep(1) + assert cfg.val2 == 1 + sleep(1) + assert cfg.val1 == 2 + #assert cfg.val2 == 2 diff --git a/test/test_option_calculation.py b/test/test_option_calculation.py index 2e8a34f..cc5880e 100644 --- a/test/test_option_calculation.py +++ b/test/test_option_calculation.py @@ -53,6 +53,10 @@ def is_config(config, **kwargs): return 'no' +def ret_from_config(config): + return config.val1 + + def return_raise(*arg): raise Exception('test') @@ -273,6 +277,19 @@ def test_callback_with_error(): assert cfg.val1 == 'no' +def test_callback_with_context_value(): + val1 = StrOption("val1", "") + val2 = StrOption("val2", "", callback=ret_from_config, callback_params={'': ((None,),)}) + maconfig = OptionDescription('rootconfig', '', [val1, val2]) + cfg = Config(maconfig) + cfg.val1 = 'yes' + assert cfg.val1 == 'yes' + assert cfg.val2 == 'yes' + cfg.val1 = 'no' + assert cfg.val1 == 'no' + assert cfg.val2 == 'no' + + def test_callback_value(): val1 = StrOption('val1', "", 'val') val2 = StrOption('val2', "", callback=return_value, callback_params={'': ((val1, False),)}) diff --git a/test/test_option_consistency.py b/test/test_option_consistency.py index f46b499..b6f3bcb 100644 --- a/test/test_option_consistency.py +++ b/test/test_option_consistency.py @@ -807,3 +807,27 @@ def test_consistency_network_netmask_mandatory(): c.read_only() c.cfgimpl_get_settings().remove('mandatory') c.make_dict() + + +def test_consistency_has_dependency(): + a = IPOption('a', '') + b = NetmaskOption('b', '') + od = OptionDescription('od', '', [a, b]) + b.impl_add_consistency('ip_netmask', a) + c = Config(od) + assert c.cfgimpl_get_description().a.impl_has_dependency() is True + assert c.cfgimpl_get_description().b.impl_has_dependency() is True + assert c.cfgimpl_get_description().a.impl_has_dependency(False) is True + assert c.cfgimpl_get_description().b.impl_has_dependency(False) is True + + +def test_consistency_not_equal_has_dependency(): + a = IntOption('a', '') + b = IntOption('b', '') + od = OptionDescription('od', '', [a, b]) + a.impl_add_consistency('not_equal', b) + c = Config(od) + assert c.cfgimpl_get_description().a.impl_has_dependency() is False + assert c.cfgimpl_get_description().b.impl_has_dependency() is False + assert c.cfgimpl_get_description().a.impl_has_dependency(False) is True + assert c.cfgimpl_get_description().b.impl_has_dependency(False) is True diff --git a/test/test_option_validator.py b/test/test_option_validator.py index 78b774f..a8a3c58 100644 --- a/test/test_option_validator.py +++ b/test/test_option_validator.py @@ -87,6 +87,11 @@ def value_empty(value, empty, values): raise ValueError('error') +def valid_from_config(value, config): + if config.opt1 != u'yes': + raise ValueError("c'est une erreur") + + def test_validator(): opt1 = StrOption('opt1', '', validator=return_true, default='val') raises(ValueError, "StrOption('opt2', '', validator=return_false, default='val')") @@ -284,6 +289,17 @@ def test_validator_params_context(): assert 'validator' in cfg.cfgimpl_get_settings() +def test_validator_params_context_value(): + opt1 = StrOption('opt1', '', 'yes') + opt2 = StrOption('opt2', '', validator=valid_from_config, validator_params={'': ((None,),)}, default='val') + root = OptionDescription('root', '', [opt1, opt2]) + cfg = Config(root) + assert cfg.opt1 == 'yes' + assert cfg.opt2 == 'val' + cfg.opt1 = 'no' + raises(ValueError, "cfg.opt2") + + def test_validator_params_key(): opt1 = StrOption('opt1', '', validator=return_true, validator_params={'param': ('yes',)}, default='val') raises(ConfigError, "StrOption('opt2', '', validator=return_true, validator_params={'param_unknown': ('yes',)}, default='val')") @@ -447,3 +463,21 @@ def test_validator_slave_param(): cfg.ip_admin_eth0.netmask_admin_eth0 = ['val'] cfg.ip_admin_eth0.ip_admin_eth0 = ['yes', 'yes'] cfg.ip_admin_eth0.netmask_admin_eth0[1] = 'val' + + +def test_validator_dependencies(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise") + netmask_admin_eth0 = StrOption('netmask_admin_eth0', + "masque du sous-reseau", + validator=return_true, + validator_params={'param': ((ip_admin_eth0, False),)}) + opt2 = StrOption('opt2', '', validator=return_false) + root = OptionDescription('root', '', [ip_admin_eth0, netmask_admin_eth0, opt2]) + cfg = Config(root) + assert cfg.cfgimpl_get_description().ip_admin_eth0.impl_has_dependency() is False + assert cfg.cfgimpl_get_description().netmask_admin_eth0.impl_has_dependency() is True + assert cfg.cfgimpl_get_description().opt2.impl_has_dependency() is False + # + assert cfg.cfgimpl_get_description().ip_admin_eth0.impl_has_dependency(False) is True + assert cfg.cfgimpl_get_description().netmask_admin_eth0.impl_has_dependency(False) is False + assert cfg.cfgimpl_get_description().opt2.impl_has_dependency(False) is False diff --git a/test/test_symlink.py b/test/test_symlink.py index 592d244..cf96c2a 100644 --- a/test/test_symlink.py +++ b/test/test_symlink.py @@ -145,3 +145,16 @@ def test_symlink_slaves(): interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 raises(ValueError, 'interface1.impl_set_group_type(groups.master)') + + +#____________________________________________________________ +def test_symlink_dependency(): + boolopt = BoolOption("b", "", default=False) + linkopt = SymLinkOption("c", boolopt) + descr = OptionDescription("opt", "", + [linkopt, OptionDescription("s1", "", [boolopt])]) + config = Config(descr) + assert config.cfgimpl_get_description().s1.b.impl_has_dependency() is False + assert config.cfgimpl_get_description().c.impl_has_dependency() is True + assert config.cfgimpl_get_description().s1.b.impl_has_dependency(False) is True + assert config.cfgimpl_get_description().c.impl_has_dependency(False) is False diff --git a/tiramisu/config.py b/tiramisu/config.py index 0625d46..edb6334 100644 --- a/tiramisu/config.py +++ b/tiramisu/config.py @@ -74,12 +74,15 @@ class SubConfig(object): only_expired=False, only=('values', 'properties', 'permissives', 'settings'), opt=None, - path=None): + path=None, + orig_opts=None): """reset all settings in cache :param only_expired: if True reset only expired cached values :type only_expired: boolean """ + if orig_opts is None: + orig_opts = set() context = self._cfgimpl_get_context() if 'values' in only: values = context.cfgimpl_get_values() @@ -117,11 +120,18 @@ class SubConfig(object): spath2 = spath[-1] spath3 = None except AttributeError: - subpath = '.'.join(spath[:-3]) - dynsubopt = getattr(descr, subpath) - spath1 = spath[-3] - spath2 = spath[-2] - spath3 = spath[-1] + if len(spath) == 2: + subpath = '.'.join(spath) + spath1 = spath[-2] + spath2 = spath[-1] + spath3 = None + dynsubopt = descr + else: + subpath = '.'.join(spath[:-3]) + spath1 = spath[-3] + spath2 = spath[-2] + spath3 = spath[-1] + dynsubopt = getattr(descr, subpath) dynopt = dynsubopt._getattr(spath1, context=context, dyn=False) for suffix in dynopt._impl_get_suffixes(context): path = subpath + '.' + spath1 + suffix + '.' + spath2 + suffix @@ -140,16 +150,18 @@ class SubConfig(object): settings._p_.delcache(path) if 'settings' in only or 'permissives' in only: settings._pp_.delcache(path) - for option in getattr(opt, '_dependencies', []): + for option in opt._get_dependencies(self): + if option in orig_opts: + continue if 'values' in only: - option.reset_cache(opt, values, 'values') + option.reset_cache(opt, values, 'values', orig_opts) if 'settings' in only: - option.reset_cache(opt, settings, 'settings') + option.reset_cache(opt, settings, 'settings', orig_opts) else: if 'properties' in only: - option.reset_cache(opt, settings, 'properties') + option.reset_cache(opt, settings, 'properties', orig_opts) if 'permissives' in only: - option.reset_cache(opt, settings, 'permissives') + option.reset_cache(opt, settings, 'permissives', orig_opts) else: if 'values' in only: values._p_.reset_all_cache() @@ -655,8 +667,8 @@ class _CommonConfig(SubConfig): def _impl_build_all_caches(self, force_store_values): descr = self.cfgimpl_get_description() if not descr.impl_already_build_caches(): - descr.impl_build_cache_option() - descr.impl_build_cache(self) + descr._build_cache_option() + descr._build_cache(self) descr.impl_build_force_store_values(self, force_store_values) def read_only(self): @@ -825,11 +837,14 @@ class GroupConfig(_CommonConfig): only_expired=False, only=('values', 'settings'), opt=None, - path=None): + path=None, + orig_opts=set()): if isinstance(self, MetaConfig): - super(GroupConfig, self).cfgimpl_reset_cache(only_expired=only_expired, only=only, opt=opt, path=path) + super(GroupConfig, self).cfgimpl_reset_cache(only_expired=only_expired, only=only, + opt=opt, path=path, orig_opts=orig_opts) for child in self._impl_children: - child.cfgimpl_reset_cache(only_expired=only_expired, only=only, opt=opt, path=path) + child.cfgimpl_reset_cache(only_expired=only_expired, only=only, opt=opt, path=path, + orig_opts=orig_opts) def set_value(self, path, value, _commit=True): """Setattr not in current GroupConfig, but in each children diff --git a/tiramisu/option/baseoption.py b/tiramisu/option/baseoption.py index 912ba52..6db1d09 100644 --- a/tiramisu/option/baseoption.py +++ b/tiramisu/option/baseoption.py @@ -67,7 +67,8 @@ def validate_callback(callback, callback_params, type_, callbackoption): ' not a {} for first argument' ).format(type_, type(option))) if cur_opt != callbackoption: - cur_opt._add_dependencies(callbackoption) + cur_opt._add_dependency(callbackoption) + callbackoption._has_dependency = True def _validate_force_permissive(force_permissive): #validate force_permissive @@ -84,6 +85,8 @@ def validate_callback(callback, callback_params, type_, callbackoption): raise ValueError(_('{0}_params with length of ' 'tuple as 1 must only have ' 'None as first value').format(type_)) + if callbk == ((None,)): + callbackoption._has_calc_context = True return elif len(callbk) != 2: raise ValueError(_('{0}_params must only have 1 or 2 ' @@ -126,6 +129,7 @@ class Base(object): #other '_has_dependency', '_dependencies', + '_has_calc_context', '__weakref__' ) @@ -198,12 +202,26 @@ class Base(object): validator_params[''] = tuple(params) return validator_params - def _set_has_dependency(self): - if not self._is_symlinkoption(): - self._has_dependency = True + def impl_has_dependency(self, self_is_dep=True): + if self_is_dep is True: + if self.impl_is_master_slaves(): + return True + return getattr(self, '_has_dependency', False) + else: + return hasattr(self, '_dependencies') - def impl_has_dependency(self): - return getattr(self, '_has_dependency', False) + def _get_dependencies(self, context): + if context: + od = context.cfgimpl_get_description() + if context and hasattr(od, '_dependencies'): + return set(od._dependencies) | set(getattr(self, '_dependencies', STATIC_TUPLE)) + else: + return getattr(self, '_dependencies', STATIC_TUPLE) + + def _add_dependency(self, option): + options = set(self._get_dependencies(None)) + options.add(option) + self._dependencies = tuple(options) def impl_set_callback(self, callback, callback_params=None, _init=False): if callback is None and callback_params is not None: @@ -242,7 +260,7 @@ class Base(object): def impl_getproperties(self): return self._properties - def _set_readonly(self, has_extra): + def _set_readonly(self): if not self.impl_is_readonly(): _setattr = object.__setattr__ dico = self._informations @@ -252,10 +270,9 @@ class Base(object): else: dico = tuple([keys, tuple(dico.values())]) _setattr(self, '_informations', dico) - if has_extra: - extra = getattr(self, '_extra', None) - if extra is not None: - _setattr(self, '_extra', tuple([tuple(extra.keys()), tuple(extra.values())])) + extra = getattr(self, '_extra', None) + if extra is not None: + _setattr(self, '_extra', tuple([tuple(extra.keys()), tuple(extra.values())])) def _impl_setsubdyn(self, subdyn): self._subdyn = subdyn @@ -385,13 +402,15 @@ class BaseOption(Base): name = name.encode('utf8') return name - def reset_cache(self, opt, obj, type_): + def reset_cache(self, opt, obj, type_, orig_opts): context = obj._getcontext() path = self.impl_getpath(context) obj._p_.delcache(path) + orig_opts.add(opt) context.cfgimpl_reset_cache(only=(type_,), opt=self, - path=path) + path=path, + orig_opts=orig_opts) def _is_symlinkoption(self): return False @@ -410,14 +429,6 @@ def validate_requires_arg(new_option, multi, requires, name): know more about the description of the requires dictionary """ - def set_dependency(option): - if not getattr(option, '_dependencies', None): - options = set() - else: - options = set(option._dependencies) - options.add(new_option) - option._dependencies = tuple(options) - def get_option(require): option = require['option'] if not hasattr(option, '_is_symlinkoption'): @@ -427,7 +438,7 @@ def validate_requires_arg(new_option, multi, requires, name): raise ValueError(_('malformed requirements ' 'multi option must not set ' 'as requires of non multi option {0}').format(name)) - set_dependency(option) + option._add_dependency(new_option) return option def _set_expected(action, inverse, transitive, same_action, option, expected, operator): @@ -453,7 +464,7 @@ def validate_requires_arg(new_option, multi, requires, name): raise ValueError(_('malformed requirements expected must have ' 'option and value for option {0}').format(name)) option = exp['option'] - set_dependency(option) + option._add_dependency(new_option) if option is not None: err = option._validate(exp['value']) if err: @@ -561,7 +572,13 @@ class SymLinkOption(OnlyOption): _setattr = object.__setattr__ _setattr(self, '_name', name) _setattr(self, '_opt', opt) - opt._set_has_dependency() + opt._add_dependency(self) + + def impl_has_dependency(self, self_is_dep=True): + """If self_is_dep is True, it has dependency (self._opt), so return True + if self_is_dep is False, cannot has validation or callback, so return False + """ + return self_is_dep is True def _is_symlinkoption(self): return True diff --git a/tiramisu/option/masterslave.py b/tiramisu/option/masterslave.py index 23e00f7..d6da954 100644 --- a/tiramisu/option/masterslave.py +++ b/tiramisu/option/masterslave.py @@ -58,6 +58,9 @@ class MasterSlaves(object): if add: for child in childs: child._master_slaves = self + if child != self.master: + child._add_dependency(self) + self.master._add_dependency(self) def is_master(self, opt): master = self.master.impl_getname() @@ -270,7 +273,9 @@ class MasterSlaves(object): " which has {1} as master").format( name, self.getmaster(opt).impl_getname())) - def reset_cache(self, opt, values, type_): + def reset_cache(self, opt, values, type_, orig_opts): + path = self.getmaster(opt).impl_getpath(values._getcontext()) + values._p_.delcache(path) for slave in self.getslaves(opt): slave_path = slave.impl_getpath(values._getcontext()) values._p_.delcache(slave_path) diff --git a/tiramisu/option/option.py b/tiramisu/option/option.py index 2b550e2..1024db9 100644 --- a/tiramisu/option/option.py +++ b/tiramisu/option/option.py @@ -28,6 +28,7 @@ from ..setting import log, undefined, debug from ..autolib import carry_out_calculation from ..error import (ConfigError, ValueWarning, PropertiesOptionError, display_list) +from itertools import combinations ALLOWED_CONST_LIST = ['_cons_not_equal'] @@ -93,7 +94,6 @@ class Option(OnlyOption): else: val_call = (validator, validator_params) self._val_call = (val_call, None) - self._set_has_dependency() if extra is not None: _setattr(self, '_extra', extra) if unique != undefined and not isinstance(unique, bool): @@ -131,11 +131,6 @@ class Option(OnlyOption): def impl_is_multi(self): return getattr(self, '_multi', 1) != 1 - def _add_dependencies(self, option): - options = set(getattr(self, '_dependencies', tuple())) - options.add(option) - self._dependencies = tuple(options) - def _launch_consistency(self, current_opt, func, option, value, context, index, submulti_index, opts, warnings_only, transitive): @@ -480,7 +475,7 @@ class Option(OnlyOption): if init: # FIXME if func != 'not_equal': - opt._set_has_dependency() + opt._has_dependency = True def impl_add_consistency(self, func, *other_opts, **params): """Add consistency means that value will be validate with other_opts @@ -517,7 +512,11 @@ class Option(OnlyOption): opt._unique = True if func != '_cons_not_equal': #consistency could generate warnings or errors - self._set_has_dependency() + self._has_dependency = True + for opt in all_cons_opts: + if opt != self: + self._add_dependency(opt) + opt._add_dependency(self) def _valid_consistency(self, option, value, context, index, submulti_idx, display_warnings, display_error): diff --git a/tiramisu/option/optiondescription.py b/tiramisu/option/optiondescription.py index d6d9e3b..7e77378 100644 --- a/tiramisu/option/optiondescription.py +++ b/tiramisu/option/optiondescription.py @@ -42,10 +42,12 @@ del(sys) class CacheOptionDescription(BaseOption): __slots__ = ('_cache_paths', '_cache_consistencies', '_cache_force_store_values') - def impl_build_cache(self, config, path='', _consistencies=None, - cache_option=None, force_store_values=None): + def _build_cache(self, config, path='', _consistencies=None, + cache_option=None, force_store_values=None, + _dependencies=None): """validate duplicate option and set option has readonly option """ + # cache_option is None only when we start to build cache if cache_option is None: if self.impl_is_readonly(): raise ConfigError(_('option description seems to be part of an other ' @@ -54,8 +56,10 @@ class CacheOptionDescription(BaseOption): _consistencies = {} cache_option = [] force_store_values = [] + _dependencies = [] else: init = False + for option in self._impl_getchildren(dyn=False): cache_option.append(option) if path == '': @@ -63,19 +67,14 @@ class CacheOptionDescription(BaseOption): else: subpath = path + '.' + option.impl_getname() if isinstance(option, OptionDescription): - option._set_readonly(False) - option.impl_build_cache(config, subpath, _consistencies, - cache_option, force_store_values) - #cannot set multi option as OptionDescription requires + option._set_readonly() + option._build_cache(config, subpath, _consistencies, + cache_option, force_store_values, + _dependencies) else: if option.impl_is_master_slaves('master'): - if not getattr(option, '_dependencies', None): - options = set() - else: - options = set(option._dependencies) - options.add(option.impl_get_master_slaves()) - option._dependencies = tuple(options) - option._set_readonly(True) + option._add_dependency(option.impl_get_master_slaves()) + option._set_readonly() is_multi = option.impl_is_multi() if not option._is_symlinkoption() and 'force_store_value' in option.impl_getproperties(): force_store_values.append((subpath, option)) @@ -102,6 +101,9 @@ class CacheOptionDescription(BaseOption): []).append((func, all_cons_opts, params)) + # if context is set to callback, must be reset each time a value change + if hasattr(option, '_has_calc_context'): + _dependencies.append(option) is_slave = None if is_multi: all_requires = option.impl_getrequires() @@ -142,7 +144,9 @@ class CacheOptionDescription(BaseOption): opt.impl_getname())) self._cache_consistencies[opt] = tuple(cons) self._cache_force_store_values = force_store_values - self._set_readonly(False) + if _dependencies: + self._dependencies = tuple(_dependencies) + self._set_readonly() def impl_already_build_caches(self): return getattr(self, '_cache_paths', None) is not None @@ -171,7 +175,7 @@ class CacheOptionDescription(BaseOption): if value_set: config._impl_values._p_.commit() - def impl_build_cache_option(self, _currpath=None, cache_path=None, + def _build_cache_option(self, _currpath=None, cache_path=None, cache_option=None): if self.impl_is_readonly() or (_currpath is None and getattr(self, '_cache_paths', None) is not None): @@ -192,7 +196,7 @@ class CacheOptionDescription(BaseOption): cache_path.append(path) if option.impl_is_optiondescription(): _currpath.append(attr) - option.impl_build_cache_option(_currpath, cache_path, + option._build_cache_option(_currpath, cache_path, cache_option) _currpath.pop() if save: @@ -471,7 +475,6 @@ class OptionDescription(OptionDescriptionWalk): ": this option is not a multi" "").format(child.impl_getname(), self.impl_getname())) #length of master change slaves length - self._set_has_dependency() MasterSlaves(self.impl_getname(), children) else: # pragma: optional cover raise ValueError(_('group_type: {0}' diff --git a/tiramisu/storage/sqlalchemy/setting.py b/tiramisu/storage/sqlalchemy/setting.py index eb84be9..cb8f00d 100644 --- a/tiramisu/storage/sqlalchemy/setting.py +++ b/tiramisu/storage/sqlalchemy/setting.py @@ -131,8 +131,6 @@ class Settings(Cache, SqlAlchemyBase): def delete_session(session_id, session): - print session.query(_Property).all() - print session.query(_Permissive).all() settings_id = session.query(Settings).filter_by(session_id=session_id).first().id for val in session.query(_Property).filter_by(settings=settings_id).all(): session.delete(val) diff --git a/tiramisu/storage/sqlite3/storage.py b/tiramisu/storage/sqlite3/storage.py index b2aa54f..8c1a8f0 100644 --- a/tiramisu/storage/sqlite3/storage.py +++ b/tiramisu/storage/sqlite3/storage.py @@ -83,8 +83,8 @@ class Storage(object): values_table = 'CREATE TABLE IF NOT EXISTS value(path TEXT, ' values_table += 'value TEXT, owner TEXT, idx INTEGER, session_id TEXT NOT NULL, '\ 'PRIMARY KEY (path, idx, session_id))' - informations_table = 'CREATE TABLE IF NOT EXISTS information(key TEXT ' - informations_table += 'KEY, value TEXT, session_id TEXT NOT NULL, ' + informations_table = 'CREATE TABLE IF NOT EXISTS information(key TEXT,' + informations_table += 'value TEXT, session_id TEXT NOT NULL, ' informations_table += 'PRIMARY KEY (key, session_id))' self.execute(values_table, commit=False) self.execute(informations_table, commit=False)