don't display warning in mandatory_warnings
authorEmmanuel Garette <egarette@cadoles.com>
Fri, 14 Oct 2016 19:31:39 +0000 (21:31 +0200)
committerEmmanuel Garette <egarette@cadoles.com>
Fri, 14 Oct 2016 19:31:39 +0000 (21:31 +0200)
test/test_mandatory.py
test/test_option_calculation.py
test/test_option_consistency.py
tiramisu/option/baseoption.py
tiramisu/value.py

index 6ed8084..b28a620 100644 (file)
@@ -400,7 +400,6 @@ def test_mandatory_warnings_ro():
     config.str = 'a'
     config.read_only()
     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:
         delete_session('config', config.impl_getsessionid())
     except ValueError:
@@ -417,7 +416,6 @@ def test_mandatory_warnings_rw():
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
     config.str = 'a'
     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:
         delete_session('config', 'man100')
     except ValueError:
@@ -435,7 +433,6 @@ def test_mandatory_warnings_disabled():
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
     setting[descr.str].append('disabled')
     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:
         delete_session('config', 'man101')
     except ValueError:
@@ -453,8 +450,7 @@ def test_mandatory_warnings_hidden():
     config.str
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
     setting[descr.str].append('hidden')
-    assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
-    assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str', 'str1', 'unicode2', 'str3']
+    assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
     try:
         delete_session('config', 'man102')
     except ValueError:
@@ -673,10 +669,8 @@ def test_mandatory_warnings_validate():
     config = Config(descr, session_id='man111')
     config.str = ''
     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'
     raises(ValueError, "list(config.cfgimpl_get_values().mandatory_warnings())")
-    assert list(config.cfgimpl_get_values().mandatory_warnings(validate=False)) == ['str1', 'str3']
     try:
         delete_session('config', 'man111')
     except ValueError:
@@ -689,8 +683,7 @@ def test_mandatory_warnings_validate_empty():
     config = Config(descr, session_id='man112')
     config.str = ''
     config.read_only()
-    raises(ConfigError, "list(config.cfgimpl_get_values().mandatory_warnings())")
-    assert list(config.cfgimpl_get_values().mandatory_warnings(validate=False)) == ['str', 'str1', 'str3', 'unicode1']
+    assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'str3', 'unicode1']
     try:
         delete_session('config', 'man112')
     except ValueError:
index 9da8103..d4fa050 100644 (file)
@@ -477,7 +477,7 @@ def test_callback_master_and_slaves_master4():
     cfg.read_write()
     cfg.cfgimpl_get_settings().append('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():
@@ -498,7 +498,7 @@ def test_consistency_master_and_slaves_master_mandatory_transitive():
     cfg.read_write()
     raises(PropertiesOptionError, "cfg.val1.val1")
     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():
@@ -517,7 +517,7 @@ def test_consistency_master_and_slaves_master_mandatory_non_transitive():
     maconfig = OptionDescription('rootconfig', '', [interface1, interface2])
     cfg = Config(maconfig)
     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():
index 37dcc9b..f83e135 100644 (file)
@@ -551,6 +551,24 @@ def test_consistency_broadcast_error():
     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():
     a = NetworkOption('a', '', '192.168.1.0')
     b = NetmaskOption('b', '', '255.255.255.128')
index f7baa7f..0b656aa 100644 (file)
@@ -403,6 +403,7 @@ class Option(OnlyOption):
                 all_cons_vals.append(value)
             else:
                 #if context, calculate value, otherwise get default value
+                path = None
                 if context is not undefined:
                     if isinstance(opt, DynSymLinkOption):
                         path = opt.impl_getpath(context)
@@ -437,7 +438,8 @@ class Option(OnlyOption):
 
     def impl_validate(self, value, context=undefined, validate=True,
                       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 context: Config's context
@@ -507,16 +509,18 @@ class Option(OnlyOption):
                                            self.impl_get_display_name())
                     return ValueError(msg)
                 warning = None
-                error = calculation_validator(_value)
-                if not error:
-                    error = self._second_level_validation(_value, self._is_warnings_only())
-                if error:
-                    if debug:
-                        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
+                error = None
+                if display_warnings:
+                    error = calculation_validator(_value)
+                    if not error:
+                        error = self._second_level_validation(_value, self._is_warnings_only())
+                    if error:
+                        if debug:
+                            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 context launch consistency validation
                 #if context is not undefined:
@@ -524,7 +528,8 @@ class Option(OnlyOption):
                                               _index, submulti_index)
                 if ret:
                     if isinstance(ret, ValueWarning):
