diff --git a/src/rougail/annotator/constrainte.py b/src/rougail/annotator/constrainte.py index 6a53f56d..38cca26f 100644 --- a/src/rougail/annotator/constrainte.py +++ b/src/rougail/annotator/constrainte.py @@ -116,6 +116,17 @@ class ConstrainteAnnotator: xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles) msg = _(f'cannot find check function "{check.name}" in {xmlfiles}') raise DictConsistencyError(msg, 1) + check.is_in_leadership = self.objectspace.paths.get_leader(check.target) is not None + # let's replace the target by the path + try: + check.target = self.objectspace.paths.get_variable_obj(check.target) + except DictConsistencyError as err: + if err.errno == 36: + xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles) + msg = _(f'the target "{check.target}" in check cannot be a dynamic ' + f'variable in {xmlfiles}') + raise DictConsistencyError(msg, 22) + raise err if not hasattr(check, 'param'): continue param_option_indexes = [] @@ -129,20 +140,19 @@ class ConstrainteAnnotator: param_option_indexes.append(idx) else: # let's replace params by the path - param.text = self.objectspace.paths.get_variable_path(param.text, - check.namespace, - ) + param.text, suffix = self.objectspace.paths.get_variable_path(param.text, + check.namespace, + ) + if suffix: + xmlfiles = self.objectspace.display_xmlfiles(param.xmlfiles) + msg = _(f'the param "{param.text}" in check cannot be a dynamic ' + f'variable in {xmlfiles}') + raise DictConsistencyError(msg, 23) param_option_indexes.sort(reverse=True) for idx in param_option_indexes: check.param.pop(idx) if check.param == []: remove_indexes.append(check_idx) - continue - # let's replace the target by the path - check.target = self.objectspace.paths.get_variable_path(check.target, - check.namespace, - ) - check.is_in_leadership = self.objectspace.paths.get_leader(check.target) is not None remove_indexes.sort(reverse=True) for idx in remove_indexes: del self.objectspace.space.constraints.check[idx] @@ -152,35 +162,35 @@ class ConstrainteAnnotator: """ remove_indexes = [] for idx, check in enumerate(self.objectspace.space.constraints.check): - if check.name == 'valid_enum': - if check.target in self.valid_enums: - check_xmlfiles = self.valid_enums[check.target]['xmlfiles'] - old_xmlfiles = self.objectspace.display_xmlfiles(check_xmlfiles) - xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles) - msg = _(f'valid_enum define in {xmlfiles} but already set in {old_xmlfiles} ' - f'for "{check.target}", did you forget remove_check?') - raise DictConsistencyError(msg, 3) - if not hasattr(check, 'param'): - xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles) - msg = _(f'param is mandatory for a valid_enum of variable "{check.target}" ' - f'in {xmlfiles}') - raise DictConsistencyError(msg, 4) - variable = self.objectspace.paths.get_variable_obj(check.target) - variable_type = variable.type - values = self._set_valid_enum(variable, - check, - ) - if values: - if hasattr(variable, 'value'): - # check value - check_valid_enum_value(variable, values) - else: - # no value, set the first choice has default value - new_value = self.objectspace.value(check.xmlfiles) - new_value.name = values[0] - new_value.type = variable_type - variable.value = [new_value] - remove_indexes.append(idx) + if check.name != 'valid_enum': + continue + if check.target.path in self.valid_enums: + check_xmlfiles = self.valid_enums[check.target.path]['xmlfiles'] + old_xmlfiles = self.objectspace.display_xmlfiles(check_xmlfiles) + xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles) + msg = _(f'valid_enum define in {xmlfiles} but already set in {old_xmlfiles} ' + f'for "{check.target.name}", did you forget remove_check?') + raise DictConsistencyError(msg, 3) + if not hasattr(check, 'param'): + xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles) + msg = _(f'param is mandatory for a valid_enum of variable "{check.target.name}" ' + f'in {xmlfiles}') + raise DictConsistencyError(msg, 4) + variable_type = check.target.type + values = self._set_valid_enum(check.target, + check, + ) + if values: + if hasattr(check.target, 'value'): + # check value + check_valid_enum_value(check.target, values) + else: + # no value, set the first choice has default value + new_value = self.objectspace.value(check.xmlfiles) + new_value.name = values[0] + new_value.type = variable_type + check.target.value = [new_value] + remove_indexes.append(idx) remove_indexes.sort(reverse=True) for idx in remove_indexes: del self.objectspace.space.constraints.check[idx] @@ -250,10 +260,10 @@ class ConstrainteAnnotator: if has_variable: return None - self.valid_enums[check.target] = {'type': variable_type, - 'values': values, - 'xmlfiles': check.xmlfiles, - } + self.valid_enums[check.target.path] = {'type': variable_type, + 'values': values, + 'xmlfiles': check.xmlfiles, + } return values def check_change_warning(self): @@ -298,9 +308,14 @@ class ConstrainteAnnotator: target_names = '.'.join([normalize_family(name) \ for name in target.name.split('.')]) try: - target.name = self.objectspace.paths.get_variable_path(target_names, - condition.namespace, - ) + target.name, suffix = self.objectspace.paths.get_variable_path(target_names, + condition.namespace, + ) + if suffix: + xmlfiles = self.objectspace.display_xmlfiles(condition.xmlfiles) + msg = _(f'the target "{target.name}" in condition cannot be a dynamic ' + f'variable in {xmlfiles}') + raise DictConsistencyError(msg, 21) except DictConsistencyError as err: # for optional variable if not target.optional or err.errno != 42: @@ -402,7 +417,6 @@ class ConstrainteAnnotator: condition.source, suffix = self.objectspace.paths.get_variable_path(condition.source, namespace, allow_source=True, - with_suffix=True, ) if suffix: xmlfiles = self.objectspace.display_xmlfiles(condition.xmlfiles) @@ -491,7 +505,6 @@ class ConstrainteAnnotator: """valid and manage """ for check in self.objectspace.space.constraints.check: - variable = self.objectspace.paths.get_variable_obj(check.target) if check.name == 'valid_entier': if not hasattr(check, 'param'): msg = _(f'{check.name} must have, at least, 1 param') @@ -503,18 +516,18 @@ class ConstrainteAnnotator: f' in {xmlfiles}') raise DictConsistencyError(msg, 18) if param.name == 'mini': - variable.min_number = int(param.text) + check.target.min_number = int(param.text) elif param.name == 'maxi': - variable.max_number = int(param.text) + check.target.max_number = int(param.text) else: xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles) msg = _(f'unknown parameter "{param.name}" in check "valid_entier" ' - f'for variable "{check.target}" in {xmlfiles}') + f'for variable "{check.target.name}" in {xmlfiles}') raise DictConsistencyError(msg, 19) else: - if not hasattr(variable, 'check'): - variable.check = [] - variable.check.append(check) + if not hasattr(check.target, 'check'): + check.target.check = [] + check.target.check.append(check) def convert_fill(self) -> None: """valid and manage @@ -538,7 +551,6 @@ class ConstrainteAnnotator: # let's replace the target by the path fill.target, suffix = self.objectspace.paths.get_variable_path(fill.target, fill.namespace, - with_suffix=True, ) if suffix is not None: xmlfiles = self.objectspace.display_xmlfiles(fill.xmlfiles) @@ -591,7 +603,6 @@ class ConstrainteAnnotator: try: text, suffix = self.objectspace.paths.get_variable_path(param.text, fill.namespace, - with_suffix=True, ) param.text = text if suffix: diff --git a/src/rougail/annotator/service.py b/src/rougail/annotator/service.py index 5721161d..562d9780 100644 --- a/src/rougail/annotator/service.py +++ b/src/rougail/annotator/service.py @@ -177,9 +177,13 @@ class ServiceAnnotator: variable.mode = None variable.type = type_ if type_ == 'symlink': - variable.opt = self.objectspace.paths.get_variable_path(value, - 'services', - ) + variable.opt, suffix = self.objectspace.paths.get_variable_path(value, + 'services', + ) + if suffix: + xmlfiles = self.objectspace.display_xmlfiles(value.xmlfiles) + msg = _(f'the "{key}" in services cannot be a dynamic variable in {xmlfiles}') + raise DictConsistencyError(msg, 23) variable.multi = None else: variable.doc = key diff --git a/src/rougail/error.py b/src/rougail/error.py index ada8a764..fea02706 100644 --- a/src/rougail/error.py +++ b/src/rougail/error.py @@ -16,11 +16,6 @@ class TemplateDisabled(TemplateError): """ -class OperationError(Exception): - """Type error or value Error for Creole variable's type or values - """ - - class SpaceObjShallNotBeUpdated(Exception): """Specific behavior in case of the presence or not of an object in the space object diff --git a/src/rougail/path.py b/src/rougail/path.py index 6a1edc14..2125c564 100644 --- a/src/rougail/path.py +++ b/src/rougail/path.py @@ -1,5 +1,5 @@ from .i18n import _ -from .error import OperationError, DictConsistencyError +from .error import DictConsistencyError from .config import Config @@ -110,7 +110,6 @@ class Path: variableobj.path = full_path self.variables[full_path] = dict(name=name, family=family, - namespace=namespace, leader=None, is_dynamic=is_dynamic, variableobj=variableobj, @@ -119,7 +118,10 @@ class Path: def get_variable_obj(self, name: str, ) -> 'Variable': # pylint: disable=C0111 - return self._get_variable(name)['variableobj'] + variable, suffix = self._get_variable(name, with_suffix=True) + if suffix: + raise DictConsistencyError(_("{name} is a dynamic variable"), 36) + return variable['variableobj'] def get_variable_family_name(self, name: str, @@ -130,26 +132,14 @@ 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 OperationError('current_namespace must not be None') - if with_suffix: - dico, suffix = self._get_variable(name, - with_suffix=True, - ) - else: - dico = self._get_variable(name) - if not allow_source and dico['namespace'] not in [Config['variable_namespace'], 'services'] and current_namespace != dico['namespace']: - raise DictConsistencyError(_(f'A variable located in the "{dico["namespace"]}" namespace shall not be used in the "{current_namespace}" namespace'), 41) - 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 + dico, suffix = self._get_variable(name, + with_suffix=True, + ) + namespace = dico['variableobj'].namespace + if not allow_source and namespace not in [Config['variable_namespace'], 'services'] and current_namespace != namespace: + raise DictConsistencyError(_(f'A variable located in the "{namespace}" namespace shall not be used in the "{current_namespace}" namespace'), 41) + return dico['variableobj'].path, suffix def path_is_defined(self, name: str,