don't display warning in mandatory_warnings

This commit is contained in:
Emmanuel Garette 2016-10-14 21:31:39 +02:00
parent 2e4fdbca03
commit 24ec5a9112
5 changed files with 58 additions and 45 deletions

View File

@ -400,7 +400,6 @@ def test_mandatory_warnings_ro():
config.str = 'a' config.str = 'a'
config.read_only() config.read_only()
assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3'] assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str1', 'unicode2', 'str3']
try: try:
delete_session('config', config.impl_getsessionid()) delete_session('config', config.impl_getsessionid())
except ValueError: except ValueError:
@ -417,7 +416,6 @@ def test_mandatory_warnings_rw():
assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3'] assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
config.str = 'a' config.str = 'a'
assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3'] assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str1', 'unicode2', 'str3']
try: try:
delete_session('config', 'man100') delete_session('config', 'man100')
except ValueError: except ValueError:
@ -435,7 +433,6 @@ def test_mandatory_warnings_disabled():
assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3'] assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
setting[descr.str].append('disabled') setting[descr.str].append('disabled')
assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3'] assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str1', 'unicode2', 'str3']
try: try:
delete_session('config', 'man101') delete_session('config', 'man101')
except ValueError: except ValueError:
@ -453,8 +450,7 @@ def test_mandatory_warnings_hidden():
config.str config.str
assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3'] assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
setting[descr.str].append('hidden') setting[descr.str].append('hidden')
assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3'] assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str', 'str1', 'unicode2', 'str3']
try: try:
delete_session('config', 'man102') delete_session('config', 'man102')
except ValueError: except ValueError:
@ -673,10 +669,8 @@ def test_mandatory_warnings_validate():
config = Config(descr, session_id='man111') config = Config(descr, session_id='man111')
config.str = '' config.str = ''
raises(ValueError, "list(config.cfgimpl_get_values().mandatory_warnings())") raises(ValueError, "list(config.cfgimpl_get_values().mandatory_warnings())")
assert list(config.cfgimpl_get_values().mandatory_warnings(validate=False)) == ['str', 'str1', 'str3', 'unicode1', 'int1']
config.str = 'test' config.str = 'test'
raises(ValueError, "list(config.cfgimpl_get_values().mandatory_warnings())") raises(ValueError, "list(config.cfgimpl_get_values().mandatory_warnings())")
assert list(config.cfgimpl_get_values().mandatory_warnings(validate=False)) == ['str1', 'str3']
try: try:
delete_session('config', 'man111') delete_session('config', 'man111')
except ValueError: except ValueError:
@ -689,8 +683,7 @@ def test_mandatory_warnings_validate_empty():
config = Config(descr, session_id='man112') config = Config(descr, session_id='man112')
config.str = '' config.str = ''
config.read_only() config.read_only()
raises(ConfigError, "list(config.cfgimpl_get_values().mandatory_warnings())") assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'str3', 'unicode1']
assert list(config.cfgimpl_get_values().mandatory_warnings(validate=False)) == ['str', 'str1', 'str3', 'unicode1']
try: try:
delete_session('config', 'man112') delete_session('config', 'man112')
except ValueError: except ValueError:

View File

