reorganise Base and Option

This commit is contained in:
Emmanuel Garette 2017-07-24 18:27:24 +02:00
parent 1d251374a1
commit 32252e619b
4 changed files with 129 additions and 103 deletions

View file

@ -654,8 +654,8 @@ def test_meta_properties_meta_set_value():
ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1'])
netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, properties=('disabled',)) netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, properties=('disabled',))
interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
conf1 = Config(interface1, session_id='conf1') conf1 = Config(interface1, session_id='conf20')
conf2 = Config(interface1, session_id='conf2') conf2 = Config(interface1, session_id='conf21')
meta = MetaConfig([conf1, conf2]) meta = MetaConfig([conf1, conf2])
meta.read_write() meta.read_write()
assert conf1.make_dict() == {'ip_admin_eth0': ['192.168.1.1']} assert conf1.make_dict() == {'ip_admin_eth0': ['192.168.1.1']}
@ -694,26 +694,26 @@ def test_meta_reset():
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',))
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)
conf1 = Config(interface1, session_id='conf1') conf22 = Config(interface1, session_id='conf22')
conf1.read_write() conf22.read_write()
conf2 = Config(interface1, session_id='conf2') conf23 = Config(interface1, session_id='conf23')
conf2.read_write() conf23.read_write()
meta = MetaConfig([conf1, conf2]) meta = MetaConfig([conf22, conf23])
meta.read_write() meta.read_write()
meta.cfgimpl_get_settings().setowner(owners.meta) meta.cfgimpl_get_settings().setowner(owners.meta)
assert meta.ip_admin_eth0 == [] assert meta.ip_admin_eth0 == []
assert meta.conf1.ip_admin_eth0 == [] assert meta.conf22.ip_admin_eth0 == []
assert meta.conf2.ip_admin_eth0 == [] assert meta.conf23.ip_admin_eth0 == []
errors = meta.set_value('ip_admin_eth0', ['192.168.1.1']) errors = meta.set_value('ip_admin_eth0', ['192.168.1.1'])
assert len(errors) == 0 assert len(errors) == 0
assert meta.ip_admin_eth0 == ['192.168.1.1'] assert meta.ip_admin_eth0 == ['192.168.1.1']
assert meta.conf1.ip_admin_eth0 == ['192.168.1.1'] assert meta.conf22.ip_admin_eth0 == ['192.168.1.1']
assert meta.conf2.ip_admin_eth0 == ['192.168.1.1'] assert meta.conf23.ip_admin_eth0 == ['192.168.1.1']
meta.conf1.ip_admin_eth0 = ['192.168.1.2'] meta.conf22.ip_admin_eth0 = ['192.168.1.2']
assert meta.ip_admin_eth0 == ['192.168.1.1'] assert meta.ip_admin_eth0 == ['192.168.1.1']
assert meta.conf1.ip_admin_eth0 == ['192.168.1.2'] assert meta.conf22.ip_admin_eth0 == ['192.168.1.2']
assert meta.conf2.ip_admin_eth0 == ['192.168.1.1'] assert meta.conf23.ip_admin_eth0 == ['192.168.1.1']
meta.reset('ip_admin_eth0') meta.reset('ip_admin_eth0')
assert meta.ip_admin_eth0 == [] assert meta.ip_admin_eth0 == []
assert meta.conf1.ip_admin_eth0 == [] assert meta.conf22.ip_admin_eth0 == []
assert meta.conf2.ip_admin_eth0 == [] assert meta.conf23.ip_admin_eth0 == []

View file

@ -468,6 +468,26 @@ def test_values_with_master_and_slaves_slave():
assert cfg.ip_admin_eth0.netmask_admin_eth0 == [] assert cfg.ip_admin_eth0.netmask_admin_eth0 == []
def test_values_with_master_and_slaves_pop():
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
interface1.impl_set_group_type(groups.master)
maconfig = OptionDescription('toto', '', [interface1])
cfg = Config(maconfig)
cfg.read_write()
assert cfg.ip_admin_eth0.netmask_admin_eth0 == []
cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.145")
cfg.ip_admin_eth0.netmask_admin_eth0 = ['255.255.255.0']
cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.146")
cfg.ip_admin_eth0.netmask_admin_eth0[1] = '255.255.0.0'
assert cfg.ip_admin_eth0.ip_admin_eth0 == ['192.168.230.145', '192.168.230.146']
assert cfg.ip_admin_eth0.netmask_admin_eth0 == ['255.255.255.0', '255.255.0.0']
cfg.ip_admin_eth0.ip_admin_eth0.pop(0)
assert cfg.ip_admin_eth0.ip_admin_eth0 == ['192.168.230.146']
assert cfg.ip_admin_eth0.netmask_admin_eth0 == ['255.255.0.0']
def test_values_with_master_and_slaves_master(): def test_values_with_master_and_slaves_master():
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True) ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)

