Merge branch 'develop' into dist/risotto/risotto-2.8.0/develop

This commit is contained in:
Emmanuel Garette 2021-04-14 18:00:46 +02:00
commit 36827b6869
6 changed files with 106 additions and 159 deletions

View File

@ -120,7 +120,7 @@ class Annotator(Walk):
obj, obj,
) -> None: ) -> None:
modes_level = self.objectspace.rougailconfig['modes_level'] modes_level = self.objectspace.rougailconfig['modes_level']
if hasattr(obj, 'mode') and obj.mode not in modes_level: if self._has_mode(obj) and obj.mode not in modes_level:
msg = _(f'mode "{obj.mode}" for "{obj.name}" is not a valid mode, ' msg = _(f'mode "{obj.mode}" for "{obj.name}" is not a valid mode, '
f'valid modes are {modes_level}') f'valid modes are {modes_level}')
raise DictConsistencyError(msg, 71, obj.xmlfiles) raise DictConsistencyError(msg, 71, obj.xmlfiles)
@ -128,23 +128,29 @@ class Annotator(Walk):
def _set_default_mode(self, def _set_default_mode(self,
family: 'self.objectspace.family', family: 'self.objectspace.family',
) -> None: ) -> None:
if hasattr(family, 'mode') and 'mode' in vars(family): if not hasattr(family, 'variable'):
return
if self._has_mode(family):
family_mode = family.mode family_mode = family.mode
else: else:
family_mode = None family_mode = None
if not hasattr(family, 'variable'): leader = None
return
for variable in family.variable.values(): for variable in family.variable.values():
self.valid_mode(variable) if leader is None and hasattr(family, 'leadership') and family.leadership:
leader = variable
if isinstance(variable, self.objectspace.family): if isinstance(variable, self.objectspace.family):
if not variable.leadership: # set default mode a subfamily
if family_mode and not self._has_mode(variable): if family_mode and not self._has_mode(variable):
self._set_auto_mode(variable, family_mode) self._set_auto_mode(variable, family_mode)
continue
func = self._set_default_mode_leader
else: else:
func = self._set_default_mode_variable # set default mode to a variable
func(variable, family_mode) self.valid_mode(variable)
if leader:
self._set_default_mode_leader(leader, variable)
self._set_default_mode_variable(variable, family_mode)
if leader:
# here because follower can change leader mode
self._set_auto_mode(family, leader.mode)
@staticmethod @staticmethod
def _has_mode(obj) -> bool: def _has_mode(obj) -> bool:
@ -174,92 +180,80 @@ class Annotator(Walk):
obj.mode_auto = True obj.mode_auto = True
def _set_default_mode_leader(self, def _set_default_mode_leader(self,
leadership: 'self.objectspace.family', leader: 'self.objectspace.variable',
family_mode: str, follower: 'self.objectspace.variable',
) -> None: ) -> None:
leader_mode = None if follower.auto_save is True:
leader = next(iter(leadership.variable.values())) msg = _(f'leader/followers "{follower.name}" could not be auto_save')
for follower in leadership.variable.values(): raise DictConsistencyError(msg, 29, follower.xmlfiles)
self.valid_mode(follower) if follower.auto_freeze is True:
if follower.auto_save is True: msg = f'leader/followers "{follower.name}" could not be auto_freeze'
msg = _(f'leader/followers "{follower.name}" could not be auto_save') raise DictConsistencyError(_(msg), 30, follower.xmlfiles)
raise DictConsistencyError(msg, 29, leadership.xmlfiles) if leader == follower:
if follower.auto_freeze is True: # it's a leader
msg = f'leader/followers "{follower.name}" could not be auto_freeze' if not hasattr(leader, 'mode'):
raise DictConsistencyError(_(msg), 30, leadership.xmlfiles) self._set_auto_mode(leader, self.objectspace.rougailconfig['default_variable_mode'])
if leader_mode is not None: return
if hasattr(follower, 'mode'): if self._has_mode(follower):
follower_mode = follower.mode follower_mode = follower.mode
else: else:
follower_mode = self.objectspace.rougailconfig['default_variable_mode'] follower_mode = self.objectspace.rougailconfig['default_variable_mode']
if self.modes[leader_mode] > self.modes[follower_mode]: if self.modes[leader.mode] > self.modes[follower_mode]:
if self._has_mode(follower) and not self._has_mode(leader): if self._has_mode(follower) and not self._has_mode(leader):
# if follower has mode but not the leader # if follower has mode but not the leader
self._set_auto_mode(leader, follower_mode) self._set_auto_mode(leader, follower_mode)
else: else:
# leader's mode is minimum level # leader's mode is minimum level
if self._has_mode(follower): if self._has_mode(follower):
msg = _(f'the follower "{follower.name}" is in "{follower_mode}" mode ' msg = _(f'the follower "{follower.name}" is in "{follower_mode}" mode '
f'but leader have the higher mode "{leader_mode}"') f'but leader have the higher mode "{leader.mode}"')
raise DictConsistencyError(msg, 63, follower.xmlfiles) raise DictConsistencyError(msg, 63, follower.xmlfiles)
self._set_auto_mode(follower, leader_mode) self._set_auto_mode(follower, leader.mode)
self._set_default_mode_variable(follower,
family_mode,
)
if leader_mode is None:
if hasattr(leader, 'mode'):
leader_mode = leader.mode
else:
leader_mode = self.objectspace.rougailconfig['default_variable_mode']
if hasattr(leader, 'mode'):
leader_mode = leader.mode
self._set_auto_mode(leadership, leader_mode)
def _change_family_mode(self, def _change_family_mode(self,
family: 'self.objectspace.family', family: 'self.objectspace.family',
) -> None: ) -> None:
if hasattr(family, 'mode'): if hasattr(family, 'mode'):
family_mode = family.mode family_mode = family.mode
else: else:
family_mode = self.objectspace.rougailconfig['default_family_mode'] family_mode = self.objectspace.rougailconfig['default_family_mode']
min_variable_mode = self.objectspace.rougailconfig['modes_level'][-1] min_variable_mode = self.objectspace.rougailconfig['modes_level'][-1]
# change variable mode, but not if variables are not in a family # change variable mode, but not if variables are not in a family
is_leadership = hasattr(family, 'leadership') and family.leadership
if hasattr(family, 'variable'): if hasattr(family, 'variable'):
for variable in family.variable.values(): for idx, variable in enumerate(family.variable.values()):
if isinstance(variable, self.objectspace.family): if isinstance(variable, self.objectspace.family):
if variable.leadership: if not hasattr(variable, 'mode'):
func = self._change_variable_mode_leader variable.mode = self.objectspace.rougailconfig['default_family_mode']
else: elif idx == 0 and is_leadership:
func = None variable.mode = None
continue
else: else:
func = self._change_variable_mode self._change_variable_mode(variable, family_mode, is_leadership)
if func:
func(variable,
family_mode,
)
elif not hasattr(variable, 'mode'):
variable.mode = self.objectspace.rougailconfig['default_family_mode']
if self.modes[min_variable_mode] > self.modes[variable.mode]: if self.modes[min_variable_mode] > self.modes[variable.mode]:
min_variable_mode = variable.mode min_variable_mode = variable.mode
if isinstance(family, self.objectspace.family) and \ if not isinstance(family, self.objectspace.family) or is_leadership:
(not hasattr(family, 'mode') or family.mode != min_variable_mode): # it's Variable, Service, ... and leadership
return
if not hasattr(family, 'mode'):
# set the lower variable mode to family # set the lower variable mode to family
if self._has_mode(family):
msg = _(f'the family "{family.name}" is in "{family.mode}" mode but variables and '
f'families inside have the higher modes "{min_variable_mode}"')
raise DictConsistencyError(msg, 62, family.xmlfiles)
self._set_auto_mode(family, min_variable_mode) self._set_auto_mode(family, min_variable_mode)
if family.mode != min_variable_mode:
msg = _(f'the family "{family.name}" is in "{family.mode}" mode but variables and '
f'families inside have the higher modes "{min_variable_mode}"')
raise DictConsistencyError(msg, 62, family.xmlfiles)
def _change_variable_mode(self, def _change_variable_mode(self,
variable, variable,
family_mode: str, family_mode: str,
is_follower: bool,
) -> None: ) -> None:
if hasattr(variable, 'mode'): if hasattr(variable, 'mode'):
variable_mode = variable.mode variable_mode = variable.mode
else: else:
variable_mode = self.objectspace.rougailconfig['default_variable_mode'] variable_mode = self.objectspace.rougailconfig['default_variable_mode']
# none basic variable in high level family has to be in high level # none basic variable in high level family has to be in high level
if self.modes[variable_mode] < self.modes[family_mode]: if not is_follower and self.modes[variable_mode] < self.modes[family_mode]:
if self._has_mode(variable): if self._has_mode(variable):
msg = _(f'the variable "{variable.name}" is in "{variable_mode}" mode ' msg = _(f'the variable "{variable.name}" is in "{variable_mode}" mode '
f'but family has the higher family mode "{family_mode}"') f'but family has the higher family mode "{family_mode}"')
@ -268,18 +262,6 @@ class Annotator(Walk):
if not hasattr(variable, 'mode'): if not hasattr(variable, 'mode'):
variable.mode = variable_mode variable.mode = variable_mode
def _change_variable_mode_leader(self,
leadership,
family_mode: str,
) -> None:
for idx, follower in enumerate(leadership.variable.values()):
if idx == 0:
leader = follower
self._change_variable_mode(follower,
family_mode,
)
leader.mode = None
def dynamic_families(self): def dynamic_families(self):
"""link dynamic families to object """link dynamic families to object
""" """

