remove some try/except + consistency not works with submulti

This commit is contained in:
Emmanuel Garette 2016-01-03 13:23:15 +01:00
parent cc6b4ad7c4
commit e8764f6173
13 changed files with 273 additions and 259 deletions

View File

@ -720,38 +720,6 @@ def test_consistency_dyndescription_default():
raises(ValueError, "cfg.od.dodval2.st2val2 = 'yes'")
def test_consistency_dyndescription_multi():
st = StrOption('st', '', multi=True)
st2 = StrOption('st2', '', multi=True)
dod = DynOptionDescription('dod', '', [st, st2], callback=return_list)
od = OptionDescription('od', '', [dod])
st.impl_add_consistency('not_equal', st2)
od2 = OptionDescription('od', '', [od])
cfg = Config(od2)
cfg.od.dodval1.stval1.append('yes')
raises(ValueError, "cfg.od.dodval1.st2val1.append('yes')")
cfg.od.dodval2.stval2.append('yes')
raises(ValueError, "cfg.od.dodval2.st2val2.append('yes')")
raises(ValueError, "cfg.od.dodval1.st2val1.append('yes')")
del(cfg.od.dodval2.stval2)
raises(ValueError, "cfg.od.dodval1.st2val1.append('yes')")
cfg.od.dodval2.st2val2.append('yes')
raises(ValueError, "cfg.od.dodval2.stval2.append('yes')")
def test_consistency_dyndescription_default_multi():
st = StrOption('st', '', ['yes'], multi=True)
st2 = StrOption('st2', '', multi=True)
dod = DynOptionDescription('dod', '', [st, st2], callback=return_list)
od = OptionDescription('od', '', [dod])
st.impl_add_consistency('not_equal', st2)
od2 = OptionDescription('od', '', [od])
cfg = Config(od2)
raises(ValueError, "cfg.od.dodval1.st2val1.append('yes')")
raises(ValueError, "cfg.od.dodval1.st2val1.append('yes')")
cfg.od.dodval1.stval1.append('yes')
def test_consistency_dyndescription_default_multi2():
st = StrOption('st', '', ['yes'], multi=True)
st2 = StrOption('st2', '', ['yes'], multi=True)

View File

@ -291,6 +291,25 @@ def test_meta_master_slaves_value():
assert meta.conf1.netmask_admin_eth0 == [None]
def test_meta_master_slaves_value_default():
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1'])
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True)
interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
interface1.impl_set_group_type(groups.master)
conf1 = Config(interface1, name='conf1')
conf2 = Config(interface1, name='conf2')
meta = MetaConfig([conf1, conf2])
assert meta.conf1.netmask_admin_eth0 == [None]
meta.ip_admin_eth0 = ['192.168.1.1']
assert meta.conf1.netmask_admin_eth0 == [None]
meta.netmask_admin_eth0 = ['255.255.255.0']
assert meta.conf1.netmask_admin_eth0 == ['255.255.255.0']
meta.netmask_admin_eth0 = ['255.255.0.0']
assert meta.conf1.netmask_admin_eth0 == ['255.255.0.0']
meta.conf1.ip_admin_eth0 = ['192.168.1.1']
assert meta.conf1.netmask_admin_eth0 == [None]
def test_meta_master_slaves_owners():
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',))

View File

