default and default_multi is in value

This commit is contained in:
egarette@silique.fr 2024-08-29 08:17:06 +02:00
parent 9c36fb8fb2
commit bbec439a5e
8 changed files with 55 additions and 54 deletions

View file

@ -194,7 +194,7 @@ def test_groups_is_leader(config_type):
assert not cfg.option('leadership.netmask_admin_eth0').isleader() assert not cfg.option('leadership.netmask_admin_eth0').isleader()
assert cfg.option('leadership.netmask_admin_eth0').isfollower() assert cfg.option('leadership.netmask_admin_eth0').isfollower()
assert cfg.option('leadership.netmask_admin_eth0').path() == 'leadership.netmask_admin_eth0' assert cfg.option('leadership.netmask_admin_eth0').path() == 'leadership.netmask_admin_eth0'
assert cfg.option('leadership.netmask_admin_eth0').defaultmulti() == 'value' assert cfg.option('leadership.netmask_admin_eth0').value.defaultmulti() == 'value'
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
cfg.send() cfg.send()
# assert not list_sessions() # assert not list_sessions()

View file

@ -294,7 +294,7 @@ def test_callback(config_type):
cfg.option('val1').value.set('new-val') cfg.option('val1').value.set('new-val')
assert cfg.option('val1').value.get() == 'new-val' assert cfg.option('val1').value.get() == 'new-val'
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
assert cfg.option('val1').defaultmulti() == None assert cfg.option('val1').value.defaultmulti() == None
cfg.option('val1').value.reset() cfg.option('val1').value.reset()
assert cfg.option('val1').value.get() == 'val' assert cfg.option('val1').value.get() == 'val'
# assert not list_sessions() # assert not list_sessions()
@ -548,7 +548,7 @@ def test_callback_multi(config_type):
cfg = get_config(cfg, config_type) cfg = get_config(cfg, config_type)
assert cfg.option('val1').value.get() == ['val'] assert cfg.option('val1').value.get() == ['val']
cfg.option('val1').value.set(['new-val']) cfg.option('val1').value.set(['new-val'])
assert cfg.option('val1').defaultmulti() == None assert cfg.option('val1').value.defaultmulti() == None
assert cfg.option('val1').value.get() == ['new-val'] assert cfg.option('val1').value.get() == ['new-val']
cfg.option('val1').value.set(['new-val', 'new-val2']) cfg.option('val1').value.set(['new-val', 'new-val2'])
assert cfg.option('val1').value.get() == ['new-val', 'new-val2'] assert cfg.option('val1').value.get() == ['new-val', 'new-val2']
@ -963,7 +963,7 @@ def test_callback_leader_and_followers_leader_list(config_type):
assert cfg.option('val1.val1').value.get() == ['val', 'val'] assert cfg.option('val1.val1').value.get() == ['val', 'val']
assert cfg.option('val1.val2', 0).value.get() == None assert cfg.option('val1.val2', 0).value.get() == None
assert cfg.option('val1.val2', 1).value.get() == None assert cfg.option('val1.val2', 1).value.get() == None
default_multi = cfg.option('val1.val1').defaultmulti() default_multi = cfg.option('val1.val1').value.defaultmulti()
cfg.option('val1.val1').value.set(['val', 'val', default_multi]) cfg.option('val1.val1').value.set(['val', 'val', default_multi])
assert cfg.option('val1.val1').value.get() == ['val', 'val', None] assert cfg.option('val1.val1').value.get() == ['val', 'val', None]
assert cfg.option('val1.val2', 0).value.get() == None assert cfg.option('val1.val2', 0).value.get() == None

View file

@ -514,10 +514,10 @@ def test_accepts_multiple_changes_from_option():
od1 = OptionDescription("options", "", [s]) od1 = OptionDescription("options", "", [s])
cfg = Config(od1) cfg = Config(od1)
cfg.option('string').value.set("egg") cfg.option('string').value.set("egg")
assert cfg.option('string').default() == "string" assert cfg.option('string').value.default() == "string"
assert cfg.option('string').value.get() == "egg" assert cfg.option('string').value.get() == "egg"
cfg.option('string').value.set('blah') cfg.option('string').value.set('blah')
assert cfg.option('string').default() == "string" assert cfg.option('string').value.default() == "string"
assert cfg.option('string').value.get() == "blah" assert cfg.option('string').value.get() == "blah"
cfg.option('string').value.set('bol') cfg.option('string').value.set('bol')
assert cfg.option('string').value.get() == 'bol' assert cfg.option('string').value.get() == 'bol'

