diff --git a/src/rougail/annotator/group.py b/src/rougail/annotator/group.py index 892d7554..4662d717 100644 --- a/src/rougail/annotator/group.py +++ b/src/rougail/annotator/group.py @@ -67,8 +67,8 @@ class GroupAnnotator: leader_name, variable, group, - leader_fullname, ) + leader_space.path = leader_fullname has_a_leader = True else: xmlfiles = self.objectspace.display_xmlfiles(variable.xmlfiles) @@ -85,7 +85,6 @@ class GroupAnnotator: leader_name: str, variable: 'Variable', group: 'Group', - leader_fullname: str, ) -> None: """manage leader's variable """ @@ -121,9 +120,8 @@ class GroupAnnotator: self.objectspace.paths.set_leader(namespace, leader_family_name, leader_name, - leader_name, + leadership_name, ) - leader_space.path = leader_fullname return leader_is_hidden def manage_follower(self, diff --git a/src/rougail/annotator/variable.py b/src/rougail/annotator/variable.py index daa1f8ed..3e75a6a9 100644 --- a/src/rougail/annotator/variable.py +++ b/src/rougail/annotator/variable.py @@ -1,3 +1,5 @@ +"""Annotate variable +""" from ..i18n import _ from ..utils import normalize_family from ..error import DictConsistencyError @@ -15,14 +17,19 @@ CONVERT_OPTION = {'number': dict(opttype="IntOption", func=int), 'date': dict(opttype="DateOption"), 'unix_user': dict(opttype="UsernameOption"), 'ip': dict(opttype="IPOption", initkwargs={'allow_reserved': True}), - 'local_ip': dict(opttype="IPOption", initkwargs={'private_only': True, 'warnings_only': True}), + 'local_ip': dict(opttype="IPOption", initkwargs={'private_only': True, + 'warnings_only': True}), 'netmask': dict(opttype="NetmaskOption"), 'network': dict(opttype="NetworkOption"), 'broadcast': dict(opttype="BroadcastOption"), - 'netbios': dict(opttype="DomainnameOption", initkwargs={'type': 'netbios', 'warnings_only': True}), - 'domain': dict(opttype="DomainnameOption", initkwargs={'type': 'domainname', 'allow_ip': False}), - 'hostname': dict(opttype="DomainnameOption", initkwargs={'type': 'hostname', 'allow_ip': False}), - 'web_address': dict(opttype="URLOption", initkwargs={'allow_ip': True, 'allow_without_dot': True}), + 'netbios': dict(opttype="DomainnameOption", initkwargs={'type': 'netbios', + 'warnings_only': True}), + 'domain': dict(opttype="DomainnameOption", initkwargs={'type': 'domainname', + 'allow_ip': False}), + 'hostname': dict(opttype="DomainnameOption", initkwargs={'type': 'hostname', + 'allow_ip': False}), + 'web_address': dict(opttype="URLOption", initkwargs={'allow_ip': True, + 'allow_without_dot': True}), 'port': dict(opttype="PortOption", initkwargs={'allow_private': True}), 'mac': dict(opttype="MACOption"), 'cidr': dict(opttype="IPOption", initkwargs={'cidr': True}), @@ -41,102 +48,106 @@ RENAME_ATTIBUTES = {'description': 'doc'} class VariableAnnotator: + """Annotate variable + """ def __init__(self, objectspace, ): self.objectspace = objectspace - self.convert_variable() - self.convert_separators() + if hasattr(self.objectspace.space, 'variables'): + self.convert_variable() + self.convert_separators() + + def _convert_variable(self, + namespace: str, + variable, + variable_type: str, + ) -> None: + if not hasattr(variable, 'type'): + variable.type = 'string' + if variable.type != 'symlink' and not hasattr(variable, 'description'): + variable.description = variable.name + if hasattr(variable, 'value'): + for value in variable.value: + if not hasattr(value, 'type'): + value.type = variable.type + value.name = CONVERT_OPTION.get(value.type, {}).get('func', str)(value.name) + for key, value in RENAME_ATTIBUTES.items(): + setattr(variable, value, getattr(variable, key)) + setattr(variable, key, None) + if variable_type == 'follower': + if variable.multi is True: + variable.multi = 'submulti' + else: + variable.multi = True + self._convert_valid_enum(namespace, + variable, + ) + self._valid_type(variable) + + def _convert_valid_enum(self, + namespace, + variable, + ): + """some types are, in fact, choices + convert this kind of variables into choice + """ + if variable.type in FORCE_CHOICE: + if not hasattr(self.objectspace.space, 'constraints'): + xmlfiles = variable.xmlfiles + self.objectspace.space.constraints = self.objectspace.constraints(xmlfiles) + self.objectspace.space.constraints.namespace = namespace + if not hasattr(self.objectspace.space.constraints, 'check'): + self.objectspace.space.constraints.check = [] + check = self.objectspace.check(variable.xmlfiles) + check.name = 'valid_enum' + check.target = variable.path + check.namespace = namespace + check.param = [] + for value in FORCE_CHOICE[variable.type]: + param = self.objectspace.param(variable.xmlfiles) + param.text = value + check.param.append(param) + self.objectspace.space.constraints.check.append(check) + variable.type = 'string' + + def _valid_type(self, + variable + ) -> None: + if variable.type not in CONVERT_OPTION: + xmlf = self.objectspace.display_xmlfiles(variable.xmlfiles) + msg = _(f'unvalid type "{variable.type}" for variable "{variable.name}" in {xmlf}') + raise DictConsistencyError(msg, 36) def convert_variable(self): - def _convert_variable(variable, - variable_type, - ): - if not hasattr(variable, 'type'): - variable.type = 'string' - if variable.type != 'symlink' and not hasattr(variable, 'description'): - variable.description = variable.name - if hasattr(variable, 'value'): - for value in variable.value: - if not hasattr(value, 'type'): - value.type = variable.type - value.name = CONVERT_OPTION.get(value.type, {}).get('func', str)(value.name) - for key, value in RENAME_ATTIBUTES.items(): - setattr(variable, value, getattr(variable, key)) - setattr(variable, key, None) - if variable_type == 'follower': - if variable.multi is True: - variable.multi = 'submulti' - else: - variable.multi = True - - def _convert_valid_enum(namespace, - variable, - path, - ): - if variable.type in FORCE_CHOICE: - check = self.objectspace.check(variable.xmlfiles) - check.name = 'valid_enum' - check.target = path - check.namespace = namespace - check.param = [] - for value in FORCE_CHOICE[variable.type]: - param = self.objectspace.param(variable.xmlfiles) - param.text = value - check.param.append(param) - if not hasattr(self.objectspace.space, 'constraints'): - self.objectspace.space.constraints = self.objectspace.constraints(variable.xmlfiles) - self.objectspace.space.constraints.namespace = namespace - if not hasattr(self.objectspace.space.constraints, 'check'): - self.objectspace.space.constraints.check = [] - self.objectspace.space.constraints.check.append(check) - variable.type = 'string' - - def _valid_type(variable): - if variable.type not in CONVERT_OPTION: - xmlfiles = self.objectspace.display_xmlfiles(variable.xmlfiles) - raise DictConsistencyError(_(f'unvalid type "{variable.type}" for variable "{variable.name}" in {xmlfiles}'), 36) - - if not hasattr(self.objectspace.space, 'variables'): - return + """convert variable + """ for families in self.objectspace.space.variables.values(): - namespace = families.name - if hasattr(families, 'family'): - families.doc = families.name - for family in families.family.values(): - family.doc = family.name - family.name = normalize_family(family.name) - if hasattr(family, 'variable'): - for variable in family.variable.values(): - if isinstance(variable, self.objectspace.leadership): - for idx, follower in enumerate(variable.variable): - if idx == 0: - variable_type = 'master' - else: - variable_type = 'follower' - path = '{}.{}.{}.{}'.format(namespace, normalize_family(family.name), variable.name, follower.name) - _convert_variable(follower, - variable_type, - ) - _convert_valid_enum(namespace, - follower, - path, - ) - _valid_type(follower) - else: - path = '{}.{}.{}'.format(namespace, normalize_family(family.name), variable.name) - _convert_variable(variable, - 'variable', - ) - _convert_valid_enum(namespace, - variable, - path, - ) - _valid_type(variable) + if not hasattr(families, 'family'): + continue + families.doc = families.name + for family in families.family.values(): + family.doc = family.name + family.name = normalize_family(family.name) + if not hasattr(family, 'variable'): + continue + for variable in family.variable.values(): + if isinstance(variable, self.objectspace.leadership): + # first variable is a leader, others are follower + variable_type = 'leader' + for follower in variable.variable: + self._convert_variable(families.name, + follower, + variable_type, + ) + variable_type = 'follower' + else: + self._convert_variable(families.name, + variable, + 'variable', + ) def convert_separators(self): # pylint: disable=C0111,R0201 - if not hasattr(self.objectspace.space, 'variables'): - return for family in self.objectspace.space.variables.values(): if not hasattr(family, 'separators'): continue @@ -144,10 +155,8 @@ class VariableAnnotator: for separator in family.separators.separator: option = self.objectspace.paths.get_variable_obj(separator.name) if hasattr(option, 'separator'): - subpath = self.objectspace.paths.get_variable_path(separator.name, - separator.namespace, - ) xmlfiles = self.objectspace.display_xmlfiles(separator.xmlfiles) - raise DictConsistencyError(_(f'{subpath} already has a separator in {xmlfiles}'), 35) + msg = _(f'{separator.name} already has a separator in {xmlfiles}') + raise DictConsistencyError(msg, 35) option.separator = separator.text del family.separators diff --git a/src/rougail/path.py b/src/rougail/path.py index 7f36dcac..cb9212fa 100644 --- a/src/rougail/path.py +++ b/src/rougail/path.py @@ -79,6 +79,7 @@ class Path: new_path = namespace + '.' + leader_family_name + '.' + leader_name + '.' + name self.variables[new_path] = self.variables.pop(old_path) self.variables[new_path]['leader'] = leader_name + self.variables[new_path]['variableobj'].path = new_path if namespace == Config['variable_namespace']: self.full_paths_variables[name] = new_path @@ -94,11 +95,13 @@ class Path: variableobj, ) -> str: # pylint: disable=C0111 if '.' not in name: - full_name = '.'.join([namespace, family, name]) - self.full_paths_variables[name] = full_name + full_path = '.'.join([namespace, family, name]) + if namespace == Config['variable_namespace']: + self.full_paths_variables[name] = full_path else: - full_name = name - self.variables[full_name] = dict(name=name, + full_path = name + variableobj.path = full_path + self.variables[full_path] = dict(name=name, family=family, namespace=namespace, leader=None, @@ -107,12 +110,12 @@ class Path: ) def get_variable_name(self, - name, + name: str, ): # pylint: disable=C0111 return self._get_variable(name)['name'] def get_variable_obj(self, - name:str, + name: str, ) -> 'Variable': # pylint: disable=C0111 return self._get_variable(name)['variableobj'] diff --git a/tests/dictionaries/02autosave_hidden_frozenifin/errno_51 b/tests/dictionaries/02autosave_hidden_frozenifin/errno_51 deleted file mode 100644 index e69de29b..00000000