From e354352dc83d1fa81224b5cd29a895af000ceb44 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Wed, 14 Apr 2021 17:34:38 +0200 Subject: [PATCH] simplify group --- src/rougail/annotator/family.py | 150 +++++++++++++----------------- src/rougail/annotator/group.py | 7 +- src/rougail/annotator/property.py | 5 +- src/rougail/annotator/value.py | 17 +--- src/rougail/annotator/variable.py | 84 ++++++----------- src/rougail/objspace.py | 2 +- 6 files changed, 106 insertions(+), 159 deletions(-) diff --git a/src/rougail/annotator/family.py b/src/rougail/annotator/family.py index f30802b7..e7b22d56 100644 --- a/src/rougail/annotator/family.py +++ b/src/rougail/annotator/family.py @@ -120,7 +120,7 @@ class Annotator(Walk): obj, ) -> None: 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, ' f'valid modes are {modes_level}') raise DictConsistencyError(msg, 71, obj.xmlfiles) @@ -128,23 +128,29 @@ class Annotator(Walk): def _set_default_mode(self, family: 'self.objectspace.family', ) -> 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 else: family_mode = None - if not hasattr(family, 'variable'): - return + leader = None 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 not variable.leadership: - if family_mode and not self._has_mode(variable): - self._set_auto_mode(variable, family_mode) - continue - func = self._set_default_mode_leader + # set default mode a subfamily + if family_mode and not self._has_mode(variable): + self._set_auto_mode(variable, family_mode) else: - func = self._set_default_mode_variable - func(variable, family_mode) + # set default mode to a variable + 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 def _has_mode(obj) -> bool: @@ -174,92 +180,80 @@ class Annotator(Walk): obj.mode_auto = True def _set_default_mode_leader(self, - leadership: 'self.objectspace.family', - family_mode: str, + leader: 'self.objectspace.variable', + follower: 'self.objectspace.variable', ) -> None: - leader_mode = None - leader = next(iter(leadership.variable.values())) - for follower in leadership.variable.values(): - self.valid_mode(follower) - if follower.auto_save is True: - msg = _(f'leader/followers "{follower.name}" could not be auto_save') - raise DictConsistencyError(msg, 29, leadership.xmlfiles) - if follower.auto_freeze is True: - msg = f'leader/followers "{follower.name}" could not be auto_freeze' - raise DictConsistencyError(_(msg), 30, leadership.xmlfiles) - if leader_mode is not None: - if hasattr(follower, 'mode'): - follower_mode = follower.mode - else: - follower_mode = self.objectspace.rougailconfig['default_variable_mode'] - if self.modes[leader_mode] > self.modes[follower_mode]: - if self._has_mode(follower) and not self._has_mode(leader): - # if follower has mode but not the leader - self._set_auto_mode(leader, follower_mode) - else: - # leader's mode is minimum level - if self._has_mode(follower): - msg = _(f'the follower "{follower.name}" is in "{follower_mode}" mode ' - f'but leader have the higher mode "{leader_mode}"') - raise DictConsistencyError(msg, 63, follower.xmlfiles) - 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) + if follower.auto_save is True: + msg = _(f'leader/followers "{follower.name}" could not be auto_save') + raise DictConsistencyError(msg, 29, follower.xmlfiles) + if follower.auto_freeze is True: + msg = f'leader/followers "{follower.name}" could not be auto_freeze' + raise DictConsistencyError(_(msg), 30, follower.xmlfiles) + if leader == follower: + # it's a leader + if not hasattr(leader, 'mode'): + self._set_auto_mode(leader, self.objectspace.rougailconfig['default_variable_mode']) + return + if self._has_mode(follower): + follower_mode = follower.mode + else: + follower_mode = self.objectspace.rougailconfig['default_variable_mode'] + if self.modes[leader.mode] > self.modes[follower_mode]: + if self._has_mode(follower) and not self._has_mode(leader): + # if follower has mode but not the leader + self._set_auto_mode(leader, follower_mode) + else: + # leader's mode is minimum level + if self._has_mode(follower): + msg = _(f'the follower "{follower.name}" is in "{follower_mode}" mode ' + f'but leader have the higher mode "{leader.mode}"') + raise DictConsistencyError(msg, 63, follower.xmlfiles) + self._set_auto_mode(follower, leader.mode) def _change_family_mode(self, - family: 'self.objectspace.family', - ) -> None: + family: 'self.objectspace.family', + ) -> None: if hasattr(family, 'mode'): family_mode = family.mode else: family_mode = self.objectspace.rougailconfig['default_family_mode'] min_variable_mode = self.objectspace.rougailconfig['modes_level'][-1] # change variable mode, but not if variables are not in a family + is_leadership = hasattr(family, 'leadership') and family.leadership 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 variable.leadership: - func = self._change_variable_mode_leader - else: - func = None + if not hasattr(variable, 'mode'): + variable.mode = self.objectspace.rougailconfig['default_family_mode'] + elif idx == 0 and is_leadership: + variable.mode = None + continue else: - func = self._change_variable_mode - if func: - func(variable, - family_mode, - ) - elif not hasattr(variable, 'mode'): - variable.mode = self.objectspace.rougailconfig['default_family_mode'] + self._change_variable_mode(variable, family_mode, is_leadership) if self.modes[min_variable_mode] > self.modes[variable.mode]: min_variable_mode = variable.mode - if isinstance(family, self.objectspace.family) and \ - (not hasattr(family, 'mode') or family.mode != min_variable_mode): + if not isinstance(family, self.objectspace.family) or is_leadership: + # it's Variable, Service, ... and leadership + return + if not hasattr(family, 'mode'): # 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) + 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, variable, family_mode: str, + is_follower: bool, ) -> None: if hasattr(variable, 'mode'): variable_mode = variable.mode else: variable_mode = self.objectspace.rougailconfig['default_variable_mode'] # 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): msg = _(f'the variable "{variable.name}" is in "{variable_mode}" mode ' f'but family has the higher family mode "{family_mode}"') @@ -268,18 +262,6 @@ class Annotator(Walk): if not hasattr(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): """link dynamic families to object """ diff --git a/src/rougail/annotator/group.py b/src/rougail/annotator/group.py index a79160c7..93ca76b4 100644 --- a/src/rougail/annotator/group.py +++ b/src/rougail/annotator/group.py @@ -47,7 +47,7 @@ class Annotator(Walk): """convert groups """ # 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): continue if not family.leadership: @@ -55,7 +55,6 @@ class Annotator(Walk): if hasattr(family, 'dynamic'): msg = _(f'the family "{family.name}" cannot be leadership and dynamic together') raise DictConsistencyError(msg, 31, family.xmlfiles) - family.doc = family.description for idx, variable in enumerate(family.variable.values()): if idx == 0: # it's a leader @@ -72,3 +71,7 @@ class Annotator(Walk): if family.hidden: variable.frozen = True variable.force_default_on_freeze = True + if variable.multi is True: + variable.multi = 'submulti' + else: + variable.multi = True diff --git a/src/rougail/annotator/property.py b/src/rougail/annotator/property.py index afd4d8a6..d3fed9e0 100644 --- a/src/rougail/annotator/property.py +++ b/src/rougail/annotator/property.py @@ -106,8 +106,5 @@ class Annotator(Walk): def convert_variable(self) -> None: """convert variables """ - for variable in self.get_variables(with_leadership=True): - if isinstance(variable, self.objectspace.family): - for follower in variable.variable.values(): - self.convert_property(follower) + for variable in self.get_variables(): self.convert_property(variable) diff --git a/src/rougail/annotator/value.py b/src/rougail/annotator/value.py index 7d30d9d8..30a19246 100644 --- a/src/rougail/annotator/value.py +++ b/src/rougail/annotator/value.py @@ -45,20 +45,11 @@ class Annotator(Walk): # pylint: disable=R0903 def convert_value(self) -> None: """convert value """ - for variable in self.get_variables(with_leadership=True): - if isinstance(variable, self.objectspace.family): - variable_type = 'leader' - for follower in variable.variable.values(): - self._convert_value(follower, - variable_type, - ) - variable_type = 'follower' - else: - self._convert_value(variable) + for variable in self.get_variables(): + self._convert_value(variable) def _convert_value(self, variable, - variable_type: str=None, ) -> None: # a boolean must have value, the default value is "True" 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': variable.default = variable.value[0] 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] - if variable_type != 'leader': + if not self.objectspace.paths.is_leader(variable.path): if variable.multi == 'submulti': variable.default_multi = [value.name for value in variable.value] else: diff --git a/src/rougail/annotator/variable.py b/src/rougail/annotator/variable.py index 15c06ecd..06392428 100644 --- a/src/rougail/annotator/variable.py +++ b/src/rougail/annotator/variable.py @@ -72,45 +72,38 @@ class Walk: """ objectspace = None - def get_variables(self, - with_leadership: bool=False, - ): + def get_variables(self): """Iter all variables from the objectspace """ 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, family: 'self.objectspace.family', - with_leadership: bool ): - if hasattr(family, 'variable'): - for variable in family.variable.values(): - if isinstance(variable, self.objectspace.family): - if variable.leadership is False: - yield from self._get_variables(variable, with_leadership) - continue - if not with_leadership: - for follower in variable.variable.values(): - yield follower - continue + if not hasattr(family, 'variable'): + return + for variable in family.variable.values(): + if isinstance(variable, self.objectspace.family): + yield from self._get_variables(variable) + else: yield variable - def get_families(self, with_leadership=False): + def get_families(self): """Iter all families from the objectspace """ 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, family: 'self.objectspace.family', - with_leadership: bool, ): yield family - if hasattr(family, 'variable'): - for fam in family.variable.values(): - if isinstance(fam, self.objectspace.family) and (with_leadership or not fam.leadership): - yield from self._get_families(fam, with_leadership) + if not hasattr(family, 'variable'): + return + for fam in family.variable.values(): + if isinstance(fam, self.objectspace.family): + yield from self._get_families(fam) class Annotator(Walk): # pylint: disable=R0903 @@ -134,23 +127,11 @@ class Annotator(Walk): # pylint: disable=R0903 def convert_variable(self): """convert variable """ - for variable in self.get_variables(with_leadership=True): - if isinstance(variable, self.objectspace.family): - # 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', - ) + for variable in self.get_variables(): + self._convert_variable(variable) def _convert_variable(self, variable, - variable_type: str, ) -> None: if variable.namespace == self.objectspace.rougailconfig['variable_namespace'] and \ variable.name in self.forbidden_name: @@ -175,11 +156,6 @@ class Annotator(Walk): # pylint: disable=R0903 del variable.value variable.doc = 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) def _convert_valid_enum(self, @@ -213,21 +189,19 @@ class Annotator(Walk): # pylint: disable=R0903 """Convert variable tests value """ 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 - if variable.test: - if not hasattr(variable, 'information'): - variable.information = self.objectspace.information(variable.xmlfiles) - values = variable.test.split('|') - new_values = [] - for value in values: - if value == '': - value = None - else: - value = CONVERT_OPTION.get(variable.type, {}).get('func', str)(value) - new_values.append(value) - variable.information.test = tuple(new_values) - del variable.test + new_values = [] + for value in variable.test.split('|'): + if value == '': + value = None + else: + value = CONVERT_OPTION.get(variable.type, {}).get('func', str)(value) + new_values.append(value) + if not hasattr(variable, 'information'): + variable.information = self.objectspace.information(variable.xmlfiles) + variable.information.test = tuple(new_values) def convert_help(self): """Convert variable help diff --git a/src/rougail/objspace.py b/src/rougail/objspace.py index eb77cf0d..d153c0bd 100644 --- a/src/rougail/objspace.py +++ b/src/rougail/objspace.py @@ -38,7 +38,7 @@ FORCE_REDEFINABLES = ('family', 'follower', 'service', 'disknod', 'variables') # RougailObjSpace's elements that shall be forced to the UnRedefinable type FORCE_UNREDEFINABLES = ('value',) # RougailObjSpace's elements that shall not be modify -UNREDEFINABLE = ('multi', 'type', 'leadership') +UNREDEFINABLE = ('multi', 'type',) # RougailObjSpace's elements that did not created automaticly FORCE_ELEMENTS = ('choice', 'property_', 'information') # XML text are convert has name