View File

@ -47,7 +47,7 @@ class Annotator(Walk):
"""convert groups """convert groups
""" """
# store old leaders family name # store old leaders family name
for family in self.get_families(with_leadership=True): for family in self.get_families():
if not isinstance(family, self.objectspace.family): if not isinstance(family, self.objectspace.family):
continue continue
if not family.leadership: if not family.leadership:
@ -55,7 +55,6 @@ class Annotator(Walk):
if hasattr(family, 'dynamic'): if hasattr(family, 'dynamic'):
msg = _(f'the family "{family.name}" cannot be leadership and dynamic together') msg = _(f'the family "{family.name}" cannot be leadership and dynamic together')
raise DictConsistencyError(msg, 31, family.xmlfiles) raise DictConsistencyError(msg, 31, family.xmlfiles)
family.doc = family.description
for idx, variable in enumerate(family.variable.values()): for idx, variable in enumerate(family.variable.values()):
if idx == 0: if idx == 0:
# it's a leader # it's a leader
@ -72,3 +71,7 @@ class Annotator(Walk):
if family.hidden: if family.hidden:
variable.frozen = True variable.frozen = True
variable.force_default_on_freeze = True variable.force_default_on_freeze = True
if variable.multi is True:
variable.multi = 'submulti'
else:
variable.multi = True