@ -17,8 +17,6 @@ def test_consistency():
a.impl_add_consistency('not_equal', b)
#consistency to itself
raises(ConfigError, "a.impl_add_consistency('not_equal', a)")
#consistency with string
raises(ConfigError, "a.impl_add_consistency('not_equal', 'a')")
def test_consistency_not_exists():
@ -157,21 +155,9 @@ def test_consistency_not_equal_symlink():
def test_consistency_not_equal_submulti():
a = IntOption('a', '', multi=submulti)
b = IntOption('b', '', multi=submulti)
od = OptionDescription('od', '', [a, b])
a.impl_add_consistency('not_equal', b)
c = Config(od)
assert c.a == []
assert c.b == []
c.a = [[1]]
del(c.a)
c.a = [[1]]
raises(ValueError, "c.b = [[1]]")
c.a = [[1, 2]]
c.b = [[3]]
c.b = [[3, 1]]
c.b = [[3]]
c.b[0].append(1)
c.b = [[3], [1]]
od = OptionDescription('a', '', [a, b])
od.impl_set_group_type(groups.master)
raises(ConfigError, 'a.impl_add_consistency("not_equal", b)')
def test_consistency_not_equal_default_submulti():
@ -179,13 +165,14 @@ def test_consistency_not_equal_default_submulti():
b = IntOption('b', '', [[1]], multi=submulti)
od = OptionDescription('od', '', [a, b])
od
raises(ValueError, "a.impl_add_consistency('not_equal', b)")
raises(ConfigError, "a.impl_add_consistency('not_equal', b)")
def test_consistency_not_equal_multi():
a = IntOption('a', '', multi=True)
b = IntOption('b', '', multi=True)
od = OptionDescription('od', '', [a, b])
od = OptionDescription('a', '', [a, b])
od.impl_set_group_type(groups.master)
a.impl_add_consistency('not_equal', b)
c = Config(od)
assert c.a == []
@ -200,16 +187,15 @@ def test_consistency_not_equal_multi():
def test_consistency_not_equal_multi_default():
a = IntOption('a', '', multi=True)
b = IntOption('b', '', multi=True, default_multi=1)
od = OptionDescription('od', '', [a, b])
od = OptionDescription('a', '', [a, b])
od.impl_set_group_type(groups.master)
a.impl_add_consistency('not_equal', b)
c = Config(od)
assert c.a == []
assert c.b == []
c.a = [1]
raises(ValueError, 'c.a = [1]')
c.a = [2]
del(c.a)
c.a = [1]
raises(ValueError, "c.b = [1]")
c.b = [2]
def test_consistency_default():
@ -325,8 +311,9 @@ def test_consistency_ip_netmask_error_multi():
def test_consistency_ip_netmask_multi():
a = IPOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True)
od = OptionDescription('od', '', [a, b])
od = OptionDescription('a', '', [a, b])
b.impl_add_consistency('ip_netmask', a)
od.impl_set_group_type(groups.master)
c = Config(od)
c.a = ['192.168.1.1']
c.b = ['255.255.255.0']
@ -339,7 +326,8 @@ def test_consistency_ip_netmask_multi():
def test_consistency_network_netmask_multi():
a = NetworkOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True)
od = OptionDescription('od', '', [a, b])
od = OptionDescription('a', '', [a, b])
od.impl_set_group_type(groups.master)
b.impl_add_consistency('network_netmask', a)
c = Config(od)
c.a = ['192.168.1.1']

View File

@ -14,12 +14,12 @@ from tiramisu.i18n import _
def return_true(value, param=None):
if value == 'val' and param in [None, 'yes']:
return True
raise ValueError('error')
return ValueError('error')
def return_false(value, param=None):
if value == 'val' and param in [None, 'yes']:
raise ValueError('error')
return ValueError('error')
def return_val(value, param=None):
@ -28,7 +28,7 @@ def return_val(value, param=None):
def return_if_val(value):
if value != 'val':
raise ValueError('error')
return ValueError('error')
def test_validator():

View File

