From 2e16bc2b903b760e4aa2d115057fc6d9a76157c2 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Thu, 18 Feb 2021 14:02:07 +0100 Subject: [PATCH] update mode --- src/rougail/annotator/family.py | 73 +++++++++++++------ .../01fill_mandatory/tiramisu/base.py | 4 +- .../tiramisu/base.py | 2 +- .../00-base.xml | 16 ++-- .../00-base.xml | 26 +++---- .../20family_modeleadership/tiramisu/base.py | 6 +- .../45multi_family_basic/00-base.xml | 12 +++ .../45multi_family_basic/__init__.py | 0 .../45multi_family_basic/makedict/base.json | 1 + .../45multi_family_basic/tiramisu/base.py | 18 +++++ .../dictionaries/80mode_conflict/00-base.xml | 12 +++ .../dictionaries/80mode_conflict/__init__.py | 0 tests/dictionaries/80mode_conflict/errno_62 | 0 .../80mode_leadership_conflict/00-base.xml | 26 +++++++ .../80mode_leadership_conflict/__init__.py | 0 .../80mode_leadership_conflict/errno_63 | 0 .../80multi_family_mode_conflict/00-base.xml | 12 +++ .../80multi_family_mode_conflict/__init__.py | 0 .../80multi_family_mode_conflict/errno_61 | 0 19 files changed, 160 insertions(+), 48 deletions(-) create mode 100644 tests/dictionaries/45multi_family_basic/00-base.xml create mode 100644 tests/dictionaries/45multi_family_basic/__init__.py create mode 100644 tests/dictionaries/45multi_family_basic/makedict/base.json create mode 100644 tests/dictionaries/45multi_family_basic/tiramisu/base.py create mode 100644 tests/dictionaries/80mode_conflict/00-base.xml create mode 100644 tests/dictionaries/80mode_conflict/__init__.py create mode 100644 tests/dictionaries/80mode_conflict/errno_62 create mode 100644 tests/dictionaries/80mode_leadership_conflict/00-base.xml create mode 100644 tests/dictionaries/80mode_leadership_conflict/__init__.py create mode 100644 tests/dictionaries/80mode_leadership_conflict/errno_63 create mode 100644 tests/dictionaries/80multi_family_mode_conflict/00-base.xml create mode 100644 tests/dictionaries/80multi_family_mode_conflict/__init__.py create mode 100644 tests/dictionaries/80multi_family_mode_conflict/errno_61 diff --git a/src/rougail/annotator/family.py b/src/rougail/annotator/family.py index 6ba7a4563..adfbc26f3 100644 --- a/src/rougail/annotator/family.py +++ b/src/rougail/annotator/family.py @@ -122,29 +122,44 @@ class FamilyAnnotator(Walk): return for variable in family.variable.values(): if isinstance(variable, self.objectspace.family): - if family_mode and 'mode' not in vars(variable): - variable.mode = family_mode + if family_mode and not self._has_mode(variable): + self._set_auto_mode(variable, family_mode) continue if isinstance(variable, self.objectspace.leadership): func = self._set_default_mode_leader else: func = self._set_default_mode_variable - func(variable) + func(variable, family_mode) @staticmethod - def _set_default_mode_variable(variable: 'self.objectspace.variable', - ) -> None: + def _has_mode(obj) -> bool: + return 'mode' in vars(obj) and not hasattr(obj, 'mode_auto') + + def _set_default_mode_variable(self, + variable: 'self.objectspace.variable', + family_mode: str, + ) -> None: # auto_save or auto_freeze variable is set to 'basic' mode # if its mode is not defined by the user - if 'mode' not in vars(variable) and \ + if not self._has_mode(variable) and \ (variable.auto_save is True or variable.auto_freeze is True): - variable.mode = modes_level[0] + self._set_auto_mode(variable, modes_level[0]) # mandatory variable without value is a basic variable - if variable.mandatory is True and not hasattr(variable, 'default'): - variable.mode = modes_level[0] + elif variable.mandatory is True and \ + not hasattr(variable, 'default') and \ + not hasattr(variable, 'default_multi'): + self._set_auto_mode(variable, modes_level[0]) + elif family_mode and not self._has_mode(variable): + self._set_auto_mode(variable, family_mode) + + @staticmethod + def _set_auto_mode(obj, mode: str) -> None: + obj.mode = mode + obj.mode_auto = True def _set_default_mode_leader(self, - leadership, + leadership: 'self.objectspace.leadership', + family_mode: str, ) -> None: leader_mode = None for follower in leadership.variable: @@ -154,14 +169,23 @@ class FamilyAnnotator(Walk): if follower.auto_freeze is True: msg = f'leader/followers "{follower.name}" could not be auto_freeze' raise DictConsistencyError(_(msg), 30, leadership.xmlfiles) - self._set_default_mode_variable(follower) - if leader_mode is None: - leader_mode = leadership.variable[0].mode - else: + if leader_mode is not None: # leader's mode is minimum level if modes[leader_mode] > modes[follower.mode]: - follower.mode = leader_mode - leadership.mode = leader_mode + if self._has_mode(follower) and not self._has_mode(leadership.variable[0]): + self._set_auto_mode(leadership.variable[0], follower.mode) + else: + 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: + leader_mode = leadership.variable[0].mode + self._set_auto_mode(leadership, leadership.variable[0].mode) def _change_family_mode(self, family: 'self.objectspace.family', @@ -184,9 +208,13 @@ class FamilyAnnotator(Walk): ) if modes[min_variable_mode] > modes[variable.mode]: min_variable_mode = variable.mode - if hasattr(family, 'mode'): + if hasattr(family, 'mode') and family.mode != min_variable_mode: # set the lower variable mode to family - family.mode = min_variable_mode + 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, variable.xmlfiles) + self._set_auto_mode(family, min_variable_mode) def _change_variable_mode(self, variable, @@ -194,9 +222,12 @@ class FamilyAnnotator(Walk): is_follower=False, ) -> None: # none basic variable in high level family has to be in high level - if modes[variable.mode] < modes[family_mode] and \ - (not is_follower or variable.mode != modes_level[0]): - variable.mode = family_mode + if modes[variable.mode] < 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}"') + raise DictConsistencyError(msg, 61, variable.xmlfiles) + self._set_auto_mode(variable, family_mode) def _change_variable_mode_leader(self, leadership, diff --git a/tests/dictionaries/01fill_mandatory/tiramisu/base.py b/tests/dictionaries/01fill_mandatory/tiramisu/base.py index 23d2d55e1..d8abb72b9 100644 --- a/tests/dictionaries/01fill_mandatory/tiramisu/base.py +++ b/tests/dictionaries/01fill_mandatory/tiramisu/base.py @@ -11,8 +11,8 @@ try: from tiramisu3 import * except: from tiramisu import * -option_4 = StrOption(name="mode_conteneur_actif1", doc="No change", default="non", properties=frozenset({"mandatory", "normal"})) +option_4 = StrOption(name="mode_conteneur_actif1", doc="No change", default="non", properties=frozenset({"basic", "mandatory"})) option_3 = StrOption(name="mode_conteneur_actif", doc="No change", default=Calculation(func.calc_val, Params((ParamOption(option_4)))), properties=frozenset({"expert", "mandatory"})) -option_2 = OptionDescription(name="general", doc="general", children=[option_3, option_4], properties=frozenset({"normal"})) +option_2 = OptionDescription(name="general", doc="general", children=[option_3, option_4], properties=frozenset({"basic"})) option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2]) option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1]) diff --git a/tests/dictionaries/10leadership_mandatoryfollower/tiramisu/base.py b/tests/dictionaries/10leadership_mandatoryfollower/tiramisu/base.py index 7ab3f6e59..f7ddf7271 100644 --- a/tests/dictionaries/10leadership_mandatoryfollower/tiramisu/base.py +++ b/tests/dictionaries/10leadership_mandatoryfollower/tiramisu/base.py @@ -13,7 +13,7 @@ except: from tiramisu import * option_3 = StrOption(name="mode_conteneur_actif", doc="No change", default="oui", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"})) option_5 = NetmaskOption(name="nut_monitor_netmask", doc="Masque de l'IP du réseau de l'esclave", multi=True) -option_6 = NetworkOption(name="nut_monitor_host", doc="Adresse IP du réseau de l'esclave", multi=True, properties=frozenset({"mandatory", "normal"})) +option_6 = NetworkOption(name="nut_monitor_host", doc="Adresse IP du réseau de l'esclave", multi=True, properties=frozenset({"basic", "mandatory"})) option_4 = Leadership(name="nut_monitor_netmask", doc="Masque de l'IP du réseau de l'esclave", children=[option_5, option_6], properties=frozenset({"normal"})) option_2 = OptionDescription(name="general", doc="général", children=[option_3, option_4], properties=frozenset({"normal"})) option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2]) diff --git a/tests/dictionaries/10load_leadership_default_multi/00-base.xml b/tests/dictionaries/10load_leadership_default_multi/00-base.xml index 502983627..dc7f6d359 100644 --- a/tests/dictionaries/10load_leadership_default_multi/00-base.xml +++ b/tests/dictionaries/10load_leadership_default_multi/00-base.xml @@ -2,14 +2,14 @@ - - non - - - - value - - + + non + + + + value + + diff --git a/tests/dictionaries/10load_leadership_default_submulti/00-base.xml b/tests/dictionaries/10load_leadership_default_submulti/00-base.xml index d1cf82723..89c74adfd 100644 --- a/tests/dictionaries/10load_leadership_default_submulti/00-base.xml +++ b/tests/dictionaries/10load_leadership_default_submulti/00-base.xml @@ -2,19 +2,19 @@ - - non - - - leader - - - value - - - value1 - value2 - + + non + + + leader + + + value + + + value1 + value2 + diff --git a/tests/dictionaries/20family_modeleadership/tiramisu/base.py b/tests/dictionaries/20family_modeleadership/tiramisu/base.py index c44c4518f..28e3a12fc 100644 --- a/tests/dictionaries/20family_modeleadership/tiramisu/base.py +++ b/tests/dictionaries/20family_modeleadership/tiramisu/base.py @@ -14,8 +14,8 @@ except: option_3 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"mandatory", "normal"})) option_5 = StrOption(name="leader", doc="leader", multi=True) option_6 = StrOption(name="follower1", doc="follower1", multi=True, properties=frozenset({"normal"})) -option_7 = StrOption(name="follower2", doc="follower2", multi=True, properties=frozenset({"normal"})) -option_4 = Leadership(name="leader", doc="leader", children=[option_5, option_6, option_7], properties=frozenset({"normal"})) -option_2 = OptionDescription(name="general", doc="general", children=[option_3, option_4], properties=frozenset({"normal"})) +option_7 = StrOption(name="follower2", doc="follower2", multi=True, properties=frozenset({"basic"})) +option_4 = Leadership(name="leader", doc="leader", children=[option_5, option_6, option_7], properties=frozenset({"basic"})) +option_2 = OptionDescription(name="general", doc="general", children=[option_3, option_4], properties=frozenset({"basic"})) option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2]) option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1]) diff --git a/tests/dictionaries/45multi_family_basic/00-base.xml b/tests/dictionaries/45multi_family_basic/00-base.xml new file mode 100644 index 000000000..e62828fda --- /dev/null +++ b/tests/dictionaries/45multi_family_basic/00-base.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/tests/dictionaries/45multi_family_basic/__init__.py b/tests/dictionaries/45multi_family_basic/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/dictionaries/45multi_family_basic/makedict/base.json b/tests/dictionaries/45multi_family_basic/makedict/base.json new file mode 100644 index 000000000..536366a76 --- /dev/null +++ b/tests/dictionaries/45multi_family_basic/makedict/base.json @@ -0,0 +1 @@ +{"rougail.base.subfamily.variable": null} diff --git a/tests/dictionaries/45multi_family_basic/tiramisu/base.py b/tests/dictionaries/45multi_family_basic/tiramisu/base.py new file mode 100644 index 000000000..3f1787a3e --- /dev/null +++ b/tests/dictionaries/45multi_family_basic/tiramisu/base.py @@ -0,0 +1,18 @@ +from importlib.machinery import SourceFileLoader +from importlib.util import spec_from_loader, module_from_spec +loader = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py') +spec = spec_from_loader(loader.name, loader) +func = module_from_spec(spec) +loader.exec_module(func) +for key, value in dict(locals()).items(): + if key != ['SourceFileLoader', 'func']: + setattr(func, key, value) +try: + from tiramisu3 import * +except: + from tiramisu import * +option_4 = StrOption(name="variable", doc="variable", properties=frozenset({"basic"})) +option_3 = OptionDescription(name="subfamily", doc="subfamily", children=[option_4], properties=frozenset({"basic"})) +option_2 = OptionDescription(name="base", doc="base", children=[option_3], properties=frozenset({"basic"})) +option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2]) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1]) diff --git a/tests/dictionaries/80mode_conflict/00-base.xml b/tests/dictionaries/80mode_conflict/00-base.xml new file mode 100644 index 000000000..6b666c602 --- /dev/null +++ b/tests/dictionaries/80mode_conflict/00-base.xml @@ -0,0 +1,12 @@ + + + + + + non + + + + + diff --git a/tests/dictionaries/80mode_conflict/__init__.py b/tests/dictionaries/80mode_conflict/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/dictionaries/80mode_conflict/errno_62 b/tests/dictionaries/80mode_conflict/errno_62 new file mode 100644 index 000000000..e69de29bb diff --git a/tests/dictionaries/80mode_leadership_conflict/00-base.xml b/tests/dictionaries/80mode_leadership_conflict/00-base.xml new file mode 100644 index 000000000..c8e748e8b --- /dev/null +++ b/tests/dictionaries/80mode_leadership_conflict/00-base.xml @@ -0,0 +1,26 @@ + + + + + + non + + + + + + + + + + + + valfill + leader + + + follower1 + follower2 + + + diff --git a/tests/dictionaries/80mode_leadership_conflict/__init__.py b/tests/dictionaries/80mode_leadership_conflict/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/dictionaries/80mode_leadership_conflict/errno_63 b/tests/dictionaries/80mode_leadership_conflict/errno_63 new file mode 100644 index 000000000..e69de29bb diff --git a/tests/dictionaries/80multi_family_mode_conflict/00-base.xml b/tests/dictionaries/80multi_family_mode_conflict/00-base.xml new file mode 100644 index 000000000..f738fd481 --- /dev/null +++ b/tests/dictionaries/80multi_family_mode_conflict/00-base.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/tests/dictionaries/80multi_family_mode_conflict/__init__.py b/tests/dictionaries/80multi_family_mode_conflict/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/dictionaries/80multi_family_mode_conflict/errno_61 b/tests/dictionaries/80multi_family_mode_conflict/errno_61 new file mode 100644 index 000000000..e69de29bb