View file

@ -118,59 +118,26 @@ def validate_callback(callback, callback_params, type_, callbackoption):
#____________________________________________________________ #____________________________________________________________
# #
class Base(object): class Base(object):
"""Base use by all *Option* classes (Option, OptionDescription, SymLinkOption, ...)
"""
__slots__ = ('_name', __slots__ = ('_name',
'_informations', '_informations',
'_extra',
'_warnings_only',
'_allow_empty_list',
#multi
'_multi',
'_unique',
#value
'_default',
'_default_multi',
#calcul #calcul
'_subdyn', '_subdyn',
'_requires', '_requires',
'_properties', '_properties',
'_calc_properties', '_calc_properties',
'_val_call',
# #
'_consistencies', '_consistencies',
'_master_slaves',
'_choice_values',
'_choice_values_params',
#other #other
'_has_dependency', '_has_dependency',
'_dependencies', '_dependencies',
'__weakref__' '__weakref__'
) )
def __init__(self, name, doc, default=None, default_multi=None, def __init__(self, name, doc, requires=None, properties=None, is_multi=False):
requires=None, multi=False, unique=undefined, callback=None,
callback_params=None, validator=None, validator_params=None,
properties=None, warnings_only=False, extra=None,
allow_empty_list=undefined):
if not valid_name(name): if not valid_name(name):
raise ValueError(_("invalid name: {0} for option").format(name)) raise ValueError(_("invalid name: {0} for option").format(name))
if not multi and default_multi is not None:
raise ValueError(_("default_multi is set whereas multi is False"
" in option: {0}").format(name))
if multi is True:
is_multi = True
_multi = 0
elif multi is False:
is_multi = False
_multi = 1
elif multi is submulti:
is_multi = True
_multi = submulti
else:
raise ValueError(_('invalid multi value'))
if unique != undefined and not isinstance(unique, bool):
raise ValueError(_('unique must be a boolean'))
if not is_multi and unique is True:
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(self, is_multi, calc_properties, requires = validate_requires_arg(self, is_multi,
requires, name) requires, name)
@ -184,17 +151,6 @@ class Base(object):
' must be a tuple').format( ' must be a tuple').format(
type(properties), type(properties),
name)) name))
if validator is not None:
if multi: # and validator_params is None:
validator_params = self._build_validator_params(validator, validator_params)
validate_callback(validator, validator_params, 'validator', self)
if validator_params is None:
val_call = (validator,)
else:
val_call = (validator, validator_params)
self._val_call = (val_call, None)
self._set_has_dependency()
if calc_properties != frozenset([]) and properties is not tuple(): if calc_properties != frozenset([]) and properties is not tuple():
set_forbidden_properties = calc_properties & set(properties) set_forbidden_properties = calc_properties & set(properties)
if set_forbidden_properties != frozenset(): if set_forbidden_properties != frozenset():
@ -205,46 +161,13 @@ class Base(object):
_setattr(self, '_name', name) _setattr(self, '_name', name)
if sys.version_info[0] < 3 and isinstance(doc, str): if sys.version_info[0] < 3 and isinstance(doc, str):
doc = doc.decode('utf8') doc = doc.decode('utf8')
if extra is not None:
_setattr(self, '_extra', extra)
_setattr(self, '_informations', {'doc': doc}) _setattr(self, '_informations', {'doc': doc})
if _multi != 1:
_setattr(self, '_multi', _multi)
if warnings_only is True:
_setattr(self, '_warnings_only', warnings_only)
if calc_properties is not undefined: if calc_properties is not undefined:
_setattr(self, '_calc_properties', calc_properties) _setattr(self, '_calc_properties', calc_properties)
if requires is not undefined: if requires is not undefined:
_setattr(self, '_requires', requires) _setattr(self, '_requires', requires)
if properties is not undefined: if properties is not undefined:
_setattr(self, '_properties', properties) _setattr(self, '_properties', properties)
if multi is not False and default is None:
default = []
if allow_empty_list is not undefined:
_setattr(self, '_allow_empty_list', allow_empty_list)
if unique is not undefined:
_setattr(self, '_unique', unique)
err = self.impl_validate(default, is_multi=is_multi)
if err:
raise err
if (is_multi and default != []) or \
(not is_multi and default is not None):
if is_multi:
default = tuple(default)
_setattr(self, '_default', default)
if is_multi and default_multi is not None:
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)))
_setattr(self, '_default_multi', default_multi)
##callback is False in optiondescription
if callback is not False:
self.impl_set_callback(callback, callback_params, _init=True)
def _build_validator_params(self, validator, validator_params): def _build_validator_params(self, validator, validator_params):
if sys.version_info[0] < 3: if sys.version_info[0] < 3:
@ -290,10 +213,10 @@ class Base(object):
def impl_set_callback(self, callback, callback_params=None, _init=False): def impl_set_callback(self, callback, callback_params=None, _init=False):
if callback is None and callback_params is not None: if callback is None and callback_params is not None:
raise ValueError(_("params defined for a callback function but " raise ValueError(_("params defined for a callback function but "
"no callback defined" "no callback defined"
" yet for option {0}").format( " yet for option {0}").format(
self.impl_getname())) self.impl_getname()))
if not _init and self.impl_get_callback()[0] is not None: if not _init and self.impl_get_callback()[0] is not None:
raise ConfigError(_("a callback is already set for {0}, " raise ConfigError(_("a callback is already set for {0}, "
"cannot set another one's").format(self.impl_getname())) "cannot set another one's").format(self.impl_getname()))
@ -487,8 +410,92 @@ class Option(OnlyOption):
Reminder: an Option object is **not** a container for the value. Reminder: an Option object is **not** a container for the value.
""" """
__slots__ = tuple() __slots__ = ('_extra',
'_warnings_only',
'_allow_empty_list',
#multi
'_multi',
'_unique',
#value
'_default',
'_default_multi',
#calcul
'_val_call',
#
'_master_slaves',
'_choice_values',
'_choice_values_params',
)
_empty = '' _empty = ''
def __init__(self, name, doc, default=None, default_multi=None,
requires=None, multi=False, unique=undefined, callback=None,
callback_params=None, validator=None, validator_params=None,
properties=None, warnings_only=False, extra=None,
allow_empty_list=undefined):
_setattr = object.__setattr__
if not multi and default_multi is not None:
raise ValueError(_("default_multi is set whereas multi is False"
" in option: {0}").format(name))
if multi is True:
is_multi = True
_multi = 0
elif multi is False:
is_multi = False
_multi = 1
elif multi is submulti:
is_multi = True
_multi = submulti
else:
raise ValueError(_('invalid multi value'))
if _multi != 1:
_setattr(self, '_multi', _multi)
if multi is not False and default is None:
default = []
if validator is not None:
if multi: # and validator_params is None:
validator_params = self._build_validator_params(validator, validator_params)
validate_callback(validator, validator_params, 'validator', self)
if validator_params is None:
val_call = (validator,)
else:
val_call = (validator, validator_params)
self._val_call = (val_call, None)
self._set_has_dependency()
if extra is not None:
_setattr(self, '_extra', extra)
if unique != undefined and not isinstance(unique, bool):
raise ValueError(_('unique must be a boolean'))
if not is_multi and unique is True:
raise ValueError(_('unique must be set only with multi value'))
if warnings_only is True:
_setattr(self, '_warnings_only', warnings_only)
if allow_empty_list is not undefined:
_setattr(self, '_allow_empty_list', allow_empty_list)
super(Option, self).__init__(name, doc, requires=requires,
properties=properties, is_multi=is_multi)
if is_multi and default_multi is not None:
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)))
_setattr(self, '_default_multi', default_multi)
if unique is not undefined:
_setattr(self, '_unique', unique)
err = self.impl_validate(default, is_multi=is_multi)
if err:
raise err
if (is_multi and default != []) or \
(not is_multi and default is not None):
if is_multi:
default = tuple(default)
_setattr(self, '_default', default)
self.impl_set_callback(callback, callback_params, _init=True)
def impl_is_multi(self): def impl_is_multi(self):
return getattr(self, '_multi', 1) != 1 return getattr(self, '_multi', 1) != 1

View file

@ -406,8 +406,7 @@ class OptionDescription(OptionDescriptionWalk):
""" """
super(OptionDescription, self).__init__(name, doc=doc, super(OptionDescription, self).__init__(name, doc=doc,
requires=requires, requires=requires,
properties=properties, properties=properties)
callback=False)
child_names = [] child_names = []
dynopt_names = [] dynopt_names = []
for child in children: for child in children: