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, \ from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
StrOption, OptionDescription, SymLinkOption, IPOption, NetmaskOption, Leadership, \ StrOption, OptionDescription, SymLinkOption, IPOption, NetmaskOption, Leadership, \
undefined, Calculation, Params, ParamOption, ParamValue, ParamIndex, calc_value, \ 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.error import PropertiesOptionError, ConflictError, LeadershipError, ConfigError
from tiramisu.i18n import _ from tiramisu.i18n import _
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
@ -378,6 +378,28 @@ async def test_callback_information(config_type):
await cfg.information.set('information', 'new_value') await cfg.information.set('information', 'new_value')
assert await cfg.option('val1').value.get() == 'new_value' assert await cfg.option('val1').value.get() == 'new_value'
assert await cfg.option('val2').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() 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_network_netmask, valid_in_network, valid_broadcast, \
valid_not_equal valid_not_equal
from .autolib import Calculation, Params, ParamOption, ParamDynOption, ParamSelfOption, \ from .autolib import Calculation, Params, ParamOption, ParamDynOption, ParamSelfOption, \
ParamValue, ParamIndex, ParamSuffix, ParamInformation ParamValue, ParamIndex, ParamSuffix, ParamInformation, ParamSelfInformation
from .option import * from .option import *
from .error import APIError from .error import APIError
from .api import Config, MetaConfig, GroupConfig, MixConfig from .api import Config, MetaConfig, GroupConfig, MixConfig
@ -37,6 +37,7 @@ allfuncs = ['Calculation',
'ParamIndex', 'ParamIndex',
'ParamSuffix', 'ParamSuffix',
'ParamInformation', 'ParamInformation',
'ParamSelfInformation',
'MetaConfig', 'MetaConfig',
'MixConfig', 'MixConfig',
'GroupConfig', 'GroupConfig',

View file

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

View file

@ -128,6 +128,10 @@ class ParamInformation(Param):
self.default_value = default_value self.default_value = default_value
class ParamSelfInformation(ParamInformation):
__slots__ = tuple()
class ParamIndex(Param): class ParamIndex(Param):
__slots__ = tuple() __slots__ = tuple()
@ -297,8 +301,17 @@ async def manager_callback(callbk: Param,
return callbk.value return callbk.value
if isinstance(callbk, ParamInformation): if isinstance(callbk, ParamInformation):
if isinstance(callbk, ParamSelfInformation):
option_bag = OptionBag()
option_bag.set_option(option,
index,
config_bag,
)
else:
option_bag = None
try: 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.information_name,
callbk.default_value, callbk.default_value,
) )

View file

@ -572,7 +572,8 @@ class _CommonConfig(SubConfig):
:param key: information's key (ex: "help", "doc" :param key: information's key (ex: "help", "doc"
:param value: information's value (ex: "the help string") :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, key,
value) value)
for option in config_bag.context.cfgimpl_get_description()._cache_dependencies_information.get(key, []): 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) await config_bag.context.cfgimpl_reset_cache(option_bag)
async def impl_get_information(self, async def impl_get_information(self,
connection, config_bag,
option_bag,
key, key,
default=undefined): default,
):
"""retrieves one information's item """retrieves one information's item
:param key: the item string (ex: "help") :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, key,
default) default)

View file

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

View file

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

View file

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

View file

@ -583,33 +583,53 @@ class Values:
# information # information
async def set_information(self, async def set_information(self,
connection, config_bag,
option_bag,
key, key,
value, value,
path=None): ):
"""updates the information's attribute """updates the information's attribute
:param key: information's key (ex: "help", "doc" :param key: information's key (ex: "help", "doc"
:param value: information's value (ex: "the help string") :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, path,
key, key,
value) 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, async def get_information(self,
connection, config_bag,
option_bag,
key, key,
default=undefined, default,
path=None): ):
"""retrieves one information's item """retrieves one information's item
:param key: the item string (ex: "help") :param key: the item string (ex: "help")
""" """
return await self._p_.get_information(connection, if option_bag is None:
path, path = None
key, else:
default) 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, async def del_information(self,
connection, connection,