undefined is no more a valid value and Calculation could be a valid value

This commit is contained in:
egarette@silique.fr 2023-11-18 21:12:13 +01:00
parent 73c8db5839
commit 059c5f7407
14 changed files with 205 additions and 101 deletions

View file

@ -352,18 +352,6 @@ def test_cache_callback():
'val3': {None: ('new2', None)},
'val4': {None: ('new3', None)},
'val5': {None: (['yes'], None)}})
cfg.option('val5').value.set([undefined, 'new4'])
compare(values.get_cached(), {'val1': {None: ('new', None)},
'val2': {None: ('new', None)},
'val3': {None: ('new2', None)},
'val4': {None: ('new3', None)},
'val5': {None: (['yes', 'new4'], None)}})
cfg.value.dict()
compare(values.get_cached(), {'val1': {None: ('new', None)},
'val2': {None: ('new', None)},
'val3': {None: ('new2', None)},
'val4': {None: ('new3', None)},
'val5': {None: (['yes', 'new4'], None)}})
# assert not list_sessions()
@ -394,7 +382,7 @@ def test_cache_leader_and_followers():
# len is 0 so don't get any value
compare(values.get_cached(), {'val1.val1': {None: ([], None)}})
#
cfg.option('val1.val1').value.set([undefined])
cfg.option('val1.val1').value.set([None])
val_val2_props = {idx_val2: (val1_val2_props, None), None: (set(), None)}
compare(settings.get_cached(), {None: {None: (set(global_props), None)},
'val1.val1': {None: (val1_val1_props, None)},
@ -412,7 +400,7 @@ def test_cache_leader_and_followers():
compare(values.get_cached(), {'val1.val1': {None: ([None], None)},
'val1.val2': {idx_val2: (val_val2, None)},
})
cfg.option('val1.val1').value.set([undefined, undefined])
cfg.option('val1.val1').value.set([None, None])
cfg.value.dict()
cfg.option('val1.val2', 1).value.set('oui')
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}})
@ -444,7 +432,7 @@ def test_cache_leader_callback():
'val1.val1': {None: (val1_val1_props, None)},
})
compare(values.get_cached(), {'val1.val1': {None: ([], None)}})
cfg.option('val1.val1').value.set([undefined])
cfg.option('val1.val1').value.set([None])
compare(settings.get_cached(), {None: {None: (set(global_props), None)},
'val1.val1': {None: (val1_val1_props, None)},
})

View file

@ -264,12 +264,12 @@ def test_get_modified_values():
compare(cfg.value.exportation(), {'od.g5': {None: ['yes', 'user']}})
cfg.option('od.g4').value.set(False)
compare(cfg.value.exportation(), {'od.g5': {None: ['yes', 'user']}, 'od.g4': {None: [False, 'user']}})
cfg.option('od.g4').value.set(undefined)
cfg.option('od.g4').value.set(True)
compare(cfg.value.exportation(), {'od.g5': {None: ['yes', 'user']}, 'od.g4': {None: [True, 'user']}})
cfg.option('od.g4').value.reset()
compare(cfg.value.exportation(), {'od.g5': {None: ['yes', 'user']}})
assert cfg.option('od.g6').ismulti()
cfg.option('od.g6').value.set([undefined])
cfg.option('od.g6').value.set([None])
compare(cfg.value.exportation(), {'od.g5': {None: ['yes', 'user']}, 'od.g6': {None: [[None], 'user']}})
cfg.option('od.g6').value.set([])
compare(cfg.value.exportation(), {'od.g5': {None: ['yes', 'user']}, 'od.g6': {None: [[], 'user']}})
@ -329,10 +329,10 @@ def test_config_multi(config_type):
cfg = get_config(cfg, config_type)
assert cfg.option('test1').value.get() == []
assert cfg.option('test2').value.get() == []
cfg.option('test2').value.set([undefined])
cfg.option('test2').value.set([1])
assert cfg.option('test2').value.get() == [1]
assert cfg.option('test3').value.get() == [2]
cfg.option('test3').value.set([undefined, undefined])
cfg.option('test3').value.set([2, 1])
assert cfg.option('test3').value.get() == [2, 1]
# assert not list_sessions()

