context could be useful in a callback, now we can retrieve context in a function...
authorEmmanuel Garette <egarette@cadoles.com>
Wed, 26 Mar 2014 18:44:49 +0000 (19:44 +0100)
committerEmmanuel Garette <egarette@cadoles.com>
Wed, 26 Mar 2014 18:47:42 +0000 (19:47 +0100)
test/test_option_calculation.py
tiramisu/autolib.py
tiramisu/option.py

index 89f9291..ad1b54f 100644 (file)
@@ -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():
index 0b97644..e837f79 100644 (file)
@@ -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))
-
-                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))
+                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))
             else:
                 # callbk is a value and not a multi
                 tcparams.setdefault(key, []).append((callbk, False))
index 30277e2..d8853df 100644 (file)
@@ -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)))