View file

@ -115,18 +115,18 @@ def test_append_submulti():
# #
assert cfg.option('multi2').value.get() == [] assert cfg.option('multi2').value.get() == []
assert cfg.option('multi2').owner.get() == owners.default assert cfg.option('multi2').owner.get() == owners.default
cfg.option('multi2').value.set([cfg.option('multi2').defaultmulti()]) cfg.option('multi2').value.set([cfg.option('multi2').value.defaultmulti()])
assert cfg.option('multi2').owner.get() == owner assert cfg.option('multi2').owner.get() == owner
assert cfg.option('multi2').value.get() == [['yes']] assert cfg.option('multi2').value.get() == [['yes']]
cfg.option('multi2').value.set([cfg.option('multi2').defaultmulti(), ['no']]) cfg.option('multi2').value.set([cfg.option('multi2').value.defaultmulti(), ['no']])
assert cfg.option('multi2').value.get() == [['yes'], ['no']] assert cfg.option('multi2').value.get() == [['yes'], ['no']]
# #
assert cfg.option('multi3').value.get() == [['yes']] assert cfg.option('multi3').value.get() == [['yes']]
assert cfg.option('multi3').owner.get() == owners.default assert cfg.option('multi3').owner.get() == owners.default
cfg.option('multi3').value.set([cfg.option('multi2').defaultmulti(), []]) cfg.option('multi3').value.set([cfg.option('multi2').value.defaultmulti(), []])
assert cfg.option('multi3').owner.get() == owner assert cfg.option('multi3').owner.get() == owner
assert cfg.option('multi3').value.get() == [['yes'], []] assert cfg.option('multi3').value.get() == [['yes'], []]
cfg.option('multi3').value.set([cfg.option('multi2').defaultmulti(), [], ['no']]) cfg.option('multi3').value.set([cfg.option('multi2').value.defaultmulti(), [], ['no']])
assert cfg.option('multi3').value.get() == [['yes'], [], ['no']] assert cfg.option('multi3').value.get() == [['yes'], [], ['no']]
# assert not list_sessions() # assert not list_sessions()
@ -193,7 +193,7 @@ def test_callback_submulti_str():
owner = cfg.owner.get() owner = cfg.owner.get()
assert cfg.option('multi').owner.get() == owners.default assert cfg.option('multi').owner.get() == owners.default
assert cfg.option('multi').value.get() == [['val']] assert cfg.option('multi').value.get() == [['val']]
cfg.option('multi').value.set([['val'], cfg.option('multi').defaultmulti()]) cfg.option('multi').value.set([['val'], cfg.option('multi').value.defaultmulti()])
assert cfg.option('multi').owner.get() == owner assert cfg.option('multi').owner.get() == owner
assert cfg.option('multi').value.get() == [['val'], ['val']] assert cfg.option('multi').value.get() == [['val'], ['val']]
cfg.option('multi').value.reset() cfg.option('multi').value.reset()
@ -209,10 +209,10 @@ def test_callback_submulti_list():
owner = cfg.owner.get() owner = cfg.owner.get()
assert cfg.option('multi').value.get() == [['val', 'val']] assert cfg.option('multi').value.get() == [['val', 'val']]
assert cfg.option('multi').owner.get() == owners.default assert cfg.option('multi').owner.get() == owners.default
cfg.option('multi').value.set([['val', 'val'], cfg.option('multi').defaultmulti()]) cfg.option('multi').value.set([['val', 'val'], cfg.option('multi').value.defaultmulti()])
assert cfg.option('multi').owner.get() == owner assert cfg.option('multi').owner.get() == owner
assert cfg.option('multi').value.get() == [['val', 'val'], ['val', 'val']] assert cfg.option('multi').value.get() == [['val', 'val'], ['val', 'val']]
cfg.option('multi').value.set([['val', 'val'], cfg.option('multi').defaultmulti(), cfg.option('multi').defaultmulti()]) cfg.option('multi').value.set([['val', 'val'], cfg.option('multi').value.defaultmulti(), cfg.option('multi').value.defaultmulti()])
assert cfg.option('multi').value.get() == [['val', 'val'], ['val', 'val'], ['val', 'val']] assert cfg.option('multi').value.get() == [['val', 'val'], ['val', 'val'], ['val', 'val']]
cfg.option('multi').value.reset() cfg.option('multi').value.reset()
assert cfg.option('multi').owner.get() == owners.default assert cfg.option('multi').owner.get() == owners.default
@ -227,7 +227,7 @@ def test_callback_submulti_list_list():
owner = cfg.owner.get() owner = cfg.owner.get()
assert cfg.option('multi').value.get() == [['val', 'val']] assert cfg.option('multi').value.get() == [['val', 'val']]
assert cfg.option('multi').owner.get() == owners.default assert cfg.option('multi').owner.get() == owners.default
cfg.option('multi').value.set([['val', 'val'], cfg.option('multi').defaultmulti()]) cfg.option('multi').value.set([['val', 'val'], cfg.option('multi').value.defaultmulti()])
assert cfg.option('multi').owner.get() == owner assert cfg.option('multi').owner.get() == owner
assert cfg.option('multi').value.get() == [['val', 'val'], []] assert cfg.option('multi').value.get() == [['val', 'val'], []]
cfg.option('multi').value.reset() cfg.option('multi').value.reset()