View file

@ -6,7 +6,7 @@ do_autopath()
import pytest
from tiramisu import Config
from tiramisu import IntOption, StrOption, OptionDescription, DynOptionDescription, PasswordOption, UsernameOption, \
SymLinkOption, Leadership, undefined, Calculation, Params, \
SymLinkOption, Leadership, Calculation, Params, \
ParamOption, ParamValue, ParamIndex, calc_value
from tiramisu.error import PropertiesOptionError, ConfigError
from tiramisu.setting import groups
@ -457,7 +457,7 @@ def test_mandatory_leader_empty():
cfg.property.read_write()
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
#
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([undefined])
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([None])
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [None]
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
cfg.property.read_only()
@ -503,7 +503,7 @@ def test_mandatory_warnings_leader_empty():
od1 = OptionDescription('o', '', [interface1])
cfg = Config(od1)
cfg.property.read_write()
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([undefined])
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([None])
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [None]
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
compare(cfg.value.mandatory(), ['ip_admin_eth0.ip_admin_eth0'])

View file

@ -299,6 +299,23 @@ def test_callback(config_type):
# assert not list_sessions()
def test_callback_set(config_type):
val1 = StrOption('val1', "")
val2 = StrOption('val2', "")
od1 = OptionDescription('rootconfig', '', [val1, val2])
cfg = Config(od1)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('val2').value.set(Calculation(return_value, Params(ParamOption(val1))))
assert cfg.option('val2').value.get() == None
#
cfg.option('val1').value.set('new-val')
assert cfg.option('val2').value.get() == 'new-val'
#
cfg.option('val1').value.reset()
assert cfg.option('val2').value.get() == None
def test_params():
with pytest.raises(ValueError):
Params('str')
@ -541,6 +558,21 @@ def test_callback_multi(config_type):
# assert not list_sessions()
def test_callback_multi_set(config_type):
val1 = StrOption('val1', "", multi=True)
od1 = OptionDescription('rootconfig', '', [val1])
cfg = Config(od1)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val1').value.get() == []
#
cfg.option('val1').value.set([Calculation(return_val)])
assert cfg.option('val1').value.get() == ['val']
cfg.option('val1').value.reset()
assert cfg.option('val1').value.get() == []
# assert not list_sessions()
def test_callback_multi_value(config_type):
val1 = StrOption('val1', "", ['val'], multi=True)
option = ParamOption(val1)
@ -577,6 +609,30 @@ def test_callback_multi_value(config_type):
# assert not list_sessions()
def test_callback_multi_value_set(config_type):
val1 = StrOption('val1', "", ['val1'], multi=True)
val2 = StrOption('val2', "", ['val2'], multi=True)
od1 = OptionDescription('rootconfig', '', [val1, val2])
cfg = Config(od1)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val1').value.get() == ['val1']
assert cfg.option('val2').value.get() == ['val2']
#
cfg.option('val2').value.set(Calculation(return_value, Params(ParamOption(val1))))
assert cfg.option('val1').value.get() == ['val1']
assert cfg.option('val2').value.get() == ['val1']
#
cfg.option('val1').value.set(['val1', 'yes'])
assert cfg.option('val2').value.get() == ['val1', 'yes']
assert cfg.option('val2').value.get() == ['val1', 'yes']
#
cfg.option('val2').value.reset()
assert cfg.option('val1').value.get() == ['val1', 'yes']
assert cfg.option('val2').value.get() == ['val2']
# assert not list_sessions()
def test_callback_multi_list(config_type):
val1 = StrOption('val1', "", Calculation(return_list), multi=True, properties=('notunique',))
od1 = OptionDescription('rootconfig', '', [val1])
@ -611,7 +667,7 @@ def test_callback_multi_callback(config_type):
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val1.val1').value.get() == ['val']
cfg.option('val1.val1').value.set(['val1', undefined])
cfg.option('val1.val1').value.set(['val1', None])
assert cfg.option('val1.val1').value.get() == ['val1', None]
# assert not list_sessions()
@ -624,27 +680,53 @@ def test_callback_multi_callback_default(config_type):
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val1.val1').value.get() == []
cfg.option('val1.val1').value.set(['val1', undefined])
cfg.option('val1.val1').value.set(['val1', 'val'])
assert cfg.option('val1.val1').value.get() == ['val1', 'val']
# assert not list_sessions()
def test_callback_leader_and_followers_leader(config_type):
val1 = StrOption('val1', "", default=[Calculation(return_val)], default_multi=Calculation(return_val), multi=True, properties=('notunique',))
val2 = StrOption('val2', "", multi=True)
interface1 = Leadership('val1', '', [val1, val2])
od1 = OptionDescription('rootconfig', '', [interface1])
val1 = StrOption('val1', "", default=['val'], multi=True)
val2 = StrOption('val2', "", default=Calculation(return_value, Params(ParamOption(val1))), default_multi=Calculation(return_val), multi=True, properties=('notunique',))
val3 = StrOption('val3', "", multi=True)
interface1 = Leadership('val2', '', [val2, val3])
od1 = OptionDescription('rootconfig', '', [val1, interface1])
cfg = Config(od1)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val1.val1').value.get() == ['val']
cfg.option('val1.val1').value.set([undefined, undefined])
assert cfg.option('val1.val1').value.get() == ['val', 'val']
assert cfg.option('val1.val2', 0).value.get() == None
assert cfg.option('val1.val2', 1).value.get() == None
assert cfg.option('val1').value.get() == ['val']
assert cfg.option('val2.val2').value.get() == ['val']
#
cfg.option('val1').value.set(['val1', 'val2'])
assert cfg.option('val1').value.get() == ['val1', 'val2']
assert cfg.option('val2.val2').value.get() == ['val1', 'val2']
assert cfg.option('val2.val3', 0).value.get() == None
assert cfg.option('val2.val3', 1).value.get() == None
#
cfg.option('val1').value.set(['val'])
assert cfg.option('val2.val2').value.get() == ['val']
assert cfg.option('val2.val3', 0).value.get() == None
# assert not list_sessions()
def test_callback_leader_and_followers_leader_set(config_type):
val1 = StrOption('val1', "", default=['val1', 'val2'], multi=True)
val2 = StrOption('val2', "", multi=True)
val3 = StrOption('val3', "", multi=True)
interface1 = Leadership('val2', '', [val2, val3])
od1 = OptionDescription('rootconfig', '', [val1, interface1])
cfg = Config(od1)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val1').value.get() == ['val1', 'val2']
#
cfg.option('val2.val2').value.set(Calculation(return_value, Params(ParamOption(val1))))
assert cfg.option('val2.val2').value.get() == ['val1', 'val2']
assert cfg.option('val2.val3', 0).value.get() == None
assert cfg.option('val2.val3', 1).value.get() == None
#assert not list_sessions()
def test_callback_follower(config_type):
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", Calculation(return_value3, Params(ParamValue(['string', 'new']), {'index': ParamIndex()})), multi=True)
@ -670,6 +752,28 @@ def test_callback_follower(config_type):
# assert not list_sessions()
def test_callback_follower_set(config_type):
val1 = StrOption('val1', "")
val2 = StrOption('val2', "", default=['val1'], multi=True)
val3 = StrOption('val3', "", multi=True)
interface1 = Leadership('val2', '', [val2, val3])
od1 = OptionDescription('rootconfig', '', [val1, interface1])
cfg = Config(od1)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('val1').value.set('val')
assert cfg.option('val1').value.get() == 'val'
assert cfg.option('val2.val2').value.get() == ['val1']
assert cfg.option('val2.val3', 0).value.get() == None
#
cfg.option('val2.val3', 0).value.set(Calculation(return_value, Params(ParamOption(val1))))
assert cfg.option('val2.val3', 0).value.get() == 'val'
#
cfg.option('val1').value.set('val1')
assert cfg.option('val2.val3', 0).value.get() == 'val1'
# assert not list_sessions()
def test_callback_leader_and_followers_leader2(config_type):
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, default_multi='val2')
@ -704,7 +808,7 @@ def test_callback_leader_and_followers_leader_mandatory1(config_type):
cfg.send()
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
cfg.option('val1.val1').value.set([undefined, 'val3'])
cfg.option('val1.val1').value.set(['val', 'val3'])
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.read_only()
@ -860,7 +964,8 @@ def test_callback_leader_and_followers_leader_list(config_type):
assert cfg.option('val1.val1').value.get() == ['val', 'val']
assert cfg.option('val1.val2', 0).value.get() == None
assert cfg.option('val1.val2', 1).value.get() == None
cfg.option('val1.val1').value.set(['val', 'val', undefined])
default_multi = cfg.option('val1.val1').defaultmulti()
cfg.option('val1.val1').value.set(['val', 'val', default_multi])
assert cfg.option('val1.val1').value.get() == ['val', 'val', None]
assert cfg.option('val1.val2', 0).value.get() == None
assert cfg.option('val1.val2', 1).value.get() == None

