support callback with submulti

This commit is contained in:
Emmanuel Garette 2020-04-21 17:13:25 +02:00
parent f437bb78f3
commit 86a48ce9f1
3 changed files with 36 additions and 10 deletions

View File

@ -433,6 +433,20 @@ async def test_callback_submulti():
assert not await list_sessions() 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 @pytest.mark.asyncio
async def test_submulti_unique(): async def test_submulti_unique():
i = IntOption('int', '', multi=submulti, properties=('unique',)) i = IntOption('int', '', multi=submulti, properties=('unique',))

View File

@ -415,7 +415,7 @@ async def carry_out_calculation(option,
args, args,
kwargs) kwargs)
if isinstance(ret, list) and not option.impl_is_dynoptiondescription() and \ 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: if args or kwargs:
raise LeadershipError(_('the "{}" function with positional arguments "{}" ' raise LeadershipError(_('the "{}" function with positional arguments "{}" '
'and keyword arguments "{}" must not return ' 'and keyword arguments "{}" must not return '

View File

@ -198,15 +198,27 @@ class Values:
# now try to get default value: # now try to get default value:
value = await self.calc_value(option_bag, value = await self.calc_value(option_bag,
option_bag.option.impl_getdefault()) 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 option_bag.index is not None and isinstance(value, (list, tuple)):
# if index, must return good value for this index if value and option_bag.option.impl_is_submulti():
if len(value) > option_bag.index: # first index is a list, assume other data are list too
value = value[option_bag.index] if isinstance(value[0], list):
else: # if index, must return good value for this index
# no value for this index, retrieve default multi value if len(value) > option_bag.index:
# default_multi is already a list for submulti value = value[option_bag.index]
value = await self.calc_value(option_bag, else:
option_bag.option.impl_getdefault_multi()) # 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 return value
async def calculate_reset_cache(self, async def calculate_reset_cache(self,