Add ParamSelfInformation

This commit is contained in:
Emmanuel Garette 2021-03-06 19:23:35 +01:00
parent 7ebad5724e
commit acc86bc49f
9 changed files with 114 additions and 51 deletions

View file

@ -10,7 +10,7 @@ from tiramisu.setting import groups, owners
from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
StrOption, OptionDescription, SymLinkOption, IPOption, NetmaskOption, Leadership, \
undefined, Calculation, Params, ParamOption, ParamValue, ParamIndex, calc_value, \
valid_ip_netmask, ParamSelfOption, ParamInformation
valid_ip_netmask, ParamSelfOption, ParamInformation, ParamSelfInformation
from tiramisu.error import PropertiesOptionError, ConflictError, LeadershipError, ConfigError
from tiramisu.i18n import _
from tiramisu.storage import list_sessions
@ -378,6 +378,28 @@ async def test_callback_information(config_type):
await cfg.information.set('information', 'new_value')
assert await cfg.option('val1').value.get() == 'new_value'
assert await cfg.option('val2').value.get() == 'new_value'
await cfg.information.set('information', 'new_value2')
assert await cfg.option('val1').value.get() == 'new_value2'
assert await cfg.option('val2').value.get() == 'new_value2'
assert not await list_sessions()
@pytest.mark.asyncio
async def test_callback_information2(config_type):
val1 = StrOption('val1', "", Calculation(return_value, Params(ParamSelfInformation('information', 'no_value'))))
val2 = StrOption('val2', "", Calculation(return_value, Params(ParamSelfInformation('information'))))
val2.impl_set_information('information', 'new_value')
val3 = StrOption('val3', "", Calculation(return_value, Params(ParamSelfInformation('information'))))
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3])
async with await Config(maconfig) as cfg:
await cfg.property.read_write()
cfg = await get_config(cfg, config_type)
assert await cfg.option('val1').value.get() == 'no_value'
assert await cfg.option('val2').value.get() == 'new_value'
with pytest.raises(ConfigError):
await cfg.option('val3').value.get()
await cfg.option('val2').information.set('information', 'new_value2')
assert await cfg.option('val2').value.get() == 'new_value2'
assert not await list_sessions()

View file