View file

@ -115,8 +115,10 @@ def test_force_default_on_freeze_multi():
cfg_ori.property.read_write()
cfg = cfg_ori
# FIXME cfg = get_config(cfg_ori, config_type)
cfg.option('dummy1').value.set([undefined, True])
cfg.option('dummy2').value.set([undefined, False])
default = cfg.option('dummy1').value.default()[0]
cfg.option('dummy1').value.set([default, True])
default = cfg.option('dummy2').value.default()[0]
cfg.option('dummy2').value.set([default, False])
owner = cfg.owner.get()
assert cfg.option('dummy1').owner.get() == owner
assert cfg.option('dummy2').owner.get() == owner

View file

@ -143,7 +143,7 @@ def test_setitem(config_type):
od1 = OptionDescription("options", "", [s])
cfg = Config(od1)
cfg = get_config(cfg, config_type)
cfg.option('string').value.set([undefined, 'foo'])
cfg.option('string').value.set(['string', 'foo'])
assert cfg.option('string').value.get() == ['string', 'foo']
# assert not list_sessions()

View file

@ -8,7 +8,7 @@ from tiramisu import BoolOption, StrOption, IPOption, NetmaskOption, NetworkOpti
IntOption, OptionDescription, Leadership, Config, Params, ParamValue, ParamOption, \
ParamSelfOption, ParamIndex, ParamInformation, ParamSelfInformation, ParamSelfOption, Calculation, \
valid_ip_netmask, valid_network_netmask, \
valid_in_network, valid_broadcast, valid_not_equal, undefined
valid_in_network, valid_broadcast, valid_not_equal
from tiramisu.setting import groups
from tiramisu.error import ValueErrorWarning, ConfigError, PropertiesOptionError
from tiramisu.i18n import _
@ -713,7 +713,7 @@ def test_validator_network_netmask_multi_follower_default_multi(config_type):
cfg = Config(od2)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('a.a').value.set([undefined])
cfg.option('a.a').value.set(['192.168.1.0'])
assert cfg.option('a.a').value.get() == ['192.168.1.0']
assert cfg.option('a.b', 0).value.get() == '255.255.255.0'
# assert not list_sessions()
@ -745,10 +745,10 @@ def test_validator_network_netmask_multi_follower_default(config_type):
cfg.option('a.b', 0).value.set([u'192.168.1.0'])
with pytest.raises(ValueError):
cfg.option('a.b', 1).value.set([u'192.168.1.1'])
cfg.option('a.a').value.set(['192.168.1.0', undefined])
cfg.option('a.a').value.set(['192.168.1.0', '192.168.1.1'])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.b', 1).value.set('255.255.255.255')
cfg.option('a.a').value.set([u'192.168.1.0', u'192.168.1.1'])
cfg.option('a.a').value.set(['192.168.1.0', '192.168.1.1'])
# assert not list_sessions()
@ -790,7 +790,7 @@ def test_validator_network_netmask_multi_follower_callback(config_type):
cfg.option('a.b', 0).value.get()
with pytest.raises(ValueError):
cfg.option('a.b', 1).value.get()
cfg.option('a.a').value.set(['192.168.1.0', undefined])
cfg.option('a.a').value.set(['192.168.1.0', '192.168.1.1'])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.b', 1).value.set('255.255.255.255')
cfg.option('a.a').value.set(['192.168.1.0', '192.168.1.1'])

