validator's function can have 1 arg, 2 args or 3 args
This commit is contained in:
parent
01b7fc873e
commit
89fd367b20
5 changed files with 70 additions and 19 deletions
|
@ -1,5 +1,10 @@
|
||||||
Thu Jan 12 19:49:41 2017 +0200 Emmanuel Garette <egarette@cadoles.com>
|
Thu Jan 12 19:49:41 2017 +0200 Emmanuel Garette <egarette@cadoles.com>
|
||||||
* can mix inversed and non inversed requires
|
* can mix inversed and non inversed requires
|
||||||
|
* validator's function can have 1 arg, 2 args or 3 args without
|
||||||
|
valid_params specify by user. First arg will receive the value, second
|
||||||
|
arg will receive all values (useful for multi) and the third one will
|
||||||
|
receive index (useful for multi).
|
||||||
|
This functionaly only works for now if user not specify valid_params.
|
||||||
|
|
||||||
Wed Jan 11 22:56:30 2017 +0200 Emmanuel Garette <egarette@cadoles.com>
|
Wed Jan 11 22:56:30 2017 +0200 Emmanuel Garette <egarette@cadoles.com>
|
||||||
* copy the context in carry_out_calculation
|
* copy the context in carry_out_calculation
|
||||||
|
|
|
@ -40,6 +40,19 @@ def is_context(value, context):
|
||||||
raise ValueError('not context')
|
raise ValueError('not context')
|
||||||
|
|
||||||
|
|
||||||
|
def value_values(value, values):
|
||||||
|
if not (value == 'val' and values == ['val'] or
|
||||||
|
value == 'val1' and values == ['val1'] or
|
||||||
|
value == 'val2' and values == ['val1', 'val2']):
|
||||||
|
raise ValueError('error')
|
||||||
|
|
||||||
|
|
||||||
|
def value_values_index(value, values, index):
|
||||||
|
value_values(value, values)
|
||||||
|
if not (index == 0 or (value == 'val2' and index == 1)):
|
||||||
|
raise ValueError('error 2')
|
||||||
|
|
||||||
|
|
||||||
def test_validator():
|
def test_validator():
|
||||||
opt1 = StrOption('opt1', '', validator=return_true, default='val')
|
opt1 = StrOption('opt1', '', validator=return_true, default='val')
|
||||||
raises(ValueError, "StrOption('opt2', '', validator=return_false, default='val')")
|
raises(ValueError, "StrOption('opt2', '', validator=return_false, default='val')")
|
||||||
|
@ -60,6 +73,24 @@ def test_validator_params():
|
||||||
raises(ValueError, "cfg.opt2 = 'val'")
|
raises(ValueError, "cfg.opt2 = 'val'")
|
||||||
|
|
||||||
|
|
||||||
|
def test_validator_params_value_values():
|
||||||
|
opt1 = StrOption('opt1', '', validator=value_values, default=['val'], multi=True)
|
||||||
|
root = OptionDescription('root', '', [opt1])
|
||||||
|
cfg = Config(root)
|
||||||
|
assert cfg.opt1 == ['val']
|
||||||
|
cfg.opt1[0] = 'val1'
|
||||||
|
cfg.opt1.append('val2')
|
||||||
|
|
||||||
|
|
||||||
|
def test_validator_params_value_values_index():
|
||||||
|
opt1 = StrOption('opt1', '', validator=value_values_index, default=['val'], multi=True)
|
||||||
|
root = OptionDescription('root', '', [opt1])
|
||||||
|
cfg = Config(root)
|
||||||
|
assert cfg.opt1 == ['val']
|
||||||
|
cfg.opt1[0] = 'val1'
|
||||||
|
cfg.opt1.append('val2')
|
||||||
|
|
||||||
|
|
||||||
def test_validator_params_context():
|
def test_validator_params_context():
|
||||||
opt1 = StrOption('opt1', '', validator=is_context, validator_params={'': ((None,),)}, default='val')
|
opt1 = StrOption('opt1', '', validator=is_context, validator_params={'': ((None,),)}, default='val')
|
||||||
root = OptionDescription('root', '', [opt1])
|
root = OptionDescription('root', '', [opt1])
|
||||||
|
|
|
@ -25,7 +25,7 @@ from .setting import undefined
|
||||||
|
|
||||||
|
|
||||||
def carry_out_calculation(option, context, callback, callback_params,
|
def carry_out_calculation(option, context, callback, callback_params,
|
||||||
index=undefined):
|
index=undefined, value_index=None):
|
||||||
"""a function that carries out a calculation for an option's value
|
"""a function that carries out a calculation for an option's value
|
||||||
|
|
||||||
:param option: the option
|
:param option: the option
|
||||||
|
@ -149,6 +149,8 @@ def carry_out_calculation(option, context, callback, callback_params,
|
||||||
if callbk[0] is None: # pragma: optional cover
|
if callbk[0] is None: # pragma: optional cover
|
||||||
#Not an option, set full context
|
#Not an option, set full context
|
||||||
tcparams.setdefault(key, []).append((context.duplicate(), False))
|
tcparams.setdefault(key, []).append((context.duplicate(), False))
|
||||||
|
elif callbk[0] == 'index':
|
||||||
|
tcparams.setdefault(key, []).append((value_index, False))
|
||||||
else:
|
else:
|
||||||
# callbk is something link (opt, True|False)
|
# callbk is something link (opt, True|False)
|
||||||
opt, force_permissive = callbk
|
opt, force_permissive = callbk
|
||||||
|
|
|
@ -22,6 +22,7 @@ import re
|
||||||
from types import FunctionType
|
from types import FunctionType
|
||||||
import warnings
|
import warnings
|
||||||
import sys
|
import sys
|
||||||
|
from inspect import getargspec
|
||||||
|
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from ..setting import log, undefined, debug
|
from ..setting import log, undefined, debug
|
||||||
|
@ -58,7 +59,7 @@ def valid_name(name):
|
||||||
|
|
||||||
|
|
||||||
def validate_callback(callback, callback_params, type_):
|
def validate_callback(callback, callback_params, type_):
|
||||||
if type(callback) != FunctionType: # pragma: optional cover
|
if not isinstance(callback, FunctionType): # pragma: optional cover
|
||||||
raise ValueError(_('{0} must be a function').format(type_))
|
raise ValueError(_('{0} must be a function').format(type_))
|
||||||
if callback_params is not None:
|
if callback_params is not None:
|
||||||
if not isinstance(callback_params, dict): # pragma: optional cover
|
if not isinstance(callback_params, dict): # pragma: optional cover
|
||||||
|
@ -70,11 +71,11 @@ def validate_callback(callback, callback_params, type_):
|
||||||
key))
|
key))
|
||||||
if not isinstance(callbacks, tuple): # pragma: optional cover
|
if not isinstance(callbacks, tuple): # pragma: optional cover
|
||||||
raise ValueError(_('{0}_params must be tuple for key "{1}"'
|
raise ValueError(_('{0}_params must be tuple for key "{1}"'
|
||||||
).format(type_, key))
|
).format(type_, key))
|
||||||
for callbk in callbacks:
|
for callbk in callbacks:
|
||||||
if isinstance(callbk, tuple):
|
if isinstance(callbk, tuple):
|
||||||
if len(callbk) == 1:
|
if len(callbk) == 1:
|
||||||
if callbk != (None,): # pragma: optional cover
|
if callbk not in ((None,), ('index',)): # pragma: optional cover
|
||||||
raise ValueError(_('{0}_params with length of '
|
raise ValueError(_('{0}_params with length of '
|
||||||
'tuple as 1 must only have '
|
'tuple as 1 must only have '
|
||||||
'None as first value'))
|
'None as first value'))
|
||||||
|
@ -85,14 +86,14 @@ def validate_callback(callback, callback_params, type_):
|
||||||
option, force_permissive = callbk
|
option, force_permissive = callbk
|
||||||
if not isinstance(option, Option) and not \
|
if not isinstance(option, Option) and not \
|
||||||
isinstance(option, SymLinkOption): # pragma: optional cover
|
isinstance(option, SymLinkOption): # pragma: optional cover
|
||||||
raise ValueError(_('{0}_params must have an option'
|
raise ValueError(_('{}_params must have an option'
|
||||||
' not a {0} for first argument'
|
' not a {} for first argument'
|
||||||
).format(type_, type(option)))
|
).format(type_, type(option)))
|
||||||
if force_permissive not in [True, False]: # pragma: optional cover
|
if force_permissive not in [True, False]: # pragma: optional cover
|
||||||
raise ValueError(_('{0}_params must have a boolean'
|
raise ValueError(_('{}_params must have a boolean'
|
||||||
' not a {0} for second argument'
|
' not a {} for second argument'
|
||||||
).format(type_, type(
|
).format(type_, type(
|
||||||
force_permissive)))
|
force_permissive)))
|
||||||
#____________________________________________________________
|
#____________________________________________________________
|
||||||
#
|
#
|
||||||
|
|
||||||
|
@ -123,7 +124,7 @@ class Base(StorageBase):
|
||||||
raise ValueError(_('invalid multi value'))
|
raise ValueError(_('invalid multi value'))
|
||||||
if unique != undefined and not isinstance(unique, bool):
|
if unique != undefined and not isinstance(unique, bool):
|
||||||
raise ValueError(_('unique must be a boolean'))
|
raise ValueError(_('unique must be a boolean'))
|
||||||
if not is_multi and unique == True:
|
if not is_multi and unique is True:
|
||||||
raise ValueError(_('unique must be set only with multi value'))
|
raise ValueError(_('unique must be set only with multi value'))
|
||||||
if requires is not None:
|
if requires is not None:
|
||||||
calc_properties, requires = validate_requires_arg(is_multi,
|
calc_properties, requires = validate_requires_arg(is_multi,
|
||||||
|
@ -135,10 +136,21 @@ class Base(StorageBase):
|
||||||
properties = tuple()
|
properties = tuple()
|
||||||
if not isinstance(properties, tuple): # pragma: optional cover
|
if not isinstance(properties, tuple): # pragma: optional cover
|
||||||
raise TypeError(_('invalid properties type {0} for {1},'
|
raise TypeError(_('invalid properties type {0} for {1},'
|
||||||
' must be a tuple').format(
|
' must be a tuple').format(
|
||||||
type(properties),
|
type(properties),
|
||||||
name))
|
name))
|
||||||
if validator is not None:
|
if validator is not None:
|
||||||
|
if validator_params is None:
|
||||||
|
func_args = getargspec(validator)
|
||||||
|
defaults = func_args.defaults
|
||||||
|
if defaults is None:
|
||||||
|
defaults = []
|
||||||
|
args = func_args.args[0:len(func_args.args)-len(defaults)]
|
||||||
|
if len(args) == 2:
|
||||||
|
validator_params = {'': ((self, False),)}
|
||||||
|
elif len(args) == 3:
|
||||||
|
validator_params = {'': ((self, False), ('index',))}
|
||||||
|
|
||||||
validate_callback(validator, validator_params, 'validator')
|
validate_callback(validator, validator_params, 'validator')
|
||||||
self._set_validator(validator, validator_params)
|
self._set_validator(validator, validator_params)
|
||||||
self._set_has_dependency()
|
self._set_has_dependency()
|
||||||
|
@ -513,7 +525,7 @@ class Option(OnlyOption):
|
||||||
return ValueError(_('invalid value "{}", this value is already in "{}"').format(
|
return ValueError(_('invalid value "{}", this value is already in "{}"').format(
|
||||||
val, self.impl_get_display_name()))
|
val, self.impl_get_display_name()))
|
||||||
|
|
||||||
def calculation_validator(val):
|
def calculation_validator(val, _index):
|
||||||
validator, validator_params = self.impl_get_validator()
|
validator, validator_params = self.impl_get_validator()
|
||||||
if validator is not None:
|
if validator is not None:
|
||||||
if validator_params != {}:
|
if validator_params != {}:
|
||||||
|
@ -532,7 +544,8 @@ class Option(OnlyOption):
|
||||||
# Raise ValueError if not valid
|
# Raise ValueError if not valid
|
||||||
value = carry_out_calculation(current_opt, context=context,
|
value = carry_out_calculation(current_opt, context=context,
|
||||||
callback=validator,
|
callback=validator,
|
||||||
callback_params=validator_params_)
|
callback_params=validator_params_,
|
||||||
|
value_index=_index)
|
||||||
if isinstance(value, Exception):
|
if isinstance(value, Exception):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
@ -562,7 +575,7 @@ class Option(OnlyOption):
|
||||||
error = None
|
error = None
|
||||||
if ((display_error and not self._is_warnings_only()) or
|
if ((display_error and not self._is_warnings_only()) or
|
||||||
(display_warnings and self._is_warnings_only())):
|
(display_warnings and self._is_warnings_only())):
|
||||||
error = calculation_validator(_value)
|
error = calculation_validator(_value, _index)
|
||||||
if not error:
|
if not error:
|
||||||
error = self._second_level_validation(_value, self._is_warnings_only())
|
error = self._second_level_validation(_value, self._is_warnings_only())
|
||||||
if error:
|
if error:
|
||||||
|
|
|
@ -617,7 +617,7 @@ class Settings(object):
|
||||||
exception :exc:`~error.RequirementError` is raised.
|
exception :exc:`~error.RequirementError` is raised.
|
||||||
|
|
||||||
And at last, if no target option matches the expected values, the
|
And at last, if no target option matches the expected values, the
|
||||||
action must be removed from the option's properties list.
|
action will not add to the option's properties list.
|
||||||
|
|
||||||
:param opt: the option on wich the requirement occurs
|
:param opt: the option on wich the requirement occurs
|
||||||
:type opt: `option.Option()`
|
:type opt: `option.Option()`
|
||||||
|
|
Loading…
Reference in a new issue