simplify find() in api and PropertiesOptionError
This commit is contained in:
parent
5eb2f04202
commit
9e378faef0
11 changed files with 213 additions and 198 deletions
|
@ -24,7 +24,7 @@ def return_calc_list(val):
|
|||
return [val]
|
||||
|
||||
|
||||
def return_error():
|
||||
def return_error(*args, **kwargs):
|
||||
raise Exception('test')
|
||||
|
||||
|
||||
|
@ -83,6 +83,24 @@ def test_choiceoption_function_error():
|
|||
raises(ConfigError, "api.option('choice').value.set('val1')")
|
||||
|
||||
|
||||
def test_choiceoption_function_error_args():
|
||||
choice = ChoiceOption('choice', '', values=return_error, values_params={'': ('val1',)})
|
||||
odesc = OptionDescription('od', '', [choice])
|
||||
cfg = Config(odesc)
|
||||
api = getapi(cfg)
|
||||
api.property.read_write()
|
||||
raises(ConfigError, "api.option('choice').value.set('val1')")
|
||||
|
||||
|
||||
def test_choiceoption_function_error_kwargs():
|
||||
choice = ChoiceOption('choice', '', values=return_error, values_params={'kwargs': ('val1',)})
|
||||
odesc = OptionDescription('od', '', [choice])
|
||||
cfg = Config(odesc)
|
||||
api = getapi(cfg)
|
||||
api.property.read_write()
|
||||
raises(ConfigError, "api.option('choice').value.set('val1')")
|
||||
|
||||
|
||||
def test_choiceoption_calc_function():
|
||||
choice = ChoiceOption('choice', "", values=return_calc_list, values_params={'': ('val1',)})
|
||||
odesc = OptionDescription('od', '', [choice])
|
||||
|
|
|
@ -195,6 +195,11 @@ def test_find_in_config():
|
|||
assert len(ret) == 1
|
||||
_is_same_opt(ret[0].option.get(), api.option('gc.prop').option.get())
|
||||
#
|
||||
ret = api.option.find('prop', value=None)
|
||||
ret = api.option.find('prop')
|
||||
assert len(ret) == 1
|
||||
_is_same_opt(ret[0].option.get(), api.option('gc.prop').option.get())
|
||||
#
|
||||
api.property.read_write()
|
||||
raises(AttributeError, "assert api.option.find('prop').option.get()")
|
||||
ret = api.unrestraint.option.find(name='prop')
|
||||
|
|
|
@ -48,6 +48,11 @@ def make_metaconfig(double=False):
|
|||
return api
|
||||
|
||||
|
||||
def test_unknown_config():
|
||||
api = make_metaconfig()
|
||||
raises(ConfigError, "api.config('unknown')")
|
||||
|
||||
|
||||
#FIXME ne pas mettre 2 meta dans une config
|
||||
#FIXME ne pas mettre 2 OD differents dans un meta
|
||||
def test_none():
|
||||
|
|
|
@ -10,6 +10,7 @@ from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
|
|||
getapi, undefined
|
||||
from tiramisu.api import TIRAMISU_VERSION
|
||||
from tiramisu.error import PropertiesOptionError, ConflictError, SlaveError, ConfigError
|
||||
from tiramisu.i18n import _
|
||||
|
||||
|
||||
def return_val():
|
||||
|
@ -652,7 +653,13 @@ def test_consistency_master_and_slaves_master_mandatory_transitive():
|
|||
maconfig = OptionDescription('rootconfig', '', [interface1, interface2])
|
||||
api = getapi(Config(maconfig))
|
||||
api.property.read_write()
|
||||
raises(PropertiesOptionError, "api.option('val1.val1').value.get()")
|
||||
err = None
|
||||
try:
|
||||
api.option('val1.val1').value.get()
|
||||
except PropertiesOptionError as error:
|
||||
err = error
|
||||
assert err, 'should raises'
|
||||
assert str(err) == str(_('cannot access to {0} "{1}" because "{2}" has {3} {4}').format('option', 'val1', 'val2', 'property', '"disabled"'))
|
||||
raises(PropertiesOptionError, "api.option('val3.val3').value.get()")
|
||||
assert list(api.value.mandatory_warnings()) == []
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ from .autopath import do_autopath
|
|||
do_autopath()
|
||||
|
||||
from copy import copy
|
||||
from tiramisu.i18n import _
|
||||
from tiramisu.setting import groups
|
||||
from tiramisu import setting
|
||||
setting.expires_time = 1
|
||||
|
@ -93,16 +94,17 @@ def test_requires_invalid():
|
|||
|
||||
|
||||
def test_requires_same_action():
|
||||
a = BoolOption('activate_service', '', True)
|
||||
b = BoolOption('activate_service_web', '', True,
|
||||
requires=[{'option': a, 'expected': False, 'action': 'new'}])
|
||||
activate_service = BoolOption('activate_service', '', True)
|
||||
activate_service_web = BoolOption('activate_service_web', '', True,
|
||||
requires=[{'option': activate_service, 'expected': False,
|
||||
'action': 'new'}])
|
||||
|
||||
d = IPOption('ip_address_service_web', '',
|
||||
requires=[{'option': b, 'expected': False,
|
||||
'action': 'disabled', 'inverse': False,
|
||||
'transitive': True, 'same_action': False}])
|
||||
od = OptionDescription('service', '', [a, b, d])
|
||||
api = getapi(Config(od))
|
||||
ip_address_service_web = IPOption('ip_address_service_web', '',
|
||||
requires=[{'option': activate_service_web, 'expected': False,
|
||||
'action': 'disabled', 'inverse': False,
|
||||
'transitive': True, 'same_action': False}])
|
||||
od1 = OptionDescription('service', '', [activate_service, activate_service_web, ip_address_service_web])
|
||||
api = getapi(Config(od1))
|
||||
api.property.read_write()
|
||||
api.property.add('new')
|
||||
api.option('activate_service').value.get()
|
||||
|
@ -122,6 +124,8 @@ def test_requires_same_action():
|
|||
api.option('ip_address_service_web').value.get()
|
||||
except PropertiesOptionError as err:
|
||||
props = err.proptype
|
||||
submsg = '"disabled" (' + _('the value of "{0}" is {1}').format('activate_service', '"False"') + ')'
|
||||
assert str(err) == str(_('cannot access to {0} "{1}" because has {2} {3}').format('option', 'ip_address_service_web', 'property', submsg))
|
||||
assert frozenset(props) == frozenset(['disabled'])
|
||||
|
||||
|
||||
|
|
|
@ -662,7 +662,6 @@ class TiramisuOption(CommonTiramisu):
|
|||
for path in self.config_bag.config.find(byname=name,
|
||||
byvalue=value,
|
||||
bytype=None,
|
||||
type_='path',
|
||||
_subpath=self.path,
|
||||
config_bag=self.config_bag):
|
||||
config_bag = self.config_bag.copy('nooption')
|
||||
|
@ -900,7 +899,6 @@ class TiramisuContextOption(TiramisuContext):
|
|||
for path in self.config_bag.config.find(byname=name,
|
||||
byvalue=value,
|
||||
bytype=None,
|
||||
type_='path',
|
||||
#_subpath=self.path,
|
||||
config_bag=self.config_bag):
|
||||
config_bag = self.config_bag.copy('nooption')
|
||||
|
|
|
@ -185,7 +185,7 @@ class SubConfig(object):
|
|||
`setting.groups`
|
||||
"""
|
||||
if group_type is not None and not isinstance(group_type,
|
||||
groups.GroupType): # pragma: optional cover
|
||||
groups.GroupType):
|
||||
raise TypeError(_("unknown group_type: {0}").format(group_type))
|
||||
for child in self.cfgimpl_get_description().impl_getchildren(config_bag):
|
||||
if child.impl_is_optiondescription():
|
||||
|
@ -199,7 +199,7 @@ class SubConfig(object):
|
|||
yield name, self.getattr(name,
|
||||
None,
|
||||
nconfig_bag)
|
||||
except PropertiesOptionError: # pragma: optional cover
|
||||
except PropertiesOptionError:
|
||||
pass
|
||||
|
||||
def cfgimpl_get_children(self,
|
||||
|
@ -227,12 +227,12 @@ class SubConfig(object):
|
|||
old `SubConfig`, `Values`, `Multi` or `Settings`)
|
||||
"""
|
||||
context = self._impl_context()
|
||||
if context is None: # pragma: optional cover
|
||||
if context is None: # pragma: no cover
|
||||
raise ConfigError(_('the context does not exist anymore'))
|
||||
return context
|
||||
|
||||
def cfgimpl_get_description(self):
|
||||
if self._impl_descr is None: # pragma: optional cover
|
||||
if self._impl_descr is None:
|
||||
raise ConfigError(_('no option description found for this config'
|
||||
' (may be GroupConfig)'))
|
||||
else:
|
||||
|
@ -252,7 +252,7 @@ class SubConfig(object):
|
|||
_commit=True):
|
||||
|
||||
context = self.cfgimpl_get_context()
|
||||
if '.' in name: # pragma: optional cover
|
||||
if '.' in name:
|
||||
# when set_value
|
||||
self, name = self.cfgimpl_get_home_by_path(name,
|
||||
config_bag)
|
||||
|
@ -281,7 +281,7 @@ class SubConfig(object):
|
|||
name,
|
||||
index,
|
||||
config_bag):
|
||||
if '.' in name: # pragma: optional cover
|
||||
if '.' in name:
|
||||
self, name = self.cfgimpl_get_home_by_path(name,
|
||||
config_bag)
|
||||
option = config_bag.option
|
||||
|
@ -385,7 +385,6 @@ class SubConfig(object):
|
|||
byname,
|
||||
byvalue,
|
||||
config_bag,
|
||||
type_='option',
|
||||
_subpath=None,
|
||||
raise_if_not_found=True,
|
||||
only_path=undefined,
|
||||
|
@ -397,8 +396,6 @@ class SubConfig(object):
|
|||
:return: find list or an exception if nothing has been found
|
||||
"""
|
||||
def _filter_by_value(sconfig_bag):
|
||||
if byvalue is undefined:
|
||||
return True
|
||||
try:
|
||||
value = self.getattr(path,
|
||||
None,
|
||||
|
@ -410,9 +407,6 @@ class SubConfig(object):
|
|||
else:
|
||||
return value == byvalue
|
||||
|
||||
if type_ not in ('option', 'path', 'value'): # pragma: optional cover
|
||||
raise ValueError(_('unknown type_ type {0}'
|
||||
'for find').format(type_))
|
||||
found = False
|
||||
if only_path is not undefined:
|
||||
options = [(only_path, only_option)]
|
||||
|
@ -424,10 +418,10 @@ class SubConfig(object):
|
|||
for path, option in options:
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.option = option
|
||||
if not _filter_by_value(sconfig_bag):
|
||||
if byvalue is not undefined and not _filter_by_value(sconfig_bag):
|
||||
continue
|
||||
#remove option with propertyerror, ...
|
||||
if sconfig_bag.validate_properties:
|
||||
elif sconfig_bag.validate_properties:
|
||||
#remove option with propertyerror, ...
|
||||
try:
|
||||
self.unwrap_from_path(path,
|
||||
sconfig_bag)
|
||||
|
@ -436,18 +430,10 @@ class SubConfig(object):
|
|||
sconfig_bag)
|
||||
except PropertiesOptionError:
|
||||
continue
|
||||
if type_ == 'value':
|
||||
retval = self.getattr(path,
|
||||
None,
|
||||
sconfig_bag)
|
||||
elif type_ == 'path':
|
||||
retval = path
|
||||
elif type_ == 'option':
|
||||
retval = option
|
||||
found = True
|
||||
yield retval
|
||||
return self._find_return_results(found,
|
||||
raise_if_not_found)
|
||||
yield path
|
||||
self._find_return_results(found,
|
||||
raise_if_not_found)
|
||||
|
||||
def _find_return_results(self,
|
||||
found,
|
||||
|
@ -502,7 +488,7 @@ class SubConfig(object):
|
|||
pathsvalues = []
|
||||
if _currpath is None:
|
||||
_currpath = []
|
||||
if withoption is None and withvalue is not undefined: # pragma: optional cover
|
||||
if withoption is None and withvalue is not undefined:
|
||||
raise ValueError(_("make_dict can't filtering with value without "
|
||||
"option"))
|
||||
context = self.cfgimpl_get_context()
|
||||
|
@ -510,7 +496,6 @@ class SubConfig(object):
|
|||
for path in context.find(bytype=None,
|
||||
byname=withoption,
|
||||
byvalue=withvalue,
|
||||
type_='path',
|
||||
_subpath=self.cfgimpl_get_path(False),
|
||||
config_bag=config_bag):
|
||||
path = '.'.join(path.split('.')[:-1])
|
||||
|
@ -526,7 +511,7 @@ class SubConfig(object):
|
|||
break
|
||||
else:
|
||||
tmypath = mypath + '.'
|
||||
if not path.startswith(tmypath): # pragma: optional cover
|
||||
if not path.startswith(tmypath):
|
||||
raise AttributeError(_('unexpected path {0}, '
|
||||
'should start with {1}'
|
||||
'').format(path, mypath))
|
||||
|
@ -751,7 +736,7 @@ class Config(_CommonConfig):
|
|||
properties, permissives, values, session_id = get_storages(self,
|
||||
session_id,
|
||||
persistent)
|
||||
if not valid_name(session_id): # pragma: optional cover
|
||||
if not valid_name(session_id):
|
||||
raise ValueError(_("invalid session ID: {0} for config").format(session_id))
|
||||
self._impl_settings = Settings(self,
|
||||
properties,
|
||||
|
@ -869,7 +854,15 @@ class GroupConfig(_CommonConfig):
|
|||
nconfig_bag,
|
||||
_commit=False)
|
||||
except PropertiesOptionError as err:
|
||||
ret.append(PropertiesOptionError(str(err), err.proptype))
|
||||
ret.append(PropertiesOptionError(err._path,
|
||||
err._index,
|
||||
err._config_bag,
|
||||
err.proptype,
|
||||
err._settings,
|
||||
err._opt_type,
|
||||
err._requires,
|
||||
err._name,
|
||||
err._orig_opt))
|
||||
except (ValueError, SlaveError) as err:
|
||||
ret.append(err)
|
||||
if _commit:
|
||||
|
@ -896,7 +889,6 @@ class GroupConfig(_CommonConfig):
|
|||
byvalue=undefined,
|
||||
byname=byname,
|
||||
config_bag=config_bag,
|
||||
type_='path',
|
||||
raise_if_not_found=raise_if_not_found))
|
||||
byname = None
|
||||
byoption = self.cfgimpl_get_description().impl_get_opt_by_path(bypath)
|
||||
|
@ -918,7 +910,6 @@ class GroupConfig(_CommonConfig):
|
|||
next(child.find(None,
|
||||
byname,
|
||||
byvalue,
|
||||
type_='path',
|
||||
config_bag=config_bag,
|
||||
raise_if_not_found=False,
|
||||
only_path=bypath,
|
||||
|
@ -935,22 +926,13 @@ class GroupConfig(_CommonConfig):
|
|||
|
||||
def impl_getname(self):
|
||||
return self._impl_name
|
||||
# def __str__(self):
|
||||
# ret = ''
|
||||
# for child in self._impl_children:
|
||||
# ret += "({0})\n".format(child._impl_name)
|
||||
# if self._impl_descr is not None:
|
||||
# ret += super(GroupConfig, self).__str__()
|
||||
# return ret
|
||||
#
|
||||
# __repr__ = __str__
|
||||
|
||||
def getconfig(self,
|
||||
name):
|
||||
for child in self._impl_children:
|
||||
if name == child.impl_getname():
|
||||
return child
|
||||
raise ConfigError(_('unknown config {}').format(name))
|
||||
raise ConfigError(_('unknown config "{}"').format(name))
|
||||
|
||||
|
||||
class MetaConfig(GroupConfig):
|
||||
|
|
|
@ -55,27 +55,48 @@ def display_list(lst, separator='and', add_quote=False):
|
|||
class PropertiesOptionError(AttributeError):
|
||||
"attempt to access to an option with a property that is not allowed"
|
||||
def __init__(self,
|
||||
msg,
|
||||
path,
|
||||
index,
|
||||
config_bag,
|
||||
proptype,
|
||||
settings=None,
|
||||
datas=None,
|
||||
option_type=None):
|
||||
settings,
|
||||
opt_type=None,
|
||||
requires=None,
|
||||
name=None,
|
||||
orig_opt=None):
|
||||
self._path = path
|
||||
self._index = index
|
||||
if opt_type:
|
||||
self._opt_type = opt_type
|
||||
self._requires = requires
|
||||
self._name = name
|
||||
self._orig_opt = orig_opt
|
||||
else:
|
||||
if config_bag.option.impl_is_optiondescription():
|
||||
self._opt_type = 'optiondescription'
|
||||
else:
|
||||
self._opt_type = 'option'
|
||||
self._requires = config_bag.option.impl_getrequires()
|
||||
self._name = config_bag.option.impl_get_display_name()
|
||||
self._orig_opt = None
|
||||
self._config_bag = config_bag.copy('nooption')
|
||||
self.proptype = proptype
|
||||
self._settings = settings
|
||||
self._datas = datas
|
||||
self._type = option_type
|
||||
self._orig_opt = None
|
||||
super(PropertiesOptionError, self).__init__(msg)
|
||||
self.msg = None
|
||||
super(PropertiesOptionError, self).__init__(None)
|
||||
|
||||
def set_orig_opt(self, opt):
|
||||
self._orig_opt = opt
|
||||
|
||||
def __str__(self):
|
||||
#this part is a bit slow, so only execute when display
|
||||
if self._settings is None:
|
||||
req = {}
|
||||
else:
|
||||
req = self._settings.apply_requires(**self._datas)
|
||||
if self.msg:
|
||||
return self.msg
|
||||
req = self._settings.apply_requires(self._path,
|
||||
self._requires,
|
||||
self._index,
|
||||
True,
|
||||
self._config_bag)
|
||||
#if req != {} or self._orig_opt is not None:
|
||||
if req != {}:
|
||||
only_one = len(req) == 1
|
||||
|
@ -91,17 +112,20 @@ class PropertiesOptionError(AttributeError):
|
|||
else:
|
||||
prop_msg = _('properties')
|
||||
if self._orig_opt:
|
||||
return str(_('cannot access to {0} "{1}" because "{2}" has {3} {4}'
|
||||
'').format(self._type,
|
||||
self._orig_opt.impl_get_display_name(),
|
||||
self._datas['config_bag'].option.impl_get_display_name(),
|
||||
self.msg = str(_('cannot access to {0} "{1}" because "{2}" has {3} {4}'
|
||||
'').format(self._opt_type,
|
||||
self._orig_opt.impl_get_display_name(),
|
||||
self._name,
|
||||
prop_msg,
|
||||
msg))
|
||||
self.msg = str(_('cannot access to {0} "{1}" because has {2} {3}'
|
||||
'').format(self._opt_type,
|
||||
self._name,
|
||||
prop_msg,
|
||||
msg))
|
||||
return str(_('cannot access to {0} "{1}" because has {2} {3}'
|
||||
'').format(self._type,
|
||||
self._datas['config_bag'].option.impl_get_display_name(),
|
||||
prop_msg,
|
||||
msg))
|
||||
del self._path, self._index, self._requires, self._opt_type, self._name, self._config_bag
|
||||
del self._settings, self._orig_opt
|
||||
return self.msg
|
||||
|
||||
|
||||
#____________________________________________________________
|
||||
|
|
|
@ -25,7 +25,7 @@ from inspect import signature
|
|||
|
||||
from ..i18n import _
|
||||
from ..setting import undefined
|
||||
from ..error import ConfigError
|
||||
from ..error import ConfigError, display_list
|
||||
|
||||
STATIC_TUPLE = frozenset()
|
||||
|
||||
|
@ -162,7 +162,7 @@ class Base(object):
|
|||
set_forbidden_properties = calc_properties & properties
|
||||
if set_forbidden_properties != frozenset():
|
||||
raise ValueError(_('conflict: properties already set in '
|
||||
'requirement {0}').format(list(set_forbidden_properties)))
|
||||
'requirement {0}').format(display_list(list(set_forbidden_properties))))
|
||||
_setattr = object.__setattr__
|
||||
_setattr(self, '_name', name)
|
||||
_setattr(self, '_informations', {'doc': doc})
|
||||
|
@ -249,10 +249,9 @@ class Base(object):
|
|||
if calculator_args or calculator_kwargs:
|
||||
# there is more args/kwargs than expected!
|
||||
raise ConfigError(_('cannot find those arguments "{}" in function "{}" for "{}"'
|
||||
'').format(list(calculator_args | calculator_kwargs),
|
||||
'').format(display_list(list(calculator_args | calculator_kwargs)),
|
||||
calculator.__name__,
|
||||
self.impl_get_display_name()))
|
||||
has_self = False
|
||||
has_index = False
|
||||
if is_multi and func_args:
|
||||
# there is extra args/kwargs
|
||||
|
@ -267,16 +266,13 @@ class Base(object):
|
|||
has_index = True
|
||||
params.append(('index',))
|
||||
func_args.pop()
|
||||
if func_args:
|
||||
raise ConfigError(_('missing those arguements "{}" in function "{}" for "{}"'
|
||||
'').format(list(func_args),
|
||||
calculator.__name__,
|
||||
self.impl_get_display_name()))
|
||||
calculator_params[''] = tuple(params)
|
||||
if func_args:
|
||||
raise ConfigError(_('missing those arguments "{}" in function "{}" for "{}"'
|
||||
'').format(display_list(list(func_args)),
|
||||
calculator.__name__,
|
||||
self.impl_get_display_name()))
|
||||
if not self.impl_is_optiondescription() and self.impl_is_multi():
|
||||
if add_value and not has_self and 'self' in func_kwargs:
|
||||
# only for validator
|
||||
calculator_params['self'] = (self, False)
|
||||
if not has_index and 'index' in func_kwargs:
|
||||
calculator_params['index'] = (('index',),)
|
||||
return calculator_params
|
||||
|
@ -573,8 +569,9 @@ def validate_requires_arg(new_option,
|
|||
option = exp['option']
|
||||
option._add_dependency(new_option)
|
||||
if option is not None:
|
||||
err = option._validate(exp['value'], undefined)
|
||||
if err:
|
||||
try:
|
||||
option._validate(exp['value'], undefined)
|
||||
except ValueError as err:
|
||||
raise ValueError(_('malformed requirements expected value '
|
||||
'must be valid for option {0}'
|
||||
': {1}').format(name, err))
|
||||
|
@ -588,11 +585,13 @@ def validate_requires_arg(new_option,
|
|||
else:
|
||||
option = get_option(require)
|
||||
if expected is not None:
|
||||
err = option._validate(expected, undefined)
|
||||
if err:
|
||||
try:
|
||||
option._validate(expected, undefined)
|
||||
except ValueError as err:
|
||||
raise ValueError(_('malformed requirements expected value '
|
||||
'must be valid for option {0}'
|
||||
': {1}').format(name, err))
|
||||
option._add_dependency(new_option)
|
||||
_set_expected(action,
|
||||
inverse,
|
||||
transitive,
|
||||
|
|
|
@ -373,6 +373,7 @@ class Settings(object):
|
|||
apply_requires)
|
||||
if apply_requires:
|
||||
props |= self.apply_requires(path,
|
||||
opt.impl_getrequires(),
|
||||
index,
|
||||
False,
|
||||
config_bag)
|
||||
|
@ -405,9 +406,11 @@ class Settings(object):
|
|||
|
||||
def apply_requires(self,
|
||||
path,
|
||||
current_requires,
|
||||
index,
|
||||
debug,
|
||||
config_bag):
|
||||
readable,
|
||||
config_bag,
|
||||
name=None):
|
||||
"""carries out the jit (just in time) requirements between options
|
||||
|
||||
a requirement is a tuple of this form that comes from the option's
|
||||
|
@ -451,11 +454,10 @@ class Settings(object):
|
|||
:param path: the option's path in the config
|
||||
:type path: str
|
||||
"""
|
||||
opt = config_bag.option
|
||||
current_requires = opt.impl_getrequires()
|
||||
#current_requires = opt.impl_getrequires()
|
||||
|
||||
# filters the callbacks
|
||||
if debug:
|
||||
if readable:
|
||||
calc_properties = {}
|
||||
else:
|
||||
calc_properties = set()
|
||||
|
@ -467,25 +469,21 @@ class Settings(object):
|
|||
all_properties = None
|
||||
for requires in current_requires:
|
||||
for require in requires:
|
||||
exps, action, inverse, \
|
||||
transitive, same_action, operator = require
|
||||
exps, action, inverse, transitive, same_action, operator = require
|
||||
breaked = False
|
||||
for exp in exps:
|
||||
option, expected = exp
|
||||
for option, expected in exps:
|
||||
reqpath = option.impl_getpath(context)
|
||||
if reqpath == path or reqpath.startswith(path + '.'): # pragma: optional cover
|
||||
#FIXME c'est un peut tard !
|
||||
if reqpath == path or reqpath.startswith(path + '.'):
|
||||
raise RequirementError(_("malformed requirements "
|
||||
"imbrication detected for option:"
|
||||
" '{0}' with requirement on: "
|
||||
"'{1}'").format(path, reqpath))
|
||||
if not option.impl_is_multi():
|
||||
idx = None
|
||||
is_indexed = False
|
||||
elif option.impl_is_master_slaves('slave'):
|
||||
idx = None
|
||||
is_indexed = False
|
||||
if option.impl_is_master_slaves('slave'):
|
||||
idx = index
|
||||
is_indexed = False
|
||||
else:
|
||||
idx = None
|
||||
elif option.impl_is_multi():
|
||||
is_indexed = True
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.option = option
|
||||
|
@ -497,40 +495,44 @@ class Settings(object):
|
|||
if is_indexed:
|
||||
value = value[index]
|
||||
except PropertiesOptionError as err:
|
||||
properties = err.proptype
|
||||
if not transitive:
|
||||
if all_properties is None:
|
||||
all_properties = []
|
||||
for requires_ in opt.impl_getrequires():
|
||||
for requires_ in current_requires:
|
||||
for require_ in requires_:
|
||||
all_properties.append(require_[1])
|
||||
if not set(err.proptype) - set(all_properties):
|
||||
if not set(properties) - set(all_properties):
|
||||
continue
|
||||
properties = err.proptype
|
||||
if same_action and action not in properties: # pragma: optional cover
|
||||
if same_action and action not in properties:
|
||||
if len(properties) == 1:
|
||||
prop_msg = _('property')
|
||||
else:
|
||||
prop_msg = _('properties')
|
||||
raise RequirementError(_('cannot access to option "{0}" because '
|
||||
'required option "{1}" has {2} {3}'
|
||||
'').format(opt.impl_get_display_name(),
|
||||
'').format(name,
|
||||
option.impl_get_display_name(),
|
||||
prop_msg,
|
||||
display_list(list(properties))))
|
||||
orig_value = err
|
||||
# transitive action, force expected
|
||||
value = expected[0]
|
||||
inverse = False
|
||||
else:
|
||||
orig_value = value
|
||||
if (not inverse and value in expected or
|
||||
inverse and value not in expected):
|
||||
# transitive action, add action
|
||||
if operator != 'and':
|
||||
if debug:
|
||||
if isinstance(orig_value, PropertiesOptionError):
|
||||
for msg in orig_value._settings.apply_requires(**orig_value._datas).values():
|
||||
calc_properties.setdefault(action, []).extend(msg)
|
||||
else:
|
||||
if readable:
|
||||
for msg in self.apply_requires(err.path,
|
||||
err.requires,
|
||||
err.index,
|
||||
True,
|
||||
err.config_bag).values():
|
||||
calc_properties.setdefault(action, []).extend(msg)
|
||||
else:
|
||||
calc_properties.add(action)
|
||||
breaked = True
|
||||
break
|
||||
else:
|
||||
if (not inverse and value in expected or
|
||||
inverse and value not in expected):
|
||||
if operator != 'and':
|
||||
if readable:
|
||||
if not inverse:
|
||||
msg = _('the value of "{0}" is {1}')
|
||||
else:
|
||||
|
@ -538,12 +540,12 @@ class Settings(object):
|
|||
calc_properties.setdefault(action, []).append(
|
||||
msg.format(option.impl_get_display_name(),
|
||||
display_list(expected, 'or', add_quote=True)))
|
||||
else:
|
||||
calc_properties.add(action)
|
||||
breaked = True
|
||||
break
|
||||
elif operator == 'and':
|
||||
break
|
||||
else:
|
||||
calc_properties.add(action)
|
||||
breaked = True
|
||||
break
|
||||
elif operator == 'and':
|
||||
break
|
||||
else:
|
||||
if operator == 'and':
|
||||
calc_properties.add(action)
|
||||
|
@ -691,11 +693,6 @@ class Settings(object):
|
|||
config_bag)
|
||||
config_bag.properties = self_properties
|
||||
properties = self_properties & config_bag.setting_properties - {'frozen', 'mandatory', 'empty'}
|
||||
if not opt.impl_is_optiondescription():
|
||||
opt_type = 'option'
|
||||
else:
|
||||
opt_type = 'optiondescription'
|
||||
|
||||
|
||||
# remove permissive properties
|
||||
if (config_bag.force_permissive is True or 'permissive' in config_bag.setting_properties) and properties:
|
||||
|
@ -703,15 +700,11 @@ class Settings(object):
|
|||
properties -= self.get_context_permissive()
|
||||
# at this point an option should not remain in properties
|
||||
if properties != frozenset():
|
||||
datas = {'path': path,
|
||||
'config_bag': config_bag,
|
||||
'index': index,
|
||||
'debug': True}
|
||||
raise PropertiesOptionError(None,
|
||||
raise PropertiesOptionError(path,
|
||||
index,
|
||||
config_bag,
|
||||
properties,
|
||||
self,
|
||||
datas,
|
||||
opt_type)
|
||||
self)
|
||||
|
||||
def validate_mandatory(self,
|
||||
path,
|
||||
|
@ -735,17 +728,15 @@ class Settings(object):
|
|||
index=index):
|
||||
is_mandatory = True
|
||||
if is_mandatory:
|
||||
datas = {'path': path,
|
||||
'config_bag': config_bag,
|
||||
'index': index,
|
||||
'debug': True}
|
||||
raise PropertiesOptionError(None,
|
||||
raise PropertiesOptionError(path,
|
||||
index,
|
||||
config_bag,
|
||||
['mandatory'],
|
||||
self,
|
||||
datas,
|
||||
'option')
|
||||
self)
|
||||
|
||||
def validate_frozen(self,
|
||||
path,
|
||||
index,
|
||||
config_bag):
|
||||
if config_bag.setting_properties and \
|
||||
('everything_frozen' in config_bag.setting_properties or
|
||||
|
@ -753,7 +744,11 @@ class Settings(object):
|
|||
not ((config_bag.force_permissive is True or
|
||||
'permissive' in config_bag.setting_properties) and
|
||||
'frozen' in self.get_context_permissive()):
|
||||
return True
|
||||
raise PropertiesOptionError(path,
|
||||
index,
|
||||
config_bag,
|
||||
['frozen'],
|
||||
self)
|
||||
return False
|
||||
#____________________________________________________________
|
||||
# read only/read write
|
||||
|
|
|
@ -56,7 +56,7 @@ class Values(object):
|
|||
old `SubConfig`, `Values`, `Multi` or `Settings`)
|
||||
"""
|
||||
context = self.context()
|
||||
if context is None:
|
||||
if context is None: # pragma: no cover
|
||||
raise ConfigError(_('the context does not exist anymore'))
|
||||
return context
|
||||
|
||||
|
@ -242,7 +242,7 @@ class Values(object):
|
|||
# if value is a list and index is set
|
||||
if opt.impl_is_submulti() and (value == [] or not isinstance(value[0], list)):
|
||||
# return value only if it's a submulti and not a list of list
|
||||
_reset_cache(value,)
|
||||
_reset_cache(value)
|
||||
return value
|
||||
|
||||
if len(value) > index:
|
||||
|
@ -251,28 +251,20 @@ class Values(object):
|
|||
return value[index]
|
||||
# there is no calculate value for this index,
|
||||
# so return an other default value
|
||||
elif isinstance(value, list):
|
||||
# value is a list, but no index specified
|
||||
if opt.impl_is_submulti() and (value != [] and not isinstance(value[0], list)):
|
||||
# if submulti, return a list of value
|
||||
value = [value]
|
||||
_reset_cache(value)
|
||||
return value
|
||||
# otherwise just return the value
|
||||
return value
|
||||
elif index is not None:
|
||||
# if not list but with index
|
||||
if opt.impl_is_submulti():
|
||||
# if submulti, return a list of value
|
||||
value = [value]
|
||||
_reset_cache(value)
|
||||
return value
|
||||
else:
|
||||
# not a list or index is None
|
||||
if opt.impl_is_submulti():
|
||||
# return a list of list for a submulti
|
||||
value = [[value]]
|
||||
elif opt.impl_is_multi():
|
||||
if isinstance(value, list):
|
||||
# value is a list, but no index specified
|
||||
if (value != [] and not isinstance(value[0], list)):
|
||||
# if submulti, return a list of value
|
||||
value = [value]
|
||||
elif index is not None:
|
||||
# if submulti, return a list of value
|
||||
value = [value]
|
||||
else:
|
||||
# return a list of list for a submulti
|
||||
value = [[value]]
|
||||
elif opt.impl_is_multi() and not isinstance(value, list) and index is None:
|
||||
# return a list for a multi
|
||||
value = [value]
|
||||
_reset_cache(value)
|
||||
|
@ -375,16 +367,9 @@ class Values(object):
|
|||
config_bag)
|
||||
config_bag.properties = self_properties
|
||||
opt = config_bag.option
|
||||
if settings.validate_frozen(config_bag):
|
||||
datas = {'path': path,
|
||||
'config_bag': config_bag,
|
||||
'index': index,
|
||||
'debug': True}
|
||||
raise PropertiesOptionError(None,
|
||||
['frozen'],
|
||||
settings,
|
||||
datas,
|
||||
'option')
|
||||
settings.validate_frozen(path,
|
||||
index,
|
||||
config_bag)
|
||||
settings.validate_mandatory(path,
|
||||
index,
|
||||
value,
|
||||
|
@ -673,16 +658,9 @@ class Values(object):
|
|||
None,
|
||||
config_bag)
|
||||
config_bag.properties = self_properties
|
||||
if settings.validate_frozen(config_bag):
|
||||
datas = {'path': path,
|
||||
'config_bag': config_bag,
|
||||
'index': index,
|
||||
'debug': True}
|
||||
raise PropertiesOptionError(None,
|
||||
['frozen'],
|
||||
settings,
|
||||
datas,
|
||||
'option')
|
||||
settings.validate_frozen(path,
|
||||
index,
|
||||
config_bag)
|
||||
|
||||
#______________________________________________________________________
|
||||
# information
|
||||
|
|
Loading…
Reference in a new issue