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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -219,71 +219,45 @@ class CacheOptionDescription(BaseOption):
class OptionDescriptionWalk(CacheOptionDescription): class OptionDescriptionWalk(CacheOptionDescription):
__slots__ = ('_children',) __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, def impl_getchild(self,
name, name,
config_bag, config_bag,
subpath): subpath):
if name in self._children[0]: if name in self._children[0]:
child = self._children[1][self._children[0].index(name)] return self._children[1][self._children[0].index(name)]
if not child.impl_is_dynoptiondescription(): for child in self._children[1]:
return child if child.impl_is_dynoptiondescription():
else: cname = child.impl_getname()
child = self._impl_search_dynchild(name, if name.startswith(cname):
for value in child.impl_get_suffixes(config_bag):
if name == cname + value:
return SynDynOptionDescription(child,
subpath, subpath,
config_bag) value)
if child:
return child
raise AttributeError(_('unknown option "{0}" ' raise AttributeError(_('unknown option "{0}" '
'in optiondescription "{1}"' 'in optiondescription "{1}"'
'').format(name, self.impl_getname())) '').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, def impl_get_opt_by_path(self,
path, path,
config_bag): config_bag):
@ -299,58 +273,44 @@ class OptionDescriptionWalk(CacheOptionDescription):
subpath += '.' + step subpath += '.' + step
return opt return opt
def impl_getchildren(self, def impl_get_options(self,
bytype,
byname,
config_bag, config_bag,
dyn=True): self_opt=None):
subpath = None if self_opt is None:
for child in self._impl_st_getchildren(): self_opt = self
if dyn and child.impl_is_dynoptiondescription(): def _filter_by_name(option):
if config_bag.context is None: # pragma: no cover return byname is None or option.impl_getname() == byname
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)
else:
yield child
def _impl_st_getchildren(self, for option in self_opt.impl_getchildren(config_bag):
only_dyn=False): if option.impl_is_optiondescription():
for child in self._children[1]: for subopt in option.impl_get_options(bytype,
if only_dyn is False or child.impl_is_dynoptiondescription(): byname,
yield child
def _impl_search_dynchild(self,
name,
subpath,
config_bag): config_bag):
for child in self._impl_st_getchildren(only_dyn=True): yield subopt
#sconfig_bag = config_bag.copy('nooption') else:
#sconfig_bag.option = child if bytype is not None:
cname = child.impl_getname() if isinstance(option, bytype) and \
if name.startswith(cname): _filter_by_name(option):
option_bag = OptionBag() yield option
option_bag.set_option(child, elif _filter_by_name(option):
subpath, yield option
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, 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_get_dynchild(self,
child, child,
suffix, suffix,
subpath): subpath):

View file

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

View file

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