manage group

This commit is contained in:
Emmanuel Garette 2021-01-16 08:50:11 +01:00
parent 1d0a5fae18
commit e34d285eb3
6 changed files with 63 additions and 42 deletions

View File

@ -62,6 +62,7 @@ class ConstrainteAnnotator:
self.convert_condition_target() self.convert_condition_target()
self.convert_xxxlist_to_variable() self.convert_xxxlist_to_variable()
self.check_condition_fallback_optional() self.check_condition_fallback_optional()
self.convert_condition_source()
self.check_choice_option_condition() self.check_choice_option_condition()
self.remove_condition_with_empty_target() self.remove_condition_with_empty_target()
self.convert_condition() self.convert_condition()
@ -116,7 +117,7 @@ class ConstrainteAnnotator:
xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles) xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles)
msg = _(f'cannot find check function "{check.name}" in {xmlfiles}') msg = _(f'cannot find check function "{check.name}" in {xmlfiles}')
raise DictConsistencyError(msg, 1) raise DictConsistencyError(msg, 1)
check.is_in_leadership = self.objectspace.paths.get_leader(check.target) is not None check.is_in_leadership = self.objectspace.paths.is_in_leadership(check.target)
# let's replace the target by the path # let's replace the target by the path
try: try:
check.target = self.objectspace.paths.get_variable_obj(check.target) check.target = self.objectspace.paths.get_variable_obj(check.target)
@ -278,11 +279,12 @@ class ConstrainteAnnotator:
): ):
if target.type == 'variable': if target.type == 'variable':
variable = self.objectspace.paths.get_variable_obj(target.name) variable = self.objectspace.paths.get_variable_obj(target.name)
family = self.objectspace.paths.get_family(target.name.rsplit('.', 1)[0],
variable.namespace,
)
# it's a leader, so apply property to leadership # it's a leader, so apply property to leadership
if isinstance(family, self.objectspace.leadership) and family.variable[0].name == variable.name: if self.objectspace.paths.is_leader(target.name):
family_name = self.objectspace.paths.get_variable_family_path(target.name)
family = self.objectspace.paths.get_family(target.name.rsplit('.', 1)[0],
variable.namespace,
)
return family, family.variable return family, family.variable
return variable, [variable] return variable, [variable]
# it's a family # it's a family
@ -408,25 +410,30 @@ class ConstrainteAnnotator:
for variable in variables: for variable in variables:
setattr(variable, action, True) setattr(variable, action, True)
def convert_condition_source(self):
"""remove condition for ChoiceOption that don't have param
"""
remove_conditions = []
for condition_idx, condition in enumerate(self.objectspace.space.constraints.condition):
try:
condition.source = self.objectspace.paths.get_variable_obj(condition.source)
except DictConsistencyError as err:
if err.errno == 36:
xmlfiles = self.objectspace.display_xmlfiles(condition.xmlfiles)
msg = _(f'the source "{condition.source}" in condition cannot be a dynamic '
f'variable in {xmlfiles}')
raise DictConsistencyError(msg, 20)
def check_choice_option_condition(self): def check_choice_option_condition(self):
"""remove condition for ChoiceOption that don't have param """remove condition for ChoiceOption that don't have param
""" """
remove_conditions = [] remove_conditions = []
for condition_idx, condition in enumerate(self.objectspace.space.constraints.condition): for condition_idx, condition in enumerate(self.objectspace.space.constraints.condition):
namespace = condition.namespace namespace = condition.namespace
condition.source, suffix = self.objectspace.paths.get_variable_path(condition.source,
namespace,
allow_source=True,
)
if suffix:
xmlfiles = self.objectspace.display_xmlfiles(condition.xmlfiles)
msg = _(f'the source "{condition.source}" in condition cannot be a dynamic '
f'variable in {xmlfiles}')
raise DictConsistencyError(msg, 20)
# FIXME only string? # FIXME only string?
if condition.source in self.valid_enums and \ if condition.source.path in self.valid_enums and \
self.valid_enums[condition.source]['type'] == 'string': self.valid_enums[condition.source.path]['type'] == 'string':
valid_enum = self.valid_enums[condition.source]['values'] valid_enum = self.valid_enums[condition.source.path]['values']
remove_param = [param_idx for param_idx, param in enumerate(condition.param) \ remove_param = [param_idx for param_idx, param in enumerate(condition.param) \
if param.text not in valid_enum] if param.text not in valid_enum]
remove_param.sort(reverse=True) remove_param.sort(reverse=True)

View File

@ -22,22 +22,26 @@ class GroupAnnotator:
def convert_groups(self): # pylint: disable=C0111 def convert_groups(self): # pylint: disable=C0111
"""convert groups """convert groups
""" """
cache_paths = {}
for group in self.objectspace.space.constraints.group: for group in self.objectspace.space.constraints.group:
leader_fullname = group.leader leader_fullname = group.leader
leader = self.objectspace.paths.get_variable_obj(leader_fullname) leader = self.objectspace.paths.get_variable_obj(leader_fullname)
leader_family_name = self.objectspace.paths.get_variable_family_name(leader_fullname) if leader_fullname in cache_paths:
leader_family_path = cache_paths[leader_fullname]
else:
leader_family_path = self.objectspace.paths.get_variable_family_path(leader_fullname)
cache_paths[leader_fullname] = leader_family_path
if '.' not in leader_fullname: if '.' not in leader_fullname:
leader_fullname = '.'.join([leader.namespace, leader_family_name, leader_fullname]) leader_fullname = '.'.join([leader_family_path, leader_fullname])
follower_names = list(group.follower.keys()) follower_names = list(group.follower.keys())
leader_family = leader_fullname.rsplit('.', 1)[0] ori_leader_family = self.objectspace.paths.get_family(leader_family_path,
ori_leader_family = self.objectspace.paths.get_family(leader_family,
leader.namespace, leader.namespace,
) )
has_a_leader = False has_a_leader = False
for variable in list(ori_leader_family.variable.values()): for variable in list(ori_leader_family.variable.values()):
if has_a_leader: if has_a_leader:
# it's a follower # it's a follower
self.manage_follower(leader_family_name, self.manage_follower(leader_family_path,
variable, variable,
leadership_name, leadership_name,
follower_names, follower_names,
@ -64,13 +68,12 @@ class GroupAnnotator:
else: else:
leadership_name = leader.name leadership_name = leader.name
leader_is_hidden = self.manage_leader(leader_space, leader_is_hidden = self.manage_leader(leader_space,
leader_family_name, leader_family_path,
leadership_name, leadership_name,
leader.name, leader.name,
variable, variable,
group, group,
) )
leader_space.path = leader_fullname
has_a_leader = True has_a_leader = True
else: else:
xmlfiles = self.objectspace.display_xmlfiles(variable.xmlfiles) xmlfiles = self.objectspace.display_xmlfiles(variable.xmlfiles)
@ -111,25 +114,25 @@ class GroupAnnotator:
else: else:
leader_space.doc = leadership_name leader_space.doc = leadership_name
namespace = variable.namespace namespace = variable.namespace
leadership_path = namespace + '.' + leader_family_name + '.' + leadership_name leadership_path = leader_family_name + '.' + leadership_name
self.objectspace.paths.add_leadership(namespace, self.objectspace.paths.add_leadership(namespace,
leadership_path, leadership_path,
leader_space, leader_space,
) )
leader_family = self.objectspace.space.variables[namespace].family[leader_family_name] leader_family = self.objectspace.space.variables[namespace].family[leader_family_name.rsplit('.', 1)[-1]]
leader_family.variable[leader_name] = leader_space leader_family.variable[leader_name] = leader_space
leader_space.variable.append(variable) leader_space.variable.append(variable)
self.objectspace.paths.set_leader(namespace, self.objectspace.paths.set_leader(namespace,
leader_family_name, leader_family_name,
leader_name,
leadership_name, leadership_name,
leader_name,
) )
return leader_is_hidden return leader_is_hidden
def manage_follower(self, def manage_follower(self,
leader_family_name: str, leader_family_name: str,
variable: 'Variable', variable: 'Variable',
leader_name: str, leadership_name: str,
follower_names: List[str], follower_names: List[str],
) -> None: ) -> None:
"""manage follower """manage follower
@ -142,6 +145,6 @@ class GroupAnnotator:
raise DictConsistencyError(msg, 33) raise DictConsistencyError(msg, 33)
self.objectspace.paths.set_leader(variable.namespace, self.objectspace.paths.set_leader(variable.namespace,
leader_family_name, leader_family_name,
leadership_name,
variable.name, variable.name,
leader_name,
) )

View File

@ -312,7 +312,7 @@ class RougailObjSpace:
name = space.path + '.' + name name = space.path + '.' + name
if not self.paths.path_is_defined(name): if not self.paths.path_is_defined(name):
return None return None
old_family_name = namespace + '.' + self.paths.get_variable_family_name(name) old_family_name = self.paths.get_variable_family_path(name)
if space.path != old_family_name: if space.path != old_family_name:
xmlfiles = self.display_xmlfiles(space.xmlfiles) xmlfiles = self.display_xmlfiles(space.xmlfiles)
msg = _(f'Variable was previously create in family "{old_family_name}", ' msg = _(f'Variable was previously create in family "{old_family_name}", '
@ -437,7 +437,7 @@ class RougailObjSpace:
family_name = normalize_family(document.attrib['name']) family_name = normalize_family(document.attrib['name'])
self.paths.add_variable(namespace, self.paths.add_variable(namespace,
variableobj.name, variableobj.name,
family_name, namespace + '.' + family_name,
document.attrib.get('dynamic') is not None, document.attrib.get('dynamic') is not None,
variableobj, variableobj,
) )

View File

@ -78,20 +78,29 @@ class Path:
def set_leader(self, def set_leader(self,
namespace: str, namespace: str,
leader_family_name: str, leader_family_name: str,
leadership_name: str,
name: str, name: str,
leader_name: str,
) -> None: # pylint: disable=C0111 ) -> None: # pylint: disable=C0111
# need rebuild path and move object in new path # need rebuild path and move object in new path
old_path = namespace + '.' + leader_family_name + '.' + name old_path = leader_family_name + '.' + name
new_path = namespace + '.' + leader_family_name + '.' + leader_name + '.' + name leadership_path = leader_family_name + '.' + leadership_name
new_path = leadership_path + '.' + name
self.variables[new_path] = self.variables.pop(old_path) self.variables[new_path] = self.variables.pop(old_path)
self.variables[new_path]['leader'] = leader_name self.variables[new_path]['leader'] = leadership_path
self.variables[new_path]['variableobj'].path = new_path self.variables[new_path]['variableobj'].path = new_path
self.variables[new_path]['family'] = leadership_path
if namespace == Config['variable_namespace']: if namespace == Config['variable_namespace']:
self.full_paths_variables[name] = new_path self.full_paths_variables[name] = new_path
def get_leader(self, name): # pylint: disable=C0111 def is_in_leadership(self, name):
return self._get_variable(name)['leader'] return self._get_variable(name)['leader'] is not None
def is_leader(self, path): # pylint: disable=C0111
variable = self._get_variable(path)
if not variable['leader']:
return False
leadership = self.get_family(variable['leader'], variable['variableobj'].namespace)
return leadership.variable[0].path == path
# Variable # Variable
def add_variable(self, def add_variable(self,
@ -102,7 +111,7 @@ class Path:
variableobj, variableobj,
) -> str: # pylint: disable=C0111 ) -> str: # pylint: disable=C0111
if '.' not in name: if '.' not in name:
full_path = '.'.join([namespace, family, name]) full_path = '.'.join([family, name])
if namespace == Config['variable_namespace']: if namespace == Config['variable_namespace']:
self.full_paths_variables[name] = full_path self.full_paths_variables[name] = full_path
else: else:
@ -120,10 +129,10 @@ class Path:
) -> 'Variable': # pylint: disable=C0111 ) -> 'Variable': # pylint: disable=C0111
variable, suffix = self._get_variable(name, with_suffix=True) variable, suffix = self._get_variable(name, with_suffix=True)
if suffix: if suffix:
raise DictConsistencyError(_("{name} is a dynamic variable"), 36) raise DictConsistencyError(_(f"{name} is a dynamic variable"), 36)
return variable['variableobj'] return variable['variableobj']
def get_variable_family_name(self, def get_variable_family_path(self,
name: str, name: str,
) -> str: # pylint: disable=C0111 ) -> str: # pylint: disable=C0111
return self._get_variable(name)['family'] return self._get_variable(name)['family']

View File

@ -196,7 +196,7 @@ class Common:
def populate_properties(self, child): def populate_properties(self, child):
assert child.type == 'calculation' assert child.type == 'calculation'
action = f"ParamValue('{child.name}')" action = f"ParamValue('{child.name}')"
option_name = self.storage.get(child.source).get() option_name = self.storage.get(child.source.path).get()
kwargs = f"'condition': ParamOption({option_name}, todict=True), 'expected': ParamValue('{child.expected}')" kwargs = f"'condition': ParamOption({option_name}, todict=True), 'expected': ParamValue('{child.expected}')"
if child.inverse: if child.inverse:
kwargs += ", 'reverse_condition': ParamValue(True)" kwargs += ", 'reverse_condition': ParamValue(True)"

View File

@ -102,7 +102,9 @@ def test_error_dictionary(test_dir_error):
errno = int(i.split('_')[1]) errno = int(i.split('_')[1])
with raises(DictConsistencyError) as err: with raises(DictConsistencyError) as err:
launch_flattener(test_dir) launch_flattener(test_dir)
assert err.value.errno == errno, f'expected errno: {errno}, errno: {err.value.errno}, value: {err.value}' if err.value.errno != errno:
print(f'expected errno: {errno}, errno: {err.value.errno}')
launch_flattener(test_dir)
assert getcwd() == ORI_DIR assert getcwd() == ORI_DIR