From 835d6d6da03c2e88263d580640b92511b92a1980 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Wed, 26 Mar 2014 19:44:49 +0100 Subject: [PATCH] context could be useful in a callback, now we can retrieve context in a function (be careful to infinite loop) --- test/test_option_calculation.py | 30 ++++++++++++++ tiramisu/autolib.py | 69 ++++++++++++++++++--------------- tiramisu/option.py | 35 ++++++++++------- 3 files changed, 89 insertions(+), 45 deletions(-) diff --git a/test/test_option_calculation.py b/test/test_option_calculation.py index 89f9291..ad1b54f 100644 --- a/test/test_option_calculation.py +++ b/test/test_option_calculation.py @@ -44,6 +44,13 @@ def return_calc(i, j, k): return i + j + k +def is_config(config, **kwargs): + if isinstance(config, Config): + return 'yes' + else: + return 'no' + + def make_description(): gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref') gcdummy = BoolOption('dummy', 'dummy', default=False) @@ -254,6 +261,29 @@ def test_callback_invalid(): raises(ValueError, "StrOption('val2', '', callback=return_value, callback_params={'': 'string'})") raises(ValueError, "StrOption('val4', '', callback=return_value, callback_params={'value': (('string', False),)})") raises(ValueError, "StrOption('val4', '', callback=return_value, callback_params={'value': ((val1, 'string'),)})") + raises(ValueError, "StrOption('val4', '', callback=return_value, callback_params={'value': ((val1, False, 'unknown'),)})") + raises(ValueError, "StrOption('val4', '', callback=return_value, callback_params={'value': ((val1,),)})") + + +def test_callback_with_context(): + val1 = StrOption("val1", "", callback=is_config, callback_params={'': ((None,),), 'value': ('string',)}) + maconfig = OptionDescription('rootconfig', '', [val1]) + cfg = Config(maconfig) + assert cfg.val1 == 'yes' + + +def test_callback_with_context_named(): + val1 = StrOption("val1", "", callback=is_config, callback_params={'config': ((None,),)}) + maconfig = OptionDescription('rootconfig', '', [val1]) + cfg = Config(maconfig) + assert cfg.val1 == 'yes' + + +def test_callback_with_error(): + val1 = StrOption("val1", "", callback=is_config, callback_params={'': ('string',), 'value': ('string',)}) + maconfig = OptionDescription('rootconfig', '', [val1]) + cfg = Config(maconfig) + assert cfg.val1 == 'no' def test_callback_value(): diff --git a/tiramisu/autolib.py b/tiramisu/autolib.py index 0b97644..e837f79 100644 --- a/tiramisu/autolib.py +++ b/tiramisu/autolib.py @@ -145,39 +145,44 @@ def carry_out_calculation(option, config, callback, callback_params, for key, callbacks in callback_params.items(): for callbk in callbacks: if isinstance(callbk, tuple): - # callbk is something link (opt, True|False) - opt, force_permissive = callbk - path = config.cfgimpl_get_description().impl_get_path_by_opt( - opt) - # get value - try: - value = config._getattr(path, force_permissive=True, validate=False) - # convert to list, not modifie this multi - if value.__class__.__name__ == 'Multi': - value = list(value) - except PropertiesOptionError as err: - if force_permissive: - continue - raise ConfigError(_('unable to carry out a calculation, ' - 'option {0} has properties: {1} for: ' - '{2}').format(opt._name, - err.proptype, - option._name)) + if len(callbk) == 1: + tcparams.setdefault(key, []).append((config, False)) + else: + # callbk is something link (opt, True|False) + opt, force_permissive = callbk + path = config.cfgimpl_get_description( + ).impl_get_path_by_opt(opt) + # get value + try: + value = config._getattr(path, force_permissive=True, + validate=False) + # convert to list, not modifie this multi + if value.__class__.__name__ == 'Multi': + value = list(value) + except PropertiesOptionError as err: + if force_permissive: + continue + raise ConfigError(_('unable to carry out a calculation' + ', option {0} has properties: {1} ' + 'for: {2}').format(opt._name, + err.proptype, + option._name)) - is_multi = False - if opt.impl_is_multi(): - #opt is master, search if option is a slave - if opt.impl_get_multitype() == multitypes.master: - if option in opt.impl_get_master_slaves(): - is_multi = True - #opt is slave, search if option is an other slaves - elif opt.impl_get_multitype() == multitypes.slave: - if option in opt.impl_get_master_slaves().impl_get_master_slaves(): - is_multi = True - if is_multi: - len_multi = len(value) - one_is_multi = True - tcparams.setdefault(key, []).append((value, is_multi)) + is_multi = False + if opt.impl_is_multi(): + #opt is master, search if option is a slave + if opt.impl_get_multitype() == multitypes.master: + if option in opt.impl_get_master_slaves(): + is_multi = True + #opt is slave, search if option is an other slaves + elif opt.impl_get_multitype() == multitypes.slave: + if option in opt.impl_get_master_slaves( + ).impl_get_master_slaves(): + is_multi = True + if is_multi: + len_multi = len(value) + one_is_multi = True + tcparams.setdefault(key, []).append((value, is_multi)) else: # callbk is a value and not a multi tcparams.setdefault(key, []).append((callbk, False)) diff --git a/tiramisu/option.py b/tiramisu/option.py index 30277e2..d8853df 100644 --- a/tiramisu/option.py +++ b/tiramisu/option.py @@ -1528,16 +1528,25 @@ def validate_callback(callback, callback_params, type_): ).format(type_, key)) for callbk in callbacks: if isinstance(callbk, tuple): - option, force_permissive = callbk - if type_ == 'validator' and not force_permissive: - raise ValueError(_('validator not support tuple')) - if not isinstance(option, Option) and not \ - isinstance(option, SymLinkOption): - raise ValueError(_('{0}_params must have an option ' - 'not a {0} for first argument' - ).format(type_, type(option))) - if force_permissive not in [True, False]: - raise ValueError(_('{0}_params must have a boolean' - ' not a {0} for second argument' - ).format(type_, type( - force_permissive))) + if len(callbk) == 1: + if callbk != (None,): + raise ValueError(_('{0}_params with length of ' + 'tuple as 1 must only have ' + 'None as first value')) + elif len(callbk) != 2: + raise ValueError(_('{0}_params must only 1 or 2 as ' + 'length')) + else: + option, force_permissive = callbk + if type_ == 'validator' and not force_permissive: + raise ValueError(_('validator not support tuple')) + if not isinstance(option, Option) and not \ + isinstance(option, SymLinkOption): + raise ValueError(_('{0}_params must have an option' + ' not a {0} for first argument' + ).format(type_, type(option))) + if force_permissive not in [True, False]: + raise ValueError(_('{0}_params must have a boolean' + ' not a {0} for second argument' + ).format(type_, type( + force_permissive)))