From fbff3d9ced239bc127f2fe0bdc9df96c1969a8f1 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Sun, 30 Sep 2018 20:32:00 +0200 Subject: [PATCH] simplify optiondescription --- tiramisu/autolib.py | 48 +++--- tiramisu/config.py | 17 +- tiramisu/option/choiceoption.py | 8 +- tiramisu/option/dynoptiondescription.py | 10 +- tiramisu/option/dynsymlinkoption.py | 2 - tiramisu/option/option.py | 5 +- tiramisu/option/optiondescription.py | 174 ++++++++------------- tiramisu/option/syndynoptiondescription.py | 30 ++-- tiramisu/value.py | 12 +- 9 files changed, 124 insertions(+), 182 deletions(-) diff --git a/tiramisu/autolib.py b/tiramisu/autolib.py index ee02fe1..f8b8558 100644 --- a/tiramisu/autolib.py +++ b/tiramisu/autolib.py @@ -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 diff --git a/tiramisu/config.py b/tiramisu/config.py index 723d8cd..8af9eb2 100644 --- a/tiramisu/config.py +++ b/tiramisu/config.py @@ -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, diff --git a/tiramisu/option/choiceoption.py b/tiramisu/option/choiceoption.py index e6b47d8..33b0bd8 100644 --- a/tiramisu/option/choiceoption.py +++ b/tiramisu/option/choiceoption.py @@ -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())) diff --git a/tiramisu/option/dynoptiondescription.py b/tiramisu/option/dynoptiondescription.py index a328425..1e70beb 100644 --- a/tiramisu/option/dynoptiondescription.py +++ b/tiramisu/option/dynoptiondescription.py @@ -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, diff --git a/tiramisu/option/dynsymlinkoption.py b/tiramisu/option/dynsymlinkoption.py index 2e814b0..9dbc957 100644 --- a/tiramisu/option/dynsymlinkoption.py +++ b/tiramisu/option/dynsymlinkoption.py @@ -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): diff --git a/tiramisu/option/option.py b/tiramisu/option/option.py index 50f3aa7..5a1c1ea 100644 --- a/tiramisu/option/option.py +++ b/tiramisu/option/option.py @@ -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) diff --git a/tiramisu/option/optiondescription.py b/tiramisu/option/optiondescription.py index 5a25e47..837036b 100644 --- a/tiramisu/option/optiondescription.py +++ b/tiramisu/option/optiondescription.py @@ -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, diff --git a/tiramisu/option/syndynoptiondescription.py b/tiramisu/option/syndynoptiondescription.py index 219f5a4..a74f00d 100644 --- a/tiramisu/option/syndynoptiondescription.py +++ b/tiramisu/option/syndynoptiondescription.py @@ -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 diff --git a/tiramisu/value.py b/tiramisu/value.py index 300fcf3..dd72e98 100644 --- a/tiramisu/value.py +++ b/tiramisu/value.py @@ -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,