add custom validator
This commit is contained in:
parent
b353c6ba60
commit
5969eaa2d6
|
@ -40,6 +40,8 @@ class Config(object):
|
||||||
#mandatory means: a mandatory option has to have a value that is not None
|
#mandatory means: a mandatory option has to have a value that is not None
|
||||||
_cfgimpl_mandatory = True
|
_cfgimpl_mandatory = True
|
||||||
_cfgimpl_frozen = True
|
_cfgimpl_frozen = True
|
||||||
|
#enables validation function for options if set
|
||||||
|
_cfgimpl_validator = False
|
||||||
_cfgimpl_owner = default_owner
|
_cfgimpl_owner = default_owner
|
||||||
_cfgimpl_toplevel = None
|
_cfgimpl_toplevel = None
|
||||||
|
|
||||||
|
@ -248,9 +250,9 @@ class Config(object):
|
||||||
return value
|
return value
|
||||||
else:
|
else:
|
||||||
return value
|
return value
|
||||||
|
rootconfig = self._cfgimpl_get_toplevel()
|
||||||
try:
|
try:
|
||||||
result = opt_or_descr.getcallback_value(
|
result = opt_or_descr.getcallback_value(rootconfig)
|
||||||
self._cfgimpl_get_toplevel())
|
|
||||||
except NoValueReturned, err:
|
except NoValueReturned, err:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
@ -264,7 +266,8 @@ class Config(object):
|
||||||
raise ConfigError('invalid calculated value returned'
|
raise ConfigError('invalid calculated value returned'
|
||||||
' for option {0} : shall not be a list'.format(name))
|
' for option {0} : shall not be a list'.format(name))
|
||||||
_result = result
|
_result = result
|
||||||
if _result != None and not opt_or_descr.validate(_result):
|
if _result != None and not opt_or_descr.validate(_result,
|
||||||
|
rootconfig._cfgimpl_validator):
|
||||||
raise ConfigError('invalid calculated value returned'
|
raise ConfigError('invalid calculated value returned'
|
||||||
' for option {0}'.format(name))
|
' for option {0}'.format(name))
|
||||||
self._cfgimpl_values[name] = _result
|
self._cfgimpl_values[name] = _result
|
||||||
|
@ -455,6 +458,7 @@ class Config(object):
|
||||||
rootconfig.cfgimpl_disable_property('hidden')
|
rootconfig.cfgimpl_disable_property('hidden')
|
||||||
rootconfig.cfgimpl_enable_property('disabled')
|
rootconfig.cfgimpl_enable_property('disabled')
|
||||||
rootconfig._cfgimpl_mandatory = True
|
rootconfig._cfgimpl_mandatory = True
|
||||||
|
rootconfig._cfgimpl_validator = True
|
||||||
|
|
||||||
def cfgimpl_read_write(self):
|
def cfgimpl_read_write(self):
|
||||||
"convenience method to freeze, hidde and disable"
|
"convenience method to freeze, hidde and disable"
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
# the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/
|
# the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/
|
||||||
# the whole pypy projet is under MIT licence
|
# the whole pypy projet is under MIT licence
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
|
from types import FunctionType
|
||||||
from tiramisu.basetype import HiddenBaseType, DisabledBaseType
|
from tiramisu.basetype import HiddenBaseType, DisabledBaseType
|
||||||
from tiramisu.error import (ConfigError, ConflictConfigError, NotFoundError,
|
from tiramisu.error import (ConfigError, ConflictConfigError, NotFoundError,
|
||||||
RequiresError, RequirementRecursionError, MandatoryError,
|
RequiresError, RequirementRecursionError, MandatoryError,
|
||||||
|
@ -92,7 +93,7 @@ class Option(HiddenBaseType, DisabledBaseType):
|
||||||
_force_default_on_freeze = False
|
_force_default_on_freeze = False
|
||||||
def __init__(self, name, doc, default=None, default_multi=None,
|
def __init__(self, name, doc, default=None, default_multi=None,
|
||||||
requires=None, mandatory=False, multi=False, callback=None,
|
requires=None, mandatory=False, multi=False, callback=None,
|
||||||
callback_params=None):
|
callback_params=None, validator=None, validator_args={}):
|
||||||
"""
|
"""
|
||||||
:param default: ['bla', 'bla', 'bla']
|
:param default: ['bla', 'bla', 'bla']
|
||||||
:param default_multi: 'bla' (used in case of a reset to default only at
|
:param default_multi: 'bla' (used in case of a reset to default only at
|
||||||
|
@ -103,6 +104,14 @@ class Option(HiddenBaseType, DisabledBaseType):
|
||||||
self._requires = requires
|
self._requires = requires
|
||||||
self._mandatory = mandatory
|
self._mandatory = mandatory
|
||||||
self.multi = multi
|
self.multi = multi
|
||||||
|
self._validator = None
|
||||||
|
self._validator_args = None
|
||||||
|
if validator is not None:
|
||||||
|
if type(validator) != FunctionType:
|
||||||
|
raise TypeError("validator must be a function")
|
||||||
|
self._validator = validator
|
||||||
|
if validator_args is not None:
|
||||||
|
self._validator_args = validator_args
|
||||||
if not self.multi and default_multi is not None:
|
if not self.multi and default_multi is not None:
|
||||||
raise ConfigError("a default_multi is set whereas multi is False"
|
raise ConfigError("a default_multi is set whereas multi is False"
|
||||||
" in option: {0}".format(name))
|
" in option: {0}".format(name))
|
||||||
|
@ -123,17 +132,29 @@ class Option(HiddenBaseType, DisabledBaseType):
|
||||||
if self.multi == True:
|
if self.multi == True:
|
||||||
if default == None:
|
if default == None:
|
||||||
default = []
|
default = []
|
||||||
if not isinstance(default, list) or not self.validate(default):
|
if not isinstance(default, list):
|
||||||
raise ConfigError("invalid default value {0} "
|
raise ConfigError("invalid default value {0} "
|
||||||
"for option {1} : not list type".format(str(default), name))
|
"for option {1} : not list type".format(str(default), name))
|
||||||
|
if not self.validate(default, False):
|
||||||
|
raise ConfigError("invalid default value {0} "
|
||||||
|
"for option {1}".format(str(default), name))
|
||||||
else:
|
else:
|
||||||
if default != None and not self.validate(default):
|
if default != None and not self.validate(default, False):
|
||||||
raise ConfigError("invalid default value {0} "
|
raise ConfigError("invalid default value {0} "
|
||||||
"for option {1}".format(str(default), name))
|
"for option {1}".format(str(default), name))
|
||||||
self.default = default
|
self.default = default
|
||||||
self.properties = [] # 'hidden', 'disabled'...
|
self.properties = [] # 'hidden', 'disabled'...
|
||||||
|
|
||||||
def validate(self, value):
|
def validate(self, value, validate=True):
|
||||||
|
"""
|
||||||
|
:param value: the option's value
|
||||||
|
:param validate: if true enables ``self._validator`` validation
|
||||||
|
"""
|
||||||
|
# customizing the validator
|
||||||
|
if validate and value is not None and self._validator is not None:
|
||||||
|
if not self._validator(value, **self._validator_args):
|
||||||
|
return False
|
||||||
|
# generic calculation
|
||||||
if self.multi == False:
|
if self.multi == False:
|
||||||
# None allows the reset of the value
|
# None allows the reset of the value
|
||||||
if value != None:
|
if value != None:
|
||||||
|
@ -235,7 +256,8 @@ class Option(HiddenBaseType, DisabledBaseType):
|
||||||
:param who : is **not necessarily** a owner because it cannot be a list
|
:param who : is **not necessarily** a owner because it cannot be a list
|
||||||
:type who: string """
|
:type who: string """
|
||||||
name = self._name
|
name = self._name
|
||||||
if not self.validate(value):
|
rootconfig = config._cfgimpl_get_toplevel()
|
||||||
|
if not self.validate(value, rootconfig._cfgimpl_validator):
|
||||||
raise ConfigError('invalid value %s for option %s' % (value, name))
|
raise ConfigError('invalid value %s for option %s' % (value, name))
|
||||||
if self.is_mandatory():
|
if self.is_mandatory():
|
||||||
# value shall not be '' for a mandatory option
|
# value shall not be '' for a mandatory option
|
||||||
|
@ -253,7 +275,7 @@ class Option(HiddenBaseType, DisabledBaseType):
|
||||||
|
|
||||||
if config.is_frozen() and self.is_frozen():
|
if config.is_frozen() and self.is_frozen():
|
||||||
raise TypeError('cannot change the value to %s for '
|
raise TypeError('cannot change the value to %s for '
|
||||||
'option %s' % (str(value), name))
|
'option %s this option is frozen' % (str(value), name))
|
||||||
apply_requires(self, config)
|
apply_requires(self, config)
|
||||||
if type(config._cfgimpl_values[name]) == Multi:
|
if type(config._cfgimpl_values[name]) == Multi:
|
||||||
config._cfgimpl_previous_values[name] = list(config._cfgimpl_values[name])
|
config._cfgimpl_previous_values[name] = list(config._cfgimpl_values[name])
|
||||||
|
@ -283,7 +305,8 @@ class ChoiceOption(Option):
|
||||||
|
|
||||||
def __init__(self, name, doc, values, default=None, default_multi=None,
|
def __init__(self, name, doc, values, default=None, default_multi=None,
|
||||||
requires=None, mandatory=False, multi=False, callback=None,
|
requires=None, mandatory=False, multi=False, callback=None,
|
||||||
callback_params=None, open_values=False):
|
callback_params=None, open_values=False, validator=None,
|
||||||
|
validator_args={}):
|
||||||
self.values = values
|
self.values = values
|
||||||
if open_values not in [True, False]:
|
if open_values not in [True, False]:
|
||||||
raise ConfigError('Open_values must be a boolean for '
|
raise ConfigError('Open_values must be a boolean for '
|
||||||
|
@ -292,7 +315,8 @@ class ChoiceOption(Option):
|
||||||
super(ChoiceOption, self).__init__(name, doc, default=default,
|
super(ChoiceOption, self).__init__(name, doc, default=default,
|
||||||
default_multi=default_multi, callback=callback,
|
default_multi=default_multi, callback=callback,
|
||||||
callback_params=callback_params, requires=requires,
|
callback_params=callback_params, requires=requires,
|
||||||
multi=multi, mandatory=mandatory)
|
multi=multi, mandatory=mandatory, validator=validator,
|
||||||
|
validator_args=validator_args)
|
||||||
|
|
||||||
def _validate(self, value):
|
def _validate(self, value):
|
||||||
if not self.open_values:
|
if not self.open_values:
|
||||||
|
@ -306,14 +330,6 @@ class BoolOption(Option):
|
||||||
def _validate(self, value):
|
def _validate(self, value):
|
||||||
return isinstance(value, bool)
|
return isinstance(value, bool)
|
||||||
|
|
||||||
# config level validator
|
|
||||||
# def setoption(self, config, value, who):
|
|
||||||
# name = self._name
|
|
||||||
# if value and self._validator is not None:
|
|
||||||
# toplevel = config._cfgimpl_get_toplevel()
|
|
||||||
# self._validator(toplevel)
|
|
||||||
# super(BoolOption, self).setoption(config, value, who)
|
|
||||||
|
|
||||||
class IntOption(Option):
|
class IntOption(Option):
|
||||||
opt_type = 'int'
|
opt_type = 'int'
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue