From 1cd8873e5bf84a6249508c73ad869b6999dd4636 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Sat, 11 Apr 2020 20:45:28 +0200 Subject: [PATCH] add fill/auto with dynamic option --- src/rougail/annotator.py | 7 ++- src/rougail/loader.py | 19 +++++-- src/rougail/objspace.py | 52 ++++++++++++++----- .../20family_dynamic_calc/00-base.xml | 25 +++++++++ .../20family_dynamic_calc/makedict/base.json | 1 + .../20family_dynamic_calc/result/00-base.xml | 31 +++++++++++ 6 files changed, 118 insertions(+), 17 deletions(-) create mode 100644 tests/flattener_dicos/20family_dynamic_calc/00-base.xml create mode 100644 tests/flattener_dicos/20family_dynamic_calc/makedict/base.json create mode 100644 tests/flattener_dicos/20family_dynamic_calc/result/00-base.xml diff --git a/src/rougail/annotator.py b/src/rougail/annotator.py index 7e2bfacc..a38a94f2 100644 --- a/src/rougail/annotator.py +++ b/src/rougail/annotator.py @@ -237,6 +237,7 @@ class ServiceAnnotator: self.paths.add_variable('services', path, 'service', + False, variable, ) return variable @@ -1116,7 +1117,11 @@ class SpaceAnnotator(object): # if param.optional is True: # param_option_indexes.append(fill_idx) try: - param.text = self.paths.get_variable_path(param.text, namespace) + param.text, suffix = self.paths.get_variable_path(param.text, + namespace, + with_suffix=True) + if suffix: + param.suffix = suffix except CreoleDictConsistencyError as err: if param.optional is True: param_option_indexes.append(fill_idx) diff --git a/src/rougail/loader.py b/src/rougail/loader.py index b6637b2f..097a4360 100644 --- a/src/rougail/loader.py +++ b/src/rougail/loader.py @@ -11,7 +11,7 @@ from tiramisu import (StrOption, OptionDescription, DynOptionDescription, PortOp NetworkOption, NetmaskOption, DomainnameOption, BroadcastOption, URLOption, EmailOption, FilenameOption, UsernameOption, DateOption, PasswordOption, BoolOption, MACOption, Leadership, submulti, - Params, ParamSelfOption, ParamOption, ParamValue, Calculation, calc_value, + Params, ParamSelfOption, ParamOption, ParamDynOption, ParamValue, Calculation, calc_value, groups, owners) from tiramisu.error import ConfigError @@ -431,7 +431,7 @@ class Variable(Common): transitive = False else: raise CreoleLoaderError(_('unknown transitive boolean {}').format(transitive)) - value = [param.text, transitive] + value = [param.text, transitive, param.attrib.get('suffix')] elif param.attrib['type'] == 'number': value = int(param.text) else: @@ -462,10 +462,21 @@ class Variable(Common): if len(value) == 3: for param in value[1]: if isinstance(param[1], list): + option = self.storage.get(param[1][0]).get() + param_kwargs = {'notraisepropertyerror': param[1][1]} if value[0] in FUNC_TO_DICT: - param_value = ParamOption(self.storage.get(param[1][0]).get(), notraisepropertyerror=param[1][1], todict=True) + param_kwargs['todict'] = True + if not param[1][2]: + param_value = ParamOption(option, + **param_kwargs, + ) else: - param_value = ParamOption(self.storage.get(param[1][0]).get(), notraisepropertyerror=param[1][1]) + family = '.'.join(param[1][0].split('.', 3)[:2]) + param_value = ParamDynOption(option, + param[1][2], + self.storage.get(family).get(), + **param_kwargs, + ) else: param_value = ParamValue(param[1]) if not param[0]: diff --git a/src/rougail/objspace.py b/src/rougail/objspace.py index 306be9fd..284ec2a7 100644 --- a/src/rougail/objspace.py +++ b/src/rougail/objspace.py @@ -197,6 +197,7 @@ class CreoleObjSpace(object): self.paths.add_variable(namespace, name, family.name, + False, variable_obj, ) return variable_obj @@ -423,7 +424,13 @@ class CreoleObjSpace(object): if list(child) != []: self.xml_parse_document(child, creoleobj, namespace, is_in_family) - def _fill_creoleobj_path_attribute(self, space, child, namespace, document, creoleobj): # pylint: disable=R0913 + def _fill_creoleobj_path_attribute(self, + space, + child, + namespace, + document, + creoleobj, + ): # pylint: disable=R0913 """Fill self.paths attributes """ if not isinstance(space, self.help): # pylint: disable=E1101 @@ -432,6 +439,7 @@ class CreoleObjSpace(object): self.paths.add_variable(namespace, child.attrib['name'], family_name, + document.attrib.get('dynamic') != None, creoleobj) if child.attrib.get('redefine', 'False') == 'True': if namespace == 'creole': @@ -655,8 +663,10 @@ class Path: new_path = namespace + '.' + leader_family_name + '.' + leader_name + '.' + name self.add_variable(namespace, new_path, - family=dico['family'], - creoleobj=dico['creoleobj']) + dico['family'], + False, + dico['creoleobj'], + ) name = new_path dico = self._get_variable(name) if dico['leader'] != None: @@ -671,8 +681,9 @@ class Path: def add_variable(self, namespace: str, name: str, - family: str=None, - creoleobj=None, + family: str, + is_dynamic: bool, + creoleobj, ) -> str: # pylint: disable=C0111 if namespace == 'creole' or '.' in name: varname = name @@ -682,6 +693,7 @@ class Path: family=family, namespace=namespace, leader=None, + is_dynamic=is_dynamic, creoleobj=creoleobj) def get_variable_name(self, @@ -717,22 +729,32 @@ class Path: name: str, current_namespace: str, allow_source: str=False, + with_suffix: bool=False, ) -> str: # pylint: disable=C0111 if current_namespace is None: # pragma: no cover raise CreoleOperationError('current_namespace must not be None') - dico = self._get_variable(name) + if with_suffix: + dico, suffix = self._get_variable(name, + with_suffix=True, + ) + else: + dico = self._get_variable(name) if not allow_source: if dico['namespace'] not in ['creole', 'services'] and current_namespace != dico['namespace']: raise CreoleDictConsistencyError(_('A variable located in the {} namespace ' 'shall not be used in the {} namespace').format( dico['namespace'], current_namespace)) if '.' in dico['name']: - return dico['name'] - list_path = [dico['namespace'], dico['family']] - if dico['leader'] is not None: - list_path.append(dico['leader']) - list_path.append(dico['name']) - return '.'.join(list_path) + value = dico['name'] + else: + list_path = [dico['namespace'], dico['family']] + if dico['leader'] is not None: + list_path.append(dico['leader']) + list_path.append(dico['name']) + value = '.'.join(list_path) + if with_suffix: + return value, suffix + return value def path_is_defined(self, name: str, @@ -741,10 +763,16 @@ class Path: def _get_variable(self, name: str, + with_suffix: bool=False, ) -> str: if name not in self.variables: if name.startswith('creole.'): name = name.split('.')[-1] if name not in self.variables: + for var_name, variable in self.variables.items(): + if variable['is_dynamic'] and name.startswith(var_name): + return variable, name[len(var_name):] raise CreoleDictConsistencyError(_('unknown option {}').format(name)) + if with_suffix: + return self.variables[name], None return self.variables[name] diff --git a/tests/flattener_dicos/20family_dynamic_calc/00-base.xml b/tests/flattener_dicos/20family_dynamic_calc/00-base.xml new file mode 100644 index 00000000..7fa2ca78 --- /dev/null +++ b/tests/flattener_dicos/20family_dynamic_calc/00-base.xml @@ -0,0 +1,25 @@ + + + + + + + val1 + val2 + + + + + val + + + + + + + + + vardynval1 + + + diff --git a/tests/flattener_dicos/20family_dynamic_calc/makedict/base.json b/tests/flattener_dicos/20family_dynamic_calc/makedict/base.json new file mode 100644 index 00000000..0f79db59 --- /dev/null +++ b/tests/flattener_dicos/20family_dynamic_calc/makedict/base.json @@ -0,0 +1 @@ +{"creole.general.varname": ["val1", "val2"], "creole.dynval1.vardynval1": "val", "creole.dynval2.vardynval2": "val", "creole.new.newvar": null} diff --git a/tests/flattener_dicos/20family_dynamic_calc/result/00-base.xml b/tests/flattener_dicos/20family_dynamic_calc/result/00-base.xml new file mode 100644 index 00000000..ed8c4a24 --- /dev/null +++ b/tests/flattener_dicos/20family_dynamic_calc/result/00-base.xml @@ -0,0 +1,31 @@ + + + + + normal + + mandatory + normal + val1 + val2 + + + + normal + + mandatory + normal + val + + + + normal + + normal + + creole.dyn.vardyn + + + + +