@ -18,8 +18,7 @@
# the whole pypy projet is under MIT licence
# ____________________________________________________________
"enables us to carry out a calculation and return an option's value"
from .error import PropertiesOptionError, ConfigError, ContextError, \
SlaveError
from .error import PropertiesOptionError, ConfigError, SlaveError
from .i18n import _
from .setting import undefined
# ____________________________________________________________
@ -145,7 +144,7 @@ def carry_out_calculation(option, context, callback, callback_params,
for callbk in callbacks:
if isinstance(callbk, tuple):
if context is undefined:
raise ContextError() # pragma: optional cover
return undefined
if callbk[0] is None: # pragma: optional cover
#Not an option, set full context
tcparams.setdefault(key, []).append((context, False))

View File

@ -34,12 +34,6 @@ class ConfigError(Exception):
pass
class ContextError(Exception):
"""context needed but not given
"""
pass
class ConflictError(Exception):
"duplicate options are present in a single config"
pass

View File

@ -25,8 +25,7 @@ import warnings
from ..i18n import _
from ..setting import log, undefined
from ..autolib import carry_out_calculation
from ..error import ConfigError, ValueWarning, PropertiesOptionError,\
ContextError
from ..error import ConfigError, ValueWarning, PropertiesOptionError
from ..storage import get_storages_option
@ -142,10 +141,9 @@ class Base(StorageBase):
allow_empty_list)
if multi is not False and default is None:
default = []
try:
self.impl_validate(default, is_multi=is_multi)
except ContextError:
pass
err = self.impl_validate(default, is_multi=is_multi)
if err:
raise err
self._set_default_values(default, default_multi, is_multi)
##callback is False in optiondescription
if callback is not False:
@ -347,7 +345,7 @@ class BaseOption(Base):
def _impl_valid_unicode(self, value):
if not isinstance(value, unicode) and not isinstance(value, str):
raise ValueError(_('invalid unicode or string'))
return ValueError(_('invalid unicode or string'))
class OnlyOption(BaseOption):
@ -413,21 +411,17 @@ class Option(OnlyOption):
option == opt:
all_cons_vals.append(opt_value)
elif self.impl_is_submulti():
print option._name, opt_value
all_cons_vals.append(opt_value[index][submulti_index])
else:
all_cons_vals.append(opt_value[index])
except IndexError, err:
#value is not already set, could be higher index
#so return if no value and not default_value
log.debug('indexerror in _launch_consistency: {0}'.format(err))
return
except PropertiesOptionError as err:
log.debug('propertyerror in _launch_consistency: {0}'.format(err))
if transitive:
raise err
else:
return
getattr(self, func)(all_cons_opts, all_cons_vals, warnings_only)
return getattr(self, func)(all_cons_opts, all_cons_vals, warnings_only)
def impl_validate(self, value, context=undefined, validate=True,
force_index=None, force_submulti_index=None,
@ -467,52 +461,44 @@ class Option(OnlyOption):
else:
validator_params_ = {'': (val,)}
# Raise ValueError if not valid
try:
carry_out_calculation(current_opt, context=context,
value = carry_out_calculation(current_opt, context=context,
callback=validator,
callback_params=validator_params_)
except ContextError:
pass
if isinstance(value, Exception):
return value
def do_validation(_value, _index, submulti_index):
if _value is None:
return
# option validation
try:
self._validate(_value, context, current_opt)
except ValueError as err: # pragma: optional cover
err = self._validate(_value, context, current_opt)
if err:
log.debug('do_validation: value: {0}, index: {1}, '
'submulti_index: {2}'.format(_value, _index,
submulti_index),
exc_info=True)
raise ValueError(_('invalid value for option {0}: {1}'
return ValueError(_('invalid value for option {0}: {1}'
'').format(self.impl_getname(), err))
error = None
warning = None
try:
# valid with self._validator
calculation_validator(_value)
self._second_level_validation(_value, self._is_warnings_only())
except ValueError as error:
error = calculation_validator(_value)
if not error:
error = self._second_level_validation(_value, self._is_warnings_only())
if error:
log.debug(_('do_validation for {0}: error in value').format(
self.impl_getname()), exc_info=True)
if self._is_warnings_only():
warning = error
error = None
if error is None and warning is None:
try:
# if context launch consistency validation
#if context is not undefined:
self._valid_consistency(current_opt, _value, context,
ret = self._valid_consistency(current_opt, _value, context,
_index, submulti_index)
except ValueError as error:
log.debug(_('do_validation for {0}: error in consistency').format(
self.impl_getname()), exc_info=True)
pass
except ValueWarning as warning:
log.debug(_('do_validation for {0}: warning in consistency').format(
self.impl_getname()), exc_info=True)
pass
if ret:
if isinstance(ret, ValueWarning):
warning = ret
elif isinstance(ret, ValueError):
error = ret
if warning:
msg = _("warning on the value of the option {0}: {1}").format(
self.impl_getname(), warning)
@ -522,7 +508,7 @@ class Option(OnlyOption):
ValueWarning,
self.__class__.__name__, 0)
elif error:
raise ValueError(_("invalid value for option {0}: {1}").format(
return ValueError(_("invalid value for option {0}: {1}").format(
self.impl_getname(), error))
# generic calculation
@ -532,7 +518,7 @@ class Option(OnlyOption):
if is_multi is None:
is_multi = self.impl_is_multi()
if not is_multi:
do_validation(value, None, None)
return do_validation(value, None, None)
elif force_index is not None:
if self.impl_is_submulti() and force_submulti_index is None:
if not isinstance(value, list): # pragma: optional cover
@ -540,25 +526,31 @@ class Option(OnlyOption):
" must be a list").format(
value, self.impl_getname()))
for idx, val in enumerate(value):
do_validation(val, force_index, idx)
err = do_validation(val, force_index, idx)
if err:
return err
else:
do_validation(value, force_index, force_submulti_index)
else:
if not isinstance(value, list): # pragma: optional cover
raise ValueError(_("invalid value {0} for option {1} which "
return do_validation(value, force_index, force_submulti_index)
elif not isinstance(value, list): # pragma: optional cover
return ValueError(_("invalid value {0} for option {1} which "
"must be a list").format(value,
self.impl_getname()))
elif self.impl_is_submulti() and force_submulti_index is None:
for idx, val in enumerate(value):
if self.impl_is_submulti() and force_submulti_index is None:
if not isinstance(val, list): # pragma: optional cover
raise ValueError(_("invalid value {0} for option {1} "
return ValueError(_("invalid value {0} for option {1} "
"which must be a list of list"
"").format(value,
self.impl_getname()))
for slave_idx, slave_val in enumerate(val):
do_validation(slave_val, idx, slave_idx)
err = do_validation(slave_val, idx, slave_idx)
if err:
return err
else:
do_validation(val, idx, force_submulti_index)
for idx, val in enumerate(value):
err = do_validation(val, idx, force_submulti_index)
if err:
return err
def impl_is_master_slaves(self, type_='both'):
"""FIXME
@ -585,7 +577,12 @@ class Option(OnlyOption):
dynod = self._impl_getsubdyn()
else:
dynod = None
if self.impl_is_submulti():
raise ConfigError(_('cannot add consistency with submulti option'))
is_multi = self.impl_is_multi()
for opt in other_opts:
if opt.impl_is_submulti():
raise ConfigError(_('cannot add consistency with submulti option'))
if not isinstance(opt, Option): # pragma: optional cover
raise ConfigError(_('consistency must be set with an option'))
if opt._is_subdyn():
@ -601,7 +598,7 @@ class Option(OnlyOption):
'dynoptiondescription but not all'))
if self is opt: # pragma: optional cover
raise ConfigError(_('cannot add consistency with itself'))
if self.impl_is_multi() != opt.impl_is_multi(): # pragma: optional cover
if is_multi != opt.impl_is_multi(): # pragma: optional cover
raise ConfigError(_('every options in consistency must be '
'multi or none'))
@ -630,9 +627,8 @@ class Option(OnlyOption):
raise ValueError(_('unknow parameter {0} in consistency').format(unknown_params))
self._add_consistency(func, all_cons_opts, params)
#validate default value when add consistency
try:
self.impl_validate(self.impl_getdefault())
except ValueError, err:
err = self.impl_validate(self.impl_getdefault())
if err:
self._del_consistency()
raise err
@ -640,7 +636,7 @@ class Option(OnlyOption):
if context is not undefined:
descr = context.cfgimpl_get_description()
if descr._cache_consistencies is None:
return True
return
#consistencies is something like [('_cons_not_equal', (opt1, opt2))]
if isinstance(option, DynSymLinkOption):
consistencies = descr._cache_consistencies.get(option._impl_getopt())
@ -664,15 +660,14 @@ class Option(OnlyOption):
opts.append(opt._impl_to_dyn(name, path))
else:
opts = all_cons_opts
try:
opts[0]._launch_consistency(func, option, value, context,
err = opts[0]._launch_consistency(func, option, value, context,
index, submulti_idx, opts,
warnings_only, transitive)
except ValueError as err:
if err:
if warnings_only:
raise ValueWarning(err.message, option)
return ValueWarning(err.message, option)
else:
raise err
return err
def _cons_not_equal(self, opts, vals, warnings_only):
for idx_inf, val_inf in enumerate(vals):
@ -683,7 +678,7 @@ class Option(OnlyOption):
else:
msg = _("same value for {0} and {1}, must be different")
log.debug('_cons_not_equal: {0} and {1} are not different'.format(val_inf, val_sup))
raise ValueError(msg.format(opts[idx_inf].impl_getname(),
return ValueError(msg.format(opts[idx_inf].impl_getname(),
opts[idx_inf + idx_sup + 1].impl_getname()))
# serialize/unserialize
@ -804,9 +799,8 @@ def validate_requires_arg(multi, requires, name):
'multi option must not set '
'as requires of non multi option {0}').format(name))
if expected is not None:
try:
option._validate(expected)
except ValueError as err: # pragma: optional cover
err = option._validate(expected)
if err:
raise ValueError(_('malformed requirements second argument '
'must be valid for option {0}'
': {1}').format(name, err))
@ -887,6 +881,9 @@ class SymLinkOption(OnlyOption):
def _is_subdyn(self):
return getattr(self._impl_getopt(), '_subdyn', None) is not None
def _get_consistencies(self):
return ()
class DynSymLinkOption(object):
__slots__ = ('_dyn', '_opt', '_name')

View File

@ -21,7 +21,7 @@
# ____________________________________________________________
from ..i18n import _
from ..setting import log, undefined
from ..error import SlaveError, ConfigError, PropertiesOptionError
from ..error import SlaveError, PropertiesOptionError
from .baseoption import DynSymLinkOption, SymLinkOption, Option
@ -180,6 +180,7 @@ class MasterSlaves(object):
master=master)
master_is_meta = values._is_meta(master, masterp)
multi = values._get_multi(opt, path)
#if masterlen is [], test properties (has no value, don't get any value)
if masterlen == 0:
if validate_properties:
props = context.cfgimpl_get_settings().validate_properties(opt, False,

View File

@ -23,9 +23,9 @@ import re
import sys
from IPy import IP
from types import FunctionType
from ..setting import log, undefined
from ..setting import undefined
from ..error import ConfigError, ContextError
from ..error import ConfigError
from ..i18n import _
from .baseoption import Option, validate_callback
from ..autolib import carry_out_calculation
@ -83,15 +83,15 @@ class ChoiceOption(Option):
values = carry_out_calculation(current_opt, context=context,
callback=values,
callback_params=values_params)
if not isinstance(values, list): # pragma: optional cover
if values is not undefined and not isinstance(values, list): # pragma: optional cover
raise ConfigError(_('calculated values for {0} is not a list'
'').format(self.impl_getname()))
return values
def _validate(self, value, context=undefined, current_opt=undefined):
values = self.impl_get_values(context, current_opt=current_opt)
if not value in values: # pragma: optional cover
raise ValueError(_('value {0} is not permitted, '
if values is not undefined and not value in values: # pragma: optional cover
return ValueError(_('value {0} is not permitted, '
'only {1} is allowed'
'').format(value,
values))
@ -103,7 +103,7 @@ class BoolOption(Option):
def _validate(self, value, context=undefined, current_opt=undefined):
if not isinstance(value, bool):
raise ValueError(_('invalid boolean')) # pragma: optional cover
return ValueError(_('invalid boolean')) # pragma: optional cover
class IntOption(Option):
@ -112,7 +112,7 @@ class IntOption(Option):
def _validate(self, value, context=undefined, current_opt=undefined):
if not isinstance(value, int):
raise ValueError(_('invalid integer')) # pragma: optional cover
return ValueError(_('invalid integer')) # pragma: optional cover
class FloatOption(Option):
@ -121,7 +121,7 @@ class FloatOption(Option):
def _validate(self, value, context=undefined, current_opt=undefined):
if not isinstance(value, float):
raise ValueError(_('invalid float')) # pragma: optional cover
return ValueError(_('invalid float')) # pragma: optional cover
class StrOption(Option):
@ -130,7 +130,7 @@ class StrOption(Option):
def _validate(self, value, context=undefined, current_opt=undefined):
if not isinstance(value, str):
raise ValueError(_('invalid string')) # pragma: optional cover
return ValueError(_('invalid string')) # pragma: optional cover
if sys.version_info[0] >= 3: # pragma: optional cover
@ -146,7 +146,7 @@ else:
def _validate(self, value, context=undefined, current_opt=undefined):
if not isinstance(value, unicode):
raise ValueError(_('invalid unicode')) # pragma: optional cover
return ValueError(_('invalid unicode')) # pragma: optional cover
class IPOption(Option):
@ -175,15 +175,17 @@ class IPOption(Option):
def _validate(self, value, context=undefined, current_opt=undefined):
# sometimes an ip term starts with a zero
# but this does not fit in some case, for example bind does not like it
self._impl_valid_unicode(value)
err = self._impl_valid_unicode(value)
if err:
return err
for val in value.split('.'):
if val.startswith("0") and len(val) > 1:
raise ValueError(_('invalid IP')) # pragma: optional cover
return ValueError(_('invalid IP')) # pragma: optional cover
# 'standard' validation
try:
IP('{0}/32'.format(value))
except ValueError: # pragma: optional cover
raise ValueError(_('invalid IP'))
return ValueError(_('invalid IP'))
def _second_level_validation(self, value, warnings_only):
ip = IP('{0}/32'.format(value))
@ -192,13 +194,13 @@ class IPOption(Option):
msg = _("IP is in reserved class")
else:
msg = _("invalid IP, mustn't be in reserved class")
raise ValueError(msg)
return ValueError(msg)
if self._get_extra('_private_only') and not ip.iptype() == 'PRIVATE': # pragma: optional cover
if warnings_only:
msg = _("IP is not in private class")
else:
msg = _("invalid IP, must be in private class")
raise ValueError(msg)
return ValueError(msg)
def _cons_in_network(self, opts, vals, warnings_only):
if len(vals) != 3:
@ -213,10 +215,10 @@ class IPOption(Option):
else:
msg = _('invalid IP {0} ({1}) not in network {2} ({3}) with '
'netmask {4} ({5})')
raise ValueError(msg.format(ip, opts[0].impl_getname(), network,
return ValueError(msg.format(ip, opts[0].impl_getname(), network,
opts[1].impl_getname(), netmask, opts[2].impl_getname()))
# test if ip is not network/broadcast IP
opts[2]._cons_ip_netmask((opts[2], opts[0]), (netmask, ip), warnings_only)
return opts[2]._cons_ip_netmask((opts[2], opts[0]), (netmask, ip), warnings_only)
class PortOption(Option):
@ -275,14 +277,16 @@ class PortOption(Option):
def _validate(self, value, context=undefined, current_opt=undefined):
if isinstance(value, int):
value = unicode(value)
self._impl_valid_unicode(value)
err = self._impl_valid_unicode(value)
if err:
return err
if self._get_extra('_allow_range') and ":" in str(value): # pragma: optional cover
value = str(value).split(':')
if len(value) != 2:
raise ValueError(_('invalid port, range must have two values '
return ValueError(_('invalid port, range must have two values '
'only'))
if not value[0] < value[1]:
raise ValueError(_('invalid port, first port in range must be'
return ValueError(_('invalid port, first port in range must be'
' smaller than the second one'))
else:
value = [value]
@ -291,9 +295,9 @@ class PortOption(Option):
try:
val = int(val)
except ValueError: # pragma: optional cover
raise ValueError(_('invalid port'))
return ValueError(_('invalid port'))
if not self._get_extra('_min_value') <= val <= self._get_extra('_max_value'): # pragma: optional cover
raise ValueError(_('invalid port, must be an integer between {0} '
return ValueError(_('invalid port, must be an integer between {0} '
'and {1}').format(self._get_extra('_min_value'),
self._get_extra('_max_value')))
@ -303,11 +307,13 @@ class NetworkOption(Option):
__slots__ = tuple()
def _validate(self, value, context=undefined, current_opt=undefined):
self._impl_valid_unicode(value)
err = self._impl_valid_unicode(value)
if err:
return err
try:
IP(value)
except ValueError: # pragma: optional cover
raise ValueError(_('invalid network address'))
return ValueError(_('invalid network address'))
def _second_level_validation(self, value, warnings_only):
ip = IP(value)
@ -316,7 +322,7 @@ class NetworkOption(Option):
msg = _("network address is in reserved class")
else:
msg = _("invalid network address, mustn't be in reserved class")
raise ValueError(msg)
return ValueError(msg)
class NetmaskOption(Option):
@ -324,23 +330,25 @@ class NetmaskOption(Option):
__slots__ = tuple()
def _validate(self, value, context=undefined, current_opt=undefined):
self._impl_valid_unicode(value)
err = self._impl_valid_unicode(value)
if err:
return err
try:
IP('0.0.0.0/{0}'.format(value))
except ValueError: # pragma: optional cover
raise ValueError(_('invalid netmask address'))
return ValueError(_('invalid netmask address'))
def _cons_network_netmask(self, opts, vals, warnings_only):
#opts must be (netmask, network) options
if None in vals:
return
self.__cons_netmask(opts, vals[0], vals[1], False, warnings_only)
return self.__cons_netmask(opts, vals[0], vals[1], False, warnings_only)
def _cons_ip_netmask(self, opts, vals, warnings_only):
#opts must be (netmask, ip) options
if None in vals:
return
self.__cons_netmask(opts, vals[0], vals[1], True, warnings_only)
return self.__cons_netmask(opts, vals[0], vals[1], True, warnings_only)
def __cons_netmask(self, opts, val_netmask, val_ipnetwork, make_net,
warnings_only):
@ -364,7 +372,7 @@ class NetmaskOption(Option):
if not make_net:
msg = _('invalid network {0} ({1}) with netmask {2}')
if msg is not None: # pragma: optional cover
raise ValueError(msg.format(val_ipnetwork, opts[1].impl_getname(),
return ValueError(msg.format(val_ipnetwork, opts[1].impl_getname(),
val_netmask))
@ -372,11 +380,13 @@ class BroadcastOption(Option):
__slots__ = tuple()
def _validate(self, value, context=undefined, current_opt=undefined):
self._impl_valid_unicode(value)
err = self._impl_valid_unicode(value)
if err:
return err
try:
IP('{0}/32'.format(value))
except ValueError: # pragma: optional cover
raise ValueError(_('invalid broadcast address'))
return ValueError(_('invalid broadcast address'))
def _cons_broadcast(self, opts, vals, warnings_only):
if len(vals) != 3:
@ -385,7 +395,7 @@ class BroadcastOption(Option):
return
broadcast, network, netmask = vals
if IP('{0}/{1}'.format(network, netmask)).broadcast() != IP(broadcast):
raise ValueError(_('invalid broadcast {0} ({1}) with network {2} '
return ValueError(_('invalid broadcast {0} ({1}) with network {2} '
'({3}) and netmask {4} ({5})').format(
broadcast, opts[0].impl_getname(), network,
opts[1].impl_getname(), netmask, opts[2].impl_getname())) # pragma: optional cover
@ -430,13 +440,15 @@ class DomainnameOption(Option):
extra=extra)
def _validate(self, value, context=undefined, current_opt=undefined):
self._impl_valid_unicode(value)
err = self._impl_valid_unicode(value)
if err:
return err
def _valid_length(val):
if len(val) < 1:
raise ValueError(_("invalid domainname's length (min 1)"))
return ValueError(_("invalid domainname's length (min 1)"))
if len(val) > part_name_length:
raise ValueError(_("invalid domainname's length (max {0})"
return ValueError(_("invalid domainname's length (max {0})"
"").format(part_name_length))
if self._get_extra('_allow_ip') is True: # pragma: optional cover
@ -451,23 +463,25 @@ class DomainnameOption(Option):
part_name_length = 63
if self._get_extra('_dom_type') == 'domainname':
if not self._get_extra('_allow_without_dot') and not "." in value:
raise ValueError(_("invalid domainname, must have dot"))
return ValueError(_("invalid domainname, must have dot"))
if len(value) > 255:
raise ValueError(_("invalid domainname's length (max 255)"))
return ValueError(_("invalid domainname's length (max 255)"))
for dom in value.split('.'):
_valid_length(dom)
err = _valid_length(dom)
if err:
return err
else:
_valid_length(value)
return _valid_length(value)
def _second_level_validation(self, value, warnings_only):
def _valid_char(val):
if self._get_extra('_has_upper').search(val):
raise ValueError(_('some characters are uppercase'))
return ValueError(_('some characters are uppercase'))
if not self._get_extra('_domain_re').search(val):
if warnings_only:
raise ValueError(_('some characters may cause problems'))
return ValueError(_('some characters may cause problems'))
else:
raise ValueError(_('invalid domainname'))
return ValueError(_('invalid domainname'))
#not for IP
if self._get_extra('_allow_ip') is True:
try:
@ -477,9 +491,9 @@ class DomainnameOption(Option):
pass
if self._get_extra('_dom_type') == 'domainname':
for dom in value.split('.'):
_valid_char(dom)
return _valid_char(dom)
else:
_valid_char(value)
return _valid_char(value)
class EmailOption(DomainnameOption):
@ -487,17 +501,19 @@ class EmailOption(DomainnameOption):
username_re = re.compile(r"^[\w!#$%&'*+\-/=?^`{|}~.]+$")
def _validate(self, value, context=undefined, current_opt=undefined):
self._impl_valid_unicode(value)
err = self._impl_valid_unicode(value)
if err:
return err
splitted = value.split('@', 1)
try:
username, domain = splitted
except ValueError: # pragma: optional cover
raise ValueError(_('invalid email address, must contains one @'
))
if len(splitted) == 1:
return ValueError(_('invalid email address, must contains one @'))
username, domain = value.split('@', 1)
if not self.username_re.search(username):
raise ValueError(_('invalid username in email address')) # pragma: optional cover
super(EmailOption, self)._validate(domain)
super(EmailOption, self)._second_level_validation(domain, False)
return ValueError(_('invalid username in email address')) # pragma: optional cover
err = super(EmailOption, self)._validate(domain)
if err:
return err
return super(EmailOption, self)._second_level_validation(domain, False)
def _second_level_validation(self, value, warnings_only):
pass
@ -509,36 +525,41 @@ class URLOption(DomainnameOption):
path_re = re.compile(r"^[A-Za-z0-9\-\._~:/\?#\[\]@!%\$&\'\(\)\*\+,;=]+$")
def _validate(self, value, context=undefined, current_opt=undefined):
self._impl_valid_unicode(value)
err = self._impl_valid_unicode(value)
if err:
return err
match = self.proto_re.search(value)
if not match: # pragma: optional cover
raise ValueError(_('invalid url, must start with http:// or '
return ValueError(_('invalid url, must start with http:// or '
'https://'))
value = value[len(match.group(0)):]
# get domain/files
splitted = value.split('/', 1)
try:
domain, files = splitted
except ValueError:
if len(splitted) == 1:
domain = value
files = None
else:
domain, files = splitted
# if port in domain
splitted = domain.split(':', 1)
try:
domain, port = splitted
except ValueError: # pragma: optional cover
if len(splitted) == 1:
domain = splitted[0]
port = 0
else:
domain, port = splitted
if not 0 <= int(port) <= 65535:
raise ValueError(_('invalid url, port must be an between 0 and '
return ValueError(_('invalid url, port must be an between 0 and '
'65536')) # pragma: optional cover
# validate domainname
super(URLOption, self)._validate(domain)
super(URLOption, self)._second_level_validation(domain, False)
err = super(URLOption, self)._validate(domain)
if err:
return err
err = super(URLOption, self)._second_level_validation(domain, False)
if err:
return err
# validate file
if files is not None and files != '' and not self.path_re.search(files):
raise ValueError(_('invalid url, must ends with a valid resource name')) # pragma: optional cover
return ValueError(_('invalid url, must ends with a valid resource name')) # pragma: optional cover
def _second_level_validation(self, value, warnings_only):
pass
@ -550,10 +571,12 @@ class UsernameOption(Option):
username_re = re.compile(r"^[a-z_][a-z0-9_-]{0,30}[$a-z0-9_-]{0,1}$")
def _validate(self, value, context=undefined, current_opt=undefined):
self._impl_valid_unicode(value)
err = self._impl_valid_unicode(value)
if err:
return err
match = self.username_re.search(value)
if not match:
raise ValueError(_('invalid username')) # pragma: optional cover
return ValueError(_('invalid username')) # pragma: optional cover
class FilenameOption(Option):
@ -561,7 +584,9 @@ class FilenameOption(Option):
path_re = re.compile(r"^[a-zA-Z0-9\-\._~/+]+$")
def _validate(self, value, context=undefined, current_opt=undefined):
self._impl_valid_unicode(value)
err = self._impl_valid_unicode(value)
if err:
return err
match = self.path_re.search(value)
if not match:
raise ValueError(_('invalid filename')) # pragma: optional cover
return ValueError(_('invalid filename')) # pragma: optional cover

View File

@ -111,15 +111,32 @@ class OptionDescription(BaseOption, StorageOptionDescription):
#cannot set multi option as OptionDescription requires
else:
option._set_readonly(True)
is_multi = option.impl_is_multi()
for func, all_cons_opts, params in option._get_consistencies():
all_cons_opts[0]._valid_consistencies(all_cons_opts[1:])
option._valid_consistencies(all_cons_opts[1:])
if is_multi:
is_slave = option.impl_is_master_slaves()
if not is_slave:
raise ValueError(_('malformed consistency option {0} '
'must be a master/slaves').format(
option.impl_getname()))
masterslaves = option.impl_get_master_slaves()
for opt in all_cons_opts:
if is_multi:
if not opt.impl_is_master_slaves():
raise ValueError(_('malformed consistency option {0} '
'must not be a multi for {1}').format(
option.impl_getname(), opt.impl_getname()))
elif masterslaves != opt.impl_get_master_slaves():
raise ValueError(_('malformed consistency option {0} '
'must be in same master/slaves for {1}').format(
option.impl_getname(), opt.impl_getname()))
_consistencies.setdefault(opt,
[]).append((func,
all_cons_opts,
params))
is_slave = None
if option.impl_is_multi():
if is_multi:
all_requires = option.impl_getrequires()
if all_requires != tuple():
for requires in all_requires:

View File

@ -19,7 +19,7 @@
# ____________________________________________________________
from ...i18n import _
from ...setting import undefined
from ...error import ConfigError, ContextError
from ...error import ConfigError
static_tuple = tuple()
static_set = frozenset()
@ -94,15 +94,12 @@ class StorageBase(object):
_setattr(self, '_default', default)
if is_multi and default_multi is not None:
try:
self._validate(default_multi)
except ValueError as err: # pragma: optional cover
err = self._validate(default_multi)
if err:
raise ValueError(_("invalid default_multi value {0} "
"for option {1}: {2}").format(
str(default_multi),
self.impl_getname(), str(err)))
except ContextError, err:
pass
_setattr(self, '_default_multi', default_multi)
# information

View File

@ -326,7 +326,9 @@ class _Base(SqlAlchemyBase):
def _set_default_values(self, default, default_multi):
self._default = default
if self.impl_is_multi() and default_multi is not None:
self._validate(default_multi)
err = self._validate(default_multi)
if err:
raise err
self._default_multi = default_multi
def _get_consistencies(self):

View File

@ -78,7 +78,8 @@ class Values(object):
if meta is not None:
try:
value = meta.cfgimpl_get_values(
)._get_cached_value(opt, path, index=index, from_masterslave=True)
)._get_cached_value(opt, path, index=index, submulti_index=submulti_index,
from_masterslave=True)
if isinstance(value, Multi):
if index is not None:
value = value[index]
@ -207,8 +208,8 @@ class Values(object):
force_permissive=False, trusted_cached_properties=True,
validate_properties=True,
setting_properties=undefined, self_properties=undefined,
index=None, from_masterslave=False, with_meta=True,
masterlen=undefined, check_frozen=False):
index=None, submulti_index=undefined, from_masterslave=False,
with_meta=True, masterlen=undefined, check_frozen=False):
context = self._getcontext()
settings = context.cfgimpl_get_settings()
if path is None:
@ -257,6 +258,7 @@ class Values(object):
with_meta=with_meta,
masterlen=masterlen,
index=index,
submulti_index=submulti_index,
check_frozen=check_frozen)
# cache doesn't work with SubMulti yet
if not isinstance(val, SubMulti) and 'cache' in setting_properties and \
@ -325,12 +327,11 @@ class Values(object):
force_submulti_index = None
else:
force_submulti_index = submulti_index
try:
opt.impl_validate(value, context,
err = opt.impl_validate(value, context,
'validator' in setting_properties,
force_index=force_index,
force_submulti_index=force_submulti_index)
except ValueError, err:
if err:
config_error = err
value = None
@ -373,13 +374,15 @@ class Values(object):
if 'validator' in setting_properties:
fake_context = context._gen_fake_values()
fake_values = fake_context.cfgimpl_get_values()
fake_values._setvalue(opt, path, value)
props = fake_values.validate(opt, value, path, check_frozen,
force_permissive, setting_properties,
not_raises=not_raises)
if props and not_raises:
return
fake_values._setvalue(opt, path, value)
opt.impl_validate(value, fake_context)
err = opt.impl_validate(value, fake_context)
if err:
raise err
self._setvalue(opt, path, value)
def _setvalue(self, opt, path, value):
@ -811,8 +814,10 @@ class Multi(list):
self._store()
def _validate(self, value, fake_context, force_index, submulti=False):
self.opt.impl_validate(value, context=fake_context,
err = self.opt.impl_validate(value, context=fake_context,
force_index=force_index)
if err:
raise err
def pop(self, index, force=False):
"""the list value can be updated (poped)
@ -877,9 +882,11 @@ class SubMulti(Multi):
super(SubMulti, self)._validate(value, fake_context,
force_index, submulti)
else:
self.opt.impl_validate(value, context=fake_context,
err = self.opt.impl_validate(value, context=fake_context,
force_index=self._index,
force_submulti_index=force_index)
if err:
raise err
def _get_validated_value(self, index):
values = self._getcontext().cfgimpl_get_values()