View file

@ -54,17 +54,13 @@ def test_symlink_default(config_type):
assert not cfg.option('c').ismulti() assert not cfg.option('c').ismulti()
assert not cfg.option('s1.b').issubmulti() assert not cfg.option('s1.b').issubmulti()
assert not cfg.option('c').issubmulti() assert not cfg.option('c').issubmulti()
assert not cfg.option('s1.b').default()
assert not cfg.option('c').default()
assert not cfg.option('s1.b').value.default() assert not cfg.option('s1.b').value.default()
assert not cfg.option('c').value.default() assert not cfg.option('c').value.default()
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
assert not cfg.option('s1.b').defaultmulti() assert not cfg.option('s1.b').value.defaultmulti()
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
assert not cfg.option('c').defaultmulti() assert not cfg.option('c').value.defaultmulti()
cfg.option("s1.b").value.set(True) cfg.option("s1.b").value.set(True)
assert not cfg.option('s1.b').default()
assert not cfg.option('c').default()
assert not cfg.option('s1.b').value.default() assert not cfg.option('s1.b').value.default()
assert not cfg.option('c').value.default() assert not cfg.option('c').value.default()
## assert not list_sessions() ## assert not list_sessions()
@ -82,19 +78,15 @@ def test_symlink_default_multi(config_type):
assert cfg.option('c').ismulti() assert cfg.option('c').ismulti()
assert not cfg.option('s1.b').issubmulti() assert not cfg.option('s1.b').issubmulti()
assert not cfg.option('c').issubmulti() assert not cfg.option('c').issubmulti()
assert cfg.option('s1.b').default() == [False]
assert cfg.option('c').default() == [False]
assert cfg.option('s1.b').value.default() == [False] assert cfg.option('s1.b').value.default() == [False]
assert cfg.option('c').value.default() == [False] assert cfg.option('c').value.default() == [False]
assert cfg.option('s1.b').defaultmulti() assert cfg.option('s1.b').value.defaultmulti()
assert cfg.option('c').defaultmulti() assert cfg.option('c').value.defaultmulti()
cfg.option("s1.b").value.set([True]) cfg.option("s1.b").value.set([True])
assert cfg.option('s1.b').default() == [False]
assert cfg.option('c').default() == [False]
assert cfg.option('s1.b').value.default() == [False] assert cfg.option('s1.b').value.default() == [False]
assert cfg.option('c').value.default() == [False] assert cfg.option('c').value.default() == [False]
assert cfg.option('s1.b').defaultmulti() assert cfg.option('s1.b').value.defaultmulti()
assert cfg.option('c').defaultmulti() assert cfg.option('c').value.defaultmulti()
## assert not list_sessions() ## assert not list_sessions()

View file

