some improvements
This commit is contained in:
parent
c81a2bcdbf
commit
e6a949635f
8 changed files with 184 additions and 124 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
Mon Oct 10 21:39:04 2016 +0200 Emmanuel Garette <egarette@cadoles.com>
|
||||||
|
* consistency with default value for all values now works
|
||||||
|
* warnings works now even if default value is None
|
||||||
|
|
||||||
Thu Sep 22 08:25:33 2016 +0200 Emmanuel Garette <egarette@cadoles.com>
|
Thu Sep 22 08:25:33 2016 +0200 Emmanuel Garette <egarette@cadoles.com>
|
||||||
* force_store_value is rebuild if needed
|
* force_store_value is rebuild if needed
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,23 @@ def test_consistency_warnings_only():
|
||||||
assert w != []
|
assert w != []
|
||||||
|
|
||||||
|
|
||||||
|
def test_consistency_warnings_only_more_option():
|
||||||
|
a = IntOption('a', '')
|
||||||
|
b = IntOption('b', '')
|
||||||
|
d = IntOption('d', '')
|
||||||
|
od = OptionDescription('od', '', [a, b, d])
|
||||||
|
a.impl_add_consistency('not_equal', b, d, warnings_only=True)
|
||||||
|
c = Config(od)
|
||||||
|
c.a = 1
|
||||||
|
warnings.simplefilter("always", ValueWarning)
|
||||||
|
with warnings.catch_warnings(record=True) as w:
|
||||||
|
c.b = 1
|
||||||
|
assert w != []
|
||||||
|
with warnings.catch_warnings(record=True) as w:
|
||||||
|
c.d = 1
|
||||||
|
assert w != []
|
||||||
|
|
||||||
|
|
||||||
def test_consistency_not_equal():
|
def test_consistency_not_equal():
|
||||||
a = IntOption('a', '')
|
a = IntOption('a', '')
|
||||||
b = IntOption('b', '')
|
b = IntOption('b', '')
|
||||||
|
@ -283,10 +300,7 @@ def test_consistency_ip_in_network_len_error():
|
||||||
b = NetmaskOption('b', '')
|
b = NetmaskOption('b', '')
|
||||||
c = IPOption('c', '')
|
c = IPOption('c', '')
|
||||||
od = OptionDescription('od', '', [a, b, c])
|
od = OptionDescription('od', '', [a, b, c])
|
||||||
c.impl_add_consistency('in_network', a)
|
raises(ConfigError, "c.impl_add_consistency('in_network', a)")
|
||||||
cfg = Config(od)
|
|
||||||
cfg
|
|
||||||
raises(ConfigError, "cfg.a = '192.168.2.0'")
|
|
||||||
|
|
||||||
|
|
||||||
def test_consistency_ip_netmask_network_error():
|
def test_consistency_ip_netmask_network_error():
|
||||||
|
@ -338,6 +352,17 @@ def test_consistency_network_netmask_multi():
|
||||||
raises(ValueError, "c.a = ['192.168.1.1']")
|
raises(ValueError, "c.a = ['192.168.1.1']")
|
||||||
|
|
||||||
|
|
||||||
|
def test_consistency_network_netmask_multi_slave_default_multi():
|
||||||
|
a = NetworkOption('a', '', default_multi=u'192.168.1.0', multi=True, properties=('mandatory',))
|
||||||
|
b = NetmaskOption('b', '', default_multi=u'255.255.255.0', multi=True, properties=('mandatory',))
|
||||||
|
od = OptionDescription('a', '', [a, b])
|
||||||
|
od.impl_set_group_type(groups.master)
|
||||||
|
b.impl_add_consistency('network_netmask', a)
|
||||||
|
c = Config(od)
|
||||||
|
c.read_write()
|
||||||
|
c.a.append()
|
||||||
|
|
||||||
|
|
||||||
def test_consistency_network_netmask_multi_slave_default():
|
def test_consistency_network_netmask_multi_slave_default():
|
||||||
a = NetworkOption('a', '', multi=True, properties=('mandatory',))
|
a = NetworkOption('a', '', multi=True, properties=('mandatory',))
|
||||||
b = NetmaskOption('b', '', default_multi=u'255.255.255.0', multi=True, properties=('mandatory',))
|
b = NetmaskOption('b', '', default_multi=u'255.255.255.0', multi=True, properties=('mandatory',))
|
||||||
|
|
|
@ -11,7 +11,7 @@ from tiramisu.error import ValueWarning
|
||||||
from tiramisu.i18n import _
|
from tiramisu.i18n import _
|
||||||
|
|
||||||
|
|
||||||
msg_err = _("attention, {0} could be an invalid {1} for option {2}, {3}")
|
msg_err = _('attention, "{0}" could be an invalid {1} for "{2}", {3}')
|
||||||
|
|
||||||
|
|
||||||
def return_true(value, param=None):
|
def return_true(value, param=None):
|
||||||
|
@ -99,7 +99,7 @@ def test_validator_warning():
|
||||||
cfg.opt2 = 'val'
|
cfg.opt2 = 'val'
|
||||||
assert len(w) == 1
|
assert len(w) == 1
|
||||||
assert w[0].message.opt == opt2
|
assert w[0].message.opt == opt2
|
||||||
assert str(w[0].message) == msg_err.format('val', opt2.display_name, 'opt2', 'test error')
|
assert str(w[0].message) == msg_err.format('val', opt2._display_name, 'opt2', 'test error')
|
||||||
#
|
#
|
||||||
with warnings.catch_warnings(record=True) as w:
|
with warnings.catch_warnings(record=True) as w:
|
||||||
cfg.opt3.append('val')
|
cfg.opt3.append('val')
|
||||||
|
@ -109,7 +109,7 @@ def test_validator_warning():
|
||||||
cfg.opt3.append('val1')
|
cfg.opt3.append('val1')
|
||||||
assert len(w) == 1
|
assert len(w) == 1
|
||||||
assert w[0].message.opt == opt3
|
assert w[0].message.opt == opt3
|
||||||
assert str(w[0].message) == msg_err.format('val1', opt3.display_name, 'opt3', 'test error')
|
assert str(w[0].message) == msg_err.format('val1', opt3._display_name, 'opt3', 'test error')
|
||||||
raises(ValueError, "cfg.opt2 = 1")
|
raises(ValueError, "cfg.opt2 = 1")
|
||||||
#
|
#
|
||||||
with warnings.catch_warnings(record=True) as w:
|
with warnings.catch_warnings(record=True) as w:
|
||||||
|
@ -117,9 +117,9 @@ def test_validator_warning():
|
||||||
cfg.opt3.append('val')
|
cfg.opt3.append('val')
|
||||||
assert len(w) == 2
|
assert len(w) == 2
|
||||||
assert w[0].message.opt == opt2
|
assert w[0].message.opt == opt2
|
||||||
assert str(w[0].message) == msg_err.format('val', opt2.display_name, 'opt2', 'test error')
|
assert str(w[0].message) == msg_err.format('val', opt2._display_name, 'opt2', 'test error')
|
||||||
assert w[1].message.opt == opt3
|
assert w[1].message.opt == opt3
|
||||||
assert str(w[0].message) == msg_err.format('val', opt2.display_name, 'opt2', 'test error')
|
assert str(w[0].message) == msg_err.format('val', opt2._display_name, 'opt2', 'test error')
|
||||||
|
|
||||||
|
|
||||||
def test_validator_warning_disabled():
|
def test_validator_warning_disabled():
|
||||||
|
@ -155,8 +155,10 @@ def test_validator_warning_disabled():
|
||||||
|
|
||||||
|
|
||||||
def test_validator_warning_master_slave():
|
def test_validator_warning_master_slave():
|
||||||
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise", multi=True, validator=return_false, warnings_only=True)
|
display_name_ip = "ip reseau autorise"
|
||||||
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-reseau", multi=True, validator=return_if_val, warnings_only=True)
|
display_name_netmask = "masque du sous-reseau"
|
||||||
|
ip_admin_eth0 = StrOption('ip_admin_eth0', display_name_ip, multi=True, validator=return_false, warnings_only=True)
|
||||||
|
netmask_admin_eth0 = StrOption('netmask_admin_eth0', display_name_netmask, multi=True, validator=return_if_val, warnings_only=True)
|
||||||
interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
|
interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
|
||||||
interface1.impl_set_group_type(groups.master)
|
interface1.impl_set_group_type(groups.master)
|
||||||
assert interface1.impl_get_group_type() == groups.master
|
assert interface1.impl_get_group_type() == groups.master
|
||||||
|
@ -171,29 +173,29 @@ def test_validator_warning_master_slave():
|
||||||
cfg.ip_admin_eth0.netmask_admin_eth0 = ['val1']
|
cfg.ip_admin_eth0.netmask_admin_eth0 = ['val1']
|
||||||
assert len(w) == 1
|
assert len(w) == 1
|
||||||
assert w[0].message.opt == netmask_admin_eth0
|
assert w[0].message.opt == netmask_admin_eth0
|
||||||
assert str(w[0].message) == msg_err.format('val1', netmask_admin_eth0.display_name, 'netmask_admin_eth0', 'test error')
|
assert str(w[0].message) == msg_err.format('val1', netmask_admin_eth0._display_name, display_name_netmask, 'test error')
|
||||||
#
|
#
|
||||||
with warnings.catch_warnings(record=True) as w:
|
with warnings.catch_warnings(record=True) as w:
|
||||||
cfg.ip_admin_eth0.ip_admin_eth0 = ['val']
|
cfg.ip_admin_eth0.ip_admin_eth0 = ['val']
|
||||||
assert len(w) == 1
|
assert len(w) == 1
|
||||||
assert w[0].message.opt == ip_admin_eth0
|
assert w[0].message.opt == ip_admin_eth0
|
||||||
assert str(w[0].message) == msg_err.format('val', ip_admin_eth0.display_name, 'ip_admin_eth0', 'test error')
|
assert str(w[0].message) == msg_err.format('val', ip_admin_eth0._display_name, display_name_ip, 'test error')
|
||||||
#
|
#
|
||||||
with warnings.catch_warnings(record=True) as w:
|
with warnings.catch_warnings(record=True) as w:
|
||||||
cfg.ip_admin_eth0.ip_admin_eth0 = ['val', 'val1', 'val1']
|
cfg.ip_admin_eth0.ip_admin_eth0 = ['val', 'val1', 'val1']
|
||||||
assert len(w) == 1
|
assert len(w) == 1
|
||||||
assert w[0].message.opt == ip_admin_eth0
|
assert w[0].message.opt == ip_admin_eth0
|
||||||
assert str(w[0].message) == msg_err.format('val', ip_admin_eth0.display_name, 'ip_admin_eth0', 'test error')
|
assert str(w[0].message) == msg_err.format('val', ip_admin_eth0._display_name, display_name_ip, 'test error')
|
||||||
#
|
#
|
||||||
with warnings.catch_warnings(record=True) as w:
|
with warnings.catch_warnings(record=True) as w:
|
||||||
cfg.ip_admin_eth0.ip_admin_eth0 = ['val1', 'val', 'val1']
|
cfg.ip_admin_eth0.ip_admin_eth0 = ['val1', 'val', 'val1']
|
||||||
assert len(w) == 1
|
assert len(w) == 1
|
||||||
assert w[0].message.opt == ip_admin_eth0
|
assert w[0].message.opt == ip_admin_eth0
|
||||||
assert str(w[0].message) == msg_err.format('val', ip_admin_eth0.display_name, 'ip_admin_eth0', 'test error')
|
assert str(w[0].message) == msg_err.format('val', ip_admin_eth0._display_name, display_name_ip, 'test error')
|
||||||
#
|
#
|
||||||
warnings.resetwarnings()
|
warnings.resetwarnings()
|
||||||
with warnings.catch_warnings(record=True) as w:
|
with warnings.catch_warnings(record=True) as w:
|
||||||
cfg.ip_admin_eth0.ip_admin_eth0 = ['val1', 'val1', 'val']
|
cfg.ip_admin_eth0.ip_admin_eth0 = ['val1', 'val1', 'val']
|
||||||
assert len(w) == 1
|
assert len(w) == 1
|
||||||
assert w[0].message.opt == ip_admin_eth0
|
assert w[0].message.opt == ip_admin_eth0
|
||||||
assert str(w[0].message) == msg_err.format('val', ip_admin_eth0.display_name, 'ip_admin_eth0', 'test error')
|
assert str(w[0].message) == msg_err.format('val', ip_admin_eth0._display_name, display_name_ip, 'test error')
|
||||||
|
|
|
@ -367,8 +367,8 @@ class Option(OnlyOption):
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
_empty = ''
|
_empty = ''
|
||||||
|
|
||||||
def _launch_consistency(self, func, option, value, context, index,
|
def _launch_consistency(self, current_opt, func, option, value, context,
|
||||||
submulti_index, all_cons_opts, warnings_only,
|
index, submulti_index, all_cons_opts, warnings_only,
|
||||||
transitive):
|
transitive):
|
||||||
"""Launch consistency now
|
"""Launch consistency now
|
||||||
|
|
||||||
|
@ -434,7 +434,7 @@ class Option(OnlyOption):
|
||||||
#only check properties for slaves
|
#only check properties for slaves
|
||||||
val_consistencies = False
|
val_consistencies = False
|
||||||
if val_consistencies:
|
if val_consistencies:
|
||||||
return getattr(self, func)(all_cons_opts, all_cons_vals, warnings_only)
|
return getattr(self, func)(current_opt, all_cons_opts, all_cons_vals, warnings_only)
|
||||||
|
|
||||||
def impl_validate(self, value, context=undefined, validate=True,
|
def impl_validate(self, value, context=undefined, validate=True,
|
||||||
force_index=None, force_submulti_index=None,
|
force_index=None, force_submulti_index=None,
|
||||||
|
@ -483,37 +483,41 @@ class Option(OnlyOption):
|
||||||
|
|
||||||
def do_validation(_value, _index, submulti_index):
|
def do_validation(_value, _index, submulti_index):
|
||||||
if _value is None:
|
if _value is None:
|
||||||
return
|
error = warning = None
|
||||||
# option validation
|
else:
|
||||||
err = self._validate(_value, context, current_opt,
|
# option validation
|
||||||
returns_raise=True)
|
err = self._validate(_value, context, current_opt,
|
||||||
if err:
|
returns_raise=True)
|
||||||
if debug:
|
if err:
|
||||||
log.debug('do_validation: value: {0}, index: {1}, '
|
if debug:
|
||||||
'submulti_index: {2}'.format(_value, _index,
|
log.debug('do_validation: value: {0}, index: {1}, '
|
||||||
submulti_index),
|
'submulti_index: {2}'.format(_value, _index,
|
||||||
exc_info=True)
|
submulti_index),
|
||||||
err_msg = '{0}'.format(err)
|
exc_info=True)
|
||||||
if err_msg:
|
err_msg = '{0}'.format(err)
|
||||||
msg = _('{0} is an invalid {1} for option {2}, {3}'
|
name = self.impl_getdoc()
|
||||||
'').format(_value, self.display_name,
|
if name is None or name == '':
|
||||||
self.impl_getname(), err_msg)
|
name = self.impl_getname()
|
||||||
else:
|
if err_msg:
|
||||||
msg = _('{0} is an invalid {1} for option {2}'
|
msg = _('"{0}" is an invalid {1} for "{2}", {3}'
|
||||||
'').format(_value, self.display_name,
|
'').format(_value, self._display_name,
|
||||||
self.impl_getname())
|
self.impl_get_display_name(), err_msg)
|
||||||
return ValueError(msg)
|
else:
|
||||||
warning = None
|
msg = _('"{0}" is an invalid {1} for "{2}"'
|
||||||
error = calculation_validator(_value)
|
'').format(_value, self._display_name,
|
||||||
if not error:
|
self.impl_get_display_name())
|
||||||
error = self._second_level_validation(_value, self._is_warnings_only())
|
return ValueError(msg)
|
||||||
if error:
|
warning = None
|
||||||
if debug:
|
error = calculation_validator(_value)
|
||||||
log.debug(_('do_validation for {0}: error in value').format(
|
if not error:
|
||||||
self.impl_getname()), exc_info=True)
|
error = self._second_level_validation(_value, self._is_warnings_only())
|
||||||
if self._is_warnings_only():
|
if error:
|
||||||
warning = error
|
if debug:
|
||||||
error = None
|
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:
|
if error is None and warning is None:
|
||||||
# if context launch consistency validation
|
# if context launch consistency validation
|
||||||
#if context is not undefined:
|
#if context is not undefined:
|
||||||
|
@ -527,8 +531,8 @@ class Option(OnlyOption):
|
||||||
else:
|
else:
|
||||||
return ret
|
return ret
|
||||||
if warning:
|
if warning:
|
||||||
msg = _("attention, {0} could be an invalid {1} for option {2}, {3}").format(
|
msg = _('attention, "{0}" could be an invalid {1} for "{2}", {3}').format(
|
||||||
_value, self.display_name, self.impl_getname(), warning)
|
_value, self._display_name, self.impl_get_display_name(), warning)
|
||||||
if context is undefined or 'warnings' in \
|
if context is undefined or 'warnings' in \
|
||||||
context.cfgimpl_get_settings():
|
context.cfgimpl_get_settings():
|
||||||
warnings.warn_explicit(ValueWarning(msg, self),
|
warnings.warn_explicit(ValueWarning(msg, self),
|
||||||
|
@ -537,13 +541,13 @@ class Option(OnlyOption):
|
||||||
elif error:
|
elif error:
|
||||||
err_msg = '{0}'.format(error)
|
err_msg = '{0}'.format(error)
|
||||||
if err_msg:
|
if err_msg:
|
||||||
msg = _("{0} is an invalid {1} for option {2}, {3}"
|
msg = _('"{0}" is an invalid {1} for "{2}", {3}'
|
||||||
"").format(_value, self.display_name,
|
'').format(_value, self._display_name,
|
||||||
self.impl_getname(), err_msg)
|
self.impl_get_display_name(), err_msg)
|
||||||
else:
|
else:
|
||||||
msg = _("{0} is an invalid {1} for option {2}"
|
msg = _('"{0}" is an invalid {1} for "{2}"'
|
||||||
"").format(_value, self.display_name,
|
'').format(_value, self._display_name,
|
||||||
self.impl_getname())
|
self.impl_get_display_name())
|
||||||
return ValueError(msg)
|
return ValueError(msg)
|
||||||
|
|
||||||
# generic calculation
|
# generic calculation
|
||||||
|
@ -618,6 +622,12 @@ class Option(OnlyOption):
|
||||||
"accesses the Option's doc"
|
"accesses the Option's doc"
|
||||||
return self.impl_get_information('doc')
|
return self.impl_get_information('doc')
|
||||||
|
|
||||||
|
def impl_get_display_name(self):
|
||||||
|
name = self.impl_getdoc()
|
||||||
|
if name is None or name == '':
|
||||||
|
name = self.impl_getname()
|
||||||
|
return name
|
||||||
|
|
||||||
def _valid_consistencies(self, other_opts):
|
def _valid_consistencies(self, other_opts):
|
||||||
if self._is_subdyn():
|
if self._is_subdyn():
|
||||||
dynod = self._impl_getsubdyn()
|
dynod = self._impl_getsubdyn()
|
||||||
|
@ -706,27 +716,42 @@ class Option(OnlyOption):
|
||||||
opts.append(opt._impl_to_dyn(name, path))
|
opts.append(opt._impl_to_dyn(name, path))
|
||||||
else:
|
else:
|
||||||
opts = all_cons_opts
|
opts = all_cons_opts
|
||||||
err = opts[0]._launch_consistency(func, option, value, context,
|
err = opts[0]._launch_consistency(self, func, option, value,
|
||||||
index, submulti_idx, opts,
|
context, index, submulti_idx,
|
||||||
warnings_only, transitive)
|
opts, warnings_only,
|
||||||
|
transitive)
|
||||||
if err:
|
if err:
|
||||||
if warnings_only:
|
if warnings_only:
|
||||||
return ValueWarning(str(err), option)
|
return ValueWarning(str(err), option)
|
||||||
else:
|
else:
|
||||||
return err
|
return err
|
||||||
|
|
||||||
def _cons_not_equal(self, opts, vals, warnings_only):
|
def _cons_not_equal(self, current_opt, opts, vals, warnings_only):
|
||||||
|
equal = set()
|
||||||
|
is_current = False
|
||||||
for idx_inf, val_inf in enumerate(vals):
|
for idx_inf, val_inf in enumerate(vals):
|
||||||
for idx_sup, val_sup in enumerate(vals[idx_inf + 1:]):
|
for idx_sup, val_sup in enumerate(vals[idx_inf + 1:]):
|
||||||
if val_inf == val_sup is not None:
|
if val_inf == val_sup is not None:
|
||||||
if warnings_only:
|
for opt_ in [opts[idx_inf], opts[idx_inf + idx_sup + 1]]:
|
||||||
msg = _("value for {0} and {1} should be different")
|
if opt_ == current_opt:
|
||||||
else:
|
is_current = True
|
||||||
msg = _("value for {0} and {1} must be different")
|
else:
|
||||||
if debug:
|
equal.add('"{}"'.format(opt_.impl_get_display_name()))
|
||||||
log.debug('_cons_not_equal: {0} and {1} are not different'.format(val_inf, val_sup))
|
if equal:
|
||||||
return ValueError(msg.format(opts[idx_inf].impl_getname(),
|
if debug:
|
||||||
opts[idx_inf + idx_sup + 1].impl_getname()))
|
log.debug(_('_cons_not_equal: {} are not different').format(display_list(list(equal))))
|
||||||
|
if is_current:
|
||||||
|
if warnings_only:
|
||||||
|
msg = _('should be different from the value of {}')
|
||||||
|
else:
|
||||||
|
msg = _('must be different from the value of {}')
|
||||||
|
return ValueError(msg.format(display_list(list(equal))))
|
||||||
|
else:
|
||||||
|
if warnings_only:
|
||||||
|
msg = _('value for {} should be different')
|
||||||
|
else:
|
||||||
|
msg = _('value for {} must be different')
|
||||||
|
return ValueError(msg.format(display_list(list(equal))))
|
||||||
|
|
||||||
# serialize/unserialize
|
# serialize/unserialize
|
||||||
def _impl_convert_consistencies(self, descr, load=False):
|
def _impl_convert_consistencies(self, descr, load=False):
|
||||||
|
|
|
@ -36,8 +36,8 @@ class ChoiceOption(Option):
|
||||||
|
|
||||||
The option can also have the value ``None``
|
The option can also have the value ``None``
|
||||||
"""
|
"""
|
||||||
__slots__ = tuple('_init')
|
__slots__ = tuple()
|
||||||
display_name = _('choice')
|
_display_name = _('choice')
|
||||||
|
|
||||||
def __init__(self, name, doc, values, default=None,
|
def __init__(self, name, doc, values, default=None,
|
||||||
values_params=None, default_multi=None, requires=None,
|
values_params=None, default_multi=None, requires=None,
|
||||||
|
@ -56,9 +56,7 @@ class ChoiceOption(Option):
|
||||||
raise TypeError(_('values must be a tuple or a function for {0}'
|
raise TypeError(_('values must be a tuple or a function for {0}'
|
||||||
).format(name))
|
).format(name))
|
||||||
session = self.getsession()
|
session = self.getsession()
|
||||||
#cannot add values and values_params in database before add option
|
self.impl_set_choice_values_params(values, values_params, session)
|
||||||
#set in _init temporary
|
|
||||||
self._init = (values, values_params)
|
|
||||||
super(ChoiceOption, self).__init__(name, doc, default=default,
|
super(ChoiceOption, self).__init__(name, doc, default=default,
|
||||||
default_multi=default_multi,
|
default_multi=default_multi,
|
||||||
callback=callback,
|
callback=callback,
|
||||||
|
@ -70,9 +68,7 @@ class ChoiceOption(Option):
|
||||||
properties=properties,
|
properties=properties,
|
||||||
warnings_only=warnings_only,
|
warnings_only=warnings_only,
|
||||||
session=session)
|
session=session)
|
||||||
self.impl_set_choice_values_params(values, values_params, session)
|
self.commit(session)
|
||||||
session.commit()
|
|
||||||
del(self._init)
|
|
||||||
|
|
||||||
def impl_get_values(self, context, current_opt=undefined,
|
def impl_get_values(self, context, current_opt=undefined,
|
||||||
returns_raise=False):
|
returns_raise=False):
|
||||||
|
@ -80,10 +76,7 @@ class ChoiceOption(Option):
|
||||||
current_opt = self
|
current_opt = self
|
||||||
params = undefined
|
params = undefined
|
||||||
#FIXME cache? but in context...
|
#FIXME cache? but in context...
|
||||||
if '_init' in dir(self):
|
values = self._choice_values
|
||||||
values, params = self._init
|
|
||||||
else:
|
|
||||||
values = self._choice_values
|
|
||||||
if isinstance(values, FunctionType):
|
if isinstance(values, FunctionType):
|
||||||
if context is None:
|
if context is None:
|
||||||
values = []
|
values = []
|
||||||
|
@ -122,7 +115,7 @@ class ChoiceOption(Option):
|
||||||
class BoolOption(Option):
|
class BoolOption(Option):
|
||||||
"represents a choice between ``True`` and ``False``"
|
"represents a choice between ``True`` and ``False``"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
display_name = _('boolean')
|
_display_name = _('boolean')
|
||||||
|
|
||||||
def _validate(self, value, context=undefined, current_opt=undefined,
|
def _validate(self, value, context=undefined, current_opt=undefined,
|
||||||
returns_raise=False):
|
returns_raise=False):
|
||||||
|
@ -133,7 +126,7 @@ class BoolOption(Option):
|
||||||
class IntOption(Option):
|
class IntOption(Option):
|
||||||
"represents a choice of an integer"
|
"represents a choice of an integer"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
display_name = _('integer')
|
_display_name = _('integer')
|
||||||
|
|
||||||
def _validate(self, value, context=undefined, current_opt=undefined,
|
def _validate(self, value, context=undefined, current_opt=undefined,
|
||||||
returns_raise=False):
|
returns_raise=False):
|
||||||
|
@ -144,7 +137,7 @@ class IntOption(Option):
|
||||||
class FloatOption(Option):
|
class FloatOption(Option):
|
||||||
"represents a choice of a floating point number"
|
"represents a choice of a floating point number"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
display_name = _('float')
|
_display_name = _('float')
|
||||||
|
|
||||||
def _validate(self, value, context=undefined, current_opt=undefined,
|
def _validate(self, value, context=undefined, current_opt=undefined,
|
||||||
returns_raise=False):
|
returns_raise=False):
|
||||||
|
@ -155,7 +148,7 @@ class FloatOption(Option):
|
||||||
class StrOption(Option):
|
class StrOption(Option):
|
||||||
"represents the choice of a string"
|
"represents the choice of a string"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
display_name = _('string')
|
_display_name = _('string')
|
||||||
|
|
||||||
def _validate(self, value, context=undefined, current_opt=undefined,
|
def _validate(self, value, context=undefined, current_opt=undefined,
|
||||||
returns_raise=False):
|
returns_raise=False):
|
||||||
|
@ -173,7 +166,7 @@ else:
|
||||||
"represents the choice of a unicode string"
|
"represents the choice of a unicode string"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
_empty = u''
|
_empty = u''
|
||||||
display_name = _('unicode string')
|
_display_name = _('unicode string')
|
||||||
|
|
||||||
def _validate(self, value, context=undefined, current_opt=undefined,
|
def _validate(self, value, context=undefined, current_opt=undefined,
|
||||||
returns_raise=False):
|
returns_raise=False):
|
||||||
|
@ -184,7 +177,7 @@ else:
|
||||||
class PasswordOption(Option):
|
class PasswordOption(Option):
|
||||||
"represents the choice of a password"
|
"represents the choice of a password"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
display_name = _('password')
|
_display_name = _('password')
|
||||||
|
|
||||||
def _validate(self, value, context=undefined, current_opt=undefined,
|
def _validate(self, value, context=undefined, current_opt=undefined,
|
||||||
returns_raise=False):
|
returns_raise=False):
|
||||||
|
@ -196,7 +189,7 @@ class PasswordOption(Option):
|
||||||
class IPOption(Option):
|
class IPOption(Option):
|
||||||
"represents the choice of an ip"
|
"represents the choice of an ip"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
display_name = _('IP')
|
_display_name = _('IP')
|
||||||
|
|
||||||
def __init__(self, name, doc, default=None, default_multi=None,
|
def __init__(self, name, doc, default=None, default_multi=None,
|
||||||
requires=None, multi=False, callback=None,
|
requires=None, multi=False, callback=None,
|
||||||
|
@ -250,7 +243,7 @@ class IPOption(Option):
|
||||||
msg = _("must be in private class")
|
msg = _("must be in private class")
|
||||||
return ValueError(msg)
|
return ValueError(msg)
|
||||||
|
|
||||||
def _cons_in_network(self, opts, vals, warnings_only):
|
def _cons_in_network(self, current_opt, opts, vals, warnings_only):
|
||||||
if len(vals) != 3:
|
if len(vals) != 3:
|
||||||
raise ConfigError(_('invalid len for vals')) # pragma: optional cover
|
raise ConfigError(_('invalid len for vals')) # pragma: optional cover
|
||||||
if None in vals:
|
if None in vals:
|
||||||
|
@ -264,7 +257,7 @@ class IPOption(Option):
|
||||||
return ValueError(msg.format(network, netmask,
|
return ValueError(msg.format(network, netmask,
|
||||||
opts[1].impl_getname(), opts[2].impl_getname()))
|
opts[1].impl_getname(), opts[2].impl_getname()))
|
||||||
# test if ip is not network/broadcast IP
|
# test if ip is not network/broadcast IP
|
||||||
return opts[2]._cons_ip_netmask((opts[2], opts[0]), (netmask, ip), warnings_only)
|
return opts[2]._cons_ip_netmask(current_opt, (opts[2], opts[0]), (netmask, ip), warnings_only)
|
||||||
|
|
||||||
|
|
||||||
class PortOption(Option):
|
class PortOption(Option):
|
||||||
|
@ -279,7 +272,7 @@ class PortOption(Option):
|
||||||
"""
|
"""
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
port_re = re.compile(r"^[0-9]*$")
|
port_re = re.compile(r"^[0-9]*$")
|
||||||
display_name = _('port')
|
_display_name = _('port')
|
||||||
|
|
||||||
def __init__(self, name, doc, default=None, default_multi=None,
|
def __init__(self, name, doc, default=None, default_multi=None,
|
||||||
requires=None, multi=False, callback=None,
|
requires=None, multi=False, callback=None,
|
||||||
|
@ -355,7 +348,7 @@ class PortOption(Option):
|
||||||
class NetworkOption(Option):
|
class NetworkOption(Option):
|
||||||
"represents the choice of a network"
|
"represents the choice of a network"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
display_name = _('network address')
|
_display_name = _('network address')
|
||||||
|
|
||||||
def _validate(self, value, context=undefined, current_opt=undefined,
|
def _validate(self, value, context=undefined, current_opt=undefined,
|
||||||
returns_raise=False):
|
returns_raise=False):
|
||||||
|
@ -385,7 +378,7 @@ class NetworkOption(Option):
|
||||||
class NetmaskOption(Option):
|
class NetmaskOption(Option):
|
||||||
"represents the choice of a netmask"
|
"represents the choice of a netmask"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
display_name = _('netmask address')
|
_display_name = _('netmask address')
|
||||||
|
|
||||||
def _validate(self, value, context=undefined, current_opt=undefined,
|
def _validate(self, value, context=undefined, current_opt=undefined,
|
||||||
returns_raise=False):
|
returns_raise=False):
|
||||||
|
@ -402,13 +395,13 @@ class NetmaskOption(Option):
|
||||||
except ValueError: # pragma: optional cover
|
except ValueError: # pragma: optional cover
|
||||||
return ValueError()
|
return ValueError()
|
||||||
|
|
||||||
def _cons_network_netmask(self, opts, vals, warnings_only):
|
def _cons_network_netmask(self, current_opt, opts, vals, warnings_only):
|
||||||
#opts must be (netmask, network) options
|
#opts must be (netmask, network) options
|
||||||
if None in vals:
|
if None in vals:
|
||||||
return
|
return
|
||||||
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):
|
def _cons_ip_netmask(self, current_opt, opts, vals, warnings_only):
|
||||||
#opts must be (netmask, ip) options
|
#opts must be (netmask, ip) options
|
||||||
if None in vals:
|
if None in vals:
|
||||||
return
|
return
|
||||||
|
@ -439,7 +432,7 @@ class NetmaskOption(Option):
|
||||||
|
|
||||||
class BroadcastOption(Option):
|
class BroadcastOption(Option):
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
display_name = _('broadcast address')
|
_display_name = _('broadcast address')
|
||||||
|
|
||||||
def _validate(self, value, context=undefined, current_opt=undefined,
|
def _validate(self, value, context=undefined, current_opt=undefined,
|
||||||
returns_raise=False):
|
returns_raise=False):
|
||||||
|
@ -451,7 +444,7 @@ class BroadcastOption(Option):
|
||||||
except ValueError: # pragma: optional cover
|
except ValueError: # pragma: optional cover
|
||||||
return ValueError()
|
return ValueError()
|
||||||
|
|
||||||
def _cons_broadcast(self, opts, vals, warnings_only):
|
def _cons_broadcast(self, current_opt, opts, vals, warnings_only):
|
||||||
if len(vals) != 3:
|
if len(vals) != 3:
|
||||||
raise ConfigError(_('invalid len for vals')) # pragma: optional cover
|
raise ConfigError(_('invalid len for vals')) # pragma: optional cover
|
||||||
if None in vals:
|
if None in vals:
|
||||||
|
@ -470,7 +463,7 @@ class DomainnameOption(Option):
|
||||||
fqdn: with tld, not supported yet
|
fqdn: with tld, not supported yet
|
||||||
"""
|
"""
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
display_name = _('domain name')
|
_display_name = _('domain name')
|
||||||
|
|
||||||
def __init__(self, name, doc, default=None, default_multi=None,
|
def __init__(self, name, doc, default=None, default_multi=None,
|
||||||
requires=None, multi=False, callback=None,
|
requires=None, multi=False, callback=None,
|
||||||
|
@ -569,7 +562,7 @@ class DomainnameOption(Option):
|
||||||
class EmailOption(DomainnameOption):
|
class EmailOption(DomainnameOption):
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
username_re = re.compile(r"^[\w!#$%&'*+\-/=?^`{|}~.]+$")
|
username_re = re.compile(r"^[\w!#$%&'*+\-/=?^`{|}~.]+$")
|
||||||
display_name = _('email address')
|
_display_name = _('email address')
|
||||||
|
|
||||||
def _validate(self, value, context=undefined, current_opt=undefined,
|
def _validate(self, value, context=undefined, current_opt=undefined,
|
||||||
returns_raise=False):
|
returns_raise=False):
|
||||||
|
@ -595,7 +588,7 @@ class URLOption(DomainnameOption):
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
proto_re = re.compile(r'(http|https)://')
|
proto_re = re.compile(r'(http|https)://')
|
||||||
path_re = re.compile(r"^[A-Za-z0-9\-\._~:/\?#\[\]@!%\$&\'\(\)\*\+,;=]+$")
|
path_re = re.compile(r"^[A-Za-z0-9\-\._~:/\?#\[\]@!%\$&\'\(\)\*\+,;=]+$")
|
||||||
display_name = _('URL')
|
_display_name = _('URL')
|
||||||
|
|
||||||
def _validate(self, value, context=undefined, current_opt=undefined,
|
def _validate(self, value, context=undefined, current_opt=undefined,
|
||||||
returns_raise=False):
|
returns_raise=False):
|
||||||
|
@ -643,7 +636,7 @@ class UsernameOption(Option):
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
#regexp build with 'man 8 adduser' informations
|
#regexp build with 'man 8 adduser' informations
|
||||||
username_re = re.compile(r"^[a-z_][a-z0-9_-]{0,30}[$a-z0-9_-]{0,1}$")
|
username_re = re.compile(r"^[a-z_][a-z0-9_-]{0,30}[$a-z0-9_-]{0,1}$")
|
||||||
display_name = _('username')
|
_display_name = _('username')
|
||||||
|
|
||||||
def _validate(self, value, context=undefined, current_opt=undefined,
|
def _validate(self, value, context=undefined, current_opt=undefined,
|
||||||
returns_raise=False):
|
returns_raise=False):
|
||||||
|
@ -658,7 +651,7 @@ class UsernameOption(Option):
|
||||||
class FilenameOption(Option):
|
class FilenameOption(Option):
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
path_re = re.compile(r"^[a-zA-Z0-9\-\._~/+]+$")
|
path_re = re.compile(r"^[a-zA-Z0-9\-\._~/+]+$")
|
||||||
display_name = _('file name')
|
_display_name = _('file name')
|
||||||
|
|
||||||
def _validate(self, value, context=undefined, current_opt=undefined,
|
def _validate(self, value, context=undefined, current_opt=undefined,
|
||||||
returns_raise=False):
|
returns_raise=False):
|
||||||
|
|
|
@ -165,7 +165,7 @@ class StorageBase(object):
|
||||||
val_call = tuple([callback, callback_params])
|
val_call = tuple([callback, callback_params])
|
||||||
self._val_call = (val, val_call)
|
self._val_call = (val, val_call)
|
||||||
|
|
||||||
def impl_set_choice_values_params(self, values, values_params):
|
def impl_set_choice_values_params(self, values, values_params, session):
|
||||||
self._choice_values = values
|
self._choice_values = values
|
||||||
if values_params is not None:
|
if values_params is not None:
|
||||||
self._choice_values_params = values_params
|
self._choice_values_params = values_params
|
||||||
|
|
|
@ -129,14 +129,14 @@ class _PropertyOption(SqlAlchemyBase):
|
||||||
class _Information(SqlAlchemyBase):
|
class _Information(SqlAlchemyBase):
|
||||||
__tablename__ = 'information'
|
__tablename__ = 'information'
|
||||||
id = Column(Integer, primary_key=True)
|
id = Column(Integer, primary_key=True)
|
||||||
option = Column(String, index=True, nullable=False)
|
option = Column(String, ForeignKey('baseoption.id'), nullable=False)
|
||||||
key = Column(String)
|
key = Column(String)
|
||||||
value = Column(PickleType)
|
value = Column(PickleType)
|
||||||
|
|
||||||
def __init__(self, option, key, value):
|
# def __init__(self, option, key, value):
|
||||||
self.option = option
|
# self.option = option
|
||||||
self.key = key
|
# self.key = key
|
||||||
self.value = value
|
# self.value = value
|
||||||
|
|
||||||
|
|
||||||
#____________________________________________________________
|
#____________________________________________________________
|
||||||
|
@ -392,6 +392,7 @@ class _Base(SqlAlchemyBase):
|
||||||
# collection_class=attribute_mapped_collection('key'),
|
# collection_class=attribute_mapped_collection('key'),
|
||||||
# cascade="all, delete-orphan")
|
# cascade="all, delete-orphan")
|
||||||
# _informations = association_proxy("_infos", "value")
|
# _informations = association_proxy("_infos", "value")
|
||||||
|
_informations = relationship("_Information")
|
||||||
_default = Column(PickleType)
|
_default = Column(PickleType)
|
||||||
_default_multi = Column(PickleType)
|
_default_multi = Column(PickleType)
|
||||||
_subdyn = Column(Integer)
|
_subdyn = Column(Integer)
|
||||||
|
@ -450,7 +451,8 @@ class _Base(SqlAlchemyBase):
|
||||||
if allow_empty_list is not undefined:
|
if allow_empty_list is not undefined:
|
||||||
self._allow_empty_list = allow_empty_list
|
self._allow_empty_list = allow_empty_list
|
||||||
if doc is not undefined:
|
if doc is not undefined:
|
||||||
self._informations = {'doc': doc}
|
self._informations = [_Information(key='doc', value=doc)]
|
||||||
|
#self._informations = {'doc': doc}
|
||||||
if opt is not undefined:
|
if opt is not undefined:
|
||||||
self._opt = opt.id
|
self._opt = opt.id
|
||||||
if extra is not undefined:
|
if extra is not undefined:
|
||||||
|
@ -489,10 +491,14 @@ class _Base(SqlAlchemyBase):
|
||||||
return self.id
|
return self.id
|
||||||
|
|
||||||
def impl_get_callback(self):
|
def impl_get_callback(self):
|
||||||
|
a=self.getsession().query(_Base).filter_by(id=self.id).first()
|
||||||
ret = self._callback
|
ret = self._callback
|
||||||
if ret is None:
|
if ret is None:
|
||||||
return (None, {})
|
return (None, {})
|
||||||
return ret, self._callback_params
|
params = self._callback_params
|
||||||
|
if params is None:
|
||||||
|
params = {}
|
||||||
|
return ret, params
|
||||||
|
|
||||||
def impl_get_validator(self):
|
def impl_get_validator(self):
|
||||||
ret = self._validator
|
ret = self._validator
|
||||||
|
@ -559,7 +565,13 @@ class _Base(SqlAlchemyBase):
|
||||||
def _set_callback(self, callback, callback_params):
|
def _set_callback(self, callback, callback_params):
|
||||||
self._callback = callback
|
self._callback = callback
|
||||||
if callback_params is not None:
|
if callback_params is not None:
|
||||||
self._callback_params = callback_params
|
opt._callback_params = callback_params
|
||||||
|
#session = self.getsession()
|
||||||
|
#opt = session.query(_Base).filter_by(id=self.id).first()
|
||||||
|
#opt._callback = callback
|
||||||
|
#if callback_params is not None:
|
||||||
|
# opt._callback_params = callback_params
|
||||||
|
#session.commit()
|
||||||
|
|
||||||
def impl_set_choice_values_params(self, values, values_params, session):
|
def impl_set_choice_values_params(self, values, values_params, session):
|
||||||
self._choice_values = values
|
self._choice_values = values
|
||||||
|
@ -632,11 +644,10 @@ class _Base(SqlAlchemyBase):
|
||||||
# information
|
# information
|
||||||
def impl_set_information(self, key, value):
|
def impl_set_information(self, key, value):
|
||||||
session = self.getsession()
|
session = self.getsession()
|
||||||
# self._informations[key] = value
|
|
||||||
val = session.query(_Information).filter_by(
|
val = session.query(_Information).filter_by(
|
||||||
option=self.id, key=key).first()
|
option=self.id, key=key).first()
|
||||||
if val is None:
|
if val is None:
|
||||||
session.add(_Information(self.id, key, value))
|
session.add(_Information(self, key, value))
|
||||||
else:
|
else:
|
||||||
val.value = value
|
val.value = value
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
|
@ -771,11 +771,13 @@ class Multi(list):
|
||||||
raise value
|
raise value
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def _get_validated_value(self, index):
|
def _getdefaultvalue(self, index):
|
||||||
values = self._getcontext().cfgimpl_get_values()
|
values = self._getcontext().cfgimpl_get_values()
|
||||||
return values._get_validated_value(self.opt, self.path,
|
value = values._getdefaultvalue(self.opt, self.path, True, index,
|
||||||
True, False, True,
|
undefined, True)
|
||||||
index=index)
|
if self.opt.impl_is_submulti():
|
||||||
|
value = SubMulti(value, self.context, self.opt, self.path, index)
|
||||||
|
return value
|
||||||
|
|
||||||
def append(self, value=undefined, force=False, setitem=True, validate=True,
|
def append(self, value=undefined, force=False, setitem=True, validate=True,
|
||||||
force_permissive=False):
|
force_permissive=False):
|
||||||
|
@ -787,7 +789,7 @@ class Multi(list):
|
||||||
" which is a slave").format(self.opt.impl_getname()))
|
" which is a slave").format(self.opt.impl_getname()))
|
||||||
index = self.__len__()
|
index = self.__len__()
|
||||||
if value is undefined:
|
if value is undefined:
|
||||||
value = self._get_validated_value(index)
|
value = self._getdefaultvalue(index)
|
||||||
if validate and value not in [None, undefined]:
|
if validate and value not in [None, undefined]:
|
||||||
context = self._getcontext()
|
context = self._getcontext()
|
||||||
setting = context.cfgimpl_get_settings()
|
setting = context.cfgimpl_get_settings()
|
||||||
|
@ -943,9 +945,7 @@ class SubMulti(Multi):
|
||||||
if err:
|
if err:
|
||||||
raise err
|
raise err
|
||||||
|
|
||||||
def _get_validated_value(self, index):
|
def _getdefaultvalue(self, index):
|
||||||
values = self._getcontext().cfgimpl_get_values()
|
values = self._getcontext().cfgimpl_get_values()
|
||||||
return values._get_validated_value(self.opt, self.path,
|
return values._getdefaultvalue(self.opt, self.path, True, index,
|
||||||
True, False, True,
|
self._index, True)
|
||||||
index=index,
|
|
||||||
submulti_index=self._index)
|
|
||||||
|
|
Loading…
Reference in a new issue