diff --git a/tests/test_submulti.py b/tests/test_submulti.py index 92d5a24..ac880b7 100644 --- a/tests/test_submulti.py +++ b/tests/test_submulti.py @@ -433,6 +433,20 @@ async def test_callback_submulti(): assert not await list_sessions() +@pytest.mark.asyncio +async def test_callback_submulti_follower(): + multi = StrOption('multi', '', multi=True) + multi2 = StrOption('multi2', '', Calculation(return_list), multi=submulti) + od = Leadership('multi', '', [multi, multi2]) + od = OptionDescription('multi', '', [od]) + async with await Config(od) as cfg: + await cfg.property.read_write() + assert await cfg.option('multi.multi').value.get() == [] + await cfg.option('multi.multi').value.set(['val']) + assert await cfg.option('multi.multi2', 0).value.get() == ['val', 'val'] + assert not await list_sessions() + + @pytest.mark.asyncio async def test_submulti_unique(): i = IntOption('int', '', multi=submulti, properties=('unique',)) diff --git a/tiramisu/autolib.py b/tiramisu/autolib.py index d4ea3df..bc1bf86 100644 --- a/tiramisu/autolib.py +++ b/tiramisu/autolib.py @@ -415,7 +415,7 @@ async def carry_out_calculation(option, args, kwargs) if isinstance(ret, list) and not option.impl_is_dynoptiondescription() and \ - option.impl_is_follower(): + option.impl_is_follower() and not option.impl_is_submulti(): if args or kwargs: raise LeadershipError(_('the "{}" function with positional arguments "{}" ' 'and keyword arguments "{}" must not return ' diff --git a/tiramisu/value.py b/tiramisu/value.py index 9de473b..73c81ce 100644 --- a/tiramisu/value.py +++ b/tiramisu/value.py @@ -198,15 +198,27 @@ class Values: # now try to get default value: value = await self.calc_value(option_bag, option_bag.option.impl_getdefault()) - if option_bag.option.impl_is_multi() and option_bag.index is not None and isinstance(value, (list, tuple)): - # if index, must return good value for this index - if len(value) > option_bag.index: - value = value[option_bag.index] - else: - # no value for this index, retrieve default multi value - # default_multi is already a list for submulti - value = await self.calc_value(option_bag, - option_bag.option.impl_getdefault_multi()) + if option_bag.index is not None and isinstance(value, (list, tuple)): + if value and option_bag.option.impl_is_submulti(): + # first index is a list, assume other data are list too + if isinstance(value[0], list): + # if index, must return good value for this index + if len(value) > option_bag.index: + value = value[option_bag.index] + else: + # no value for this index, retrieve default multi value + # default_multi is already a list for submulti + value = await self.calc_value(option_bag, + option_bag.option.impl_getdefault_multi()) + elif option_bag.option.impl_is_multi(): + # if index, must return good value for this index + if len(value) > option_bag.index: + value = value[option_bag.index] + else: + # no value for this index, retrieve default multi value + # default_multi is already a list for submulti + value = await self.calc_value(option_bag, + option_bag.option.impl_getdefault_multi()) return value async def calculate_reset_cache(self,