View file

@ -7,7 +7,7 @@ import warnings
from tiramisu.setting import groups, owners
from tiramisu import StrOption, IntOption, OptionDescription, submulti, Leadership, Config, \
MetaConfig, undefined, Params, ParamOption, Calculation
MetaConfig, Params, ParamOption, Calculation
from tiramisu.error import LeadershipError, PropertiesOptionError
@ -107,26 +107,26 @@ def test_append_submulti():
owner = cfg.owner.get()
assert cfg.option('multi').value.get() == []
assert cfg.option('multi').owner.get() == owners.default
cfg.option('multi').value.set([undefined])
cfg.option('multi').value.set([[]])
assert cfg.option('multi').owner.get() == owner
assert cfg.option('multi').value.get() == [[]]
cfg.option('multi').value.set([undefined, ['no']])
cfg.option('multi').value.set([[], ['no']])
assert cfg.option('multi').value.get() == [[], ['no']]
#
assert cfg.option('multi2').value.get() == []
assert cfg.option('multi2').owner.get() == owners.default
cfg.option('multi2').value.set([undefined])
cfg.option('multi2').value.set([cfg.option('multi2').defaultmulti()])
assert cfg.option('multi2').owner.get() == owner
assert cfg.option('multi2').value.get() == [['yes']]
cfg.option('multi2').value.set([undefined, ['no']])
cfg.option('multi2').value.set([cfg.option('multi2').defaultmulti(), ['no']])
assert cfg.option('multi2').value.get() == [['yes'], ['no']]
#
assert cfg.option('multi3').value.get() == [['yes']]
assert cfg.option('multi3').owner.get() == owners.default
cfg.option('multi3').value.set([undefined, undefined])
cfg.option('multi3').value.set([cfg.option('multi2').defaultmulti(), []])
assert cfg.option('multi3').owner.get() == owner
assert cfg.option('multi3').value.get() == [['yes'], []]
cfg.option('multi3').value.set([undefined, undefined, ['no']])
cfg.option('multi3').value.set([cfg.option('multi2').defaultmulti(), [], ['no']])
assert cfg.option('multi3').value.get() == [['yes'], [], ['no']]
# assert not list_sessions()
@ -193,7 +193,7 @@ def test_callback_submulti_str():
owner = cfg.owner.get()
assert cfg.option('multi').owner.get() == owners.default
assert cfg.option('multi').value.get() == [['val']]
cfg.option('multi').value.set([['val'], undefined])
cfg.option('multi').value.set([['val'], cfg.option('multi').defaultmulti()])
assert cfg.option('multi').owner.get() == owner
assert cfg.option('multi').value.get() == [['val'], ['val']]
cfg.option('multi').value.reset()
@ -209,13 +209,13 @@ def test_callback_submulti_list():
owner = cfg.owner.get()
assert cfg.option('multi').value.get() == [['val', 'val']]
assert cfg.option('multi').owner.get() == owners.default
cfg.option('multi').value.set([['val', 'val'], undefined])
#assert cfg.option('multi').owner.get() == owner
#assert cfg.option('multi').value.get() == [['val', 'val'], ['val', 'val']]
#cfg.option('multi').value.set([['val', 'val'], undefined, undefined])
#assert cfg.option('multi').value.get() == [['val', 'val'], ['val', 'val'], ['val', 'val']]
#cfg.option('multi').value.reset()
#assert cfg.option('multi').owner.get() == owners.default
cfg.option('multi').value.set([['val', 'val'], cfg.option('multi').defaultmulti()])
assert cfg.option('multi').owner.get() == owner
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()])
assert cfg.option('multi').value.get() == [['val', 'val'], ['val', 'val'], ['val', 'val']]
cfg.option('multi').value.reset()
assert cfg.option('multi').owner.get() == owners.default
# assert not list_sessions()
@ -227,7 +227,7 @@ def test_callback_submulti_list_list():
owner = cfg.owner.get()
assert cfg.option('multi').value.get() == [['val', 'val']]
assert cfg.option('multi').owner.get() == owners.default
cfg.option('multi').value.set([['val', 'val'], undefined])
cfg.option('multi').value.set([['val', 'val'], cfg.option('multi').defaultmulti()])
assert cfg.option('multi').owner.get() == owner
assert cfg.option('multi').value.get() == [['val', 'val'], []]
cfg.option('multi').value.reset()

View file

@ -28,6 +28,7 @@ from .setting import ConfigBag, OptionBag, owners, groups, undefined, \
from .config import KernelConfig, KernelGroupConfig, KernelMetaConfig, KernelMixConfig
from .option import RegexpOption, OptionDescription, ChoiceOption
from .todict import TiramisuDict
from .autolib import Calculation
TIRAMISU_VERSION = 4
@ -615,15 +616,7 @@ class TiramisuOptionValue(CommonTiramisuOption):
"""Change option's value"""
option_bag = options_bag[-1]
values = option_bag.config_bag.context.get_values()
if isinstance(value, list):
while undefined in value:
idx = value.index(undefined)
soption_bag = option_bag.copy()
soption_bag.index = idx
value[idx] = values.get_default_value(soption_bag)
elif value == undefined:
value = values.get_default_value(option_bag)
if option_bag.option.impl_is_leader() and \
if not isinstance(value, Calculation) and option_bag.option.impl_is_leader() and \
len(value) < self._config_bag.context.get_length_leadership(options_bag[-2]):
raise LeadershipError(_('cannot reduce length of the leader "{}"'
'').format(option_bag.option.impl_get_display_name()))

View file

@ -212,6 +212,9 @@ class Calculation:
for_settings=for_settings,
)
def __deepcopy__(x, memo):
return x
def manager_callback(callback: Callable,
param: Param,

View file

@ -31,6 +31,7 @@ from .setting import OptionBag, ConfigBag, Settings, undefined, groups
from .value import Values, owners
from .i18n import _
from .cacheobj import Cache
from .autolib import Calculation
class _SubConfig:

View file

@ -186,7 +186,7 @@ class Leadership(OptionDescription):
)
values.set_storage_value(foption_bag_index.path,
index,
values.get_value(foption_bag_index),
values.get_value(foption_bag_index)[0],
owner,
)

View file

@ -144,7 +144,7 @@ class CacheOptionDescription(BaseOption):
leader = option.impl_get_leadership().get_leader()
for leader_option_bag in do_option_bags(leader):
leader_option_bag.properties = frozenset()
follower_len = len(values.get_value(leader_option_bag))
follower_len = len(values.get_value(leader_option_bag)[0])
if option.issubdyn():
subpath = leader_option_bag.option.rootpath
doption = option.to_dynoption(subpath,
@ -162,7 +162,7 @@ class CacheOptionDescription(BaseOption):
)
if values.hasvalue(subpath, index=index):
continue
value = values.get_value(option_bag)
value = values.get_value(option_bag)[0]
if value is None:
continue
values.set_storage_value(subpath,
@ -173,7 +173,7 @@ class CacheOptionDescription(BaseOption):
else:
for option_bag in do_option_bags(option):
option_bag.properties = frozenset()
value = values.get_value(option_bag)
value = values.get_value(option_bag)[0]
if value is None:
continue
if values.hasvalue(option_bag.path):

View file

@ -65,7 +65,7 @@ class Values:
)
# no cached value so get value
if not is_cached:
value = self.get_value(option_bag)
value, has_calculation = self.get_value(option_bag)
# validates and warns value
if not validated:
validate = option_bag.option.impl_validate(value,
@ -78,7 +78,7 @@ class Values:
check_error=False,
)
# set value to cache
if not is_cached:
if not is_cached and not has_calculation:
cache.setcache(option_bag,
value,
validated=validate,
@ -106,7 +106,10 @@ class Values:
# the value is a default value
# get it
value = self.get_default_value(option_bag)
return value
value, has_calculation = self.get_calculated_value(option_bag,
value,
)
return value, has_calculation
def get_default_value(self,
option_bag: OptionBag,
@ -122,9 +125,9 @@ class Values:
return moption_bag.config_bag.context.get_values().get_cached_value(moption_bag)
# now try to get calculated value:
value = self.get_calculated_value(option_bag,
option_bag.option.impl_getdefault(),
)
value, _has_calculation = self.get_calculated_value(option_bag,
option_bag.option.impl_getdefault(),
)
if option_bag.index is not None and isinstance(value, (list, tuple)) \
and (not option_bag.option.impl_is_submulti() or \
not value or isinstance(value[0], list)):
@ -135,9 +138,9 @@ class Values:
else:
# no value for this index, retrieve default multi value
# default_multi is already a list for submulti
value = self.get_calculated_value(option_bag,
option_bag.option.impl_getdefault_multi(),
)
value, _has_calculation = self.get_calculated_value(option_bag,
option_bag.option.impl_getdefault_multi(),
)
return value
def get_calculated_value(self,
@ -147,6 +150,7 @@ class Values:
) -> Any:
"""value could be a calculation, in this case do calculation
"""
has_calculation = False
if isinstance(value, Calculation):
try:
value = value.execute(option_bag)
@ -154,18 +158,21 @@ class Values:
msg = _(f'error when calculating "{option_bag.option.impl_get_display_name()}": '
f'{err} : {option_bag.path}')
raise ConfigError(msg) from err
has_calculation = True
elif isinstance(value, list):
# if value is a list, do subcalculation
for idx, val in enumerate(value):
value[idx] = self.get_calculated_value(option_bag,
val,
reset_cache=False,
)
value[idx], _has_calculation = self.get_calculated_value(option_bag,
val,
reset_cache=False,
)
if _has_calculation:
has_calculation = True
if reset_cache:
self.reset_cache_after_calculation(option_bag,
value,
)
return value
return value, has_calculation
#______________________________________________________________________
def check_force_to_metaconfig(self,
@ -248,27 +255,31 @@ class Values:
"""set value to option
"""
owner = self.get_context_owner()
if 'validator' in option_bag.config_bag.properties:
self.setvalue_validation(value,
option_bag,
)
setting_properties = option_bag.config_bag.properties
ori_value = value
if 'validator' in setting_properties:
value, has_calculation = self.setvalue_validation(value,
option_bag,
)
if isinstance(value, list):
elif isinstance(value, list):
# copy
value = value.copy()
self._setvalue(option_bag,
value,
ori_value,
owner,
)
setting_properties = option_bag.config_bag.properties
validator = 'validator' in setting_properties and \
'demoting_error_warning' not in setting_properties
if validator:
if validator and not has_calculation:
cache = option_bag.config_bag.context.get_values_cache()
cache.setcache(option_bag,
value,
validated=validator,
)
elif 'validator' in setting_properties and has_calculation:
cache = option_bag.config_bag.context.get_values_cache()
cache.delcache(option_bag.path)
if 'force_store_value' in setting_properties and option_bag.option.impl_is_leader():
leader = option_bag.option.impl_get_leadership()
leader.follower_force_store_value(value,
@ -286,10 +297,10 @@ class Values:
# First validate properties with this value
opt = option_bag.option
settings.validate_frozen(option_bag)
val = self.get_calculated_value(option_bag,
value,
False,
)
val, has_calculation = self.get_calculated_value(option_bag,
value,
False,
)
settings.validate_mandatory(val,
option_bag,
)
@ -300,10 +311,11 @@ class Values:
)
if 'warnings' in option_bag.config_bag.properties:
# No error found so emit warnings
opt.impl_validate(value,
opt.impl_validate(val,
option_bag,
check_error=False,
)
return val, has_calculation
def _setvalue(self,
option_bag: OptionBag,
@ -362,7 +374,7 @@ class Values:
option_bag.config_bag,
properties=frozenset(),
)
indexes = range(len(self.get_value(loption_bag)))
indexes = range(len(self.get_value(loption_bag)[0]))
else:
indexes = [None]
for index in indexes:
@ -370,7 +382,7 @@ class Values:
index,
option_bag.config_bag,
)
default_value = [self.get_value(coption_bag), owners.forced]
default_value = [self.get_value(coption_bag)[0], owners.forced]
self._values.setdefault(coption_bag.path, {})[index] = default_value
def _get_modified_parent(self,