optimize
This commit is contained in:
parent
4df36a5548
commit
620e8bbf2e
10 changed files with 231 additions and 219 deletions
|
@ -709,7 +709,7 @@ def test_groups_with_leader_importation():
|
||||||
maconfig = OptionDescription('toto', '', [interface1])
|
maconfig = OptionDescription('toto', '', [interface1])
|
||||||
api = Config(maconfig)
|
api = Config(maconfig)
|
||||||
api.property.read_write()
|
api.property.read_write()
|
||||||
api.value.importation((('ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0',), (None, (0, 1)), (('192.168.1.1', '192.168.1.0'), ('255.255.255.255', '255.255.255.0')), ('user', ('user', 'user'))))
|
api.value.importation([['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'], [None, [0, 1]], [['192.168.1.1', '192.168.1.0'], ['255.255.255.255', '255.255.255.0']], ['user', ['user', 'user']]])
|
||||||
api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1', '192.168.1.0']
|
api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1', '192.168.1.0']
|
||||||
api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.255.255'
|
api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.255.255'
|
||||||
api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == '255.255.255.0'
|
api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == '255.255.255.0'
|
||||||
|
|
109
tiramisu/api.py
109
tiramisu/api.py
|
@ -101,7 +101,7 @@ class CommonTiramisu(TiramisuHelp):
|
||||||
raise APIError('index must be set only with a follower option')
|
raise APIError('index must be set only with a follower option')
|
||||||
self._length = self._subconfig.cfgimpl_get_length_leadership(self._option_bag)
|
self._length = self._subconfig.cfgimpl_get_length_leadership(self._option_bag)
|
||||||
if index >= self._length:
|
if index >= self._length:
|
||||||
raise LeadershipError(_('index "{}" is higher than the leadership length "{}" '
|
raise LeadershipError(_('index "{}" is greater than the leadership length "{}" '
|
||||||
'for option "{}"').format(index,
|
'for option "{}"').format(index,
|
||||||
self._length,
|
self._length,
|
||||||
option.impl_get_display_name()))
|
option.impl_get_display_name()))
|
||||||
|
@ -118,7 +118,8 @@ class CommonTiramisuOption(CommonTiramisu):
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
name: str,
|
name: str,
|
||||||
subconfig: Union[KernelConfig, SubConfig],
|
subconfig: Union[KernelConfig, SubConfig],
|
||||||
option_bag: OptionBag) -> None:
|
option_bag: OptionBag,
|
||||||
|
config: 'Config'=None) -> None:
|
||||||
self._option_bag = option_bag
|
self._option_bag = option_bag
|
||||||
self._name = name
|
self._name = name
|
||||||
self._subconfig = subconfig
|
self._subconfig = subconfig
|
||||||
|
@ -136,7 +137,7 @@ class CommonTiramisuOption(CommonTiramisu):
|
||||||
raise APIError(_('index must be set with the follower option "{}"').format(self._option_bag.path))
|
raise APIError(_('index must be set with the follower option "{}"').format(self._option_bag.path))
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
raise APIError(_('unknown method {}').format(name))
|
raise APIError(_('unknown method {} in {}').format(name, self.__class__.__name__))
|
||||||
|
|
||||||
|
|
||||||
class _TiramisuOptionOptionDescription(CommonTiramisuOption):
|
class _TiramisuOptionOptionDescription(CommonTiramisuOption):
|
||||||
|
@ -144,6 +145,14 @@ class _TiramisuOptionOptionDescription(CommonTiramisuOption):
|
||||||
_allow_optiondescription = True
|
_allow_optiondescription = True
|
||||||
_follower_need_index = False
|
_follower_need_index = False
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
name: str,
|
||||||
|
subconfig: Union[KernelConfig, SubConfig],
|
||||||
|
option_bag: OptionBag,
|
||||||
|
config: "Subconfig") -> None:
|
||||||
|
super().__init__(name, subconfig, option_bag)
|
||||||
|
self._config = config
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
"""Get Tiramisu option"""
|
"""Get Tiramisu option"""
|
||||||
return self._option_bag.option
|
return self._option_bag.option
|
||||||
|
@ -195,27 +204,22 @@ class _TiramisuOptionOptionDescription(CommonTiramisuOption):
|
||||||
only_raises=False):
|
only_raises=False):
|
||||||
"""Get properties for an option"""
|
"""Get properties for an option"""
|
||||||
settings = self._option_bag.config_bag.context.cfgimpl_get_settings()
|
settings = self._option_bag.config_bag.context.cfgimpl_get_settings()
|
||||||
properties = settings.getproperties(self._option_bag,
|
|
||||||
apply_requires=False)
|
|
||||||
if not only_raises:
|
if not only_raises:
|
||||||
return properties
|
return settings.getproperties(self._option_bag,
|
||||||
|
apply_requires=False)
|
||||||
# do not check cache properties/permissives which are not save (unrestraint, ...)
|
# do not check cache properties/permissives which are not save (unrestraint, ...)
|
||||||
return settings.calc_raises_properties(properties,
|
return settings.calc_raises_properties(self._option_bag,
|
||||||
settings.get_context_properties(),
|
apply_requires=False)
|
||||||
settings.get_context_properties())
|
|
||||||
|
|
||||||
def __call__(self,
|
def __call__(self,
|
||||||
path: str,
|
name: str,
|
||||||
index: Optional[int]=None) -> 'TiramisuOption':
|
index: Optional[int]=None) -> 'TiramisuOption':
|
||||||
"""Select an option by path"""
|
"""Select an option by path"""
|
||||||
subpath = self._option_bag.option.impl_getname() + '.' + path
|
path = self._option_bag.path + '.' + name
|
||||||
subconfig, name = self._subconfig.cfgimpl_get_home_by_path(subpath,
|
|
||||||
self._option_bag.config_bag)
|
|
||||||
path = self._option_bag.path + '.' + path
|
|
||||||
return TiramisuOption(name,
|
return TiramisuOption(name,
|
||||||
path,
|
path,
|
||||||
index,
|
index,
|
||||||
subconfig,
|
self._config,
|
||||||
self._option_bag.config_bag)
|
self._option_bag.config_bag)
|
||||||
|
|
||||||
|
|
||||||
|
@ -288,18 +292,18 @@ class TiramisuOptionOption(CommonTiramisuOption):
|
||||||
def __new__(cls,
|
def __new__(cls,
|
||||||
name,
|
name,
|
||||||
subconfig,
|
subconfig,
|
||||||
option_bag):
|
option_bag,
|
||||||
option = subconfig.cfgimpl_get_description().get_child(name,
|
config):
|
||||||
option_bag.config_bag,
|
if option_bag.option.impl_is_optiondescription():
|
||||||
subconfig.cfgimpl_get_path())
|
|
||||||
if option.impl_is_optiondescription():
|
|
||||||
return _TiramisuOptionOptionDescription(name=name,
|
return _TiramisuOptionOptionDescription(name=name,
|
||||||
subconfig=subconfig,
|
subconfig=subconfig,
|
||||||
option_bag=option_bag)
|
option_bag=option_bag,
|
||||||
|
config=config)
|
||||||
else:
|
else:
|
||||||
return _TiramisuOptionOption(name=name,
|
return _TiramisuOptionOption(name=name,
|
||||||
subconfig=subconfig,
|
subconfig=subconfig,
|
||||||
option_bag=option_bag)
|
option_bag=option_bag,
|
||||||
|
config=config)
|
||||||
|
|
||||||
|
|
||||||
class TiramisuOptionOwner(CommonTiramisuOption):
|
class TiramisuOptionOwner(CommonTiramisuOption):
|
||||||
|
@ -309,7 +313,8 @@ class TiramisuOptionOwner(CommonTiramisuOption):
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
name: str,
|
name: str,
|
||||||
subconfig: Union[KernelConfig, SubConfig],
|
subconfig: Union[KernelConfig, SubConfig],
|
||||||
option_bag: OptionBag) -> None:
|
option_bag: OptionBag,
|
||||||
|
config: Optional['SubConfig']) -> None:
|
||||||
|
|
||||||
super().__init__(name,
|
super().__init__(name,
|
||||||
subconfig,
|
subconfig,
|
||||||
|
@ -348,7 +353,8 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
name: str,
|
name: str,
|
||||||
subconfig: Union[KernelConfig, SubConfig],
|
subconfig: Union[KernelConfig, SubConfig],
|
||||||
option_bag: OptionBag) -> None:
|
option_bag: OptionBag,
|
||||||
|
config: Optional['SubConfig']) -> None:
|
||||||
super().__init__(name,
|
super().__init__(name,
|
||||||
subconfig,
|
subconfig,
|
||||||
option_bag)
|
option_bag)
|
||||||
|
@ -360,13 +366,10 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
||||||
"""Get properties for an option"""
|
"""Get properties for an option"""
|
||||||
option = self._option_bag.option
|
option = self._option_bag.option
|
||||||
self._test_follower_index()
|
self._test_follower_index()
|
||||||
properties = self._option_bag.properties
|
|
||||||
if not only_raises:
|
if not only_raises:
|
||||||
return properties
|
return self._option_bag.properties
|
||||||
# do not check cache properties/permissives which are not save (unrestraint, ...)
|
# do not check cache properties/permissives which are not save (unrestraint, ...)
|
||||||
return self._settings.calc_raises_properties(properties,
|
return self._settings.calc_raises_properties(self._option_bag)
|
||||||
self._settings.get_context_properties(),
|
|
||||||
self._settings.get_context_properties())
|
|
||||||
|
|
||||||
def add(self, prop):
|
def add(self, prop):
|
||||||
"""Add new property for an option"""
|
"""Add new property for an option"""
|
||||||
|
@ -406,7 +409,8 @@ class TiramisuOptionPermissive(CommonTiramisuOption):
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
name: str,
|
name: str,
|
||||||
subconfig: Union[KernelConfig, SubConfig],
|
subconfig: Union[KernelConfig, SubConfig],
|
||||||
option_bag: OptionBag) -> None:
|
option_bag: OptionBag,
|
||||||
|
config: Optional['SubConfig']) -> None:
|
||||||
super().__init__(name,
|
super().__init__(name,
|
||||||
subconfig,
|
subconfig,
|
||||||
option_bag)
|
option_bag)
|
||||||
|
@ -554,6 +558,7 @@ class _TiramisuOptionValueChoiceOption:
|
||||||
|
|
||||||
|
|
||||||
class _TiramisuOptionValueOptionDescription:
|
class _TiramisuOptionValueOptionDescription:
|
||||||
|
|
||||||
def dict(self,
|
def dict(self,
|
||||||
flatten=False,
|
flatten=False,
|
||||||
withvalue=undefined,
|
withvalue=undefined,
|
||||||
|
@ -583,18 +588,15 @@ class TiramisuOptionValue(CommonTiramisuOption):
|
||||||
def __new__(cls,
|
def __new__(cls,
|
||||||
name,
|
name,
|
||||||
subconfig,
|
subconfig,
|
||||||
option_bag):
|
option_bag,
|
||||||
if subconfig is not None:
|
config):
|
||||||
|
types = [CommonTiramisuOption]
|
||||||
|
if option_bag.option and option_bag.option.impl_is_optiondescription():
|
||||||
|
types.append(_TiramisuOptionValueOptionDescription)
|
||||||
|
elif subconfig is not None:
|
||||||
option = subconfig.cfgimpl_get_description().get_child(name,
|
option = subconfig.cfgimpl_get_description().get_child(name,
|
||||||
option_bag.config_bag,
|
option_bag.config_bag,
|
||||||
subconfig.cfgimpl_get_path())
|
subconfig.cfgimpl_get_path())
|
||||||
else:
|
|
||||||
option = None
|
|
||||||
types = [CommonTiramisuOption]
|
|
||||||
if option:
|
|
||||||
if option.impl_is_optiondescription():
|
|
||||||
types.append(_TiramisuOptionValueOptionDescription)
|
|
||||||
else:
|
|
||||||
types.append(_TiramisuOptionValueOption)
|
types.append(_TiramisuOptionValueOption)
|
||||||
if isinstance(option, ChoiceOption):
|
if isinstance(option, ChoiceOption):
|
||||||
types.append(_TiramisuOptionValueChoiceOption)
|
types.append(_TiramisuOptionValueChoiceOption)
|
||||||
|
@ -606,6 +608,12 @@ class TiramisuOptionValue(CommonTiramisuOption):
|
||||||
types.append(_TiramisuOptionValueGroup)
|
types.append(_TiramisuOptionValueGroup)
|
||||||
new_type_dict = {'_allow_optiondescription': cls._allow_optiondescription,
|
new_type_dict = {'_allow_optiondescription': cls._allow_optiondescription,
|
||||||
'_follower_need_index': cls._follower_need_index}
|
'_follower_need_index': cls._follower_need_index}
|
||||||
|
if option_bag.option and option_bag.option.impl_is_optiondescription():
|
||||||
|
new_type = type('TiramisuOptionValue', tuple(types), new_type_dict)(name=name,
|
||||||
|
subconfig=subconfig,
|
||||||
|
option_bag=option_bag,
|
||||||
|
config=config)
|
||||||
|
else:
|
||||||
new_type = type('TiramisuOptionValue', tuple(types), new_type_dict)(name=name,
|
new_type = type('TiramisuOptionValue', tuple(types), new_type_dict)(name=name,
|
||||||
subconfig=subconfig,
|
subconfig=subconfig,
|
||||||
option_bag=option_bag)
|
option_bag=option_bag)
|
||||||
|
@ -642,14 +650,31 @@ class _TiramisuOption(CommonTiramisu):
|
||||||
self._option_bag.index = self._index
|
self._option_bag.index = self._index
|
||||||
self._option_bag.config_bag = self._config_bag
|
self._option_bag.config_bag = self._config_bag
|
||||||
self._tiramisu_dict = None
|
self._tiramisu_dict = None
|
||||||
|
self._config = None
|
||||||
if not self._registers:
|
if not self._registers:
|
||||||
_registers(self._registers, 'TiramisuOption')
|
_registers(self._registers, 'TiramisuOption')
|
||||||
|
|
||||||
|
def _get_config(self):
|
||||||
|
if self._config is None and self._subconfig is not None:
|
||||||
|
self._config = self._subconfig.get_subconfig(self._option_bag)
|
||||||
|
return self._config
|
||||||
|
|
||||||
def __getattr__(self, subfunc: str) -> Any:
|
def __getattr__(self, subfunc: str) -> Any:
|
||||||
if subfunc in self._registers:
|
if subfunc in self._registers:
|
||||||
|
subconfig = self._subconfig
|
||||||
|
if subconfig:
|
||||||
|
option_bag = self._option_bag
|
||||||
|
option = self._get_option()
|
||||||
|
if option.impl_is_optiondescription() and subfunc == 'option':
|
||||||
|
config = self._get_config()
|
||||||
|
else:
|
||||||
|
config = None
|
||||||
|
else:
|
||||||
|
config = None
|
||||||
return self._registers[subfunc](self._name,
|
return self._registers[subfunc](self._name,
|
||||||
self._subconfig,
|
subconfig,
|
||||||
self._option_bag)
|
self._option_bag,
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
@ -1240,7 +1265,7 @@ class _TiramisuContextConfigReset():
|
||||||
"""Remove all datas to current config (informations, values, properties, ...)"""
|
"""Remove all datas to current config (informations, values, properties, ...)"""
|
||||||
# Option's values
|
# Option's values
|
||||||
context_owner = self._config_bag.context.cfgimpl_get_values().get_context_owner()
|
context_owner = self._config_bag.context.cfgimpl_get_values().get_context_owner()
|
||||||
self._config_bag.context.cfgimpl_get_values()._p_.importation((tuple(), tuple(), tuple(), tuple()))
|
self._config_bag.context.cfgimpl_get_values()._p_.importation(([], [], [], []))
|
||||||
self._config_bag.context.cfgimpl_get_values()._p_.setvalue(None,
|
self._config_bag.context.cfgimpl_get_values()._p_.setvalue(None,
|
||||||
None,
|
None,
|
||||||
context_owner,
|
context_owner,
|
||||||
|
|
|
@ -254,18 +254,20 @@ def carry_out_calculation(option,
|
||||||
if isinstance(ret, list) and not option.impl_is_dynoptiondescription() and \
|
if isinstance(ret, list) and not option.impl_is_dynoptiondescription() and \
|
||||||
option.impl_is_follower():
|
option.impl_is_follower():
|
||||||
if args or kwargs:
|
if args or kwargs:
|
||||||
raise LeadershipError(_('function "{}" with arguments "{}" and "{}" '
|
raise LeadershipError(_('the "{}" function with positional arguments "{}" '
|
||||||
'return the list "{}" for the follower option "{}"'
|
'and keyword arguments "{}" must not return '
|
||||||
|
'a list ("{}") for the follower option "{}"'
|
||||||
'').format(callback.__name__,
|
'').format(callback.__name__,
|
||||||
args,
|
args,
|
||||||
kwargs,
|
kwargs,
|
||||||
ret,
|
ret,
|
||||||
option.impl_get_display_name()))
|
option.impl_get_display_name()))
|
||||||
else:
|
else:
|
||||||
raise LeadershipError(_('function "{}" return the list "{}" for the follower option "{}"'
|
raise LeadershipError(_('the "{}" function must not return a list ("{}") '
|
||||||
|
'for the follower option "{}"'
|
||||||
'').format(callback.__name__,
|
'').format(callback.__name__,
|
||||||
ret,
|
ret,
|
||||||
option.impl_getname()))
|
option.impl_get_display_name()))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -281,7 +281,8 @@ class SubConfig(object):
|
||||||
|
|
||||||
def getattr(self,
|
def getattr(self,
|
||||||
name,
|
name,
|
||||||
option_bag):
|
option_bag,
|
||||||
|
from_follower=False):
|
||||||
"""
|
"""
|
||||||
attribute notation mechanism for accessing the value of an option
|
attribute notation mechanism for accessing the value of an option
|
||||||
:param name: attribute name
|
:param name: attribute name
|
||||||
|
@ -310,14 +311,15 @@ class SubConfig(object):
|
||||||
return context.getattr(soption_bag.path,
|
return context.getattr(soption_bag.path,
|
||||||
soption_bag)
|
soption_bag)
|
||||||
|
|
||||||
|
if not from_follower or option_bag.option.impl_getrequires():
|
||||||
self.cfgimpl_get_settings().validate_properties(option_bag)
|
self.cfgimpl_get_settings().validate_properties(option_bag)
|
||||||
|
|
||||||
if option.impl_is_follower():
|
if option.impl_is_follower() and not from_follower:
|
||||||
length = self.cfgimpl_get_length_leadership(option_bag)
|
length = self.cfgimpl_get_length_leadership(option_bag)
|
||||||
follower_len = self.cfgimpl_get_values()._p_.get_max_length(option_bag.path)
|
follower_len = self.cfgimpl_get_values()._p_.get_max_length(option_bag.path)
|
||||||
if follower_len > length:
|
if follower_len > length:
|
||||||
raise LeadershipError(_('follower option "{}" has higher length "{}" than the leader '
|
raise LeadershipError(_('the follower option "{}" has greater length ({}) than the leader '
|
||||||
'length "{}"').format(option.impl_get_display_name(),
|
'length ({})').format(option.impl_get_display_name(),
|
||||||
follower_len,
|
follower_len,
|
||||||
length,
|
length,
|
||||||
option_bag.index))
|
option_bag.index))
|
||||||
|
@ -332,7 +334,8 @@ class SubConfig(object):
|
||||||
soption_bag.fromconsistency = option_bag.fromconsistency.copy()
|
soption_bag.fromconsistency = option_bag.fromconsistency.copy()
|
||||||
try:
|
try:
|
||||||
value.append(self.getattr(name,
|
value.append(self.getattr(name,
|
||||||
soption_bag))
|
soption_bag,
|
||||||
|
from_follower=True))
|
||||||
except PropertiesOptionError as err:
|
except PropertiesOptionError as err:
|
||||||
value.append(err)
|
value.append(err)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -54,7 +54,7 @@ class BroadcastOption(Option):
|
||||||
warnings_only,
|
warnings_only,
|
||||||
context):
|
context):
|
||||||
if len(vals) != 3:
|
if len(vals) != 3:
|
||||||
raise ConfigError(_('invalid len for vals'))
|
raise ConfigError(_('invalid broadcast consistency, a network and a netmask are needed'))
|
||||||
if None in vals:
|
if None in vals:
|
||||||
return
|
return
|
||||||
broadcast, network, netmask = vals
|
broadcast, network, netmask = vals
|
||||||
|
|
|
@ -121,6 +121,7 @@ class OptionBag:
|
||||||
'config_bag',
|
'config_bag',
|
||||||
'ori_option', # original option (for example useful for symlinkoption)
|
'ori_option', # original option (for example useful for symlinkoption)
|
||||||
'properties', # properties of current option
|
'properties', # properties of current option
|
||||||
|
'properties_setted',
|
||||||
'apply_requires', # apply requires or not for this option
|
'apply_requires', # apply requires or not for this option
|
||||||
'fromconsistency' # history for consistency
|
'fromconsistency' # history for consistency
|
||||||
)
|
)
|
||||||
|
@ -151,8 +152,15 @@ class OptionBag:
|
||||||
return self.option
|
return self.option
|
||||||
elif key == 'apply_requires':
|
elif key == 'apply_requires':
|
||||||
return True
|
return True
|
||||||
|
elif key == 'properties_setted':
|
||||||
|
return False
|
||||||
raise KeyError('unknown key {} for OptionBag'.format(key)) # pragma: no cover
|
raise KeyError('unknown key {} for OptionBag'.format(key)) # pragma: no cover
|
||||||
|
|
||||||
|
def __setattr__(self, key, val):
|
||||||
|
super().__setattr__(key, val)
|
||||||
|
if key == 'properties':
|
||||||
|
self.properties_setted = True
|
||||||
|
|
||||||
def __delattr__(self, key):
|
def __delattr__(self, key):
|
||||||
if key in ['properties', 'permissives']:
|
if key in ['properties', 'permissives']:
|
||||||
try:
|
try:
|
||||||
|
@ -379,7 +387,7 @@ 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 = self._p_.getcache(None,
|
is_cached, props, validated = self._p_.getcache(None,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
{},
|
{},
|
||||||
|
@ -392,7 +400,8 @@ class Settings(object):
|
||||||
None,
|
None,
|
||||||
props,
|
props,
|
||||||
{},
|
{},
|
||||||
props)
|
props,
|
||||||
|
True)
|
||||||
return props
|
return props
|
||||||
|
|
||||||
def getproperties(self,
|
def getproperties(self,
|
||||||
|
@ -410,7 +419,7 @@ class Settings(object):
|
||||||
|
|
||||||
if apply_requires:
|
if apply_requires:
|
||||||
props = config_bag.properties
|
props = config_bag.properties
|
||||||
is_cached, props = self._p_.getcache(path,
|
is_cached, props, validated = self._p_.getcache(path,
|
||||||
config_bag.expiration_time,
|
config_bag.expiration_time,
|
||||||
index,
|
index,
|
||||||
props,
|
props,
|
||||||
|
@ -431,7 +440,8 @@ class Settings(object):
|
||||||
index,
|
index,
|
||||||
props,
|
props,
|
||||||
props,
|
props,
|
||||||
config_bag.properties)
|
config_bag.properties,
|
||||||
|
True)
|
||||||
return props
|
return props
|
||||||
|
|
||||||
def get_context_permissives(self):
|
def get_context_permissives(self):
|
||||||
|
@ -744,13 +754,18 @@ class Settings(object):
|
||||||
#____________________________________________________________
|
#____________________________________________________________
|
||||||
# validate properties
|
# validate properties
|
||||||
def calc_raises_properties(self,
|
def calc_raises_properties(self,
|
||||||
option_properties,
|
option_bag,
|
||||||
config_properties,
|
apply_requires=True):
|
||||||
config_permissives):
|
raises_properties = option_bag.config_bag.properties - SPECIAL_PROPERTIES
|
||||||
properties = option_properties & config_properties - SPECIAL_PROPERTIES
|
|
||||||
# remove global permissive properties
|
# remove global permissive properties
|
||||||
if properties and ('permissive' in config_properties):
|
if raises_properties and ('permissive' in raises_properties):
|
||||||
properties -= config_permissives
|
raises_properties -= option_bag.config_bag.permissives
|
||||||
|
if apply_requires and option_bag.properties_setted:
|
||||||
|
option_properties = option_bag.properties
|
||||||
|
else:
|
||||||
|
option_properties = self.getproperties(option_bag,
|
||||||
|
apply_requires=apply_requires)
|
||||||
|
properties = option_properties & raises_properties
|
||||||
# at this point an option should not remain in properties
|
# at this point an option should not remain in properties
|
||||||
return properties
|
return properties
|
||||||
|
|
||||||
|
@ -764,11 +779,9 @@ class Settings(object):
|
||||||
was present
|
was present
|
||||||
"""
|
"""
|
||||||
config_bag = option_bag.config_bag
|
config_bag = option_bag.config_bag
|
||||||
if not config_bag.properties: # pragma: no cover
|
if not config_bag.properties or config_bag.properties == frozenset(['cache']): # pragma: no cover
|
||||||
return
|
return
|
||||||
properties = self.calc_raises_properties(option_bag.properties,
|
properties = self.calc_raises_properties(option_bag)
|
||||||
config_bag.properties,
|
|
||||||
config_bag.permissives)
|
|
||||||
if properties != frozenset():
|
if properties != frozenset():
|
||||||
raise PropertiesOptionError(option_bag,
|
raise PropertiesOptionError(option_bag,
|
||||||
properties,
|
properties,
|
||||||
|
|
4
tiramisu/storage/cache/dictionary.py
vendored
4
tiramisu/storage/cache/dictionary.py
vendored
|
@ -22,8 +22,8 @@ class Cache(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._cache = {}
|
self._cache = {}
|
||||||
|
|
||||||
def _setcache(self, path, index, val, time):
|
def _setcache(self, path, index, val, time, validated):
|
||||||
self._cache.setdefault(path, {})[index] = (val, int(time))
|
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)
|
||||||
|
|
|
@ -20,6 +20,8 @@ from ...setting import undefined
|
||||||
from ...i18n import _
|
from ...i18n import _
|
||||||
from ...log import log
|
from ...log import log
|
||||||
|
|
||||||
|
from copy import deepcopy
|
||||||
|
|
||||||
|
|
||||||
class Values(Cache):
|
class Values(Cache):
|
||||||
__slots__ = ('_values',
|
__slots__ = ('_values',
|
||||||
|
@ -30,7 +32,7 @@ class Values(Cache):
|
||||||
"""init plugin means create values storage
|
"""init plugin means create values storage
|
||||||
"""
|
"""
|
||||||
#(('path1',), (index1,), (value1,), ('owner1'))
|
#(('path1',), (index1,), (value1,), ('owner1'))
|
||||||
self._values = (tuple(), tuple(), tuple(), tuple())
|
self._values = ([], [], [], [])
|
||||||
self._informations = {}
|
self._informations = {}
|
||||||
# should init cache too
|
# should init cache too
|
||||||
super(Values, self).__init__(storage)
|
super(Values, self).__init__(storage)
|
||||||
|
@ -38,33 +40,30 @@ class Values(Cache):
|
||||||
def commit(self):
|
def commit(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _setvalue_info(self, nb, idx, value, values, index, vidx):
|
def _setvalue_info(self, nb, idx, value, index, follower_idx=None):
|
||||||
lst = list(self._values[nb])
|
lst = self._values[nb]
|
||||||
if idx is None:
|
|
||||||
if index is None or nb == 0:
|
|
||||||
lst.append(value)
|
|
||||||
else:
|
|
||||||
lst.append((value,))
|
|
||||||
else:
|
|
||||||
if index is None or nb == 0:
|
if index is None or nb == 0:
|
||||||
|
# not follower or path
|
||||||
lst[idx] = value
|
lst[idx] = value
|
||||||
else:
|
else:
|
||||||
if nb == 1:
|
# follower
|
||||||
if index in lst[idx]:
|
if nb == 1 and index in lst[idx]:
|
||||||
vidx = lst[idx].index(index)
|
follower_idx = lst[idx].index(index)
|
||||||
else:
|
|
||||||
vidx = None
|
|
||||||
if vidx is None:
|
|
||||||
tval = list(lst[idx])
|
tval = list(lst[idx])
|
||||||
|
if follower_idx is None:
|
||||||
tval.append(value)
|
tval.append(value)
|
||||||
lst[idx] = tuple(tval)
|
else:
|
||||||
elif nb != 1:
|
tval[follower_idx] = value
|
||||||
tval = list(lst[idx])
|
lst[idx] = tval
|
||||||
tval[vidx] = value
|
return follower_idx
|
||||||
lst[idx] = tuple(tval)
|
|
||||||
lst[idx] = tuple(lst[idx])
|
def _add_new_value(self, index, nb, value):
|
||||||
values.append(tuple(lst))
|
if index is None or nb == 0:
|
||||||
return vidx
|
# not follower or path
|
||||||
|
self._values[nb].append(value)
|
||||||
|
else:
|
||||||
|
# follower
|
||||||
|
self._values[nb].append([value])
|
||||||
|
|
||||||
# value
|
# value
|
||||||
def setvalue(self,
|
def setvalue(self,
|
||||||
|
@ -77,20 +76,20 @@ class Values(Cache):
|
||||||
a specified value must be associated to an owner
|
a specified value must be associated to an owner
|
||||||
"""
|
"""
|
||||||
log.debug('setvalue %s %s %s %s %s', path, value, owner, index, id(self))
|
log.debug('setvalue %s %s %s %s %s', path, value, owner, index, id(self))
|
||||||
values = []
|
|
||||||
vidx = None
|
|
||||||
|
|
||||||
|
#if isinstance(value, list):
|
||||||
|
# value = value
|
||||||
if path in self._values[0]:
|
if path in self._values[0]:
|
||||||
idx = self._values[0].index(path)
|
idx = self._values[0].index(path)
|
||||||
|
self._setvalue_info(0, idx, path, index)
|
||||||
|
follower_idx = self._setvalue_info(1, idx, index, index)
|
||||||
|
self._setvalue_info(2, idx, value, index, follower_idx)
|
||||||
|
self._setvalue_info(3, idx, owner, index, follower_idx)
|
||||||
else:
|
else:
|
||||||
idx = None
|
self._add_new_value(index, 0, path)
|
||||||
vidx = self._setvalue_info(0, idx, path, values, index, vidx)
|
self._add_new_value(index, 1, index)
|
||||||
vidx = self._setvalue_info(1, idx, index, values, index, vidx)
|
self._add_new_value(index, 2, value)
|
||||||
if isinstance(value, list):
|
self._add_new_value(index, 3, owner)
|
||||||
value = tuple(value)
|
|
||||||
vidx = self._setvalue_info(2, idx, value, values, index, vidx)
|
|
||||||
self._setvalue_info(3, idx, owner, values, index, vidx)
|
|
||||||
self._values = tuple(values)
|
|
||||||
|
|
||||||
def hasvalue(self, path, index=None):
|
def hasvalue(self, path, index=None):
|
||||||
"""if path has a value
|
"""if path has a value
|
||||||
|
@ -114,16 +113,8 @@ class Values(Cache):
|
||||||
path_idx = self._values[0].index(path)
|
path_idx = self._values[0].index(path)
|
||||||
# get the "index" position
|
# get the "index" position
|
||||||
subidx = self._values[1][path_idx].index(index)
|
subidx = self._values[1][path_idx].index(index)
|
||||||
# transform tuple to list
|
|
||||||
values = list(self._values)
|
|
||||||
values_idx = list(values[1])
|
|
||||||
lvalues = list(values_idx[path_idx])
|
|
||||||
# reduce to one the index
|
# reduce to one the index
|
||||||
lvalues[subidx] = lvalues[subidx] - 1
|
self._values[1][path_idx][subidx] -= 1
|
||||||
# store modification
|
|
||||||
values_idx[path_idx] = tuple(lvalues)
|
|
||||||
values[1] = tuple(values_idx)
|
|
||||||
self._values = tuple(values)
|
|
||||||
|
|
||||||
def resetvalue_index(self,
|
def resetvalue_index(self,
|
||||||
path,
|
path,
|
||||||
|
@ -131,23 +122,16 @@ class Values(Cache):
|
||||||
commit):
|
commit):
|
||||||
log.debug('resetvalue_index %s %s %s', path, index, id(self))
|
log.debug('resetvalue_index %s %s %s', path, index, id(self))
|
||||||
def _resetvalue(nb):
|
def _resetvalue(nb):
|
||||||
values_idx = list(values[nb])
|
del self._values[nb][path_idx]
|
||||||
del(values_idx[path_idx])
|
|
||||||
values[nb] = tuple(values_idx)
|
|
||||||
|
|
||||||
def _resetvalue_index(nb):
|
def _resetvalue_index(nb):
|
||||||
values_idx = list(values[nb])
|
del self._values[nb][path_idx][subidx]
|
||||||
lvalues = list(values_idx[path_idx])
|
|
||||||
del(lvalues[subidx])
|
|
||||||
values_idx[path_idx] = tuple(lvalues)
|
|
||||||
values[nb] = tuple(values_idx)
|
|
||||||
|
|
||||||
path_idx = self._values[0].index(path)
|
path_idx = self._values[0].index(path)
|
||||||
indexes = self._values[1][path_idx]
|
indexes = self._values[1][path_idx]
|
||||||
if index in indexes:
|
if index in indexes:
|
||||||
subidx = indexes.index(index)
|
subidx = indexes.index(index)
|
||||||
values = list(self._values)
|
if len(self._values[1][path_idx]) == 1:
|
||||||
if len(values[1][path_idx]) == 1:
|
|
||||||
_resetvalue(0)
|
_resetvalue(0)
|
||||||
_resetvalue(1)
|
_resetvalue(1)
|
||||||
_resetvalue(2)
|
_resetvalue(2)
|
||||||
|
@ -156,7 +140,6 @@ class Values(Cache):
|
||||||
_resetvalue_index(1)
|
_resetvalue_index(1)
|
||||||
_resetvalue_index(2)
|
_resetvalue_index(2)
|
||||||
_resetvalue_index(3)
|
_resetvalue_index(3)
|
||||||
self._values = tuple(values)
|
|
||||||
|
|
||||||
def resetvalue(self,
|
def resetvalue(self,
|
||||||
path,
|
path,
|
||||||
|
@ -165,17 +148,13 @@ class Values(Cache):
|
||||||
"""
|
"""
|
||||||
log.debug('resetvalue %s %s', path, id(self))
|
log.debug('resetvalue %s %s', path, id(self))
|
||||||
def _resetvalue(nb):
|
def _resetvalue(nb):
|
||||||
lst = list(self._values[nb])
|
self._values[nb].pop(idx)
|
||||||
lst.pop(idx)
|
|
||||||
values.append(tuple(lst))
|
|
||||||
values = []
|
|
||||||
if path in self._values[0]:
|
if path in self._values[0]:
|
||||||
idx = self._values[0].index(path)
|
idx = self._values[0].index(path)
|
||||||
_resetvalue(0)
|
_resetvalue(0)
|
||||||
_resetvalue(1)
|
_resetvalue(1)
|
||||||
_resetvalue(2)
|
_resetvalue(2)
|
||||||
_resetvalue(3)
|
_resetvalue(3)
|
||||||
self._values = tuple(values)
|
|
||||||
|
|
||||||
# owner
|
# owner
|
||||||
def setowner(self,
|
def setowner(self,
|
||||||
|
@ -186,14 +165,10 @@ class Values(Cache):
|
||||||
"""
|
"""
|
||||||
idx = self._values[0].index(path)
|
idx = self._values[0].index(path)
|
||||||
if index is None:
|
if index is None:
|
||||||
vidx = None
|
follower_idx = None
|
||||||
else:
|
else:
|
||||||
vidx = self._values[1][idx].index(index)
|
follower_idx = self._values[1][idx].index(index)
|
||||||
values = []
|
self._setvalue_info(3, idx, owner, index, follower_idx)
|
||||||
self._setvalue_info(3, idx, owner, values, index, vidx)
|
|
||||||
lst = list(self._values)
|
|
||||||
lst[3] = tuple(values[0])
|
|
||||||
self._values = tuple(lst)
|
|
||||||
|
|
||||||
def get_max_length(self,
|
def get_max_length(self,
|
||||||
path):
|
path):
|
||||||
|
@ -293,10 +268,10 @@ class Values(Cache):
|
||||||
self._informations = {}
|
self._informations = {}
|
||||||
|
|
||||||
def exportation(self):
|
def exportation(self):
|
||||||
return self._values
|
return deepcopy(self._values)
|
||||||
|
|
||||||
def importation(self, export):
|
def importation(self, export):
|
||||||
self._values = export
|
self._values = deepcopy(export)
|
||||||
|
|
||||||
|
|
||||||
def delete_session(session_id):
|
def delete_session(session_id):
|
||||||
|
|
|
@ -31,22 +31,16 @@ class Cache(DictCache):
|
||||||
self._storage = storage
|
self._storage = storage
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
def setcache(self, path, index, val, self_props, props):
|
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
|
||||||
"""
|
"""
|
||||||
if 'cache' in props or 'cache' in self_props:
|
if 'cache' in props or 'cache' in self_props:
|
||||||
log.debug('setcache {} with index {} and value {} in {} ({})'.format(path, index, val,
|
log.debug('setcache %s with index %s and value %s in %s (%s)',
|
||||||
_display_classname(self),
|
path, index, val, _display_classname(self), id(self))
|
||||||
id(self)))
|
self._setcache(path, index, val, time(), validated)
|
||||||
self._setcache(path, index, val, time())
|
log.debug('not setcache %s with index %s and value %s and props %s and %s in %s (%s)',
|
||||||
log.debug('not setcache {} with index {} and value {} and props {} and {} in {} ({})'.format(path,
|
path, index, val, props, self_props, _display_classname(self), id(self))
|
||||||
index,
|
|
||||||
val,
|
|
||||||
props,
|
|
||||||
self_props,
|
|
||||||
_display_classname(self),
|
|
||||||
id(self)))
|
|
||||||
|
|
||||||
def getcache(self,
|
def getcache(self,
|
||||||
path,
|
path,
|
||||||
|
@ -55,12 +49,12 @@ class Cache(DictCache):
|
||||||
props,
|
props,
|
||||||
self_props,
|
self_props,
|
||||||
type_):
|
type_):
|
||||||
no_cache = False, None
|
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 = self._getcache(path, index)
|
||||||
if indexed is None:
|
if indexed is None:
|
||||||
return no_cache
|
return no_cache
|
||||||
value, timestamp = indexed
|
value, timestamp, validated = indexed
|
||||||
if type_ == 'context_props':
|
if type_ == 'context_props':
|
||||||
# cached value is settings properties so value is props
|
# cached value is settings properties so value is props
|
||||||
props = value
|
props = value
|
||||||
|
@ -77,18 +71,18 @@ class Cache(DictCache):
|
||||||
if timestamp + expiration_time >= ntime:
|
if timestamp + expiration_time >= ntime:
|
||||||
log.debug('getcache in cache (1) %s %s %s %s %s', path, value, _display_classname(self),
|
log.debug('getcache in cache (1) %s %s %s %s %s', path, value, _display_classname(self),
|
||||||
id(self), index)
|
id(self), index)
|
||||||
return True, value
|
return True, value, validated
|
||||||
#else:
|
else:
|
||||||
# log.debug('getcache expired value for path {} < {}'.format(
|
log.debug('getcache expired value for path %s < %s',
|
||||||
# timestamp + expiration_time, ntime))
|
timestamp + expiration_time, ntime)
|
||||||
# # if expired, remove from cache
|
# if expired, remove from cache
|
||||||
# #self.delcache(path)
|
# self.delcache(path)
|
||||||
else:
|
else:
|
||||||
log.debug('getcache in cache (2) %s %s %s %s %s', path, value, _display_classname(self),
|
log.debug('getcache in cache (2) %s %s %s %s %s', path, value, _display_classname(self),
|
||||||
id(self), index)
|
id(self), index)
|
||||||
return True, value
|
return True, value, validated
|
||||||
log.debug('getcache {} with index {} not in {} cache'.format(path, index,
|
log.debug('getcache %s with index %s not in %s cache',
|
||||||
_display_classname(self)))
|
path, index, _display_classname(self))
|
||||||
return no_cache
|
return no_cache
|
||||||
|
|
||||||
def delcache(self, path):
|
def delcache(self, path):
|
||||||
|
@ -108,5 +102,5 @@ class Cache(DictCache):
|
||||||
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 {} for {} ({})'.format(self._cache, _display_classname(self), id(self)))
|
log.debug('get_chached %s for %s (%s)', self._cache, _display_classname(self), id(self))
|
||||||
return self._get_cached()
|
return self._get_cached()
|
||||||
|
|
|
@ -62,32 +62,32 @@ 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 = self._p_.getcache(option_bag.path,
|
is_cached, value, validated = self._p_.getcache(option_bag.path,
|
||||||
option_bag.config_bag.expiration_time,
|
option_bag.config_bag.expiration_time,
|
||||||
option_bag.index,
|
option_bag.index,
|
||||||
setting_properties,
|
setting_properties,
|
||||||
option_bag.properties,
|
option_bag.properties,
|
||||||
'value')
|
'value')
|
||||||
|
if not validated:
|
||||||
if not is_cached:
|
|
||||||
# no cached value so get value
|
# no cached value so get value
|
||||||
value = self.getvalue(option_bag)
|
value = self.getvalue(option_bag)
|
||||||
# validate value
|
# validate value
|
||||||
opt = option_bag.option
|
option_bag.option.impl_validate(value,
|
||||||
opt.impl_validate(value,
|
|
||||||
option_bag,
|
option_bag,
|
||||||
check_error=True)
|
check_error=True)
|
||||||
if 'warnings' in setting_properties:
|
|
||||||
opt.impl_validate(value,
|
|
||||||
option_bag,
|
|
||||||
check_error=False)
|
|
||||||
# store value in cache
|
# store value in cache
|
||||||
if not is_cached:
|
validator = 'validator' in option_bag.config_bag.properties
|
||||||
|
if not is_cached or validator:
|
||||||
self._p_.setcache(option_bag.path,
|
self._p_.setcache(option_bag.path,
|
||||||
option_bag.index,
|
option_bag.index,
|
||||||
value,
|
value,
|
||||||
option_bag.properties,
|
option_bag.properties,
|
||||||
setting_properties)
|
setting_properties,
|
||||||
|
validator)
|
||||||
|
if 'warnings' in setting_properties:
|
||||||
|
option_bag.option.impl_validate(value,
|
||||||
|
option_bag,
|
||||||
|
check_error=False)
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
# return a copy, so value cannot be modified
|
# return a copy, so value cannot be modified
|
||||||
return value.copy()
|
return value.copy()
|
||||||
|
@ -174,7 +174,7 @@ 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 = self._p_.getcache(option_bag.path,
|
is_cache, cache_value, validated = self._p_.getcache(option_bag.path,
|
||||||
None,
|
None,
|
||||||
option_bag.index,
|
option_bag.index,
|
||||||
option_bag.config_bag.properties,
|
option_bag.config_bag.properties,
|
||||||
|
@ -508,7 +508,7 @@ class Values(object):
|
||||||
current_value = self.get_cached_value(option_bag)
|
current_value = self.get_cached_value(option_bag)
|
||||||
length = len(current_value)
|
length = len(current_value)
|
||||||
if index >= length:
|
if index >= length:
|
||||||
raise IndexError(_('index "{}" is higher than the length "{}" '
|
raise IndexError(_('index {} is greater than the length {} '
|
||||||
'for option "{}"').format(index,
|
'for option "{}"').format(index,
|
||||||
length,
|
length,
|
||||||
option_bag.option.impl_get_display_name()))
|
option_bag.option.impl_get_display_name()))
|
||||||
|
|
Loading…
Reference in a new issue