@ -18,7 +18,7 @@ from .function import calc_value, calc_value_property_help, valid_ip_netmask, \
valid_network_netmask, valid_in_network, valid_broadcast, \
valid_not_equal
from .autolib import Calculation, Params, ParamOption, ParamDynOption, ParamSelfOption, \
ParamValue, ParamIndex, ParamSuffix, ParamInformation
ParamValue, ParamIndex, ParamSuffix, ParamInformation, ParamSelfInformation
from .option import *
from .error import APIError
from .api import Config, MetaConfig, GroupConfig, MixConfig
@ -37,6 +37,7 @@ allfuncs = ['Calculation',
'ParamIndex',
'ParamSuffix',
'ParamInformation',
'ParamSelfInformation',
'MetaConfig',
'MixConfig',
'GroupConfig',

View file

@ -464,24 +464,23 @@ class TiramisuOptionInformation(CommonTiramisuOption):
@option_and_connection
async def get(self, key, default=undefined):
"""Get information"""
path = self._option_bag.path
values = self._option_bag.config_bag.context.cfgimpl_get_values()
try:
return await values.get_information(self._option_bag.config_bag.connection,
key,
path=path)
except ValueError:
return self._option_bag.option.impl_get_information(key, default)
return await values.get_information(self._option_bag.config_bag,
self._option_bag,
key,
default,
)
@option_and_connection
async def set(self, key, value):
"""Set information"""
path = self._option_bag.path
values = self._option_bag.config_bag.context.cfgimpl_get_values()
await values.set_information(self._option_bag.config_bag.connection,
await values.set_information(self._option_bag.config_bag,
self._option_bag,
key,
value,
path=path)
)
@option_and_connection
async def reset(self,
@ -890,10 +889,12 @@ class TiramisuContextInformation(TiramisuConfig):
default=undefined,
):
"""Get an information"""
return await self._config_bag.context.impl_get_information(self._config_bag.connection,
name,
default,
)
values = self._config_bag.context.cfgimpl_get_values()
return await values.get_information(self._config_bag,
None,
name,
default,
)
@connection
async def set(self,

View file

@ -128,6 +128,10 @@ class ParamInformation(Param):
self.default_value = default_value
class ParamSelfInformation(ParamInformation):
__slots__ = tuple()
class ParamIndex(Param):
__slots__ = tuple()
@ -297,8 +301,17 @@ async def manager_callback(callbk: Param,
return callbk.value
if isinstance(callbk, ParamInformation):
if isinstance(callbk, ParamSelfInformation):
option_bag = OptionBag()
option_bag.set_option(option,
index,
config_bag,
)
else:
option_bag = None
try:
return await config_bag.context.impl_get_information(config_bag.connection,
return await config_bag.context.impl_get_information(config_bag,
option_bag,
callbk.information_name,
callbk.default_value,
)

View file

@ -572,7 +572,8 @@ class _CommonConfig(SubConfig):
:param key: information's key (ex: "help", "doc"
:param value: information's value (ex: "the help string")
"""
await self._impl_values.set_information(config_bag.connection,
await self._impl_values.set_information(config_bag,
None,
key,
value)
for option in config_bag.context.cfgimpl_get_description()._cache_dependencies_information.get(key, []):
@ -583,14 +584,17 @@ class _CommonConfig(SubConfig):
await config_bag.context.cfgimpl_reset_cache(option_bag)
async def impl_get_information(self,
connection,
config_bag,
option_bag,
key,
default=undefined):
default,
):
"""retrieves one information's item
:param key: the item string (ex: "help")
"""
return await self._impl_values.get_information(connection,
return await self._impl_values.get_information(config_bag,
option_bag,
key,
default)

View file

@ -27,7 +27,7 @@ from itertools import chain
from .baseoption import BaseOption, submulti, STATIC_TUPLE
from ..i18n import _
from ..setting import undefined, OptionBag, Undefined
from ..autolib import Calculation, Params, ParamOption, ParamInformation
from ..autolib import Calculation, Params, ParamOption, ParamInformation, ParamSelfInformation
from ..error import (ConfigError, ValueWarning, ValueErrorWarning, PropertiesOptionError,
ValueOptionError, display_list)
from .syndynoption import SynDynOption
@ -67,7 +67,7 @@ class Option(BaseOption):
warnings_only: bool=False,
extra: Optional[Dict]=None):
_setattr = object.__setattr__
_dependencies_information = []
_dependencies_information = [[], []]
if not multi and default_multi is not None:
raise ValueError(_("default_multi is set whereas multi is False"
" in option: {0}").format(name))
@ -107,8 +107,10 @@ class Option(BaseOption):
if isinstance(param, ParamOption):
param.option._add_dependency(self)
self._has_dependency = True
elif isinstance(param, ParamSelfInformation):
_dependencies_information[1].append(param.information_name)
elif isinstance(param, ParamInformation):
_dependencies_information.append(param.information_name)
_dependencies_information[0].append(param.information_name)
self._validators = tuple(validators)
if extra is not None and extra != {}:
@ -165,7 +167,7 @@ class Option(BaseOption):
if is_multi and isinstance(default, list):
default = tuple(default)
_setattr(self, '_default', default)
if _dependencies_information:
if _dependencies_information[0] or _dependencies_information[1]:
self._dependencies_information = _dependencies_information
def value_dependencies(self,
@ -188,8 +190,10 @@ class Option(BaseOption):
for param in chain(value.params.args, value.params.kwargs.values()):
if isinstance(param, ParamOption):
param.option._add_dependency(self)
elif isinstance(param, ParamSelfInformation):
_dependencies_information[1].append(param.information_name)
elif isinstance(param, ParamInformation):
_dependencies_information.append(param.information_name)
_dependencies_information[0].append(param.information_name)
#__________________________________________________________________________
# option's information
@ -203,8 +207,14 @@ class Option(BaseOption):
def impl_is_dynsymlinkoption(self) -> bool:
return False
def get_dependencies_information(self) -> List[str]:
return getattr(self, '_dependencies_information', [])
def get_dependencies_information(self,
itself=False,
) -> List[str]:
if itself:
idx = 1
else:
idx = 0
return getattr(self, '_dependencies_information', [[], []])[idx]
def get_type(self) -> str:
# _display_name for compatibility with older version than 3.0rc3
@ -449,7 +459,7 @@ class Option(BaseOption):
self._display_name,
option_bag.ori_option,
'{0}'.format(err),
err_index)
err_index) from err
warnings.warn_explicit(ValueErrorWarning(val,
self._display_name,
option_bag.ori_option,

View file

@ -257,16 +257,12 @@ class Values:
connection,
path,
key,
default):
):
"""retrieves one information's item
:param key: the item string (ex: "help")
"""
value = self._storage.get_informations().get(path, {}).get(key, default)
if value is undefined:
raise ValueError(_("information's item"
" not found: {0}").format(key))
return value
return self._storage.get_informations().get(path, {})[key]
async def del_information(self,
connection,

View file

@ -186,7 +186,7 @@ class Values:
connection,
path,
key,
default):
):
"""retrieves one information's item
:param key: the item string (ex: "help")
@ -197,12 +197,8 @@ class Values:
"session_id = $2 AND path = $3",
key, self._storage.database_id, path)
if value is None:
if default is undefined:
raise ValueError(_("information's item"
" not found: {0}").format(key))
return default
else:
return loads(value)
raise KeyError()
return loads(value)
async def del_information(self,
connection,

View file

@ -583,33 +583,53 @@ class Values:
# information
async def set_information(self,
connection,
config_bag,
option_bag,
key,
value,
path=None):
):
"""updates the information's attribute
:param key: information's key (ex: "help", "doc"
:param value: information's value (ex: "the help string")
"""
await self._p_.set_information(connection,
if option_bag is None:
path = None
else:
path = option_bag.path
await self._p_.set_information(config_bag.connection,
path,
key,
value)
if path is not None:
for option in option_bag.option.get_dependencies_information(itself=True):
await config_bag.context.cfgimpl_reset_cache(option_bag)
async def get_information(self,
connection,
config_bag,
option_bag,
key,
default=undefined,
path=None):
default,
):
"""retrieves one information's item
:param key: the item string (ex: "help")
"""
return await self._p_.get_information(connection,
path,
key,
default)
if option_bag is None:
path = None
else:
path = option_bag.path
try:
return await self._p_.get_information(config_bag.connection,
path,
key,
)
except KeyError as err:
if option_bag:
return option_bag.option.impl_get_information(key, default)
if default is not undefined:
return default
raise ValueError(_("information's item not found: {0}").format(key))
async def del_information(self,
connection,