refactore carry_out_calculation + test + documentation
This commit is contained in:
parent
30ff0fb72b
commit
90ae9aa70d
@ -4,7 +4,7 @@ from py.test import raises
|
||||
from tiramisu.setting import groups
|
||||
from tiramisu.config import Config
|
||||
from tiramisu.option import ChoiceOption, BoolOption, IntOption, FloatOption, \
|
||||
StrOption, OptionDescription
|
||||
StrOption, OptionDescription, SymLinkOption
|
||||
from tiramisu.error import PropertiesOptionError, ConflictError, SlaveError, ConfigError
|
||||
|
||||
|
||||
@ -12,11 +12,19 @@ def return_val():
|
||||
return 'val'
|
||||
|
||||
|
||||
def return_list():
|
||||
def return_concat(*args):
|
||||
return '.'.join(list(args))
|
||||
|
||||
|
||||
def return_list(value=None):
|
||||
return ['val', 'val']
|
||||
|
||||
|
||||
def return_value(value):
|
||||
def return_list2(*args):
|
||||
return list(args)
|
||||
|
||||
|
||||
def return_value(value=None):
|
||||
return value
|
||||
|
||||
|
||||
@ -298,18 +306,73 @@ def test_callback():
|
||||
|
||||
def test_callback_value():
|
||||
val1 = StrOption('val1', "", 'val')
|
||||
val2 = StrOption('val2', "", callback=return_value, callback_params={'': (('val1', False),)})
|
||||
maconfig = OptionDescription('rootconfig', '', [val1, val2])
|
||||
val2 = StrOption('val2', "", callback=return_value, callback_params={'': ((val1, False),)})
|
||||
val3 = StrOption('val3', "", callback=return_value, callback_params={'': ('yes',)})
|
||||
val4 = StrOption('val4', "", callback=return_value, callback_params={'value': ((val1, False),)})
|
||||
val5 = StrOption('val5', "", callback=return_value, callback_params={'value': ('yes',)})
|
||||
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3, val4, val5])
|
||||
cfg = Config(maconfig)
|
||||
cfg.read_write()
|
||||
assert cfg.val1 == 'val'
|
||||
assert cfg.val2 == 'val'
|
||||
assert cfg.val4 == 'val'
|
||||
cfg.val1 = 'new-val'
|
||||
assert cfg.val1 == 'new-val'
|
||||
assert cfg.val2 == 'new-val'
|
||||
assert cfg.val4 == 'new-val'
|
||||
del(cfg.val1)
|
||||
assert cfg.val1 == 'val'
|
||||
assert cfg.val2 == 'val'
|
||||
assert cfg.val3 == 'yes'
|
||||
assert cfg.val4 == 'val'
|
||||
assert cfg.val5 == 'yes'
|
||||
|
||||
|
||||
def test_callback_value_tuple():
|
||||
val1 = StrOption('val1', "", 'val1')
|
||||
val2 = StrOption('val2', "", 'val2')
|
||||
val3 = StrOption('val3', "", callback=return_concat, callback_params={'': ((val1, False), (val2, False))})
|
||||
val4 = StrOption('val4', "", callback=return_concat, callback_params={'': ('yes', 'no')})
|
||||
raises(ValueError, "StrOption('val4', '', callback=return_concat, callback_params={'value': ('yes', 'no')})")
|
||||
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3, val4])
|
||||
cfg = Config(maconfig)
|
||||
cfg.read_write()
|
||||
assert cfg.val1 == 'val1'
|
||||
assert cfg.val2 == 'val2'
|
||||
assert cfg.val3 == 'val1.val2'
|
||||
assert cfg.val4 == 'yes.no'
|
||||
cfg.val1 = 'new-val'
|
||||
assert cfg.val3 == 'new-val.val2'
|
||||
del(cfg.val1)
|
||||
assert cfg.val3 == 'val1.val2'
|
||||
|
||||
|
||||
def test_callback_value_force_permissive():
|
||||
val1 = StrOption('val1', "", 'val', properties=('disabled',))
|
||||
val2 = StrOption('val2', "", callback=return_value, callback_params={'': ((val1, False),)})
|
||||
val3 = StrOption('val3', "", callback=return_value, callback_params={'': ((val1, True),)})
|
||||
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3])
|
||||
cfg = Config(maconfig)
|
||||
cfg.read_only()
|
||||
raises(ConfigError, "cfg.val2")
|
||||
assert cfg.val3 is None
|
||||
|
||||
|
||||
def test_callback_symlink():
|
||||
val1 = StrOption('val1', "", 'val')
|
||||
val2 = SymLinkOption('val2', val1)
|
||||
val3 = StrOption('val3', "", callback=return_value, callback_params={'': ((val2, False),)})
|
||||
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3])
|
||||
cfg = Config(maconfig)
|
||||
cfg.read_write()
|
||||
assert cfg.val1 == 'val'
|
||||
assert cfg.val3 == 'val'
|
||||
cfg.val1 = 'new-val'
|
||||
assert cfg.val1 == 'new-val'
|
||||
assert cfg.val3 == 'new-val'
|
||||
del(cfg.val1)
|
||||
assert cfg.val1 == 'val'
|
||||
assert cfg.val3 == 'val'
|
||||
|
||||
|
||||
def test_callback_list():
|
||||
@ -336,21 +399,28 @@ def test_callback_multi():
|
||||
|
||||
def test_callback_multi_value():
|
||||
val1 = StrOption('val1', "", ['val'], multi=True)
|
||||
val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params={'': (('val1', False),)})
|
||||
maconfig = OptionDescription('rootconfig', '', [val1, val2])
|
||||
val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params={'': ((val1, False),)})
|
||||
val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params={'': ('yes',)})
|
||||
val4 = StrOption('val4', "", multi=True, callback=return_list2, callback_params={'': ((val1, False), 'yes')})
|
||||
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3, val4])
|
||||
cfg = Config(maconfig)
|
||||
cfg.read_write()
|
||||
assert cfg.val1 == ['val']
|
||||
assert cfg.val2 == ['val']
|
||||
assert cfg.val4 == ['val', 'yes']
|
||||
cfg.val1 = ['new-val']
|
||||
assert cfg.val1 == ['new-val']
|
||||
assert cfg.val2 == ['new-val']
|
||||
assert cfg.val4 == ['new-val', 'yes']
|
||||
cfg.val1.append('new-val2')
|
||||
assert cfg.val1 == ['new-val', 'new-val2']
|
||||
assert cfg.val2 == ['new-val', 'new-val2']
|
||||
assert cfg.val4 == ['new-val', 'yes', 'new-val2', 'yes']
|
||||
del(cfg.val1)
|
||||
assert cfg.val1 == ['val']
|
||||
assert cfg.val2 == ['val']
|
||||
assert cfg.val3 == ['yes']
|
||||
assert cfg.val4 == ['val', 'yes']
|
||||
|
||||
|
||||
def test_callback_multi_list():
|
||||
@ -455,41 +525,67 @@ def test_callback_master_and_slaves_slave_list():
|
||||
|
||||
def test_callback_master_and_slaves_value():
|
||||
val1 = StrOption('val1', "", multi=True)
|
||||
val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params={'': (('val1.val1', False),)})
|
||||
interface1 = OptionDescription('val1', '', [val1, val2])
|
||||
val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params={'': ((val1, False),)})
|
||||
val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params={'': ('yes',)})
|
||||
val4 = StrOption('val4', '', multi=True, default=['val10', 'val11'])
|
||||
val5 = StrOption('val5', "", multi=True, callback=return_value, callback_params={'': ((val4, False),)})
|
||||
interface1 = OptionDescription('val1', '', [val1, val2, val3, val5])
|
||||
interface1.impl_set_group_type(groups.master)
|
||||
maconfig = OptionDescription('rootconfig', '', [interface1])
|
||||
maconfig = OptionDescription('rootconfig', '', [interface1, val4])
|
||||
cfg = Config(maconfig)
|
||||
cfg.read_write()
|
||||
assert cfg.val1.val1 == []
|
||||
assert cfg.val1.val2 == []
|
||||
assert cfg.val1.val3 == []
|
||||
assert cfg.val1.val5 == []
|
||||
#
|
||||
cfg.val1.val1 = ['val1']
|
||||
assert cfg.val1.val1 == ['val1']
|
||||
assert cfg.val1.val2 == ['val1']
|
||||
assert cfg.val1.val3 == ['yes']
|
||||
assert cfg.val1.val5 == ['val10']
|
||||
#
|
||||
cfg.val1.val1.append('val2')
|
||||
assert cfg.val1.val1 == ['val1', 'val2']
|
||||
assert cfg.val1.val2 == ['val1', 'val2']
|
||||
assert cfg.val1.val3 == ['yes', 'yes']
|
||||
assert cfg.val1.val5 == ['val10', 'val11']
|
||||
#
|
||||
cfg.val1.val1 = ['val1', 'val2', 'val3']
|
||||
assert cfg.val1.val1 == ['val1', 'val2', 'val3']
|
||||
assert cfg.val1.val2 == ['val1', 'val2', 'val3']
|
||||
assert cfg.val1.val3 == ['yes', 'yes', 'yes']
|
||||
assert cfg.val1.val5 == ['val10', 'val11', None]
|
||||
#
|
||||
cfg.val1.val1.pop(2)
|
||||
assert cfg.val1.val1 == ['val1', 'val2']
|
||||
assert cfg.val1.val2 == ['val1', 'val2']
|
||||
assert cfg.val1.val3 == ['yes', 'yes']
|
||||
assert cfg.val1.val5 == ['val10', 'val11']
|
||||
#
|
||||
cfg.val1.val2 = ['val2', 'val2']
|
||||
cfg.val1.val3 = ['val2', 'val2']
|
||||
cfg.val1.val5 = ['val2', 'val2']
|
||||
assert cfg.val1.val2 == ['val2', 'val2']
|
||||
assert cfg.val1.val3 == ['val2', 'val2']
|
||||
assert cfg.val1.val5 == ['val2', 'val2']
|
||||
#
|
||||
cfg.val1.val1.append('val3')
|
||||
assert cfg.val1.val2 == ['val2', 'val2', 'val3']
|
||||
assert cfg.val1.val3 == ['val2', 'val2', 'yes']
|
||||
assert cfg.val1.val5 == ['val2', 'val2', None]
|
||||
cfg.cfgimpl_get_settings().remove('cache')
|
||||
cfg.val4 = ['val10', 'val11', 'val12']
|
||||
#if value is already set, not updated !
|
||||
cfg.val1.val1.pop(2)
|
||||
cfg.val1.val1.append('val3')
|
||||
cfg.val1.val1 = ['val1', 'val2', 'val3']
|
||||
assert cfg.val1.val5 == ['val2', 'val2', 'val12']
|
||||
|
||||
|
||||
def test_callback_hidden():
|
||||
opt1 = BoolOption('opt1', '')
|
||||
opt2 = BoolOption('opt2', '', callback=return_value, callback_params={'': (('od1.opt1', False),)})
|
||||
opt2 = BoolOption('opt2', '', callback=return_value, callback_params={'': ((opt1, False),)})
|
||||
od1 = OptionDescription('od1', '', [opt1], properties=('hidden',))
|
||||
od2 = OptionDescription('od2', '', [opt2])
|
||||
maconfig = OptionDescription('rootconfig', '', [od1, od2])
|
||||
@ -502,7 +598,7 @@ def test_callback_hidden():
|
||||
|
||||
def test_callback_two_disabled():
|
||||
opt1 = BoolOption('opt1', '', properties=('disabled',))
|
||||
opt2 = BoolOption('opt2', '', callback=return_value, callback_params={'': (('od1.opt1', False),)}, properties=('disabled',))
|
||||
opt2 = BoolOption('opt2', '', callback=return_value, callback_params={'': ((opt1, False),)}, properties=('disabled',))
|
||||
od1 = OptionDescription('od1', '', [opt1])
|
||||
od2 = OptionDescription('od2', '', [opt2])
|
||||
maconfig = OptionDescription('rootconfig', '', [od1, od2])
|
||||
@ -513,7 +609,7 @@ def test_callback_two_disabled():
|
||||
|
||||
def test_callback_calculating_disabled():
|
||||
opt1 = BoolOption('opt1', '', properties=('disabled',))
|
||||
opt2 = BoolOption('opt2', '', callback=return_value, callback_params={'': (('od1.opt1', False),)})
|
||||
opt2 = BoolOption('opt2', '', callback=return_value, callback_params={'': ((opt1, False),)})
|
||||
od1 = OptionDescription('od1', '', [opt1])
|
||||
od2 = OptionDescription('od2', '', [opt2])
|
||||
maconfig = OptionDescription('rootconfig', '', [od1, od2])
|
||||
@ -524,7 +620,7 @@ def test_callback_calculating_disabled():
|
||||
|
||||
def test_callback_calculating_mandatory():
|
||||
opt1 = BoolOption('opt1', '', properties=('disabled',))
|
||||
opt2 = BoolOption('opt2', '', callback=return_value, callback_params={'': (('od1.opt1', False),)}, properties=('mandatory',))
|
||||
opt2 = BoolOption('opt2', '', callback=return_value, callback_params={'': ((opt1, False),)}, properties=('mandatory',))
|
||||
od1 = OptionDescription('od1', '', [opt1])
|
||||
od2 = OptionDescription('od2', '', [opt2])
|
||||
maconfig = OptionDescription('rootconfig', '', [od1, od2])
|
||||
@ -535,10 +631,47 @@ def test_callback_calculating_mandatory():
|
||||
|
||||
def test_callback_two_disabled_multi():
|
||||
opt1 = BoolOption('opt1', '', properties=('disabled',))
|
||||
opt2 = BoolOption('opt2', '', callback=return_value, callback_params={'': (('od1.opt1', False),)}, properties=('disabled',), multi=True)
|
||||
opt2 = BoolOption('opt2', '', callback=return_value, callback_params={'': ((opt1, False),)}, properties=('disabled',), multi=True)
|
||||
od1 = OptionDescription('od1', '', [opt1])
|
||||
od2 = OptionDescription('od2', '', [opt2])
|
||||
maconfig = OptionDescription('rootconfig', '', [od1, od2])
|
||||
cfg = Config(maconfig)
|
||||
cfg.read_write()
|
||||
raises(PropertiesOptionError, 'cfg.od2.opt2')
|
||||
|
||||
|
||||
def test_callback_multi_list_params():
|
||||
val1 = StrOption('val1', "", multi=True, default=['val1', 'val2'])
|
||||
val2 = StrOption('val2', "", multi=True, callback=return_list, callback_params={'': ((val1, False),)})
|
||||
oval2 = OptionDescription('val2', '', [val2])
|
||||
maconfig = OptionDescription('rootconfig', '', [val1, oval2])
|
||||
cfg = Config(maconfig)
|
||||
cfg.read_write()
|
||||
assert cfg.val2.val2 == ['val', 'val', 'val', 'val']
|
||||
|
||||
|
||||
def test_callback_multi_list_params_key():
|
||||
val1 = StrOption('val1', "", multi=True, default=['val1', 'val2'])
|
||||
val2 = StrOption('val2', "", multi=True, callback=return_list, callback_params={'value': ((val1, False),)})
|
||||
oval2 = OptionDescription('val2', '', [val2])
|
||||
maconfig = OptionDescription('rootconfig', '', [val1, oval2])
|
||||
cfg = Config(maconfig)
|
||||
cfg.read_write()
|
||||
assert cfg.val2.val2 == ['val', 'val', 'val', 'val']
|
||||
|
||||
|
||||
def test_callback_multi_multi():
|
||||
val1 = StrOption('val1', "", multi=True, default=['val1', 'val2', 'val3'])
|
||||
val2 = StrOption('val2', "", multi=True, default=['val11', 'val12'])
|
||||
val3 = StrOption('val3', "", default='val4')
|
||||
val4 = StrOption('val4', "", multi=True, callback=return_list2, callback_params={'': ((val1, False), (val2, False))})
|
||||
val5 = StrOption('val5', "", multi=True, callback=return_list2, callback_params={'': ((val1, False), (val3, False))})
|
||||
val6 = StrOption('val6', "", multi=True, default=['val21', 'val22', 'val23'])
|
||||
val7 = StrOption('val7', "", multi=True, callback=return_list2, callback_params={'': ((val1, False), (val6, False))})
|
||||
raises(ValueError, "StrOption('val8', '', multi=True, callback=return_list2, callback_params={'value': ((val1, False), (val6, False))})")
|
||||
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3, val4, val5, val6, val7])
|
||||
cfg = Config(maconfig)
|
||||
cfg.read_write()
|
||||
raises(ConfigError, "cfg.val4")
|
||||
assert cfg.val5 == ['val1', 'val4', 'val2', 'val4', 'val3', 'val4']
|
||||
assert cfg.val7 == ['val1', 'val21', 'val2', 'val22', 'val3', 'val23']
|
||||
|
59
test/test_option_validator.py
Normal file
59
test/test_option_validator.py
Normal file
@ -0,0 +1,59 @@
|
||||
import autopath
|
||||
from py.test import raises
|
||||
|
||||
from tiramisu.config import Config
|
||||
from tiramisu.option import StrOption, OptionDescription
|
||||
from tiramisu.error import ConfigError
|
||||
|
||||
|
||||
def return_true(value, param=None):
|
||||
if value == 'val' and param in [None, 'yes']:
|
||||
return True
|
||||
|
||||
|
||||
def return_false(value, param=None):
|
||||
if value == 'val' and param in [None, 'yes']:
|
||||
return False
|
||||
|
||||
|
||||
def return_val(value, param=None):
|
||||
return 'val'
|
||||
|
||||
|
||||
def test_validator():
|
||||
opt1 = StrOption('opt1', '', validator=return_true, default='val')
|
||||
raises(ValueError, "StrOption('opt2', '', validator=return_false, default='val')")
|
||||
raises(ConfigError, "StrOption('opt3', '', validator=return_val, default='val')")
|
||||
opt2 = StrOption('opt2', '', validator=return_false)
|
||||
opt3 = StrOption('opt3', '', validator=return_val)
|
||||
root = OptionDescription('root', '', [opt1, opt2, opt3])
|
||||
cfg = Config(root)
|
||||
assert cfg.opt1 == 'val'
|
||||
raises(ValueError, "cfg.opt2 = 'val'")
|
||||
raises(ConfigError, "cfg.opt3 = 'val'")
|
||||
|
||||
|
||||
def test_validator_params():
|
||||
opt1 = StrOption('opt1', '', validator=return_true, validator_params={'': ('yes',)}, default='val')
|
||||
raises(ValueError, "StrOption('opt2', '', validator=return_false, validator_params={'': ('yes',)}, default='val')")
|
||||
raises(ConfigError, "StrOption('opt3', '', validator=return_val, validator_params={'': ('yes',)}, default='val')")
|
||||
opt2 = StrOption('opt2', '', validator=return_false, validator_params={'': ('yes',)})
|
||||
opt3 = StrOption('opt3', '', validator=return_val, validator_params={'': ('yes',)})
|
||||
root = OptionDescription('root', '', [opt1, opt2, opt3])
|
||||
cfg = Config(root)
|
||||
assert cfg.opt1 == 'val'
|
||||
raises(ValueError, "cfg.opt2 = 'val'")
|
||||
raises(ConfigError, "cfg.opt3 = 'val'")
|
||||
|
||||
|
||||
def test_validator_params_key():
|
||||
opt1 = StrOption('opt1', '', validator=return_true, validator_params={'param': ('yes',)}, default='val')
|
||||
raises(TypeError, "StrOption('opt2', '', validator=return_true, validator_params={'param_unknown': ('yes',)}, default='val')")
|
||||
root = OptionDescription('root', '', [opt1])
|
||||
cfg = Config(root)
|
||||
assert cfg.opt1 == 'val'
|
||||
|
||||
|
||||
def test_validator_params_option():
|
||||
opt0 = StrOption('opt0', '', default='val')
|
||||
raises(ValueError, "opt1 = StrOption('opt1', '', validator=return_true, validator_params={'': ((opt0, False),)}, default='val')")
|
@ -23,11 +23,9 @@ from tiramisu.error import PropertiesOptionError, ConfigError
|
||||
from tiramisu.i18n import _
|
||||
# ____________________________________________________________
|
||||
|
||||
def carry_out_calculation(name,
|
||||
config,
|
||||
callback,
|
||||
callback_params,
|
||||
index=None):
|
||||
|
||||
def carry_out_calculation(name, config, callback, callback_params,
|
||||
index=None, max_len=None):
|
||||
"""a function that carries out a calculation for an option's value
|
||||
|
||||
:param name: the option name (`opt._name`)
|
||||
@ -40,36 +38,104 @@ def carry_out_calculation(name,
|
||||
:type callback_params: dict
|
||||
:param index: if an option is multi, only calculates the nth value
|
||||
:type index: int
|
||||
:param max_len: max length for a multi
|
||||
:type max_len: int
|
||||
|
||||
* if no callback_params:
|
||||
=> calculate()
|
||||
|
||||
* if callback_params={'': ('yes',)}
|
||||
=> calculate('yes')
|
||||
|
||||
* if callback_params={'value': ('yes',)}
|
||||
=> calculate(value='yes')
|
||||
|
||||
* if callback_params={'': ('yes', 'no')}
|
||||
=> calculate('yes', 'no')
|
||||
|
||||
* if callback_params={'value': ('yes', 'no')}
|
||||
=> ValueError()
|
||||
|
||||
* if callback_params={'': ((opt1, False),)}
|
||||
|
||||
- a simple option:
|
||||
opt1 == 11
|
||||
=> calculate(11)
|
||||
|
||||
- a multi option:
|
||||
opt1 == [1, 2, 3]
|
||||
=> calculate(1)
|
||||
=> calculate(2)
|
||||
=> calculate(3)
|
||||
|
||||
* if callback_params={'value': ((opt1, False),)}
|
||||
|
||||
- a simple option:
|
||||
opt1 == 11
|
||||
=> calculate(value=11)
|
||||
|
||||
- a multi option:
|
||||
opt1 == [1, 2, 3]
|
||||
=> calculate(value=1)
|
||||
=> calculate(value=2)
|
||||
=> calculate(value=3)
|
||||
|
||||
* if callback_params={'': ((opt1, False), (opt2, False))}
|
||||
|
||||
- a multi option with a simple option
|
||||
opt1 == [1, 2, 3]
|
||||
opt2 == 11
|
||||
=> calculate(1, 11)
|
||||
=> calculate(2, 11)
|
||||
=> calculate(3, 11)
|
||||
|
||||
- a multi option with an other multi option but with same length
|
||||
opt1 == [1, 2, 3]
|
||||
opt2 == [11, 12, 13]
|
||||
callback_params={'': ((opt1, False), (opt2, False))}
|
||||
=> calculate(1, 11)
|
||||
=> calculate(2, 12)
|
||||
=> calculate(3, 13)
|
||||
|
||||
- a multi option with an other multi option but with different length
|
||||
opt1 == [1, 2, 3]
|
||||
opt2 == [11, 12]
|
||||
callback_params={'': ((opt1, False), (opt2, False))}
|
||||
=> ConfigError()
|
||||
|
||||
* if callback_params={'value': ((opt1, False), (opt2, False))}
|
||||
=> ConfigError()
|
||||
|
||||
If index is not None, return a value, otherwise return:
|
||||
|
||||
* a list if one parameters have multi option
|
||||
* a value otherwise
|
||||
|
||||
If calculate return list, this list is extend to return value.
|
||||
"""
|
||||
#callback, callback_params = option.getcallback()
|
||||
#if callback_params is None:
|
||||
# callback_params = {}
|
||||
tcparams = {}
|
||||
one_is_multi = False
|
||||
len_multi = 0
|
||||
|
||||
for key, values in callback_params.items():
|
||||
for value in values:
|
||||
if type(value) == tuple:
|
||||
path, check_disabled = value
|
||||
if config is None:
|
||||
if check_disabled:
|
||||
continue
|
||||
raise ConfigError(_('no config specified but needed'))
|
||||
for key, callbacks in callback_params.items():
|
||||
for callbk in callbacks:
|
||||
if isinstance(callbk, tuple):
|
||||
option, force_permissive = callbk
|
||||
# get value
|
||||
try:
|
||||
opt_value = config._getattr(path, force_permissive=True)
|
||||
opt = config.unwrap_from_path(path, force_permissive=True)
|
||||
path = config.cfgimpl_get_description().impl_get_path_by_opt(option)
|
||||
value = config._getattr(path, force_permissive=True)
|
||||
except PropertiesOptionError as err:
|
||||
if check_disabled:
|
||||
if force_permissive:
|
||||
continue
|
||||
raise ConfigError(_('unable to carry out a calculation, '
|
||||
'option {0} has properties: {1} for: '
|
||||
'{2}').format(path, err.proptype,
|
||||
'{2}').format(option._name, err.proptype,
|
||||
name))
|
||||
is_multi = opt.impl_is_multi()
|
||||
is_multi = option.impl_is_multi()
|
||||
if is_multi:
|
||||
if opt_value is not None:
|
||||
len_value = len(opt_value)
|
||||
if value is not None:
|
||||
len_value = len(value)
|
||||
if len_multi != 0 and len_multi != len_value:
|
||||
raise ConfigError(_('unable to carry out a '
|
||||
'calculation, option value with'
|
||||
@ -77,16 +143,23 @@ def carry_out_calculation(name,
|
||||
'length for: {0}').format(name))
|
||||
len_multi = len_value
|
||||
one_is_multi = True
|
||||
tcparams.setdefault(key, []).append((opt_value, is_multi))
|
||||
tcparams.setdefault(key, []).append((value, is_multi))
|
||||
else:
|
||||
tcparams.setdefault(key, []).append((value, False))
|
||||
tcparams.setdefault(key, []).append((callbk, False))
|
||||
|
||||
if one_is_multi:
|
||||
ret = []
|
||||
if index:
|
||||
range_ = [index]
|
||||
if index < len_multi:
|
||||
range_ = [index]
|
||||
else:
|
||||
range_ = []
|
||||
ret = None
|
||||
else:
|
||||
range_ = range(len_multi)
|
||||
if max_len and max_len < len_multi:
|
||||
range_ = range(max_len)
|
||||
else:
|
||||
range_ = range(len_multi)
|
||||
for incr in range_:
|
||||
tcp = {}
|
||||
params = []
|
||||
@ -97,15 +170,9 @@ def carry_out_calculation(name,
|
||||
if key == '':
|
||||
params.append(value[incr])
|
||||
else:
|
||||
if len(value) > incr:
|
||||
tcp[key] = value[incr]
|
||||
else:
|
||||
tcp[key] = ''
|
||||
tcp[key] = value[incr]
|
||||
else:
|
||||
if key == '':
|
||||
params.append(value)
|
||||
else:
|
||||
tcp[key] = value
|
||||
params.append(value)
|
||||
calc = calculate(name, callback, params, tcp)
|
||||
if index:
|
||||
ret = calc
|
||||
@ -114,7 +181,6 @@ def carry_out_calculation(name,
|
||||
ret.extend(calc)
|
||||
else:
|
||||
ret.append(calc)
|
||||
|
||||
return ret
|
||||
else:
|
||||
tcp = {}
|
||||
@ -130,7 +196,6 @@ def carry_out_calculation(name,
|
||||
|
||||
|
||||
def calculate(name, callback, params, tcparams):
|
||||
# FIXME we don't need the option's name down there.
|
||||
"""wrapper that launches the 'callback'
|
||||
|
||||
:param callback: callback name
|
||||
|
@ -26,7 +26,7 @@ from copy import copy, deepcopy
|
||||
from types import FunctionType
|
||||
from IPy import IP
|
||||
|
||||
from tiramisu.error import ConflictError
|
||||
from tiramisu.error import ConflictError, ConfigError
|
||||
from tiramisu.setting import groups, multitypes
|
||||
from tiramisu.i18n import _
|
||||
from tiramisu.autolib import carry_out_calculation
|
||||
@ -97,8 +97,8 @@ class BaseOption(object):
|
||||
"frozen" (which has noting to do with the high level "freeze"
|
||||
propertie or "read_only" property)
|
||||
"""
|
||||
if not name.startswith('_state') and \
|
||||
name not in ('_cache_paths', '_consistencies'):
|
||||
if not name.startswith('_state') and name not in ('_cache_paths',
|
||||
'_consistencies'):
|
||||
is_readonly = False
|
||||
# never change _name
|
||||
if name == '_name':
|
||||
@ -327,7 +327,7 @@ class Option(BaseOption):
|
||||
|
||||
def __init__(self, name, doc, default=None, default_multi=None,
|
||||
requires=None, multi=False, callback=None,
|
||||
callback_params=None, validator=None, validator_args=None,
|
||||
callback_params=None, validator=None, validator_params=None,
|
||||
properties=None):
|
||||
"""
|
||||
:param name: the option's name
|
||||
@ -344,18 +344,15 @@ class Option(BaseOption):
|
||||
:param callback_params: the callback's parameter
|
||||
:param validator: the name of a function which stands for a custom
|
||||
validation of the value
|
||||
:param validator_args: the validator's parameters
|
||||
:param validator_params: the validator's parameters
|
||||
:param properties: tuple of default properties
|
||||
|
||||
"""
|
||||
super(Option, self).__init__(name, doc, requires, properties)
|
||||
self._multi = multi
|
||||
if validator is not None:
|
||||
if type(validator) != FunctionType:
|
||||
raise TypeError(_("validator must be a function"))
|
||||
if validator_args is None:
|
||||
validator_args = {}
|
||||
self._validator = (validator, validator_args)
|
||||
validate_callback(validator, validator_params, 'validator')
|
||||
self._validator = (validator, validator_params)
|
||||
else:
|
||||
self._validator = None
|
||||
if not self._multi and default_multi is not None:
|
||||
@ -377,11 +374,7 @@ class Option(BaseOption):
|
||||
"no callback defined"
|
||||
" yet for option {0}").format(name))
|
||||
if callback is not None:
|
||||
if type(callback) != FunctionType:
|
||||
raise ValueError('callback must be a function')
|
||||
if callback_params is not None and \
|
||||
not isinstance(callback_params, dict):
|
||||
raise ValueError('callback_params must be a dict')
|
||||
validate_callback(callback, callback_params, 'callback')
|
||||
self._callback = (callback, callback_params)
|
||||
else:
|
||||
self._callback = None
|
||||
@ -448,11 +441,23 @@ class Option(BaseOption):
|
||||
|
||||
def val_validator(val):
|
||||
if self._validator is not None:
|
||||
callback_params = deepcopy(self._validator[1])
|
||||
callback_params.setdefault('', []).insert(0, val)
|
||||
return carry_out_calculation(self._name, config=context,
|
||||
callback=self._validator[0],
|
||||
callback_params=callback_params)
|
||||
if self._validator[1] is not None:
|
||||
validator_params = deepcopy(self._validator[1])
|
||||
if '' in validator_params:
|
||||
lst = list(validator_params[''])
|
||||
lst.insert(0, val)
|
||||
validator_params[''] = tuple(lst)
|
||||
else:
|
||||
validator_params[''] = (val,)
|
||||
else:
|
||||
validator_params = {'': (val,)}
|
||||
ret = carry_out_calculation(self._name, config=context,
|
||||
callback=self._validator[0],
|
||||
callback_params=validator_params)
|
||||
if ret not in [False, True]:
|
||||
raise ConfigError(_('validator should return a boolean, '
|
||||
'not {0}').format(ret))
|
||||
return ret
|
||||
else:
|
||||
return True
|
||||
|
||||
@ -566,7 +571,7 @@ class ChoiceOption(Option):
|
||||
def __init__(self, name, doc, values, default=None, default_multi=None,
|
||||
requires=None, multi=False, callback=None,
|
||||
callback_params=None, open_values=False, validator=None,
|
||||
validator_args=None, properties=()):
|
||||
validator_params=None, properties=()):
|
||||
"""
|
||||
:param values: is a list of values the option can possibly take
|
||||
"""
|
||||
@ -584,7 +589,7 @@ class ChoiceOption(Option):
|
||||
requires=requires,
|
||||
multi=multi,
|
||||
validator=validator,
|
||||
validator_args=validator_args,
|
||||
validator_params=validator_params,
|
||||
properties=properties)
|
||||
|
||||
def impl_get_values(self):
|
||||
@ -702,7 +707,7 @@ class IPOption(Option):
|
||||
|
||||
def __init__(self, name, doc, default=None, default_multi=None,
|
||||
requires=None, multi=False, callback=None,
|
||||
callback_params=None, validator=None, validator_args=None,
|
||||
callback_params=None, validator=None, validator_params=None,
|
||||
properties=None, only_private=False):
|
||||
self._only_private = only_private
|
||||
super(IPOption, self).__init__(name, doc, default=default,
|
||||
@ -712,7 +717,7 @@ class IPOption(Option):
|
||||
requires=requires,
|
||||
multi=multi,
|
||||
validator=validator,
|
||||
validator_args=validator_args,
|
||||
validator_params=validator_params,
|
||||
properties=properties)
|
||||
|
||||
def _validate(self, value):
|
||||
@ -738,7 +743,7 @@ class PortOption(Option):
|
||||
|
||||
def __init__(self, name, doc, default=None, default_multi=None,
|
||||
requires=None, multi=False, callback=None,
|
||||
callback_params=None, validator=None, validator_args=None,
|
||||
callback_params=None, validator=None, validator_params=None,
|
||||
properties=None, allow_range=False, allow_zero=False,
|
||||
allow_wellknown=True, allow_registred=True,
|
||||
allow_private=False):
|
||||
@ -772,7 +777,7 @@ class PortOption(Option):
|
||||
requires=requires,
|
||||
multi=multi,
|
||||
validator=validator,
|
||||
validator_args=validator_args,
|
||||
validator_params=validator_params,
|
||||
properties=properties)
|
||||
|
||||
def _validate(self, value):
|
||||
@ -857,7 +862,7 @@ class DomainnameOption(Option):
|
||||
|
||||
def __init__(self, name, doc, default=None, default_multi=None,
|
||||
requires=None, multi=False, callback=None,
|
||||
callback_params=None, validator=None, validator_args=None,
|
||||
callback_params=None, validator=None, validator_params=None,
|
||||
properties=None, allow_ip=False, type_='domainname'):
|
||||
#netbios: for MS domain
|
||||
#hostname: to identify the device
|
||||
@ -876,7 +881,7 @@ class DomainnameOption(Option):
|
||||
requires=requires,
|
||||
multi=multi,
|
||||
validator=validator,
|
||||
validator_args=validator_args,
|
||||
validator_params=validator_params,
|
||||
properties=properties)
|
||||
|
||||
def _validate(self, value):
|
||||
@ -1252,3 +1257,33 @@ def validate_requires_arg(requires, name):
|
||||
require[3], require[4], require[5]))
|
||||
ret.append(tuple(ret_action))
|
||||
return frozenset(config_action.keys()), tuple(ret)
|
||||
|
||||
|
||||
def validate_callback(callback, callback_params, type_):
|
||||
if type(callback) != FunctionType:
|
||||
raise ValueError(_('{0} should be a function').format(type_))
|
||||
if callback_params is not None:
|
||||
if not isinstance(callback_params, dict):
|
||||
raise ValueError(_('{0}_params should be a dict').format(type_))
|
||||
for key, callbacks in callback_params.items():
|
||||
if key != '' and len(callbacks) != 1:
|
||||
raise ValueError(_('{0}_params with key {1} should not have '
|
||||
'length different to 1').format(type_,
|
||||
key))
|
||||
if not isinstance(callbacks, tuple):
|
||||
raise ValueError(_('{0}_params should be tuple for key "{1}"'
|
||||
).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 should have an option '
|
||||
'not a {0} for first argument'
|
||||
).format(type_, type(option)))
|
||||
if force_permissive not in [True, False]:
|
||||
raise ValueError(_('{0}_params should have a boolean'
|
||||
'not a {0} for second argument'
|
||||
).format(type_, type(force_permissive)))
|
||||
|
@ -124,7 +124,7 @@ class Values(object):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _getcallback_value(self, opt, index=None):
|
||||
def _getcallback_value(self, opt, index=None, max_len=None):
|
||||
"""
|
||||
retrieves a value for the options that have a callback
|
||||
|
||||
@ -139,7 +139,7 @@ class Values(object):
|
||||
return carry_out_calculation(opt._name, config=self.context(),
|
||||
callback=callback,
|
||||
callback_params=callback_params,
|
||||
index=index)
|
||||
index=index, max_len=max_len)
|
||||
|
||||
def __getitem__(self, opt):
|
||||
"enables us to use the pythonic dictionary-like access to values"
|
||||
@ -190,6 +190,7 @@ class Values(object):
|
||||
if opt.impl_has_callback() and (
|
||||
self._is_default_owner(path) or
|
||||
(is_frozen and 'force_default_on_freeze' in setting[opt])):
|
||||
lenmaster = None
|
||||
no_value_slave = False
|
||||
if (opt.impl_is_multi() and
|
||||
opt.impl_get_multitype() == multitypes.slave):
|
||||
@ -202,7 +203,7 @@ class Values(object):
|
||||
|
||||
if not no_value_slave:
|
||||
try:
|
||||
value = self._getcallback_value(opt)
|
||||
value = self._getcallback_value(opt, max_len=lenmaster)
|
||||
except ConfigError as config_error:
|
||||
value = None
|
||||
# should not raise PropertiesOptionError if option is
|
||||
@ -389,20 +390,27 @@ class Multi(list):
|
||||
|
||||
def _valid_slave(self, value):
|
||||
#if slave, had values until master's one
|
||||
values = self.context().cfgimpl_get_values()
|
||||
masterp = self.context().cfgimpl_get_description().impl_get_path_by_opt(
|
||||
self.opt.impl_get_master_slaves())
|
||||
mastervalue = getattr(self.context(), masterp)
|
||||
masterlen = len(mastervalue)
|
||||
valuelen = len(value)
|
||||
if valuelen > masterlen or (valuelen < masterlen and
|
||||
not self.context().cfgimpl_get_values(
|
||||
)._is_default_owner(self.path)):
|
||||
not values._is_default_owner(self.path)):
|
||||
raise SlaveError(_("invalid len for the slave: {0}"
|
||||
" which has {1} as master").format(
|
||||
self.opt._name, masterp))
|
||||
elif valuelen < masterlen:
|
||||
for num in range(0, masterlen - valuelen):
|
||||
value.append(self.opt.impl_getdefault_multi())
|
||||
if self.opt.impl_has_callback():
|
||||
# if callback add a value, but this value will not change
|
||||
# anymore automaticly (because this value has owner)
|
||||
index = value.__len__()
|
||||
value.append(values._getcallback_value(self.opt,
|
||||
index=index))
|
||||
else:
|
||||
value.append(self.opt.impl_getdefault_multi())
|
||||
#else: same len so do nothing
|
||||
return value
|
||||
|
||||
@ -420,8 +428,17 @@ class Multi(list):
|
||||
self.opt._name, slave._name))
|
||||
elif len(value_slave) < masterlen:
|
||||
for num in range(0, masterlen - len(value_slave)):
|
||||
value_slave.append(slave.impl_getdefault_multi(),
|
||||
force=True)
|
||||
if slave.impl_has_callback():
|
||||
# if callback add a value, but this value will not
|
||||
# change anymore automaticly (because this value
|
||||
# has owner)
|
||||
index = value_slave.__len__()
|
||||
value_slave.append(
|
||||
values._getcallback_value(slave, index=index),
|
||||
force=True)
|
||||
else:
|
||||
value_slave.append(slave.impl_getdefault_multi(),
|
||||
force=True)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self._validate(value)
|
||||
|
Loading…
Reference in New Issue
Block a user