@ -477,7 +477,7 @@ def test_callback_master_and_slaves_master4():
cfg.read_write() cfg.read_write()
cfg.cfgimpl_get_settings().append('expert') cfg.cfgimpl_get_settings().append('expert')
cfg.cfgimpl_get_settings().setpermissive(('expert',)) cfg.cfgimpl_get_settings().setpermissive(('expert',))
assert list(cfg.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == [] assert list(cfg.cfgimpl_get_values().mandatory_warnings()) == []
def test_consistency_master_and_slaves_master_mandatory_transitive(): def test_consistency_master_and_slaves_master_mandatory_transitive():
@ -498,7 +498,7 @@ def test_consistency_master_and_slaves_master_mandatory_transitive():
cfg.read_write() cfg.read_write()
raises(PropertiesOptionError, "cfg.val1.val1") raises(PropertiesOptionError, "cfg.val1.val1")
raises(PropertiesOptionError, "cfg.val3.val3") raises(PropertiesOptionError, "cfg.val3.val3")
assert list(cfg.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == [] assert list(cfg.cfgimpl_get_values().mandatory_warnings()) == []
def test_consistency_master_and_slaves_master_mandatory_non_transitive(): def test_consistency_master_and_slaves_master_mandatory_non_transitive():
@ -517,7 +517,7 @@ def test_consistency_master_and_slaves_master_mandatory_non_transitive():
maconfig = OptionDescription('rootconfig', '', [interface1, interface2]) maconfig = OptionDescription('rootconfig', '', [interface1, interface2])
cfg = Config(maconfig) cfg = Config(maconfig)
cfg.read_write() cfg.read_write()
assert list(cfg.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ["val1.val1"] assert list(cfg.cfgimpl_get_values().mandatory_warnings()) == ["val1.val1"]
def test_callback_master_and_slaves_master_list(): def test_callback_master_and_slaves_master_list():

View File

@ -551,6 +551,24 @@ def test_consistency_broadcast_error():
raises(ConfigError, "c.a = ['192.168.1.0']") raises(ConfigError, "c.a = ['192.168.1.0']")
def test_consistency_broadcast_warnings():
warnings.simplefilter("always", ValueWarning)
a = NetworkOption('a', '', properties=('mandatory', 'disabled'))
b = NetmaskOption('b', '', properties=('mandatory', 'disabled'))
c = NetmaskOption('c', '', properties=('mandatory', 'disabled'))
od = OptionDescription('a', '', [a, b, c])
b.impl_add_consistency('network_netmask', a, warnings_only=True)
c = Config(od)
with warnings.catch_warnings(record=True) as w:
c.a = '192.168.1.4'
c.b = '255.255.255.0'
assert len(w) == 1
c.read_write()
with warnings.catch_warnings(record=True) as w:
list(c.cfgimpl_get_values().mandatory_warnings())
assert len(w) == 0
def test_consistency_broadcast_default_1(): def test_consistency_broadcast_default_1():
a = NetworkOption('a', '', '192.168.1.0') a = NetworkOption('a', '', '192.168.1.0')
b = NetmaskOption('b', '', '255.255.255.128') b = NetmaskOption('b', '', '255.255.255.128')

View File

@ -403,6 +403,7 @@ class Option(OnlyOption):
all_cons_vals.append(value) all_cons_vals.append(value)
else: else:
#if context, calculate value, otherwise get default value #if context, calculate value, otherwise get default value
path = None
if context is not undefined: if context is not undefined:
if isinstance(opt, DynSymLinkOption): if isinstance(opt, DynSymLinkOption):
path = opt.impl_getpath(context) path = opt.impl_getpath(context)
@ -437,7 +438,8 @@ class Option(OnlyOption):
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,
current_opt=undefined, is_multi=None): current_opt=undefined, is_multi=None,
display_warnings=True):
""" """
:param value: the option's value :param value: the option's value
:param context: Config's context :param context: Config's context
@ -507,16 +509,18 @@ class Option(OnlyOption):
self.impl_get_display_name()) self.impl_get_display_name())
return ValueError(msg) return ValueError(msg)
warning = None warning = None
error = calculation_validator(_value) error = None
if not error: if display_warnings:
error = self._second_level_validation(_value, self._is_warnings_only()) error = calculation_validator(_value)
if error: if not error:
if debug: error = self._second_level_validation(_value, self._is_warnings_only())
log.debug(_('do_validation for {0}: error in value').format( if error:
self.impl_getname()), exc_info=True) if debug:
if self._is_warnings_only(): log.debug(_('do_validation for {0}: error in value').format(
warning = error self.impl_getname()), exc_info=True)
error = None 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:
@ -524,7 +528,8 @@ class Option(OnlyOption):
_index, submulti_index) _index, submulti_index)
if ret: if ret:
if isinstance(ret, ValueWarning): if isinstance(ret, ValueWarning):
warning = ret if display_warnings:
warning = ret
elif isinstance(ret, ValueError): elif isinstance(ret, ValueError):
error = ret error = ret
else: else:
@ -991,12 +996,14 @@ class DynSymLinkOption(object):
return base_path + '.' + self._dyn return base_path + '.' + self._dyn
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, is_multi=None): force_index=None, force_submulti_index=None, is_multi=None,
display_warnings=True):
return self._impl_getopt().impl_validate(value, context, validate, return self._impl_getopt().impl_validate(value, context, validate,
force_index, force_index,
force_submulti_index, force_submulti_index,
current_opt=self, current_opt=self,
is_multi=is_multi) is_multi=is_multi,
display_warnings=display_warnings)
def impl_is_dynsymlinkoption(self): def impl_is_dynsymlinkoption(self):
return True return True

View File

