value None in multi values
This commit is contained in:
parent
3780b6f947
commit
4ec7dff6c4
5 changed files with 58 additions and 27 deletions
19
config.py
19
config.py
|
@ -74,7 +74,8 @@ class Config(object):
|
||||||
self._cfgimpl_value_owners[child._name] = 'fill'
|
self._cfgimpl_value_owners[child._name] = 'fill'
|
||||||
else:
|
else:
|
||||||
if child.is_multi():
|
if child.is_multi():
|
||||||
self._cfgimpl_value_owners[child._name] = ['default']
|
self._cfgimpl_value_owners[child._name] = ['default' \
|
||||||
|
for i in range(len(child.getdefault() ))]
|
||||||
else:
|
else:
|
||||||
self._cfgimpl_value_owners[child._name] = 'default'
|
self._cfgimpl_value_owners[child._name] = 'default'
|
||||||
elif isinstance(child, OptionDescription):
|
elif isinstance(child, OptionDescription):
|
||||||
|
@ -197,7 +198,6 @@ class Config(object):
|
||||||
(self.__class__, name))
|
(self.__class__, name))
|
||||||
if name in self._cfgimpl_value_owners:
|
if name in self._cfgimpl_value_owners:
|
||||||
owner = self._cfgimpl_value_owners[name]
|
owner = self._cfgimpl_value_owners[name]
|
||||||
# special owners
|
|
||||||
if owner in special_owners:
|
if owner in special_owners:
|
||||||
value = self._cfgimpl_values[name]
|
value = self._cfgimpl_values[name]
|
||||||
if value != None:
|
if value != None:
|
||||||
|
@ -214,16 +214,14 @@ class Config(object):
|
||||||
config=self._cfgimpl_get_toplevel())
|
config=self._cfgimpl_get_toplevel())
|
||||||
# this result **shall not** be a list
|
# this result **shall not** be a list
|
||||||
# for example, [1, 2, 3, None] -> [1, 2, 3, result]
|
# for example, [1, 2, 3, None] -> [1, 2, 3, result]
|
||||||
#
|
|
||||||
if type(result) == list:
|
if type(result) == list:
|
||||||
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))
|
||||||
if result != None and not opt_or_descr._validate(result):
|
if result != None and not opt_or_descr._validate(result):
|
||||||
raise ConfigError('invalid calculated value returned'
|
raise ConfigError('invalid calculated value returned'
|
||||||
' for option {0}'.format(name))
|
' for option {0}'.format(name))
|
||||||
|
|
||||||
if opt_or_descr.is_multi():
|
if opt_or_descr.is_multi():
|
||||||
if value == None:
|
if value == []:
|
||||||
_result = [result]
|
_result = [result]
|
||||||
else:
|
else:
|
||||||
_result = []
|
_result = []
|
||||||
|
@ -243,6 +241,17 @@ class Config(object):
|
||||||
and opt_or_descr.getdefault() == None:
|
and opt_or_descr.getdefault() == None:
|
||||||
raise MandatoryError("option: {0} is mandatory "
|
raise MandatoryError("option: {0} is mandatory "
|
||||||
"and shall have a value".format(name))
|
"and shall have a value".format(name))
|
||||||
|
# for multi types with None in the value (ex: ["egg", None, "spam"])
|
||||||
|
# None is replaced by default_multi
|
||||||
|
if not isinstance(opt_or_descr, OptionDescription):
|
||||||
|
if opt_or_descr.is_multi() and None in self._cfgimpl_values[name]:
|
||||||
|
newvalue = []
|
||||||
|
for val in self._cfgimpl_values[name]:
|
||||||
|
if val is None:
|
||||||
|
newvalue.append(opt_or_descr.default_multi)
|
||||||
|
else:
|
||||||
|
newvalue.append(val)
|
||||||
|
return newvalue
|
||||||
return self._cfgimpl_values[name]
|
return self._cfgimpl_values[name]
|
||||||
|
|
||||||
def __dir__(self):
|
def __dir__(self):
|
||||||
|
|
21
option.py
21
option.py
|
@ -45,9 +45,15 @@ class Option(HiddenBaseType, DisabledBaseType, ModeBaseType):
|
||||||
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))
|
||||||
|
if default_multi is not None and not self._validate(default_multi):
|
||||||
|
raise ConfigError("invalid default_multi value {0} "
|
||||||
|
"for option {1}".format(str(default_multi), name))
|
||||||
self.default_multi = default_multi
|
self.default_multi = default_multi
|
||||||
#if self.multi and default_multi is None:
|
#if self.multi and default_multi is None:
|
||||||
# _cfgimpl_warnings[name] = DefaultMultiWarning
|
# _cfgimpl_warnings[name] = DefaultMultiWarning
|
||||||
|
if callback is not None and (default is not None or default_multi is not None):
|
||||||
|
raise ConfigError("defaut values not allowed if option: {0}"
|
||||||
|
"is calculated".format(name))
|
||||||
self.callback = callback
|
self.callback = callback
|
||||||
if self.callback is None and callback_params is not None:
|
if self.callback is None and callback_params is not None:
|
||||||
raise ConfigError("params defined for a callback function but"
|
raise ConfigError("params defined for a callback function but"
|
||||||
|
@ -56,15 +62,17 @@ class Option(HiddenBaseType, DisabledBaseType, ModeBaseType):
|
||||||
if mode not in modes:
|
if mode not in modes:
|
||||||
raise ConfigError("mode {0} not available".format(mode))
|
raise ConfigError("mode {0} not available".format(mode))
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
_default = default
|
if self.multi == True:
|
||||||
if default != None:
|
if default == None:
|
||||||
if self.multi == True and type(default) != list:
|
default = []
|
||||||
|
if type(default) != list or not self.validate(default):
|
||||||
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):
|
else:
|
||||||
|
if default != None and not self.validate(default):
|
||||||
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
|
||||||
|
|
||||||
def validate(self, value):
|
def validate(self, value):
|
||||||
if self.multi == False:
|
if self.multi == False:
|
||||||
|
@ -79,7 +87,8 @@ class Option(HiddenBaseType, DisabledBaseType, ModeBaseType):
|
||||||
for val in value:
|
for val in value:
|
||||||
if val != None:
|
if val != None:
|
||||||
# None allows the reset of the value
|
# None allows the reset of the value
|
||||||
return self._validate(val)
|
if not self._validate(val):
|
||||||
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def getdefault(self):
|
def getdefault(self):
|
||||||
|
|
|
@ -7,7 +7,7 @@ from error import SpecialOwnersError
|
||||||
|
|
||||||
def make_description():
|
def make_description():
|
||||||
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
||||||
gcdummy = BoolOption('dummy', 'dummy', default=False, callback="toto")
|
gcdummy = BoolOption('dummy', 'dummy', callback="toto")
|
||||||
objspaceoption = ChoiceOption('objspace', 'Object space',
|
objspaceoption = ChoiceOption('objspace', 'Object space',
|
||||||
['std', 'thunk'], 'std')
|
['std', 'thunk'], 'std')
|
||||||
booloption = BoolOption('bool', 'Test boolean option', default=True)
|
booloption = BoolOption('bool', 'Test boolean option', default=True)
|
||||||
|
@ -75,15 +75,15 @@ def test_change_owner():
|
||||||
# Still not getting it ? read the docs
|
# Still not getting it ? read the docs
|
||||||
config.gc.dummy = True
|
config.gc.dummy = True
|
||||||
assert config.gc._cfgimpl_value_owners['dummy'] == 'user'
|
assert config.gc._cfgimpl_value_owners['dummy'] == 'user'
|
||||||
config.cfgimpl_set_owner('eggs')
|
# config.cfgimpl_set_owner('eggs')
|
||||||
config.set(dummy=False)
|
# config.set(dummy=False)
|
||||||
assert config.gc._cfgimpl_value_owners['dummy'] == 'eggs'
|
# assert config.gc._cfgimpl_value_owners['dummy'] == 'eggs'
|
||||||
config.cfgimpl_set_owner('spam')
|
# config.cfgimpl_set_owner('spam')
|
||||||
gcdummy = config.unwrap_from_path('gc.dummy')
|
# gcdummy = config.unwrap_from_path('gc.dummy')
|
||||||
gcdummy.setowner(config.gc, 'blabla')
|
# gcdummy.setowner(config.gc, 'blabla')
|
||||||
assert config.gc._cfgimpl_value_owners['dummy'] == 'blabla'
|
# assert config.gc._cfgimpl_value_owners['dummy'] == 'blabla'
|
||||||
config.gc.dummy = True
|
# config.gc.dummy = True
|
||||||
assert config.gc._cfgimpl_value_owners['dummy'] == 'spam'
|
# assert config.gc._cfgimpl_value_owners['dummy'] == 'spam'
|
||||||
|
|
||||||
#____________________________________________________________
|
#____________________________________________________________
|
||||||
# special owners
|
# special owners
|
||||||
|
|
|
@ -37,11 +37,13 @@ def test_attribute_access():
|
||||||
assert config.string == "foo"
|
assert config.string == "foo"
|
||||||
|
|
||||||
def test_setitem():
|
def test_setitem():
|
||||||
s = StrOption("string", "", default=["string"], multi=True)
|
s = StrOption("string", "", default=["string", None, "sdfsdf"], default_multi="prout", multi=True)
|
||||||
descr = OptionDescription("options", "", [s])
|
descr = OptionDescription("options", "", [s])
|
||||||
config = Config(descr)
|
config = Config(descr)
|
||||||
config.string = ["foo", "eggs"]
|
config._cfgimpl_values['string'].append("eggs")
|
||||||
|
# config.string = ["string"].append("eggs")
|
||||||
|
print config.string
|
||||||
|
# config.string[1] = "titi"
|
||||||
|
|
||||||
def test_reset():
|
def test_reset():
|
||||||
"if value is None, resets to default owner"
|
"if value is None, resets to default owner"
|
||||||
|
@ -69,6 +71,17 @@ def test_reset_with_multi():
|
||||||
assert config._cfgimpl_value_owners['string'] == ['default']
|
assert config._cfgimpl_value_owners['string'] == ['default']
|
||||||
raises(ConfigError, "config.string = None")
|
raises(ConfigError, "config.string = None")
|
||||||
|
|
||||||
|
def test_default_with_multi():
|
||||||
|
"default with multi is a list"
|
||||||
|
s = StrOption("string", "", default=[], default_multi="string" , multi=True)
|
||||||
|
descr = OptionDescription("options", "", [s])
|
||||||
|
config = Config(descr)
|
||||||
|
assert config.string == []
|
||||||
|
s = StrOption("string", "", default=None, default_multi="string" , multi=True)
|
||||||
|
descr = OptionDescription("options", "", [s])
|
||||||
|
config = Config(descr)
|
||||||
|
assert config.string == []
|
||||||
|
|
||||||
def test_idontexist():
|
def test_idontexist():
|
||||||
descr = make_description()
|
descr = make_description()
|
||||||
cfg = Config(descr)
|
cfg = Config(descr)
|
||||||
|
|
|
@ -41,12 +41,12 @@ def test_base_config():
|
||||||
assert config.creole.general.nom_machine == "eoleng"
|
assert config.creole.general.nom_machine == "eoleng"
|
||||||
assert config.get('nom_machine') == "eoleng"
|
assert config.get('nom_machine') == "eoleng"
|
||||||
result = {'general.numero_etab': None, 'general.nombre_interfaces': 1,
|
result = {'general.numero_etab': None, 'general.nombre_interfaces': 1,
|
||||||
'general.serveur_ntp': None, 'interface1.ip_admin_eth0.ip_admin_eth0': None,
|
'general.serveur_ntp': [], 'interface1.ip_admin_eth0.ip_admin_eth0': None,
|
||||||
'general.mode_conteneur_actif': False, 'general.time_zone': 'Paris',
|
'general.mode_conteneur_actif': False, 'general.time_zone': 'Paris',
|
||||||
'interface1.ip_admin_eth0.netmask_admin_eth0': None, 'general.nom_machine':
|
'interface1.ip_admin_eth0.netmask_admin_eth0': None, 'general.nom_machine':
|
||||||
'eoleng', 'general.activer_proxy_client': False}
|
'eoleng', 'general.activer_proxy_client': False}
|
||||||
assert make_dict(config.creole) == result
|
assert make_dict(config.creole) == result
|
||||||
result = {'serveur_ntp': None, 'mode_conteneur_actif': False,
|
result = {'serveur_ntp': [], 'mode_conteneur_actif': False,
|
||||||
'ip_admin_eth0': None, 'time_zone': 'Paris', 'numero_etab': None,
|
'ip_admin_eth0': None, 'time_zone': 'Paris', 'numero_etab': None,
|
||||||
'netmask_admin_eth0': None, 'nom_machine': 'eoleng', 'activer_proxy_client':
|
'netmask_admin_eth0': None, 'nom_machine': 'eoleng', 'activer_proxy_client':
|
||||||
False, 'nombre_interfaces': 1}
|
False, 'nombre_interfaces': 1}
|
||||||
|
|
Loading…
Reference in a new issue