From 3b1dccd844b648f03841df71bcf67c323ed88335 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Sun, 21 Mar 2021 14:51:12 +0100 Subject: [PATCH] allow caching with the demoting_error_warning property --- tests/test_cache.py | 29 ++++++++++++++++++++++++ tiramisu/option/option.py | 9 +++++--- tiramisu/value.py | 47 +++++++++++++++++++++------------------ 3 files changed, 60 insertions(+), 25 deletions(-) diff --git a/tests/test_cache.py b/tests/test_cache.py index 94b0a74..4f41d2d 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -559,6 +559,8 @@ async def test_cache_global_properties(): @pytest.mark.asyncio async def test_callback_value_incr(): + global incr + incr = -1 val1 = IntOption('val1', "", Calculation(return_incr), properties=('expire',)) val2 = IntOption('val2', "", Calculation(calc_value, Params(ParamOption(val1)))) od1 = OptionDescription('rootconfig', '', [val1, val2]) @@ -579,3 +581,30 @@ async def test_callback_value_incr(): assert await cfg.option('val1').value.get() == 2 assert await cfg.option('val2').value.get() == 2 assert not await list_sessions() + + +@pytest.mark.asyncio +async def test_callback_value_incr_demoting(): + global incr + incr = -1 + val1 = IntOption('val1', "", Calculation(return_incr), properties=('expire',)) + val2 = IntOption('val2', "", Calculation(calc_value, Params(ParamOption(val1)))) + od1 = OptionDescription('rootconfig', '', [val1, val2]) + async with await Config(od1) as cfg: + await cfg.property.add('demoting_error_warning') + assert await cfg.cache.get_expiration_time() == 5 + await cfg.cache.set_expiration_time(1) + assert await cfg.cache.get_expiration_time() == 1 + await cfg.property.read_write() + assert await cfg.option('val1').value.get() == 1 + sleep(1) + assert await cfg.option('val2').value.get() == 1 + sleep(1) + assert await cfg.option('val1').value.get() == 1 + assert await cfg.option('val2').value.get() == 1 + sleep(2) + assert await cfg.option('val1').value.get() == 2 + assert await cfg.option('val2').value.get() == 2 + assert await cfg.option('val1').value.get() == 2 + assert await cfg.option('val2').value.get() == 2 + assert not await list_sessions() diff --git a/tiramisu/option/option.py b/tiramisu/option/option.py index a576e57..b9ea370 100644 --- a/tiramisu/option/option.py +++ b/tiramisu/option/option.py @@ -333,7 +333,8 @@ class Option(BaseOption): value: Any, option_bag: OptionBag, check_error: bool=True) -> None: - """ + """Return True if value is really valid + If not validate or invalid return it returns False """ config_bag = option_bag.config_bag force_index = option_bag.index @@ -341,7 +342,7 @@ class Option(BaseOption): if check_error and config_bag is not undefined and \ not 'validator' in config_bag.properties: - return + return False def _is_not_unique(value, option_bag): @@ -390,7 +391,7 @@ class Option(BaseOption): raise ValueError(_('which must not be a list').format(_value, self.impl_get_display_name())) if isinstance(_value, Calculation) and config_bag is undefined: - return + return False if _value is not None: if check_error: # option validation @@ -467,6 +468,8 @@ class Option(BaseOption): err_index), ValueErrorWarning, self.__class__.__name__, 0) + return False + return True def _validate_calculator(self, callback: Callable, diff --git a/tiramisu/value.py b/tiramisu/value.py index a14ae83..8fe229c 100644 --- a/tiramisu/value.py +++ b/tiramisu/value.py @@ -57,11 +57,12 @@ class Values: None, new=True) + #______________________________________________________________________ # get value - async def get_cached_value(self, - option_bag): + option_bag: OptionBag, + ) -> Any: """get value directly in cache if set otherwise calculated value and set it in cache @@ -75,32 +76,34 @@ class Values: option_bag.index, setting_properties, option_bag.properties, - 'value') - # FIXME hu? validated or is_cached? - if not validated: - # no cached value so get value + 'value', + ) + # no cached value so get value + if not is_cached: value = await self.getvalue(option_bag) - # validate value - await option_bag.option.impl_validate(value, - option_bag, - check_error=True) - # store value in cache - validator = 'validator' in setting_properties and 'demoting_error_warning' not in setting_properties - if not is_cached or validator: - cache.setcache(option_bag.path, - option_bag.index, - value, - option_bag.properties, - setting_properties, - validator) + # validates and warns value + if not validated: + validate = await option_bag.option.impl_validate(value, + option_bag, + check_error=True, + ) if 'warnings' in setting_properties: await option_bag.option.impl_validate(value, option_bag, - check_error=False) + check_error=False, + ) + # set value to cache + if not is_cached: + cache.setcache(option_bag.path, + option_bag.index, + value, + option_bag.properties, + setting_properties, + validate, + ) if isinstance(value, list): # return a copy, so value cannot be modified - from copy import copy - value = copy(value) + value = value.copy() # and return it return value