@ -203,7 +203,7 @@ class Values(object):
allow_empty_list = True allow_empty_list = True
else: else:
allow_empty_list = False allow_empty_list = False
isempty = (not allow_empty_list and value == []) or \ isempty = value is None or (not allow_empty_list and value == []) or \
None in value or empty in value None in value or empty in value
else: else:
isempty = value is None or value == empty isempty = value is None or value == empty
@ -225,7 +225,7 @@ class Values(object):
setting_properties=undefined, self_properties=undefined, setting_properties=undefined, self_properties=undefined,
index=None, submulti_index=undefined, from_masterslave=False, index=None, submulti_index=undefined, from_masterslave=False,
with_meta=True, masterlen=undefined, check_frozen=False, with_meta=True, masterlen=undefined, check_frozen=False,
returns_raise=False, session=None): returns_raise=False, session=None, display_warnings=True):
context = self._getcontext() context = self._getcontext()
settings = context.cfgimpl_get_settings() settings = context.cfgimpl_get_settings()
if path is None: if path is None:
@ -284,7 +284,8 @@ class Values(object):
submulti_index=submulti_index, submulti_index=submulti_index,
check_frozen=check_frozen, check_frozen=check_frozen,
returns_raise=returns_raise, returns_raise=returns_raise,
session=session) session=session,
display_warnings=display_warnings)
if isinstance(val, Exception): if isinstance(val, Exception):
if returns_raise: if returns_raise:
return val return val
@ -307,7 +308,7 @@ class Values(object):
with_meta=True, setting_properties=undefined, with_meta=True, setting_properties=undefined,
self_properties=undefined, masterlen=undefined, self_properties=undefined, masterlen=undefined,
check_frozen=False, returns_raise=False, check_frozen=False, returns_raise=False,
session=None): session=None, display_warnings=True):
"""same has getitem but don't touch the cache """same has getitem but don't touch the cache
index is None for slave value, if value returned is not a list, just return [] index is None for slave value, if value returned is not a list, just return []
""" """
@ -357,7 +358,8 @@ class Values(object):
err = opt.impl_validate(value, context, err = opt.impl_validate(value, context,
'validator' in setting_properties, 'validator' in setting_properties,
force_index=force_index, force_index=force_index,
force_submulti_index=force_submulti_index) force_submulti_index=force_submulti_index,
display_warnings=display_warnings)
if err: if err:
config_error = err config_error = err
value = None value = None
@ -602,15 +604,10 @@ class Values(object):
def del_information(self, key, raises=True): def del_information(self, key, raises=True):
self._p_.del_information(key, raises) self._p_.del_information(key, raises)
def mandatory_warnings(self, force_permissive=False, validate=True): def mandatory_warnings(self):
"""convenience function to trace Options that are mandatory and """convenience function to trace Options that are mandatory and
where no value has been set where no value has been set
:param force_permissive: do raise with permissives properties
:type force_permissive: `bool`
:param validate: validate value when calculating properties
:type validate: `bool`
:returns: generator of mandatory Option's path :returns: generator of mandatory Option's path
""" """
context = self._getcontext() context = self._getcontext()
@ -627,7 +624,7 @@ class Values(object):
if opt.impl_is_optiondescription(): if opt.impl_is_optiondescription():
if not settings.validate_properties(opt, True, False, path=path, if not settings.validate_properties(opt, True, False, path=path,
force_permissive=force_permissive, force_permissive=True,
setting_properties=setting_properties): setting_properties=setting_properties):
for path in _mandatory_warnings(opt, currpath + [name]): for path in _mandatory_warnings(opt, currpath + [name]):
yield path yield path
@ -641,21 +638,19 @@ class Values(object):
if 'mandatory' in self_properties or 'empty' in self_properties: if 'mandatory' in self_properties or 'empty' in self_properties:
err = self._get_cached_value(opt, path=path, err = self._get_cached_value(opt, path=path,
trusted_cached_properties=False, trusted_cached_properties=False,
force_permissive=force_permissive, force_permissive=True,
setting_properties=setting_properties, setting_properties=setting_properties,
self_properties=self_properties, self_properties=self_properties,
validate=validate, returns_raise=True) validate=True, returns_raise=True,
display_warnings=False)
if not isinstance(err, Exception): if not isinstance(err, Exception):
pass pass
elif isinstance(err, PropertiesOptionError): elif isinstance(err, PropertiesOptionError):
if err.proptype == ['mandatory']: if err.proptype == ['mandatory']:
yield path yield path
elif isinstance(err, ConfigError): elif isinstance(err, ConfigError):
if validate: #assume that uncalculated value is an empty value
raise err yield path
else:
#assume that uncalculated value is an empty value
yield path
else: else:
raise err raise err