From c11ae16ea0754f2ee60b5d8087080b224f084178 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Wed, 17 Feb 2021 12:17:53 +0100 Subject: [PATCH] add port_type example --- src/rougail/annotator/condition.py | 10 +- src/rougail/annotator/param.py | 94 +++++++++++-------- src/rougail/tiramisureflector.py | 2 +- .../dictionaries/70port_portlist/00-base.xml | 26 +++++ .../dictionaries/70port_portlist/__init__.py | 0 .../70port_portlist/makedict/base.json | 1 + .../70port_portlist/tiramisu/base.py | 27 ++++++ 7 files changed, 118 insertions(+), 42 deletions(-) create mode 100644 tests/dictionaries/70port_portlist/00-base.xml create mode 100644 tests/dictionaries/70port_portlist/__init__.py create mode 100644 tests/dictionaries/70port_portlist/makedict/base.json create mode 100644 tests/dictionaries/70port_portlist/tiramisu/base.py diff --git a/src/rougail/annotator/condition.py b/src/rougail/annotator/condition.py index 89ebb2ea..09fce084 100644 --- a/src/rougail/annotator/condition.py +++ b/src/rougail/annotator/condition.py @@ -235,8 +235,16 @@ class ConditionAnnotator(TargetAnnotator, ParamAnnotator, Walk): or_needed = len(condition.param) != 1 if len(condition.param) == 1: values = getattr(condition.param[0], 'text', None) + param_type = condition.param[0].type else: values = tuple([getattr(param, 'text', None) for param in condition.param]) + param_type = None + for param in condition.param: + if param_type is None or param_type == 'nil': + param_type = param.type + if param_type != param.type: + msg = _(f'param with type "{target.type}" has multi param types') + raise DictConsistencyError(msg, 59, condition.xmlfiles) param3 = self.objectspace.param(target.xmlfiles) param3.name = f'condition_{fill.index}' param3.type = 'variable' @@ -245,7 +253,7 @@ class ConditionAnnotator(TargetAnnotator, ParamAnnotator, Walk): param4 = self.objectspace.param(target.xmlfiles) param4.name = f'expected_{fill.index}' param4.text = values - param4.type = condition.param[0].type + param4.type = param_type fill.param.append(param4) if condition.name != 'disabled_if_in': param5 = self.objectspace.param(target.xmlfiles) diff --git a/src/rougail/annotator/param.py b/src/rougail/annotator/param.py index c12ab364..a6e763b1 100644 --- a/src/rougail/annotator/param.py +++ b/src/rougail/annotator/param.py @@ -45,54 +45,68 @@ class ParamAnnotator: param_to_delete = [] variable_type = self.valid_type_validation(obj) for param_idx, param in enumerate(obj.param): - if param.type == 'suffix': - if hasattr(param, 'text'): + if hasattr(param, 'text'): + if param.type == 'suffix': msg = _(f'"{param.type}" parameter must not have a value') raise DictConsistencyError(msg, 28, obj.xmlfiles) + elif param.type == 'nil': + if param.text is not None: + msg = _(f'"{param.type}" parameter must not have a value') + raise DictConsistencyError(msg, 40, obj.xmlfiles) + elif param.type == 'variable': + try: + path, suffix = self.objectspace.paths.get_variable_path(param.text, + obj.namespace, + ) + param.text = self.objectspace.paths.get_variable(path) + if variable_type and param.text.type != variable_type: + msg = _(f'"{obj.name}" has type "{variable_type}" but param has type "{param.text.type}"') + raise DictConsistencyError(msg, 26, param.xmlfiles) + if suffix: + param.suffix = suffix + family_path = self.objectspace.paths.get_variable_family_path(path) + param.family = self.objectspace.paths.get_family(family_path, + param.text.namespace, + ) + except DictConsistencyError as err: + if err.errno != 42 or not param.optional: + raise err + param_to_delete.append(param_idx) + elif variable_type: + self._convert_with_variable_type(variable_type, param) + continue + # no param.text + if param.type == 'suffix': for target in obj.target: if not self.objectspace.paths.variable_is_dynamic(target.name.path): msg = _(f'"suffix" parameter cannot be set with target "{target.name}"' f' which is not a dynamic variable') raise DictConsistencyError(msg, 53, obj.xmlfiles) - elif not hasattr(param, 'text'): - if not param.type == 'nil': - msg = _(f'"{param.type}" parameter must have a value') - raise DictConsistencyError(msg, 27, obj.xmlfiles) - param.text = None elif param.type == 'nil': - msg = _(f'"{param.type}" parameter must not have a value') - raise DictConsistencyError(msg, 40, obj.xmlfiles) - elif param.type == 'variable': - try: - path, suffix = self.objectspace.paths.get_variable_path(param.text, - obj.namespace, - ) - param.text = self.objectspace.paths.get_variable(path) - if variable_type and param.text.type != variable_type: - msg = _(f'"{obj.name}" has type "{variable_type}" but param has type "{param.text.type}"') - raise DictConsistencyError(msg, 26, param.xmlfiles) - if suffix: - param.suffix = suffix - family_path = self.objectspace.paths.get_variable_family_path(path) - param.family = self.objectspace.paths.get_family(family_path, - param.text.namespace, - ) - except DictConsistencyError as err: - if err.errno != 42 or not param.optional: - raise err - param_to_delete.append(param_idx) - elif variable_type: - if 'type' in vars(param) and variable_type != param.type: - msg = _(f'parameter has incompatible type "{param.type}" ' - f'with type "{variable_type}"') - raise DictConsistencyError(msg, 7, param.xmlfiles) - try: - param.text = CONVERT_OPTION[variable_type].get('func', str)(param.text) - except ValueError as err: - msg = _(f'unable to change type of "{param.text}" ' - f'is not a valid "{variable_type}"') - raise DictConsistencyError(msg, 13, param.xmlfiles) from err - param.type = variable_type + param.text = None + elif param.type == 'string': + param.text = '' + if variable_type: + self._convert_with_variable_type(variable_type, param) + else: + msg = _(f'"{param.type}" parameter must have a value') + raise DictConsistencyError(msg, 27, obj.xmlfiles) param_to_delete.sort(reverse=True) for param_idx in param_to_delete: obj.param.pop(param_idx) + + def _convert_with_variable_type(self, + variable_type: str, + param: 'self.objectspace.param', + ) -> None: + if 'type' in vars(param) and variable_type != param.type: + msg = _(f'parameter has incompatible type "{param.type}" ' + f'with type "{variable_type}"') + raise DictConsistencyError(msg, 7, param.xmlfiles) + try: + param.text = CONVERT_OPTION[variable_type].get('func', str)(param.text) + except ValueError as err: + msg = _(f'unable to change type of "{param.text}" ' + f'is not a valid "{variable_type}"') + raise DictConsistencyError(msg, 13, param.xmlfiles) from err + param.type = variable_type diff --git a/src/rougail/tiramisureflector.py b/src/rougail/tiramisureflector.py index 0d78bb38..295ab0f5 100644 --- a/src/rougail/tiramisureflector.py +++ b/src/rougail/tiramisureflector.py @@ -242,7 +242,7 @@ class Common: ): """Populate variable parameters """ - if param.type in ['number', 'boolean', 'nil', 'string']: + if param.type in ['number', 'boolean', 'nil', 'string', 'port']: value = param.text if param.type == 'string' and value is not None: value = self.convert_str(value) diff --git a/tests/dictionaries/70port_portlist/00-base.xml b/tests/dictionaries/70port_portlist/00-base.xml new file mode 100644 index 00000000..1a7bf309 --- /dev/null +++ b/tests/dictionaries/70port_portlist/00-base.xml @@ -0,0 +1,26 @@ + + + + + + + my_variable + my_variable + + + + + + 123 + + + + + + + example + + + + diff --git a/tests/dictionaries/70port_portlist/__init__.py b/tests/dictionaries/70port_portlist/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/dictionaries/70port_portlist/makedict/base.json b/tests/dictionaries/70port_portlist/makedict/base.json new file mode 100644 index 00000000..8445ec19 --- /dev/null +++ b/tests/dictionaries/70port_portlist/makedict/base.json @@ -0,0 +1 @@ +{"rougail.my_variable": "123", "services.ntp.ports.my_variable.name": "123", "services.ntp.ports.my_variable.protocol": "udp", "services.ntp.ports.my_variable.activate": true, "services.ntp.ports.my_variable_1.name": "123", "services.ntp.ports.my_variable_1.protocol": "tcp", "services.ntp.ports.my_variable_1.activate": true} diff --git a/tests/dictionaries/70port_portlist/tiramisu/base.py b/tests/dictionaries/70port_portlist/tiramisu/base.py new file mode 100644 index 00000000..e568c1f3 --- /dev/null +++ b/tests/dictionaries/70port_portlist/tiramisu/base.py @@ -0,0 +1,27 @@ +from importlib.machinery import SourceFileLoader +from importlib.util import spec_from_loader, module_from_spec +loader = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py') +spec = spec_from_loader(loader.name, loader) +func = module_from_spec(spec) +loader.exec_module(func) +for key, value in dict(locals()).items(): + if key != ['SourceFileLoader', 'func']: + setattr(func, key, value) +try: + from tiramisu3 import * +except: + from tiramisu import * +option_2 = PortOption(name="my_variable", doc="my_variable", default="123", allow_private=True, properties=frozenset({"mandatory", "normal"})) +option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2]) +option_7 = SymLinkOption(name="name", opt=option_2) +option_8 = StrOption(name="protocol", doc="protocol", default="udp") +option_9 = BoolOption(name="activate", doc="activate", default=Calculation(func.calc_value, Params((ParamValue(False)), kwargs={'default': ParamValue(True), 'condition_0': ParamOption(option_2), 'expected_0': ParamValue((None, '')), 'condition_operator': ParamValue("OR")}))) +option_6 = OptionDescription(name="my_variable", doc="my_variable", children=[option_7, option_8, option_9]) +option_11 = SymLinkOption(name="name", opt=option_2) +option_12 = StrOption(name="protocol", doc="protocol", default="tcp") +option_13 = BoolOption(name="activate", doc="activate", default=Calculation(func.calc_value, Params((ParamValue(False)), kwargs={'default': ParamValue(True), 'condition_0': ParamOption(option_2), 'expected_0': ParamValue((None, '')), 'condition_operator': ParamValue("OR")}))) +option_10 = OptionDescription(name="my_variable_1", doc="my_variable_1", children=[option_11, option_12, option_13]) +option_5 = OptionDescription(name="ports", doc="ports", children=[option_6, option_10]) +option_4 = OptionDescription(name="ntp", doc="ntp", children=[option_5]) +option_3 = OptionDescription(name="services", doc="services", children=[option_4], properties=frozenset({"hidden"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_3])