-                        warning = ret
+                        if display_warnings:
+                            warning = ret
                     elif isinstance(ret, ValueError):
                         error = ret
                     else:
@@ -991,12 +996,14 @@ class DynSymLinkOption(object):
             return base_path + '.' + self._dyn
 
     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,
                                                  force_index,
                                                  force_submulti_index,
                                                  current_opt=self,
-                                                 is_multi=is_multi)
+                                                 is_multi=is_multi,
+                                                 display_warnings=display_warnings)
 
     def impl_is_dynsymlinkoption(self):
         return True
index 0a25dec..300f19e 100644 (file)
@@ -203,7 +203,7 @@ class Values(object):
                             allow_empty_list = True
                         else:
                             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
             else:
                 isempty = value is None or value == empty
@@ -225,7 +225,7 @@ class Values(object):
                           setting_properties=undefined, self_properties=undefined,
                           index=None, submulti_index=undefined, from_masterslave=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()
         settings = context.cfgimpl_get_settings()
         if path is None:
@@ -284,7 +284,8 @@ class Values(object):
                                             submulti_index=submulti_index,
                                             check_frozen=check_frozen,
                                             returns_raise=returns_raise,
-                                            session=session)
+                                            session=session,
+                                            display_warnings=display_warnings)
         if isinstance(val, Exception):
             if returns_raise:
                 return val
@@ -307,7 +308,7 @@ class Values(object):
                              with_meta=True, setting_properties=undefined,
                              self_properties=undefined, masterlen=undefined,
                              check_frozen=False, returns_raise=False,
-                             session=None):
+                             session=None, display_warnings=True):
         """same has getitem but don't touch the cache
         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,
                                         'validator' in setting_properties,
                                         force_index=force_index,
-                                        force_submulti_index=force_submulti_index)
+                                        force_submulti_index=force_submulti_index,
+                                        display_warnings=display_warnings)
                 if err:
                     config_error = err
                     value = None
@@ -602,15 +604,10 @@ class Values(object):
     def del_information(self, key, raises=True):
         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
         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
         """
         context = self._getcontext()
@@ -627,7 +624,7 @@ class Values(object):
 
                 if opt.impl_is_optiondescription():
                     if not settings.validate_properties(opt, True, False, path=path,
-                                                        force_permissive=force_permissive,
+                                                        force_permissive=True,
                                                         setting_properties=setting_properties):
                         for path in _mandatory_warnings(opt, currpath + [name]):
                             yield path
@@ -641,21 +638,19 @@ class Values(object):
                     if 'mandatory' in self_properties or 'empty' in self_properties:
                         err = self._get_cached_value(opt, path=path,
                                                      trusted_cached_properties=False,
-                                                     force_permissive=force_permissive,
+                                                     force_permissive=True,
                                                      setting_properties=setting_properties,
                                                      self_properties=self_properties,
-                                                     validate=validate, returns_raise=True)
+                                                     validate=True, returns_raise=True,
+                                                     display_warnings=False)
                         if not isinstance(err, Exception):
                             pass
                         elif isinstance(err, PropertiesOptionError):
                             if err.proptype == ['mandatory']:
                                 yield path
                         elif isinstance(err, ConfigError):
-                            if validate:
-                                raise err
-                            else:
-                                #assume that uncalculated value is an empty value
-                                yield path
+                            #assume that uncalculated value is an empty value
+                            yield path
                         else:
                             raise err