for a multi mandatory, allow [] with allow_empty_list attribut
This commit is contained in:
parent
072246a203
commit
487b99b32c
6 changed files with 73 additions and 14 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
Mon Apr 20 14:44:15 2015 +0200 Emmanuel Garette <egarette@cadoles.com>
|
||||||
|
* if option is multi, the properties disallow [None] for a multi but
|
||||||
|
[] too, with allow_empty_list to True, [None] is not allowed, but you
|
||||||
|
can have empty list (so [])
|
||||||
|
|
||||||
|
|
||||||
Sun Apr 19 09:14:21 2015 +0200 Emmanuel Garette <egarette@cadoles.com>
|
Sun Apr 19 09:14:21 2015 +0200 Emmanuel Garette <egarette@cadoles.com>
|
||||||
* valid Option is an unicode or a string if needed
|
* valid Option is an unicode or a string if needed
|
||||||
* difference between option/optiondescription in PropertiesOptionError
|
* difference between option/optiondescription in PropertiesOptionError
|
||||||
|
|
|
@ -16,7 +16,9 @@ def make_description():
|
||||||
properties=('mandatory', ))
|
properties=('mandatory', ))
|
||||||
stroption3 = StrOption('str3', 'Test string option', multi=True,
|
stroption3 = StrOption('str3', 'Test string option', multi=True,
|
||||||
properties=('mandatory', ))
|
properties=('mandatory', ))
|
||||||
descr = OptionDescription('tiram', '', [stroption, stroption1, stroption2, stroption3])
|
stroption4 = StrOption('str4', 'Test string option', multi=True,
|
||||||
|
properties=('mandatory', ), allow_empty_list=True)
|
||||||
|
descr = OptionDescription('tiram', '', [stroption, stroption1, stroption2, stroption3, stroption4])
|
||||||
return descr
|
return descr
|
||||||
|
|
||||||
|
|
||||||
|
@ -123,6 +125,17 @@ def test_mandatory_multi_none():
|
||||||
def test_mandatory_multi_empty():
|
def test_mandatory_multi_empty():
|
||||||
descr = make_description()
|
descr = make_description()
|
||||||
config = Config(descr)
|
config = Config(descr)
|
||||||
|
config.str3 = []
|
||||||
|
assert config.getowner(config.unwrap_from_path('str3')) == 'user'
|
||||||
|
config.read_only()
|
||||||
|
prop = []
|
||||||
|
try:
|
||||||
|
config.str3
|
||||||
|
except PropertiesOptionError as err:
|
||||||
|
prop = err.proptype
|
||||||
|
assert 'mandatory' in prop
|
||||||
|
#
|
||||||
|
config.read_write()
|
||||||
config.str3 = ['']
|
config.str3 = ['']
|
||||||
assert config.getowner(config.unwrap_from_path('str3')) == 'user'
|
assert config.getowner(config.unwrap_from_path('str3')) == 'user'
|
||||||
config.read_only()
|
config.read_only()
|
||||||
|
@ -132,6 +145,7 @@ def test_mandatory_multi_empty():
|
||||||
except PropertiesOptionError as err:
|
except PropertiesOptionError as err:
|
||||||
prop = err.proptype
|
prop = err.proptype
|
||||||
assert 'mandatory' in prop
|
assert 'mandatory' in prop
|
||||||
|
#
|
||||||
config.read_write()
|
config.read_write()
|
||||||
config.str3 = ['yes', '']
|
config.str3 = ['yes', '']
|
||||||
assert config.getowner(config.unwrap_from_path('str3')) == 'user'
|
assert config.getowner(config.unwrap_from_path('str3')) == 'user'
|
||||||
|
@ -144,6 +158,38 @@ def test_mandatory_multi_empty():
|
||||||
assert 'mandatory' in prop
|
assert 'mandatory' in prop
|
||||||
|
|
||||||
|
|
||||||
|
def test_mandatory_multi_empty_allow_empty_list():
|
||||||
|
descr = make_description()
|
||||||
|
config = Config(descr)
|
||||||
|
config.str4 = []
|
||||||
|
assert config.getowner(config.unwrap_from_path('str4')) == 'user'
|
||||||
|
config.read_only()
|
||||||
|
prop = []
|
||||||
|
config.str4
|
||||||
|
#
|
||||||
|
config.read_write()
|
||||||
|
config.str4 = ['']
|
||||||
|
assert config.getowner(config.unwrap_from_path('str4')) == 'user'
|
||||||
|
config.read_only()
|
||||||
|
prop = []
|
||||||
|
try:
|
||||||
|
config.str4
|
||||||
|
except PropertiesOptionError as err:
|
||||||
|
prop = err.proptype
|
||||||
|
assert 'mandatory' in prop
|
||||||
|
#
|
||||||
|
config.read_write()
|
||||||
|
config.str4 = ['yes', '']
|
||||||
|
assert config.getowner(config.unwrap_from_path('str4')) == 'user'
|
||||||
|
config.read_only()
|
||||||
|
prop = []
|
||||||
|
try:
|
||||||
|
config.str4
|
||||||
|
except PropertiesOptionError as err:
|
||||||
|
prop = err.proptype
|
||||||
|
assert 'mandatory' in prop
|
||||||
|
|
||||||
|
|
||||||
def test_mandatory_multi_append():
|
def test_mandatory_multi_append():
|
||||||
descr = make_description()
|
descr = make_description()
|
||||||
config = Config(descr)
|
config = Config(descr)
|
||||||
|
|
|
@ -99,7 +99,7 @@ class Base(StorageBase):
|
||||||
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,
|
||||||
callback_params=None, validator=None, validator_params=None,
|
callback_params=None, validator=None, validator_params=None,
|
||||||
properties=None, warnings_only=False, extra=None):
|
properties=None, warnings_only=False, extra=None, allow_empty_list=False):
|
||||||
if not valid_name(name): # pragma: optional cover
|
if not valid_name(name): # pragma: optional cover
|
||||||
raise ValueError(_("invalid name: {0} for option").format(name))
|
raise ValueError(_("invalid name: {0} for option").format(name))
|
||||||
if requires is not None:
|
if requires is not None:
|
||||||
|
@ -134,7 +134,7 @@ class Base(StorageBase):
|
||||||
'requirement {0}'.format(
|
'requirement {0}'.format(
|
||||||
list(set_forbidden_properties)))
|
list(set_forbidden_properties)))
|
||||||
StorageBase.__init__(self, name, _multi, warnings_only, doc, extra,
|
StorageBase.__init__(self, name, _multi, warnings_only, doc, extra,
|
||||||
calc_properties, requires, properties)
|
calc_properties, requires, properties, allow_empty_list)
|
||||||
if multi is not False and default is None:
|
if multi is not False and default is None:
|
||||||
default = []
|
default = []
|
||||||
self.impl_validate(default)
|
self.impl_validate(default)
|
||||||
|
@ -905,7 +905,7 @@ class SymLinkOption(OnlyOption):
|
||||||
'for symlink {0}').format(name))
|
'for symlink {0}').format(name))
|
||||||
super(Base, self).__init__(name, undefined, undefined, undefined,
|
super(Base, self).__init__(name, undefined, undefined, undefined,
|
||||||
undefined, undefined, undefined, undefined,
|
undefined, undefined, undefined, undefined,
|
||||||
opt)
|
False, opt)
|
||||||
self.commit()
|
self.commit()
|
||||||
|
|
||||||
def __getattr__(self, name, context=undefined):
|
def __getattr__(self, name, context=undefined):
|
||||||
|
|
|
@ -467,7 +467,7 @@ class Settings(object):
|
||||||
else:
|
else:
|
||||||
if 'mandatory' in properties and \
|
if 'mandatory' in properties and \
|
||||||
not self._getcontext().cfgimpl_get_values()._isempty(
|
not self._getcontext().cfgimpl_get_values()._isempty(
|
||||||
opt_or_descr, value):
|
opt_or_descr, value, opt_or_descr.impl_allow_empty_list()):
|
||||||
properties.remove('mandatory')
|
properties.remove('mandatory')
|
||||||
if is_write and 'everything_frozen' in self_properties:
|
if is_write and 'everything_frozen' in self_properties:
|
||||||
properties.add('frozen')
|
properties.add('frozen')
|
||||||
|
|
|
@ -32,7 +32,8 @@ class StorageBase(object):
|
||||||
'_multi',
|
'_multi',
|
||||||
'_extra',
|
'_extra',
|
||||||
'_warnings_only',
|
'_warnings_only',
|
||||||
#valeur
|
'_allow_empty_list',
|
||||||
|
#value
|
||||||
'_default',
|
'_default',
|
||||||
'_default_multi',
|
'_default_multi',
|
||||||
#calcul
|
#calcul
|
||||||
|
@ -41,10 +42,7 @@ class StorageBase(object):
|
||||||
'_properties',
|
'_properties',
|
||||||
'_calc_properties',
|
'_calc_properties',
|
||||||
'_val_call',
|
'_val_call',
|
||||||
#'_validator',
|
#
|
||||||
#'_validator_params',
|
|
||||||
#'_callback',
|
|
||||||
#'_callback_params',
|
|
||||||
'_consistencies',
|
'_consistencies',
|
||||||
'_master_slaves',
|
'_master_slaves',
|
||||||
'_choice_values',
|
'_choice_values',
|
||||||
|
@ -62,7 +60,7 @@ class StorageBase(object):
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, name, multi, warnings_only, doc, extra, calc_properties,
|
def __init__(self, name, multi, warnings_only, doc, extra, calc_properties,
|
||||||
requires, properties, opt=undefined):
|
requires, properties, allow_empty_list, opt=undefined):
|
||||||
self._name = name
|
self._name = name
|
||||||
if doc is not undefined:
|
if doc is not undefined:
|
||||||
self._informations = {'doc': doc}
|
self._informations = {'doc': doc}
|
||||||
|
@ -81,6 +79,8 @@ class StorageBase(object):
|
||||||
self._properties = properties
|
self._properties = properties
|
||||||
if opt is not undefined:
|
if opt is not undefined:
|
||||||
self._opt = opt
|
self._opt = opt
|
||||||
|
if allow_empty_list is not False:
|
||||||
|
self._allow_empty_list = allow_empty_list
|
||||||
|
|
||||||
def _set_default_values(self, default, default_multi):
|
def _set_default_values(self, default, default_multi):
|
||||||
if ((self.impl_is_multi() and default != tuple()) or
|
if ((self.impl_is_multi() and default != tuple()) or
|
||||||
|
@ -298,6 +298,13 @@ class StorageBase(object):
|
||||||
_multi = 1
|
_multi = 1
|
||||||
return _multi == 2
|
return _multi == 2
|
||||||
|
|
||||||
|
def impl_allow_empty_list(self):
|
||||||
|
try:
|
||||||
|
return self._allow_empty_list
|
||||||
|
except AttributeError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def _get_extra(self, key):
|
def _get_extra(self, key):
|
||||||
extra = self._extra
|
extra = self._extra
|
||||||
if isinstance(extra, tuple):
|
if isinstance(extra, tuple):
|
||||||
|
@ -308,7 +315,7 @@ class StorageBase(object):
|
||||||
def _is_warnings_only(self):
|
def _is_warnings_only(self):
|
||||||
try:
|
try:
|
||||||
return self._warnings_only
|
return self._warnings_only
|
||||||
except:
|
except AttributeError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def impl_getdefault(self):
|
def impl_getdefault(self):
|
||||||
|
|
|
@ -175,13 +175,13 @@ class Values(object):
|
||||||
if hasvalue:
|
if hasvalue:
|
||||||
self._p_.resetvalue(path)
|
self._p_.resetvalue(path)
|
||||||
|
|
||||||
def _isempty(self, opt, value):
|
def _isempty(self, opt, value, allow_empty_list):
|
||||||
"convenience method to know if an option is empty"
|
"convenience method to know if an option is empty"
|
||||||
empty = opt._empty
|
empty = opt._empty
|
||||||
if value is not undefined:
|
if value is not undefined:
|
||||||
empty_not_multi = not opt.impl_is_multi() and (value is None or
|
empty_not_multi = not opt.impl_is_multi() and (value is None or
|
||||||
value == empty)
|
value == empty)
|
||||||
empty_multi = opt.impl_is_multi() and (value == [] or
|
empty_multi = opt.impl_is_multi() and ((not allow_empty_list and value == []) or
|
||||||
None in value or
|
None in value or
|
||||||
empty in value)
|
empty in value)
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in a new issue