View File

@ -106,8 +106,5 @@ class Annotator(Walk):
def convert_variable(self) -> None: def convert_variable(self) -> None:
"""convert variables """convert variables
""" """
for variable in self.get_variables(with_leadership=True): for variable in self.get_variables():
if isinstance(variable, self.objectspace.family):
for follower in variable.variable.values():
self.convert_property(follower)
self.convert_property(variable) self.convert_property(variable)

View File

@ -45,20 +45,11 @@ class Annotator(Walk): # pylint: disable=R0903
def convert_value(self) -> None: def convert_value(self) -> None:
"""convert value """convert value
""" """
for variable in self.get_variables(with_leadership=True): for variable in self.get_variables():
if isinstance(variable, self.objectspace.family): self._convert_value(variable)
variable_type = 'leader'
for follower in variable.variable.values():
self._convert_value(follower,
variable_type,
)
variable_type = 'follower'
else:
self._convert_value(variable)
def _convert_value(self, def _convert_value(self,
variable, variable,
variable_type: str=None,
) -> None: ) -> None:
# a boolean must have value, the default value is "True" # a boolean must have value, the default value is "True"
if not hasattr(variable, 'value') and variable.type == 'boolean': if not hasattr(variable, 'value') and variable.type == 'boolean':
@ -83,9 +74,9 @@ class Annotator(Walk): # pylint: disable=R0903
if variable.value[0].type == 'calculation': if variable.value[0].type == 'calculation':
variable.default = variable.value[0] variable.default = variable.value[0]
elif variable.multi: elif variable.multi:
if variable_type != 'follower': if not self.objectspace.paths.is_follower(variable.path):
variable.default = [value.name for value in variable.value] variable.default = [value.name for value in variable.value]
if variable_type != 'leader': if not self.objectspace.paths.is_leader(variable.path):
if variable.multi == 'submulti': if variable.multi == 'submulti':
variable.default_multi = [value.name for value in variable.value] variable.default_multi = [value.name for value in variable.value]
else: else:

View File

@ -72,45 +72,38 @@ class Walk:
""" """
objectspace = None objectspace = None
def get_variables(self, def get_variables(self):
with_leadership: bool=False,
):
"""Iter all variables from the objectspace """Iter all variables from the objectspace
""" """
for family in self.objectspace.space.variables.values(): for family in self.objectspace.space.variables.values():
yield from self._get_variables(family, with_leadership) yield from self._get_variables(family)
def _get_variables(self, def _get_variables(self,
family: 'self.objectspace.family', family: 'self.objectspace.family',
with_leadership: bool
): ):
if hasattr(family, 'variable'): if not hasattr(family, 'variable'):
for variable in family.variable.values(): return
if isinstance(variable, self.objectspace.family): for variable in family.variable.values():
if variable.leadership is False: if isinstance(variable, self.objectspace.family):
yield from self._get_variables(variable, with_leadership) yield from self._get_variables(variable)
continue else:
if not with_leadership:
for follower in variable.variable.values():
yield follower
continue
yield variable yield variable
def get_families(self, with_leadership=False): def get_families(self):
"""Iter all families from the objectspace """Iter all families from the objectspace
""" """
for family in self.objectspace.space.variables.values(): for family in self.objectspace.space.variables.values():
yield from self._get_families(family, with_leadership) yield from self._get_families(family)
def _get_families(self, def _get_families(self,
family: 'self.objectspace.family', family: 'self.objectspace.family',
with_leadership: bool,
): ):
yield family yield family
if hasattr(family, 'variable'): if not hasattr(family, 'variable'):
for fam in family.variable.values(): return
if isinstance(fam, self.objectspace.family) and (with_leadership or not fam.leadership): for fam in family.variable.values():
yield from self._get_families(fam, with_leadership) if isinstance(fam, self.objectspace.family):
yield from self._get_families(fam)
class Annotator(Walk): # pylint: disable=R0903 class Annotator(Walk): # pylint: disable=R0903
@ -134,23 +127,11 @@ class Annotator(Walk): # pylint: disable=R0903
def convert_variable(self): def convert_variable(self):
"""convert variable """convert variable
""" """
for variable in self.get_variables(with_leadership=True): for variable in self.get_variables():
if isinstance(variable, self.objectspace.family): self._convert_variable(variable)
# first variable is a leader, others are follower
variable_type = 'leader'
for follower in variable.variable.values():
self._convert_variable(follower,
variable_type,
)
variable_type = 'follower'
else:
self._convert_variable(variable,
'variable',
)
def _convert_variable(self, def _convert_variable(self,
variable, variable,
variable_type: str,
) -> None: ) -> None:
if variable.namespace == self.objectspace.rougailconfig['variable_namespace'] and \ if variable.namespace == self.objectspace.rougailconfig['variable_namespace'] and \
variable.name in self.forbidden_name: variable.name in self.forbidden_name:
@ -175,11 +156,6 @@ class Annotator(Walk): # pylint: disable=R0903
del variable.value del variable.value
variable.doc = variable.description variable.doc = variable.description
del variable.description del variable.description
if variable_type == 'follower':
if variable.multi is True:
variable.multi = 'submulti'
else:
variable.multi = True
self._convert_valid_enum(variable) self._convert_valid_enum(variable)
def _convert_valid_enum(self, def _convert_valid_enum(self,
@ -213,21 +189,19 @@ class Annotator(Walk): # pylint: disable=R0903
"""Convert variable tests value """Convert variable tests value
""" """
for variable in self.get_variables(): for variable in self.get_variables():
if not hasattr(variable, 'test'): if not hasattr(variable, 'test') or not variable.test:
# with we want remove test, we set "" has test value
continue continue
if variable.test: new_values = []
if not hasattr(variable, 'information'): for value in variable.test.split('|'):
variable.information = self.objectspace.information(variable.xmlfiles) if value == '':
values = variable.test.split('|') value = None
new_values = [] else:
for value in values: value = CONVERT_OPTION.get(variable.type, {}).get('func', str)(value)
if value == '': new_values.append(value)
value = None if not hasattr(variable, 'information'):
else: variable.information = self.objectspace.information(variable.xmlfiles)
value = CONVERT_OPTION.get(variable.type, {}).get('func', str)(value) variable.information.test = tuple(new_values)
new_values.append(value)
variable.information.test = tuple(new_values)
del variable.test
def convert_help(self): def convert_help(self):
"""Convert variable help """Convert variable help

View File

@ -38,7 +38,7 @@ FORCE_REDEFINABLES = ('family', 'follower', 'service', 'disknod', 'variables')
# RougailObjSpace's elements that shall be forced to the UnRedefinable type # RougailObjSpace's elements that shall be forced to the UnRedefinable type
FORCE_UNREDEFINABLES = ('value',) FORCE_UNREDEFINABLES = ('value',)
# RougailObjSpace's elements that shall not be modify # RougailObjSpace's elements that shall not be modify
UNREDEFINABLE = ('multi', 'type', 'leadership') UNREDEFINABLE = ('multi', 'type',)
# RougailObjSpace's elements that did not created automaticly # RougailObjSpace's elements that did not created automaticly
FORCE_ELEMENTS = ('choice', 'property_', 'information') FORCE_ELEMENTS = ('choice', 'property_', 'information')
# XML text are convert has name # XML text are convert has name