context could be useful in a callback, now we can retrieve context in a function (be careful to infinite loop)

This commit is contained in:
Emmanuel Garette 2014-03-26 19:44:49 +01:00
parent b3d04a1f68
commit 835d6d6da0
3 changed files with 89 additions and 45 deletions

View File

@ -44,6 +44,13 @@ def return_calc(i, j, k):
return i + j + k return i + j + k
def is_config(config, **kwargs):
if isinstance(config, Config):
return 'yes'
else:
return 'no'
def make_description(): def make_description():
gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref') gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
gcdummy = BoolOption('dummy', 'dummy', default=False) 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('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': (('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, '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(): def test_callback_value():

View File

@ -145,39 +145,44 @@ def carry_out_calculation(option, config, callback, callback_params,
for key, callbacks in callback_params.items(): for key, callbacks in callback_params.items():
for callbk in callbacks: for callbk in callbacks:
if isinstance(callbk, tuple): if isinstance(callbk, tuple):
# callbk is something link (opt, True|False) if len(callbk) == 1:
opt, force_permissive = callbk tcparams.setdefault(key, []).append((config, False))
path = config.cfgimpl_get_description().impl_get_path_by_opt( else:
opt) # callbk is something link (opt, True|False)
# get value opt, force_permissive = callbk
try: path = config.cfgimpl_get_description(
value = config._getattr(path, force_permissive=True, validate=False) ).impl_get_path_by_opt(opt)
# convert to list, not modifie this multi # get value
if value.__class__.__name__ == 'Multi': try:
value = list(value) value = config._getattr(path, force_permissive=True,
except PropertiesOptionError as err: validate=False)
if force_permissive: # convert to list, not modifie this multi
continue if value.__class__.__name__ == 'Multi':
raise ConfigError(_('unable to carry out a calculation, ' value = list(value)
'option {0} has properties: {1} for: ' except PropertiesOptionError as err:
'{2}').format(opt._name, if force_permissive:
err.proptype, continue
option._name)) 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 is_multi = False
if opt.impl_is_multi(): if opt.impl_is_multi():
#opt is master, search if option is a slave #opt is master, search if option is a slave
if opt.impl_get_multitype() == multitypes.master: if opt.impl_get_multitype() == multitypes.master:
if option in opt.impl_get_master_slaves(): if option in opt.impl_get_master_slaves():
is_multi = True is_multi = True
#opt is slave, search if option is an other slaves #opt is slave, search if option is an other slaves
elif opt.impl_get_multitype() == multitypes.slave: elif opt.impl_get_multitype() == multitypes.slave:
if option in opt.impl_get_master_slaves().impl_get_master_slaves(): if option in opt.impl_get_master_slaves(
is_multi = True ).impl_get_master_slaves():
if is_multi: is_multi = True
len_multi = len(value) if is_multi:
one_is_multi = True len_multi = len(value)
tcparams.setdefault(key, []).append((value, is_multi)) one_is_multi = True
tcparams.setdefault(key, []).append((value, is_multi))
else: else:
# callbk is a value and not a multi # callbk is a value and not a multi
tcparams.setdefault(key, []).append((callbk, False)) tcparams.setdefault(key, []).append((callbk, False))

View File

@ -1528,16 +1528,25 @@ def validate_callback(callback, callback_params, type_):
).format(type_, key)) ).format(type_, key))
for callbk in callbacks: for callbk in callbacks:
if isinstance(callbk, tuple): if isinstance(callbk, tuple):
option, force_permissive = callbk if len(callbk) == 1:
if type_ == 'validator' and not force_permissive: if callbk != (None,):
raise ValueError(_('validator not support tuple')) raise ValueError(_('{0}_params with length of '
if not isinstance(option, Option) and not \ 'tuple as 1 must only have '
isinstance(option, SymLinkOption): 'None as first value'))
raise ValueError(_('{0}_params must have an option ' elif len(callbk) != 2:
'not a {0} for first argument' raise ValueError(_('{0}_params must only 1 or 2 as '
).format(type_, type(option))) 'length'))
if force_permissive not in [True, False]: else:
raise ValueError(_('{0}_params must have a boolean' option, force_permissive = callbk
' not a {0} for second argument' if type_ == 'validator' and not force_permissive:
).format(type_, type( raise ValueError(_('validator not support tuple'))
force_permissive))) 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)))