simplify optiondescription

This commit is contained in:
Emmanuel Garette 2018-09-30 20:32:00 +02:00
parent e29e11b939
commit fbff3d9ced
9 changed files with 124 additions and 182 deletions

View file

@ -33,19 +33,19 @@ def manager_callback(callbk: Union[ParamOption, ParamValue],
option,
index: Optional[int],
orig_value,
option_bag: OptionBag,
context) -> Any:
config_bag: ConfigBag,
fromconsistency: List) -> Any:
"""replace Param by true value"""
if isinstance(callbk, ParamValue):
return callbk.value
if isinstance(callbk, ParamIndex):
return index
if context is undefined:
if config_bag is undefined:
return undefined
if isinstance(callbk, ParamContext):
#Not an option, set full context
return context.duplicate(force_values=get_default_values_storages(),
force_settings=get_default_settings_storages())
return config_bag.context.duplicate(force_values=get_default_values_storages(),
force_settings=get_default_settings_storages())
opt = callbk.option
if opt.issubdyn():
opt = opt.impl_get_dynoption(option._rootpath,
@ -69,23 +69,23 @@ def manager_callback(callbk: Union[ParamOption, ParamValue],
(not opt.impl_is_master_slaves('slave') or index is None):
return orig_value
# don't validate if option is option that we tried to validate
config_bag = option_bag.config_bag.copy()
config_bag = config_bag.copy()
config_bag.set_permissive()
config_bag.properties -= {'warnings'}
soption_bag = OptionBag()
soption_bag.set_option(opt,
path,
index_,
config_bag)
if option_bag.fromconsistency:
soption_bag.fromconsistency = option_bag.fromconsistency.copy()
option_bag = OptionBag()
option_bag.set_option(opt,
path,
index_,
config_bag)
if fromconsistency:
option_bag.fromconsistency = fromconsistency.copy()
if opt == option:
soption_bag.config_bag.properties = frozenset()
soption_bag.config_bag.remove_validation()
option_bag.config_bag.properties = frozenset()
option_bag.config_bag.remove_validation()
try:
# get value
value = context.getattr(path,
soption_bag)
value = config_bag.context.getattr(path,
option_bag)
if with_index:
return value[index]
return value
@ -97,19 +97,17 @@ def manager_callback(callbk: Union[ParamOption, ParamValue],
def carry_out_calculation(option,
context,
callback: Callable,
callback_params: Optional[Params],
index: Optional[int],
option_bag: Optional[OptionBag],
config_bag: Optional[ConfigBag],
fromconsistency: List,
orig_value=undefined,
is_validator: int=False):
"""a function that carries out a calculation for an option's value
:param option: the option
:param context: the context config in order to have
the whole options available
:param callback: the name of the callback function
:type callback: str
:param callback_params: the callback's parameters
@ -227,8 +225,8 @@ def carry_out_calculation(option,
option,
index,
orig_value,
option_bag,
context)
config_bag,
fromconsistency)
if value is undefined:
return undefined
args.append(value)
@ -240,8 +238,8 @@ def carry_out_calculation(option,
option,
index,
orig_value,
option_bag,
context)
config_bag,
fromconsistency)
if value is undefined:
return undefined
kwargs[key] = value

View file

@ -116,7 +116,7 @@ class SubConfig(object):
for woption in option_bag.option._get_dependencies(self):
option = woption()
if option.impl_is_dynoptiondescription():
for doption in option.get_syndynoptiondescriptions(option_bag,
for doption in option.get_syndynoptiondescriptions(option_bag.config_bag,
remove_none=True):
doption_path = doption.impl_getpath()
doption_bag = OptionBag()
@ -136,7 +136,7 @@ class SubConfig(object):
doption_path,
option_bag.index,
option_bag.config_bag)
for doption in desc.build_dynoptions(doption_bag):
for doption in desc.get_dynoptions(doption_bag):
doption_path = doption.impl_getpath()
doption_bag = OptionBag()
doption_bag.set_option(doption,
@ -363,16 +363,15 @@ class SubConfig(object):
found = False
if only_path is not undefined:
options = [(only_path, only_option)]
options = [only_option]
else:
options = self.cfgimpl_get_description().impl_get_options_paths(bytype,
byname,
self.cfgimpl_get_path(),
config_bag)
options = list(options)
options = self.cfgimpl_get_description().impl_get_options(bytype,
byname,
config_bag)
context = self.cfgimpl_get_context()
for path, option in options:
for option in options:
option_bag = OptionBag()
path = option.impl_getpath()
option_bag.set_option(option,
path,
None,

View file

@ -90,16 +90,12 @@ class ChoiceOption(Option):
if option_bag is undefined:
values = undefined
else:
if option_bag.config_bag == undefined:
config = undefined
else:
config = option_bag.config_bag.context
values = carry_out_calculation(current_opt,
context=config,
callback=values,
callback_params=getattr(self, '_choice_values_params', {}),
index=None,
option_bag=option_bag)
config_bag=option_bag.config_bag,
fromconsistency=[])
if values is not undefined and not isinstance(values, list):
raise ConfigError(_('calculated values for {0} is not a list'
'').format(self.impl_getname()))

View file

@ -72,15 +72,15 @@ class DynOptionDescription(OptionDescription):
'').format(self.impl_get_display_name()))
def impl_get_suffixes(self,
option_bag,
config_bag,
remove_none=False):
callback, callback_params = self.impl_get_callback()
values = carry_out_calculation(self,
option_bag.config_bag.context,
callback,
callback_params,
None,
option_bag)
config_bag,
fromconsistency=[])
if not isinstance(values, list):
raise ValueError(_('DynOptionDescription callback for option "{}", is not a list ({})'
'').format(self.impl_get_display_name(), values))
@ -103,10 +103,10 @@ class DynOptionDescription(OptionDescription):
return values_
def get_syndynoptiondescriptions(self,
option_bag,
config_bag,
remove_none=False):
subpath = self.impl_getpath().rsplit('.', 1)[0]
for suffix in self.impl_get_suffixes(option_bag,
for suffix in self.impl_get_suffixes(config_bag,
remove_none=remove_none):
yield SynDynOptionDescription(self,
subpath,

View file

@ -60,7 +60,6 @@ class DynSymLinkOption(object):
def impl_validate(self,
value,
option_bag,
context=undefined,
check_error=True):
context = option_bag.config_bag.context
soption_bag = OptionBag()
@ -72,7 +71,6 @@ class DynSymLinkOption(object):
soption_bag.fromconsistency = option_bag.fromconsistency.copy()
self._opt.impl_validate(value,
soption_bag,
context=context,
check_error=check_error)
def impl_is_dynsymlinkoption(self):

View file

@ -231,7 +231,6 @@ class Option(OnlyOption):
def impl_validate(self,
value,
option_bag,
context=undefined,
check_error=True):
"""
"""
@ -273,11 +272,11 @@ class Option(OnlyOption):
validator_params_ = Params(tuple(args), kwargs)
# Raise ValueError if not valid
carry_out_calculation(option_bag.ori_option,
context=context,
callback=validator,
callback_params=validator_params_,
index=_index,
option_bag=option_bag,
config_bag=option_bag.config_bag,
fromconsistency=option_bag.fromconsistency,
orig_value=value,
is_validator=True)

View file

@ -219,71 +219,45 @@ class CacheOptionDescription(BaseOption):
class OptionDescriptionWalk(CacheOptionDescription):
__slots__ = ('_children',)
def build_dynoptions(self,
option_bag):
option = option_bag.option
dynopt = option.getsubdyn()
rootpath = dynopt.impl_getpath()
ori_index = len(rootpath) + 1
subpaths = [rootpath] + option.impl_getpath()[ori_index:].split('.')[:-1]
for suffix in dynopt.impl_get_suffixes(option_bag):
subpath = '.'.join([subp + suffix for subp in subpaths])
if isinstance(option, OnlyOption):
yield option.impl_get_dynoption(subpath,
suffix)
else:
yield SynDynOptionDescription(option,
subpath,
suffix)
def impl_get_options_paths(self,
bytype,
byname,
_subpath,
config_bag,
self_opt=None):
if self_opt is None:
self_opt = self
def _filter_by_name(option):
return byname is None or option.impl_getname() == byname
for option in self_opt.impl_getchildren(config_bag):
if _subpath is None:
path = option.impl_getname()
else:
path = _subpath + '.' + option.impl_getname()
if option.impl_is_optiondescription():
for subopt in option.impl_get_options_paths(bytype,
byname,
path,
config_bag):
yield subopt
else:
if bytype is not None:
if isinstance(option, bytype) and \
_filter_by_name(option):
yield (path, option)
elif _filter_by_name(option):
yield (path, option)
def impl_getchild(self,
name,
config_bag,
subpath):
if name in self._children[0]:
child = self._children[1][self._children[0].index(name)]
if not child.impl_is_dynoptiondescription():
return child
else:
child = self._impl_search_dynchild(name,
subpath,
config_bag)
if child:
return child
return self._children[1][self._children[0].index(name)]
for child in self._children[1]:
if child.impl_is_dynoptiondescription():
cname = child.impl_getname()
if name.startswith(cname):
for value in child.impl_get_suffixes(config_bag):
if name == cname + value:
return SynDynOptionDescription(child,
subpath,
value)
raise AttributeError(_('unknown option "{0}" '
'in optiondescription "{1}"'
'').format(name, self.impl_getname()))
def impl_getchildren(self,
config_bag,
dyn=True):
subpath = None
for child in self._children[1]:
if dyn and child.impl_is_dynoptiondescription():
if config_bag.context is None: # pragma: no cover
raise ConfigError(_('need context'))
if subpath is None:
if config_bag.context.cfgimpl_get_description() == self:
subpath = ''
else:
subpath = self.impl_getpath()
for suffix in child.impl_get_suffixes(config_bag):
yield SynDynOptionDescription(child,
subpath,
suffix)
else:
yield child
def impl_get_opt_by_path(self,
path,
config_bag):
@ -299,61 +273,47 @@ class OptionDescriptionWalk(CacheOptionDescription):
subpath += '.' + step
return opt
def impl_getchildren(self,
def impl_get_options(self,
bytype,
byname,
config_bag,
dyn=True):
subpath = None
for child in self._impl_st_getchildren():
if dyn and child.impl_is_dynoptiondescription():
if config_bag.context is None: # pragma: no cover
raise ConfigError(_('need context'))
if subpath is None:
if config_bag.context.cfgimpl_get_description() == self:
subpath = ''
else:
subpath = self.impl_getpath()
option_bag = OptionBag()
option_bag.set_option(child,
subpath,
None,
config_bag)
for suffix in child.impl_get_suffixes(option_bag):
yield SynDynOptionDescription(child,
subpath,
suffix)
self_opt=None):
if self_opt is None:
self_opt = self
def _filter_by_name(option):
return byname is None or option.impl_getname() == byname
for option in self_opt.impl_getchildren(config_bag):
if option.impl_is_optiondescription():
for subopt in option.impl_get_options(bytype,
byname,
config_bag):
yield subopt
else:
yield child
if bytype is not None:
if isinstance(option, bytype) and \
_filter_by_name(option):
yield option
elif _filter_by_name(option):
yield option
def _impl_st_getchildren(self,
only_dyn=False):
for child in self._children[1]:
if only_dyn is False or child.impl_is_dynoptiondescription():
yield child
def get_dynoptions(self,
option_bag):
option = option_bag.option
dynopt = option.getsubdyn()
rootpath = dynopt.impl_getpath()
ori_index = len(rootpath) + 1
subpaths = [rootpath] + option.impl_getpath()[ori_index:].split('.')[:-1]
for suffix in dynopt.impl_get_suffixes(option_bag.config_bag):
subpath = '.'.join([subp + suffix for subp in subpaths])
yield self.impl_get_dynchild(option,
suffix,
subpath)
def _impl_search_dynchild(self,
name,
subpath,
config_bag):
for child in self._impl_st_getchildren(only_dyn=True):
#sconfig_bag = config_bag.copy('nooption')
#sconfig_bag.option = child
cname = child.impl_getname()
if name.startswith(cname):
option_bag = OptionBag()
option_bag.set_option(child,
subpath,
None,
config_bag)
for value in child.impl_get_suffixes(option_bag):
if name == cname + value:
return SynDynOptionDescription(child,
subpath,
value)
def _impl_get_dynchild(self,
child,
suffix,
subpath):
def impl_get_dynchild(self,
child,
suffix,
subpath):
if isinstance(child, OptionDescription):
return SynDynOptionDescription(child,
subpath,

View file

@ -49,9 +49,9 @@ class SynDynOptionDescription(object):
if name.endswith(self._suffix):
oname = name[:-len(self._suffix)]
child = self._children[1][self._children[0].index(oname)]
return self._impl_get_dynchild(child,
self._suffix,
subpath)
return self.impl_get_dynchild(child,
self._suffix,
subpath)
except ValueError:
# when oname not in self._children
pass
@ -68,20 +68,18 @@ class SynDynOptionDescription(object):
children = []
subpath = self.impl_getpath()
for child in self._opt.impl_getchildren(config_bag):
yield(self._opt._impl_get_dynchild(child,
self._suffix,
subpath))
yield self._opt.impl_get_dynchild(child,
self._suffix,
subpath)
def impl_get_options_paths(self,
bytype,
byname,
_subpath,
config_bag):
return self._opt.impl_get_options_paths(bytype,
byname,
_subpath,
config_bag,
self)
def impl_get_options(self,
bytype,
byname,
config_bag):
return self._opt.impl_get_options(bytype,
byname,
config_bag,
self)
def impl_getpath(self):
subpath = self._subpath

View file

@ -72,16 +72,13 @@ class Values(object):
# no cached value so get value
value = self.getvalue(option_bag)
# validate value
context = option_bag.config_bag.context
opt = option_bag.option
opt.impl_validate(value,
option_bag,
context=context,
check_error=True)
if 'warnings' in setting_properties:
opt.impl_validate(value,
option_bag,
context=context,
check_error=False)
# store value in cache
if not is_cached:
@ -170,11 +167,11 @@ class Values(object):
# if value has callback, calculate value
callback, callback_params = opt.impl_get_callback()
value = carry_out_calculation(opt,
context=context,
callback=callback,
callback_params=callback_params,
index=index,
option_bag=option_bag)
config_bag=config_bag,
fromconsistency=option_bag.fromconsistency)
if isinstance(value, list) and index is not None:
# if value is a list and index is set
if opt.impl_is_submulti() and (value == [] or not isinstance(value[0], list)):
@ -281,8 +278,7 @@ class Values(object):
value,
option_bag):
context = option_bag.config_bag.context
settings = context.cfgimpl_get_settings()
settings = option_bag.config_bag.context.cfgimpl_get_settings()
# First validate properties with this value
opt = option_bag.option
settings.validate_frozen(option_bag)
@ -291,13 +287,11 @@ class Values(object):
# Value must be valid for option
opt.impl_validate(value,
option_bag,
context,
check_error=True)
if 'warnings' in option_bag.config_bag.properties:
# No error found so emit warnings
opt.impl_validate(value,
option_bag,
context,
check_error=False)
def _setvalue(self,