@ -83,15 +83,20 @@ class TiramisuHelp:
return list(self._registers.keys()) return list(self._registers.keys())
return super().__dir__() return super().__dir__()
def __getattr__(self, subfunc):
raise ConfigError(_(f'please specify a valid sub function ({self.__class__.__name__}.{subfunc})'))
class CommonTiramisu(TiramisuHelp): class CommonTiramisu(TiramisuHelp):
_validate_properties = True _validate_properties = True
_allow_dynoption = False
def _set_subconfig(self) -> None: def _set_subconfig(self) -> None:
self._subconfig = self._config_bag.context.get_sub_config(self._config_bag, self._subconfig = self._config_bag.context.get_sub_config(self._config_bag,
self._path, self._path,
self._index, self._index,
validate_properties=False, validate_properties=False,
allow_dynoption=self._allow_dynoption,
) )
@ -155,7 +160,7 @@ def option_type(typ):
msg = _('please specify index with a follower option ' msg = _('please specify index with a follower option '
f'({self.__class__.__name__}.{func.__name__})') f'({self.__class__.__name__}.{func.__name__})')
raise ConfigError(msg) raise ConfigError(msg)
if self._validate_properties: if self._validate_properties and 'dont_validate_property' not in types:
settings = self._config_bag.context.get_settings() settings = self._config_bag.context.get_settings()
parent = self._subconfig.parent parent = self._subconfig.parent
if parent and parent.transitive_properties: if parent and parent.transitive_properties:
@ -191,9 +196,6 @@ class CommonTiramisuOption(CommonTiramisu):
self._config_bag = config_bag self._config_bag = config_bag
self._set_subconfig() self._set_subconfig()
def __getattr__(self, subfunc):
raise ConfigError(_(f'please specify a valid sub function ({self.__class__.__name__}.{subfunc})'))
class _TiramisuOptionWalk: class _TiramisuOptionWalk:
def _list(self, def _list(self,
@ -278,6 +280,7 @@ class _TiramisuOptionOptionDescription:
options.append(TiramisuOption(option().impl_getpath(), options.append(TiramisuOption(option().impl_getpath(),
None, None,
self._config_bag, self._config_bag,
allow_dynoption=True,
)) ))
return options return options
@ -381,18 +384,6 @@ class _TiramisuOptionOption(_TiramisuOptionOptionDescription):
"""Test if option is a symlink option""" """Test if option is a symlink option"""
return self._subconfig.option.impl_is_symlinkoption() return self._subconfig.option.impl_is_symlinkoption()
@option_type(['option', 'with_or_without_index', 'symlink'])
def default(self):
"""Get default value for an option (not for optiondescription)"""
return self._subconfig.option.impl_getdefault()
@option_type(['option', 'with_or_without_index', 'symlink'])
def defaultmulti(self):
"""Get default value when added a value for a multi option (not for optiondescription)"""
if not self._subconfig.option.impl_is_multi():
raise ConfigError(_('only multi value has defaultmulti'))
return self._subconfig.option.impl_getdefault_multi()
@option_type(['option', 'with_or_without_index']) @option_type(['option', 'with_or_without_index'])
def pattern(self) -> str: def pattern(self) -> str:
"""Get the option pattern""" """Get the option pattern"""
@ -702,11 +693,28 @@ class TiramisuOptionValue(CommonTiramisuOption, _TiramisuODGet):
else: else:
values.reset(self._subconfig) values.reset(self._subconfig)
@option_type(['option', 'with_index', 'symlink']) @option_type(['option', 'with_or_without_index', 'symlink', "dont_validate_property"])
def default(self): def default(self,
uncalculated: bool=False,
) -> Any:
"""Get default value (default of option or calculated value)""" """Get default value (default of option or calculated value)"""
if uncalculated:
return self._subconfig.option.impl_getdefault()
if self._subconfig.option.impl_is_follower() and self._subconfig.index is None:
msg = _('please specify index with a follower option '
f'({self.__class__.__name__}.{func.__name__})')
raise ConfigError(msg)
if 'force_store_value' in self._subconfig.properties and 'force_store_value' in self._config_bag.properties:
return self._get(self._subconfig)
return self._config_bag.context.get_values().get_default_value(self._subconfig) return self._config_bag.context.get_values().get_default_value(self._subconfig)
@option_type(['option', 'with_or_without_index', 'symlink', "dont_validate_property"])
def defaultmulti(self):
"""Get default value when added a value for a multi option (not for optiondescription)"""
if not self._subconfig.option.impl_is_multi():
raise ConfigError(_('only multi value has defaultmulti'))
return self._subconfig.option.impl_getdefault_multi()
@option_type(['option', 'with_index']) @option_type(['option', 'with_index'])
def valid(self): def valid(self):
"""The if the option's value is valid""" """The if the option's value is valid"""
@ -794,15 +802,16 @@ class TiramisuOption(CommonTiramisu,
config_bag: Optional[ConfigBag]=None, config_bag: Optional[ConfigBag]=None,
*, *,
subconfig: Optional[SubConfig]=None, subconfig: Optional[SubConfig]=None,
allow_dynoption: bool=False,
) -> None: ) -> None:
self._path = path self._path = path
self._index = index self._index = index
self._config_bag = config_bag self._config_bag = config_bag
self._allow_dynoption = allow_dynoption
if subconfig is None: if subconfig is None:
self._set_subconfig() self._set_subconfig()
else: else:
self._subconfig = subconfig self._subconfig = subconfig
self._tiramisu_dict = None
if not self._registers: if not self._registers:
_registers(self._registers, 'TiramisuOption') _registers(self._registers, 'TiramisuOption')
@ -1192,7 +1201,7 @@ class TiramisuContextProperty(TiramisuConfig, PropertyPermissive):
if type is None and when is None: if type is None and when is None:
return DEFAULT_PROPERTIES return DEFAULT_PROPERTIES
if type == 'current': if type == 'current':
return setting.get_context_properties(self._config_bag.context.properties_cache) return setting.get_context_properties()
if when not in ['append', 'remove']: if when not in ['append', 'remove']:
raise ValueError(_('unknown when {} (must be in append or remove)').format(when)) raise ValueError(_('unknown when {} (must be in append or remove)').format(when))
if type == 'read_only': if type == 'read_only':
@ -1267,11 +1276,8 @@ class TiramisuContextPermissive(TiramisuConfig, PropertyPermissive):
class TiramisuContextOption(TiramisuConfig, _TiramisuOptionWalk): class TiramisuContextOption(TiramisuConfig, _TiramisuOptionWalk):
def __init__(self, def __init__(self) -> None:
*args,
**kwargs) -> None:
self._tiramisu_dict = None self._tiramisu_dict = None
super().__init__(*args, **kwargs)
def __iter__(self): def __iter__(self):
root = self._config_bag.context.get_root(self._config_bag) root = self._config_bag.context.get_root(self._config_bag)
@ -1529,6 +1535,7 @@ class TiramisuAPI(TiramisuHelp):
self._orig_config_bags = orig_config_bags self._orig_config_bags = orig_config_bags
if not self._registers: if not self._registers:
_registers(self._registers, 'TiramisuContext') _registers(self._registers, 'TiramisuContext')
super().__init__()
def option(self, def option(self,
path: str, path: str,

View file

@ -624,6 +624,7 @@ class _Config(CCache):
validate_properties: bool=True, validate_properties: bool=True,
properties=undefined, properties=undefined,
true_path: Optional[str]=None, true_path: Optional[str]=None,
allow_dynoption: bool=False,
): ):
subconfig = self.get_root(config_bag) subconfig = self.get_root(config_bag)
if path is None: if path is None:
@ -649,6 +650,7 @@ class _Config(CCache):
config_bag, config_bag,
subconfig, subconfig,
with_suffix=True, with_suffix=True,
allow_dynoption=allow_dynoption,
) )
if isinstance(option, tuple): if isinstance(option, tuple):
suffix, option = option suffix, option = option

View file

@ -616,7 +616,7 @@ class Settings:
apply_requires=True, apply_requires=True,
uncalculated=False, uncalculated=False,
transitive_raise=True, transitive_raise=True,
not_unrestraint=False, not_unrestraint: bool=False,
): ):
"""raise if needed """raise if needed
""" """
@ -653,7 +653,7 @@ class Settings:
def _calc_raises_properties(self, def _calc_raises_properties(self,
subconfig, subconfig,
option_properties, option_properties,
not_unrestraint, not_unrestraint: bool,
): ):
config_bag = subconfig.config_bag config_bag = subconfig.config_bag
if not_unrestraint and config_bag.is_unrestraint: if not_unrestraint and config_bag.is_unrestraint: