feat: identifier in ParamDynOption could be a calculation

This commit is contained in:
egarette@silique.fr 2026-02-28 09:02:53 +01:00
parent 849cff522b
commit 87c1416430
2 changed files with 52 additions and 3 deletions

View file

@ -3142,3 +3142,42 @@ def test_dyn_disabled():
cfg.property.read_write()
with pytest.raises(ConfigError):
cfg.value.get()
def test_dyn_param_calculation():
var1 = StrOption("var1", "var1", default=["val1", "val2"], multi=True)
var = StrOption("var", "var", default=Calculation(calc_value, Params(ParamIdentifier())))
dyn = DynOptionDescription("dyn", "dyn", identifiers=Calculation(calc_value, Params((ParamOption(var1)))), children=[var])
var2 = StrOption(name="var2", doc="A variable calculated", default=Calculation(calc_value, Params((ParamDynOption(var, Calculation(calc_value, Params(ParamValue(["val1"]))))))))
od = OptionDescription('od', '', [var1, dyn, var2])
cfg = Config(od)
cfg.property.read_write()
assert parse_od_get(cfg.value.get()) == {'var1': ['val1', 'val2'], 'dynval1.var': 'val1', 'dynval2.var': 'val2', 'var2': 'val1'}
def test_dyn_param_calculation_var():
identifier_var = StrOption("identifier_var", "identifier_var", default=["val1"], multi=True)
var1 = StrOption("var1", "var1", default=["val1", "val2"], multi=True)
var = StrOption("var", "var", default=Calculation(calc_value, Params(ParamIdentifier())))
dyn = DynOptionDescription("dyn", "dyn", identifiers=Calculation(calc_value, Params((ParamOption(var1)))), children=[var])
var2 = StrOption(name="var2", doc="A variable calculated", default=Calculation(calc_value, Params((ParamDynOption(var, Calculation(calc_value, Params(ParamOption(identifier_var))))))))
od = OptionDescription('od', '', [identifier_var, var1, dyn, var2])
cfg = Config(od)
cfg.property.read_write()
assert parse_od_get(cfg.value.get()) == {'identifier_var': ['val1'], 'var1': ['val1', 'val2'], 'dynval1.var': 'val1', 'dynval2.var': 'val2', 'var2': 'val1'}
cfg.option('identifier_var').value.set(['val2'])
assert parse_od_get(cfg.value.get()) == {'identifier_var': ['val2'], 'var1': ['val1', 'val2'], 'dynval1.var': 'val1', 'dynval2.var': 'val2', 'var2': 'val2'}
def test_dyn_param_calculation_var_not_multi():
identifier_var = StrOption("identifier_var", "identifier_var", default="val1")
var1 = StrOption("var1", "var1", default=["val1", "val2"], multi=True)
var = StrOption("var", "var", default=Calculation(calc_value, Params(ParamIdentifier())))
dyn = DynOptionDescription("dyn", "dyn", identifiers=Calculation(calc_value, Params((ParamOption(var1)))), children=[var])
var2 = StrOption(name="var2", doc="A variable calculated", default=Calculation(calc_value, Params((ParamDynOption(var, Calculation(calc_value, Params(ParamOption(identifier_var))))))))
od = OptionDescription('od', '', [identifier_var, var1, dyn, var2])
cfg = Config(od)
cfg.property.read_write()
assert parse_od_get(cfg.value.get()) == {'identifier_var': 'val1', 'var1': ['val1', 'val2'], 'dynval1.var': 'val1', 'dynval2.var': 'val2', 'var2': 'val1'}
cfg.option('identifier_var').value.set('val2')
assert parse_od_get(cfg.value.get()) == {'identifier_var': 'val2', 'var1': ['val1', 'val2'], 'dynval1.var': 'val1', 'dynval2.var': 'val2', 'var2': 'val2'}

View file

@ -155,9 +155,9 @@ class ParamDynOption(ParamOption):
notraisepropertyerror,
raisepropertyerror,
)
if not isinstance(identifiers, list):
if not isinstance(identifiers, (list, Calculation)):
raise Exception(
_("identifiers in ParamDynOption must be a list, not {0}").format(
_("identifiers in ParamDynOption must be a list or a calculation, not {0}").format(
identifiers
)
)
@ -167,6 +167,8 @@ class ParamDynOption(ParamOption):
optional
)
)
if isinstance(identifiers, Calculation):
option.value_dependency(identifiers, type_="identifier")
self.identifiers = identifiers
self.optional = optional
@ -675,7 +677,15 @@ def manager_callback(
with_index = False
if callbk_option.issubdyn():
if isinstance(param, ParamDynOption):
identifiers = param.identifiers.copy()
if isinstance(param.identifiers, Calculation):
identifiers = get_calculated_value(
subconfig,
param.identifiers,
)[0]
if not isinstance(identifiers, list):
identifiers = [identifiers]
else:
identifiers = param.identifiers.copy()
paths = callbk_option.impl_getpath().split(".")
parents = [config_bag.context.get_root(config_bag)]
subconfigs_is_a_list = False