to_dict improvment and add display_name parameter to change impl_get_display_name function
This commit is contained in:
parent
35ef218c9c
commit
34d71901d0
9 changed files with 167 additions and 99 deletions
|
@ -565,7 +565,7 @@ def test_mandatory_warnings_validate_empty():
|
|||
cfg = Config(descr)
|
||||
cfg.option('str').value.set('')
|
||||
cfg.property.read_only()
|
||||
assert list(cfg.value.mandatory()) == ['str', 'str1', 'str3', 'unicode1']
|
||||
assert list(cfg.value.mandatory()) == ['str', 'str1', 'str3']
|
||||
|
||||
|
||||
def test_mandatory_warnings_requires():
|
||||
|
|
|
@ -180,10 +180,17 @@ def test_consistency_not_equal_many_opts(config_type):
|
|||
#
|
||||
cfg.option('a').value.set(1)
|
||||
raises(ValueError, "cfg.option('b').value.set(1)")
|
||||
assert cfg.option('b').value.get() == None
|
||||
#
|
||||
cfg.option('b').value.set(2)
|
||||
raises(ValueError, "cfg.option('f').value.set(2)")
|
||||
assert cfg.option('f').value.get() is None
|
||||
assert cfg.option('a').value.get() == 1
|
||||
assert cfg.option('b').value.get() == 2
|
||||
raises(ValueError, "cfg.option('f').value.set(1)")
|
||||
assert cfg.option('f').value.get() is None
|
||||
assert cfg.option('a').value.get() == 1
|
||||
assert cfg.option('b').value.get() == 2
|
||||
#
|
||||
cfg.option('d').value.set(3)
|
||||
raises(ValueError, "cfg.option('f').value.set(3)")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from .autopath import do_autopath
|
||||
1rom .autopath import do_autopath
|
||||
do_autopath()
|
||||
from .config import config_type, get_config
|
||||
|
||||
|
@ -127,6 +127,14 @@ def test_validator(config_type):
|
|||
cfg.option('opt2').value.set('val')
|
||||
assert len(w) == 1
|
||||
assert str(w[0].message) == msg
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
cfg.option('opt2').value.get()
|
||||
assert len(w) == 1
|
||||
assert str(w[0].message) == msg
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
cfg.option('opt2').value.get()
|
||||
assert len(w) == 1
|
||||
assert str(w[0].message) == msg
|
||||
|
||||
|
||||
def test_validator_params(config_type):
|
||||
|
|
|
@ -19,7 +19,7 @@ from time import time
|
|||
from typing import List, Set, Any, Optional, Callable, Union, Dict
|
||||
|
||||
|
||||
from .error import APIError, ConfigError, LeadershipError, PropertiesOptionError
|
||||
from .error import APIError, ConfigError, LeadershipError, PropertiesOptionError, ValueErrorWarning
|
||||
from .i18n import _
|
||||
from .setting import ConfigBag, OptionBag, owners, groups, Undefined, undefined, \
|
||||
FORBIDDEN_SET_PROPERTIES, SPECIAL_PROPERTIES, EXPIRATION_TIME
|
||||
|
@ -530,6 +530,17 @@ class _TiramisuOptionValueOption:
|
|||
else:
|
||||
return values.getdefaultvalue(self._option_bag)
|
||||
|
||||
def valid(self):
|
||||
try:
|
||||
with warnings.catch_warnings(record=True) as warns:
|
||||
self.get()
|
||||
for warn in warns:
|
||||
if isinstance(warns.message, ValueErrorWarning):
|
||||
return False
|
||||
except ValueError:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class _TiramisuOptionValueLeader:
|
||||
def pop(self, index):
|
||||
|
@ -739,52 +750,54 @@ class _TiramisuOptionDescription(_TiramisuOption):
|
|||
|
||||
def _filter(self,
|
||||
opt,
|
||||
subconfig):
|
||||
if self._config_bag.properties:
|
||||
name = opt.impl_getname()
|
||||
path = subconfig._get_subpath(name)
|
||||
subconfig,
|
||||
config_bag):
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(opt,
|
||||
path,
|
||||
opt.impl_getpath(),
|
||||
None,
|
||||
self._config_bag)
|
||||
config_bag)
|
||||
if opt.impl_is_optiondescription():
|
||||
self._subconfig.get_subconfig(option_bag)
|
||||
else:
|
||||
subconfig.getattr(name,
|
||||
config_bag.context.cfgimpl_get_settings().validate_properties(option_bag)
|
||||
return subconfig.get_subconfig(option_bag)
|
||||
subconfig.getattr(opt.impl_getname(),
|
||||
option_bag)
|
||||
|
||||
def list(self,
|
||||
type='option',
|
||||
group_type=None):
|
||||
"""List options in an optiondescription (only for optiondescription)"""
|
||||
"""List options (by default list only option)"""
|
||||
assert type in ('all', 'option', 'optiondescription'), _('unknown list type {}').format(type)
|
||||
assert group_type is None or isinstance(group_type, groups.GroupType), \
|
||||
_("unknown group_type: {0}").format(group_type)
|
||||
config_bag = self._config_bag
|
||||
if config_bag.properties and 'warnings' in config_bag.properties:
|
||||
config_bag = config_bag.copy()
|
||||
config_bag.remove_warnings()
|
||||
option = self._get_option()
|
||||
name = option.impl_getname()
|
||||
path = self._subconfig._get_subpath(name)
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(option,
|
||||
path,
|
||||
option.impl_getpath(),
|
||||
None,
|
||||
self._config_bag)
|
||||
config_bag)
|
||||
subconfig = self._subconfig.get_subconfig(option_bag)
|
||||
for opt in option.get_children(self._config_bag):
|
||||
for opt in option.get_children(config_bag):
|
||||
try:
|
||||
self._filter(opt,
|
||||
subconfig)
|
||||
subconfig,
|
||||
config_bag)
|
||||
except PropertiesOptionError:
|
||||
continue
|
||||
if opt.impl_is_optiondescription():
|
||||
if type == 'option' or (type == 'optiondescription' and group_type and \
|
||||
opt.impl_get_group_type() != group_type):
|
||||
if type == 'option' or (type == 'optiondescription' and \
|
||||
group_type and opt.impl_get_group_type() != group_type):
|
||||
continue
|
||||
elif type == 'optiondescription':
|
||||
continue
|
||||
name = opt.impl_getname()
|
||||
path = opt.impl_getpath()
|
||||
yield TiramisuOption(name,
|
||||
subconfig._get_subpath(name),
|
||||
path,
|
||||
None,
|
||||
subconfig,
|
||||
self._config_bag)
|
||||
|
@ -792,9 +805,10 @@ class _TiramisuOptionDescription(_TiramisuOption):
|
|||
def dict(self,
|
||||
clearable: str="all",
|
||||
remotable: str="minimum",
|
||||
form: List=[]) -> Dict:
|
||||
form: List=[],
|
||||
force: bool=False) -> Dict:
|
||||
"""convert config and option to tiramisu format"""
|
||||
if self._tiramisu_dict is None:
|
||||
if force or self._tiramisu_dict is None:
|
||||
option = self._get_option()
|
||||
name = option.impl_getname()
|
||||
root = self._subconfig._get_subpath(name)
|
||||
|
@ -822,6 +836,10 @@ class TiramisuOption(CommonTiramisuOption):
|
|||
subconfig: Union[None, KernelConfig, SubConfig]=None,
|
||||
config_bag: Optional[ConfigBag]=None) -> None:
|
||||
if subconfig:
|
||||
# not for groupconfig
|
||||
if '.' in name:
|
||||
subconfig, name = config_bag.context.cfgimpl_get_home_by_path(path,
|
||||
config_bag)
|
||||
option = subconfig.cfgimpl_get_description().get_child(name,
|
||||
config_bag,
|
||||
subconfig.cfgimpl_get_path())
|
||||
|
@ -1219,13 +1237,12 @@ class TiramisuContextOption(TiramisuContext):
|
|||
continue
|
||||
if opt.impl_is_optiondescription():
|
||||
if recursive:
|
||||
for toption in self._walk(opt,
|
||||
yield from self._walk(opt,
|
||||
recursive,
|
||||
type_,
|
||||
group_type,
|
||||
config_bag,
|
||||
subsubconfig):
|
||||
yield toption
|
||||
subsubconfig)
|
||||
if type_ == 'option' or (type_ == 'optiondescription' and \
|
||||
group_type and opt.impl_get_group_type() != group_type):
|
||||
continue
|
||||
|
@ -1252,20 +1269,20 @@ class TiramisuContextOption(TiramisuContext):
|
|||
config_bag = config_bag.copy()
|
||||
config_bag.remove_warnings()
|
||||
option = config_bag.context.cfgimpl_get_description()
|
||||
for toption in self._walk(option,
|
||||
yield from self._walk(option,
|
||||
recursive,
|
||||
type,
|
||||
group_type,
|
||||
config_bag,
|
||||
config_bag.context):
|
||||
yield toption
|
||||
config_bag.context)
|
||||
|
||||
def dict(self,
|
||||
clearable="all",
|
||||
remotable="minimum",
|
||||
form=[]):
|
||||
form=[],
|
||||
force=False):
|
||||
"""convert config and option to tiramisu format"""
|
||||
if self._tiramisu_dict is None:
|
||||
if force or self._tiramisu_dict is None:
|
||||
self._tiramisu_dict = TiramisuDict(Config(self._config_bag.context),
|
||||
root=None,
|
||||
clearable=clearable,
|
||||
|
@ -1499,14 +1516,16 @@ class Config(TiramisuAPI):
|
|||
descr: OptionDescription,
|
||||
session_id: str=None,
|
||||
persistent: bool=False,
|
||||
storage=None) -> None:
|
||||
storage=None,
|
||||
display_name=None) -> None:
|
||||
if isinstance(descr, KernelConfig):
|
||||
config = descr
|
||||
else:
|
||||
config = KernelConfig(descr,
|
||||
session_id=session_id,
|
||||
persistent=persistent,
|
||||
storage=storage)
|
||||
storage=storage,
|
||||
display_name=display_name)
|
||||
super().__init__(config)
|
||||
|
||||
|
||||
|
@ -1516,7 +1535,8 @@ class MetaConfig(TiramisuAPI):
|
|||
children,
|
||||
session_id: Union[str, None]=None,
|
||||
persistent: bool=False,
|
||||
optiondescription: Optional[OptionDescription]=None) -> None:
|
||||
optiondescription: Optional[OptionDescription]=None,
|
||||
display_name=None) -> None:
|
||||
if isinstance(children, KernelMetaConfig):
|
||||
config = children
|
||||
else:
|
||||
|
@ -1530,7 +1550,8 @@ class MetaConfig(TiramisuAPI):
|
|||
config = KernelMetaConfig(_children,
|
||||
session_id=session_id,
|
||||
persistent=persistent,
|
||||
optiondescription=optiondescription)
|
||||
optiondescription=optiondescription,
|
||||
display_name=display_name)
|
||||
super().__init__(config)
|
||||
|
||||
|
||||
|
@ -1540,7 +1561,8 @@ class MixConfig(TiramisuAPI):
|
|||
optiondescription: OptionDescription,
|
||||
children: List[Config],
|
||||
session_id: Optional[str]=None,
|
||||
persistent: bool=False) -> None:
|
||||
persistent: bool=False,
|
||||
display_name: Callable=None) -> None:
|
||||
if isinstance(children, KernelMixConfig):
|
||||
config = children
|
||||
else:
|
||||
|
@ -1554,7 +1576,8 @@ class MixConfig(TiramisuAPI):
|
|||
config = KernelMixConfig(optiondescription,
|
||||
_children,
|
||||
session_id=session_id,
|
||||
persistent=persistent)
|
||||
persistent=persistent,
|
||||
display_name=display_name)
|
||||
super().__init__(config)
|
||||
|
||||
|
||||
|
|
|
@ -615,7 +615,7 @@ class _CommonConfig(SubConfig):
|
|||
def _impl_build_all_caches(self):
|
||||
descr = self.cfgimpl_get_description()
|
||||
if not descr.impl_already_build_caches():
|
||||
descr._build_cache()
|
||||
descr._build_cache(display_name=self._display_name)
|
||||
config_bag = ConfigBag(context=self)
|
||||
descr.impl_build_force_store_values(config_bag)
|
||||
|
||||
|
@ -652,7 +652,8 @@ class _CommonConfig(SubConfig):
|
|||
fake_config = KernelConfig(self._impl_descr,
|
||||
persistent=False,
|
||||
force_values=get_default_values_storages(),
|
||||
force_settings=self.cfgimpl_get_settings())
|
||||
force_settings=self.cfgimpl_get_settings(),
|
||||
display_name=self._display_name)
|
||||
fake_config.cfgimpl_get_values()._p_.importation(self.cfgimpl_get_values()._p_.exportation())
|
||||
return fake_config
|
||||
|
||||
|
@ -673,7 +674,8 @@ class _CommonConfig(SubConfig):
|
|||
force_values=force_values,
|
||||
force_settings=force_settings,
|
||||
persistent=persistent,
|
||||
storage=storage)
|
||||
storage=storage,
|
||||
display_name=self._display_name)
|
||||
else:
|
||||
if session_id is None and metaconfig_prefix is not None:
|
||||
session_id = metaconfig_prefix + self.impl_getname()
|
||||
|
@ -682,7 +684,8 @@ class _CommonConfig(SubConfig):
|
|||
optiondescription=self._impl_descr,
|
||||
session_id=session_id,
|
||||
persistent=persistent,
|
||||
storage=storage)
|
||||
storage=storage,
|
||||
display_name=self._display_name)
|
||||
duplicated_config.cfgimpl_get_values()._p_.importation(self.cfgimpl_get_values()._p_.exportation())
|
||||
properties = self.cfgimpl_get_settings()._p_.exportation()
|
||||
duplicated_config.cfgimpl_get_settings()._p_.importation(properties)
|
||||
|
@ -714,7 +717,8 @@ class _CommonConfig(SubConfig):
|
|||
class KernelConfig(_CommonConfig):
|
||||
"main configuration management entry"
|
||||
__slots__ = ('__weakref__',
|
||||
'_impl_name')
|
||||
'_impl_name',
|
||||
'_display_name')
|
||||
impl_type = 'config'
|
||||
|
||||
def __init__(self,
|
||||
|
@ -723,6 +727,7 @@ class KernelConfig(_CommonConfig):
|
|||
persistent=False,
|
||||
force_values=None,
|
||||
force_settings=None,
|
||||
display_name=None,
|
||||
_duplicate=False,
|
||||
storage=None):
|
||||
""" Configuration option management class
|
||||
|
@ -738,6 +743,7 @@ class KernelConfig(_CommonConfig):
|
|||
:type persistent: `boolean`
|
||||
"""
|
||||
self._impl_meta = None
|
||||
self._display_name = display_name
|
||||
if isinstance(descr, Leadership):
|
||||
raise ConfigError(_('cannot set leadership object has root optiondescription'))
|
||||
if isinstance(descr, DynOptionDescription):
|
||||
|
@ -976,7 +982,7 @@ class KernelGroupConfig(_CommonConfig):
|
|||
|
||||
|
||||
class KernelMixConfig(KernelGroupConfig):
|
||||
__slots__ = tuple()
|
||||
__slots__ = ('_display_name',)
|
||||
impl_type = 'mix'
|
||||
|
||||
def __init__(self,
|
||||
|
@ -985,8 +991,10 @@ class KernelMixConfig(KernelGroupConfig):
|
|||
session_id=None,
|
||||
persistent=False,
|
||||
storage=None,
|
||||
display_name=None,
|
||||
_duplicate=False):
|
||||
# FIXME _duplicate
|
||||
self._display_name = display_name
|
||||
for child in children:
|
||||
if not isinstance(child, _CommonConfig):
|
||||
try:
|
||||
|
@ -1210,8 +1218,10 @@ class KernelMetaConfig(KernelMixConfig):
|
|||
persistent=False,
|
||||
optiondescription=None,
|
||||
storage=None,
|
||||
display_name=None,
|
||||
_duplicate=False):
|
||||
descr = None
|
||||
self._display_name = display_name
|
||||
if optiondescription is not None:
|
||||
if not _duplicate:
|
||||
new_children = []
|
||||
|
@ -1221,7 +1231,8 @@ class KernelMetaConfig(KernelMixConfig):
|
|||
'not {}').format(child_session_id)
|
||||
new_children.append(KernelConfig(optiondescription,
|
||||
persistent=persistent,
|
||||
session_id=child_session_id))
|
||||
session_id=child_session_id,
|
||||
display_name=self._display_name))
|
||||
children = new_children
|
||||
descr = optiondescription
|
||||
for child in children:
|
||||
|
@ -1259,17 +1270,20 @@ class KernelMetaConfig(KernelMixConfig):
|
|||
if type_ == 'config':
|
||||
config = KernelConfig(self._impl_descr,
|
||||
session_id=session_id,
|
||||
persistent=persistent)
|
||||
persistent=persistent,
|
||||
display_name=self._display_name)
|
||||
elif type_ == 'metaconfig':
|
||||
config = KernelMetaConfig([],
|
||||
optiondescription=self._impl_descr,
|
||||
session_id=session_id,
|
||||
persistent=persistent)
|
||||
persistent=persistent,
|
||||
display_name=self._display_name)
|
||||
elif type_ == 'mixconfig':
|
||||
config = KernelMixConfig(children=[],
|
||||
optiondescription=self._impl_descr,
|
||||
session_id=session_id,
|
||||
persistent=persistent)
|
||||
persistent=persistent,
|
||||
display_name=self._display_name)
|
||||
# Copy context properties/permissives
|
||||
if new:
|
||||
config.cfgimpl_get_settings().set_context_properties(self.cfgimpl_get_settings().get_context_properties(), config)
|
||||
|
|
|
@ -373,7 +373,7 @@ class BaseOption(Base):
|
|||
in options that have to be set only once, it is of course done in the
|
||||
__setattr__ method
|
||||
"""
|
||||
__slots__ = tuple()
|
||||
__slots__ = ('_display_name_function',)
|
||||
|
||||
def __getstate__(self):
|
||||
raise NotImplementedError()
|
||||
|
@ -407,7 +407,7 @@ class BaseOption(Base):
|
|||
"to know if a callback has been defined or not"
|
||||
return self.impl_get_callback()[0] is not None
|
||||
|
||||
def impl_get_display_name(self,
|
||||
def _impl_get_display_name(self,
|
||||
dyn_name: Base=None) -> str:
|
||||
name = self.impl_get_information('doc')
|
||||
if name is None or name == '':
|
||||
|
@ -417,6 +417,12 @@ class BaseOption(Base):
|
|||
name = self.impl_getname()
|
||||
return name
|
||||
|
||||
def impl_get_display_name(self,
|
||||
dyn_name: Base=None) -> str:
|
||||
if hasattr(self, '_display_name_function'):
|
||||
return self._display_name_function(self, dyn_name)
|
||||
return self._impl_get_display_name(dyn_name)
|
||||
|
||||
def reset_cache(self,
|
||||
path: str,
|
||||
values: Values,
|
||||
|
|
|
@ -43,7 +43,8 @@ class CacheOptionDescription(BaseOption):
|
|||
_consistencies_id=0,
|
||||
currpath: List[str]=None,
|
||||
cache_option=None,
|
||||
force_store_values=None) -> None:
|
||||
force_store_values=None,
|
||||
display_name=None) -> None:
|
||||
"""validate options and set option has readonly option
|
||||
"""
|
||||
# _consistencies is None only when we start to build cache
|
||||
|
@ -73,7 +74,8 @@ class CacheOptionDescription(BaseOption):
|
|||
_consistencies_id,
|
||||
sub_currpath,
|
||||
cache_option,
|
||||
force_store_values)
|
||||
force_store_values,
|
||||
display_name)
|
||||
else:
|
||||
is_multi = option.impl_is_multi()
|
||||
if not option.impl_is_symlinkoption():
|
||||
|
@ -155,6 +157,8 @@ class CacheOptionDescription(BaseOption):
|
|||
require_opt.impl_getname(), option.impl_getname()))
|
||||
if option.impl_is_readonly():
|
||||
raise ConflictError(_('duplicate option: {0}').format(option))
|
||||
if not self.impl_is_readonly() and display_name:
|
||||
option._display_name_function = display_name
|
||||
option._path = subpath
|
||||
option._set_readonly()
|
||||
if init:
|
||||
|
|
|
@ -33,6 +33,7 @@ INPUTS = ['string',
|
|||
|
||||
# return always warning (even if same warning is already returned)
|
||||
warnings.simplefilter("always", ValueWarning)
|
||||
warnings.simplefilter("always", ValueErrorWarning)
|
||||
|
||||
|
||||
class Callbacks(object):
|
||||
|
@ -621,26 +622,32 @@ class TiramisuDict:
|
|||
props = set(childapi.property.get())
|
||||
obj = self.gen_properties(props,
|
||||
isfollower,
|
||||
childapi.option.ismulti())
|
||||
childapi.option.ismulti(),
|
||||
index)
|
||||
self.calc_raises_properties(obj, childapi)
|
||||
return obj
|
||||
|
||||
def gen_properties(self,
|
||||
properties,
|
||||
isfollower=False,
|
||||
ismulti=False):
|
||||
isfollower,
|
||||
ismulti,
|
||||
index):
|
||||
obj = {}
|
||||
if not isfollower and ismulti:
|
||||
if 'empty' in properties:
|
||||
if index is None:
|
||||
obj['required'] = True
|
||||
properties.remove('empty')
|
||||
if 'mandatory' in properties:
|
||||
if index is None:
|
||||
obj['needs_len'] = True
|
||||
properties.remove('mandatory')
|
||||
elif 'mandatory' in properties:
|
||||
if index is None:
|
||||
obj['required'] = True
|
||||
properties.remove('mandatory')
|
||||
if 'frozen' in properties:
|
||||
if index is None:
|
||||
obj['readOnly'] = True
|
||||
properties.remove('frozen')
|
||||
if 'hidden' in properties:
|
||||
|
@ -744,21 +751,23 @@ class TiramisuDict:
|
|||
for value in values:
|
||||
if isinstance(value, ValueError):
|
||||
obj.setdefault('error', [])
|
||||
obj['error'].append(str(value))
|
||||
msg = str(value)
|
||||
if msg not in obj.get('error', []):
|
||||
obj['error'].append(msg)
|
||||
obj['invalid'] = True
|
||||
elif isinstance(value.message, ValueErrorWarning):
|
||||
value.message.prefix = ''
|
||||
if childapi.option.isfollower():
|
||||
obj.setdefault('invalid', [])
|
||||
obj['invalid'].append({'error': str(value.message),
|
||||
'index': value.message.index})
|
||||
else:
|
||||
obj.setdefault('error', [])
|
||||
obj['error'].append(str(value.message))
|
||||
msg = str(value.message)
|
||||
if msg not in obj.get('error', []):
|
||||
obj['error'].append(msg)
|
||||
obj['invalid'] = True
|
||||
else:
|
||||
value.message.prefix = ''
|
||||
obj.setdefault('warnings', [])
|
||||
obj['warnings'].append(str(value.message))
|
||||
msg = str(value.message)
|
||||
if msg not in obj.get('error', []):
|
||||
obj['warnings'].append(msg)
|
||||
obj['hasWarnings'] = True
|
||||
|
||||
def gen_global(self):
|
||||
|
|
|
@ -76,7 +76,8 @@ class Values(object):
|
|||
option_bag,
|
||||
check_error=True)
|
||||
# store value in cache
|
||||
validator = 'validator' in option_bag.config_bag.properties
|
||||
properties = option_bag.config_bag.properties
|
||||
validator = 'validator' in properties and 'demoting_error_warning' not in properties
|
||||
if not option_bag.fromconsistency and (not is_cached or validator):
|
||||
self._p_.setcache(option_bag.path,
|
||||
option_bag.index,
|
||||
|
@ -570,13 +571,12 @@ class Values(object):
|
|||
except PropertiesOptionError as err:
|
||||
pass
|
||||
else:
|
||||
for path in self._mandatory_warnings(context,
|
||||
yield from self._mandatory_warnings(context,
|
||||
config_bag,
|
||||
option,
|
||||
currpath + [name],
|
||||
subsubconfig,
|
||||
od_config_bag):
|
||||
yield path
|
||||
od_config_bag)
|
||||
elif not option.impl_is_symlinkoption():
|
||||
# don't verifying symlink
|
||||
try:
|
||||
|
@ -602,11 +602,8 @@ class Values(object):
|
|||
except PropertiesOptionError as err:
|
||||
if err.proptype == ['mandatory']:
|
||||
yield path
|
||||
except RequirementError:
|
||||
except (RequirementError, ConfigError):
|
||||
pass
|
||||
except ConfigError as err:
|
||||
#assume that uncalculated value is an empty value
|
||||
yield path
|
||||
|
||||
def mandatory_warnings(self,
|
||||
config_bag):
|
||||
|
|
Loading…
Reference in a new issue