diff --git a/src/rougail/annotator/family.py b/src/rougail/annotator/family.py index 0ca3c31d..52648a26 100644 --- a/src/rougail/annotator/family.py +++ b/src/rougail/annotator/family.py @@ -39,6 +39,7 @@ class FamilyAnnotator: self.change_variable_mode() self.change_family_mode() self.dynamic_families() + self.convert_help() def remove_empty_families(self): """Remove all families without any variable @@ -175,3 +176,14 @@ class FamilyAnnotator: msg = _(f'dynamic family "{family.name}" must be linked ' f'to multi variable in {xmlfiles}') raise DictConsistencyError(msg, 16) + + def convert_help(self): + """Convert variable help + """ + for families in self.objectspace.space.variables.values(): + for family in families.family.values(): + if hasattr(family, 'help'): + if not hasattr(family, 'information'): + family.information = self.objectspace.information(family.xmlfiles) + family.information.help = family.help + del family.help diff --git a/src/rougail/annotator/service.py b/src/rougail/annotator/service.py index 2ebe9a15..d7984a06 100644 --- a/src/rougail/annotator/service.py +++ b/src/rougail/annotator/service.py @@ -11,7 +11,7 @@ from ..error import DictConsistencyError ERASED_ATTRIBUTES = ('redefine', 'exists', 'fallback', 'optional', 'remove_check', 'namespace', 'remove_condition', 'path', 'instance_mode', 'index', 'is_in_leadership', 'level', 'remove_fill', 'xmlfiles', 'type', 'reflector_name', - 'reflector_object',) + 'reflector_object', 'manage') KEY_TYPE = {'variable': 'symlink', @@ -50,14 +50,12 @@ class ServiceAnnotator: self.objectspace.space.services.name = 'services' self.objectspace.space.services.doc = 'services' self.objectspace.space.services.path = 'services' - families = {} - for service_name in self.objectspace.space.services.service.keys(): - service = self.objectspace.space.services.service[service_name] - new_service = self.objectspace.service(service.xmlfiles) - new_service.path = f'services.{service_name}' - for elttype, values in vars(service).items(): + for service_name, service in self.objectspace.space.services.service.items(): + service.information = self.objectspace.information(service.xmlfiles) + service.information.manage = service.manage + service.manage = None + for elttype, values in dict(vars(service)).items(): if not isinstance(values, (dict, list)) or elttype in ERASED_ATTRIBUTES: - setattr(new_service, elttype, values) continue eltname = elttype + 's' path = '.'.join(['services', normalize_family(service_name), eltname]) @@ -72,10 +70,8 @@ class ServiceAnnotator: values, path, ) - setattr(new_service, elttype, family) - new_service.doc = new_service.name - families[service_name] = new_service - self.objectspace.space.services.service = families + setattr(service, elttype, family) + service.doc = service.name def make_group_from_elts(self, service_name, diff --git a/src/rougail/annotator/variable.py b/src/rougail/annotator/variable.py index dc127089..593975cd 100644 --- a/src/rougail/annotator/variable.py +++ b/src/rougail/annotator/variable.py @@ -54,6 +54,7 @@ class VariableAnnotator: # pylint: disable=R0903 self.objectspace = objectspace self.convert_variable() self.convert_test() + self.convert_help() def convert_variable(self): """convert variable @@ -162,16 +163,38 @@ class VariableAnnotator: # pylint: disable=R0903 def _convert_test(self, variable, ) -> None: + if not hasattr(variable, 'information'): + variable.information = self.objectspace.information(variable.xmlfiles) if hasattr(variable, 'test'): - if not variable.test: - del variable.test - return - 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.test = tuple(new_values) + if variable.test: + 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 + + def convert_help(self): + """Convert variable help + """ + for families in self.objectspace.space.variables.values(): + for family in families.family.values(): + if not hasattr(family, 'variable'): + continue + for variable in family.variable.values(): + if isinstance(variable, self.objectspace.leadership): + for follower in variable.variable: + self._convert_help(follower) + else: + self._convert_help(variable) + + def _convert_help(self, + variable, + ) -> None: + if hasattr(variable, 'help'): + variable.information.help = variable.help + del variable.help diff --git a/src/rougail/objspace.py b/src/rougail/objspace.py index 6f6ff350..00a04407 100644 --- a/src/rougail/objspace.py +++ b/src/rougail/objspace.py @@ -17,7 +17,7 @@ FORCE_UNREDEFINABLES = ('value',) # RougailObjSpace's elements that shall not be modify UNREDEFINABLE = ('multi', 'type') # RougailObjSpace's elements that did not created automaticly -FORCE_ELEMENTS = ('choice', 'property_', 'leadership') +FORCE_ELEMENTS = ('choice', 'property_', 'leadership', 'information') # XML text are convert has name FORCED_TEXT_ELTS_AS_NAME = ('choice', 'property', 'value', 'target') diff --git a/src/rougail/tiramisureflector.py b/src/rougail/tiramisureflector.py index e022f315..b86193bf 100644 --- a/src/rougail/tiramisureflector.py +++ b/src/rougail/tiramisureflector.py @@ -3,12 +3,10 @@ flattened XML specific """ from .config import Config from .annotator import ERASED_ATTRIBUTES, CONVERT_OPTION -#from .objspace import UnRedefinable, Redefinable, Atom FUNC_TO_DICT = [] -FORCE_INFORMATIONS = ['help', 'test', 'manage'] -ATTRIBUTES_ORDER = ('name', 'doc', 'default', 'multi') +ATTRIBUTES_ORDER = ('name', 'doc', 'default', 'multi', 'properties', 'max_number', 'min_number', 'dynamic', 'opt') class Root(): # pylint: disable=R0903 @@ -180,7 +178,6 @@ class Common: self.elt = elt self.option_name = None self.attrib = {} - self.informations = {} self.text = text self.elt.reflector_object = self @@ -228,7 +225,11 @@ class Common: def populate_informations(self): """Populate Tiramisu's informations """ - for key, value in self.informations.items(): + if not hasattr(self.elt, 'information'): + return + for key, value in vars(self.elt.information).items(): + if key == 'xmlfiles': + continue if isinstance(value, str): value = '"' + value.replace('"', '\"') + '"' self.text.append(f'{self.option_name}.impl_set_information("{key}", {value})') @@ -236,17 +237,9 @@ class Common: def get_attributes(self, space): # pylint: disable=R0201 """Get attributes """ - attributes = dir(space) for attr in ATTRIBUTES_ORDER: - if attr in attributes: + if hasattr(space, attr): yield attr - for attr in dir(space): - if attr not in ATTRIBUTES_ORDER: - if not attr.startswith('_') and attr not in ERASED_ATTRIBUTES: - value = getattr(space, attr) - if not isinstance(value, (list, dict)) and \ - not value.__class__.__name__ == 'Family': - yield attr @staticmethod def get_children(space): @@ -296,11 +289,7 @@ class Variable(Common): """Populate attributes """ for key in self.get_attributes(self.elt): - value = getattr(self.elt, key) - if key in FORCE_INFORMATIONS: - self.informations[key] = value - else: - self.attrib[key] = value + self.attrib[key] = getattr(self.elt, key) def parse_children(self): """Parse children @@ -346,6 +335,8 @@ class Variable(Common): self.calculate_choice(child, choices, ) + else: # pragma: no cover + raise Exception(f'unknown tag {tag}') def calculate_choice(self, child, @@ -475,9 +466,7 @@ class Family(Common): """ for key in self.get_attributes(self.elt): value = getattr(self.elt, key) - if key in FORCE_INFORMATIONS: - self.informations[key] = value - elif key == 'dynamic': + if key == 'dynamic': dynamic = value.reflector_object.get() self.attrib['suffixes'] = \ f"Calculation(func.calc_value, Params((ParamOption({dynamic}))))" diff --git a/tests/dictionaries/20family_dynamic/tiramisu/base.py b/tests/dictionaries/20family_dynamic/tiramisu/base.py index 3a501927..f5598ddf 100644 --- a/tests/dictionaries/20family_dynamic/tiramisu/base.py +++ b/tests/dictionaries/20family_dynamic/tiramisu/base.py @@ -15,6 +15,6 @@ from rougail.tiramisu import ConvertDynOptionDescription option_3 = StrOption(properties=frozenset({'mandatory', 'normal'}), name='varname', doc='No change', multi=True, default=['val1', 'val2'], default_multi='val2') option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3]) option_5 = StrOption(properties=frozenset({'normal'}), name='vardyn', doc='No change', multi=False) -option_4 = ConvertDynOptionDescription(name='dyn', doc='dyn', suffixes=Calculation(func.calc_value, Params((ParamOption(option_3)))), properties=frozenset({'normal'}), children=[option_5]) +option_4 = ConvertDynOptionDescription(name='dyn', doc='dyn', properties=frozenset({'normal'}), suffixes=Calculation(func.calc_value, Params((ParamOption(option_3)))), children=[option_5]) option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2, option_4]) option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1]) diff --git a/tests/dictionaries/20family_dynamic_calc/tiramisu/base.py b/tests/dictionaries/20family_dynamic_calc/tiramisu/base.py index fa37f444..eab80d32 100644 --- a/tests/dictionaries/20family_dynamic_calc/tiramisu/base.py +++ b/tests/dictionaries/20family_dynamic_calc/tiramisu/base.py @@ -15,7 +15,7 @@ from rougail.tiramisu import ConvertDynOptionDescription option_3 = StrOption(properties=frozenset({'mandatory', 'normal'}), name='varname', doc='No change', multi=True, default=['val1', 'val2'], default_multi='val2') option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3]) option_5 = StrOption(properties=frozenset({'mandatory', 'normal'}), name='vardyn', doc='No change', multi=False, default='val') -option_4 = ConvertDynOptionDescription(name='dyn', doc='dyn', suffixes=Calculation(func.calc_value, Params((ParamOption(option_3)))), properties=frozenset({'normal'}), children=[option_5]) +option_4 = ConvertDynOptionDescription(name='dyn', doc='dyn', properties=frozenset({'normal'}), suffixes=Calculation(func.calc_value, Params((ParamOption(option_3)))), children=[option_5]) option_7 = StrOption(properties=frozenset({'normal'}), name='newvar', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamDynOption(option_5, 'val1', option_4, notraisepropertyerror=False, todict=False)), kwargs={}))) option_6 = OptionDescription(name='new', doc='new', properties=frozenset({'normal'}), children=[option_7]) option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2, option_4, option_6]) diff --git a/tests/dictionaries/20family_dynamic_calc2/tiramisu/base.py b/tests/dictionaries/20family_dynamic_calc2/tiramisu/base.py index 8909481c..a046cc01 100644 --- a/tests/dictionaries/20family_dynamic_calc2/tiramisu/base.py +++ b/tests/dictionaries/20family_dynamic_calc2/tiramisu/base.py @@ -16,7 +16,7 @@ option_3 = StrOption(properties=frozenset({'mandatory', 'normal'}), name='varnam option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3]) option_7 = StrOption(properties=frozenset({'normal'}), name='newvar', doc='No change', multi=False) option_5 = StrOption(properties=frozenset({'mandatory', 'normal', Calculation(calc_value, Params(ParamValue('frozen'), kwargs={'condition': ParamOption(option_7, todict=True), 'expected': ParamValue('non')})), Calculation(calc_value, Params(ParamValue('force_default_on_freeze'), kwargs={'condition': ParamOption(option_7, todict=True), 'expected': ParamValue('non')}))}), name='vardyn', doc='No change', multi=False, default='val') -option_4 = ConvertDynOptionDescription(name='dyn', doc='dyn', suffixes=Calculation(func.calc_value, Params((ParamOption(option_3)))), properties=frozenset({'normal', Calculation(calc_value, Params(ParamValue('hidden'), kwargs={'condition': ParamOption(option_7, todict=True), 'expected': ParamValue('non')}))}), children=[option_5]) +option_4 = ConvertDynOptionDescription(name='dyn', doc='dyn', properties=frozenset({'normal', Calculation(calc_value, Params(ParamValue('hidden'), kwargs={'condition': ParamOption(option_7, todict=True), 'expected': ParamValue('non')}))}), suffixes=Calculation(func.calc_value, Params((ParamOption(option_3)))), children=[option_5]) option_6 = OptionDescription(name='new', doc='new', properties=frozenset({'normal'}), children=[option_7]) option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2, option_4, option_6]) option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1]) diff --git a/tests/dictionaries/20family_dynamic_calc_suffix/tiramisu/base.py b/tests/dictionaries/20family_dynamic_calc_suffix/tiramisu/base.py index 61ed3bcd..c7b9c11b 100644 --- a/tests/dictionaries/20family_dynamic_calc_suffix/tiramisu/base.py +++ b/tests/dictionaries/20family_dynamic_calc_suffix/tiramisu/base.py @@ -15,7 +15,7 @@ from rougail.tiramisu import ConvertDynOptionDescription option_3 = StrOption(properties=frozenset({'mandatory', 'normal'}), name='varname', doc='No change', multi=True, default=['val1', 'val2'], default_multi='val2') option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3]) option_5 = StrOption(properties=frozenset({'normal'}), name='vardyn', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamSuffix()), kwargs={}))) -option_4 = ConvertDynOptionDescription(name='dyn', doc='dyn', suffixes=Calculation(func.calc_value, Params((ParamOption(option_3)))), properties=frozenset({'normal'}), children=[option_5]) +option_4 = ConvertDynOptionDescription(name='dyn', doc='dyn', properties=frozenset({'normal'}), suffixes=Calculation(func.calc_value, Params((ParamOption(option_3)))), children=[option_5]) option_7 = StrOption(properties=frozenset({'normal'}), name='newvar', doc='No change', multi=False) option_6 = OptionDescription(name='new', doc='new', properties=frozenset({'normal'}), children=[option_7]) option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2, option_4, option_6]) diff --git a/tests/dictionaries/20family_dynamic_description/tiramisu/base.py b/tests/dictionaries/20family_dynamic_description/tiramisu/base.py index 73fa3ba2..7699dca7 100644 --- a/tests/dictionaries/20family_dynamic_description/tiramisu/base.py +++ b/tests/dictionaries/20family_dynamic_description/tiramisu/base.py @@ -15,6 +15,6 @@ from rougail.tiramisu import ConvertDynOptionDescription option_3 = StrOption(properties=frozenset({'mandatory', 'normal'}), name='varname', doc='No change', multi=True, default=['val1', 'val2'], default_multi='val2') option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3]) option_5 = StrOption(properties=frozenset({'normal'}), name='vardyn', doc='No change', multi=False) -option_4 = ConvertDynOptionDescription(name='dyn', doc='Dyn ', suffixes=Calculation(func.calc_value, Params((ParamOption(option_3)))), properties=frozenset({'normal'}), children=[option_5]) +option_4 = ConvertDynOptionDescription(name='dyn', doc='Dyn ', properties=frozenset({'normal'}), suffixes=Calculation(func.calc_value, Params((ParamOption(option_3)))), children=[option_5]) option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2, option_4]) option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1]) diff --git a/tests/dictionaries/20family_dynamic_number/tiramisu/base.py b/tests/dictionaries/20family_dynamic_number/tiramisu/base.py index dc7f511e..137b58ee 100644 --- a/tests/dictionaries/20family_dynamic_number/tiramisu/base.py +++ b/tests/dictionaries/20family_dynamic_number/tiramisu/base.py @@ -15,7 +15,7 @@ from rougail.tiramisu import ConvertDynOptionDescription option_3 = IntOption(properties=frozenset({'mandatory', 'normal'}), name='varname', doc='No change', multi=True, default=[1, 2], default_multi=2) option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3]) option_5 = StrOption(properties=frozenset({'mandatory', 'normal'}), name='vardyn', doc='No change', multi=False, default='val') -option_4 = ConvertDynOptionDescription(name='dyn', doc='dyn', suffixes=Calculation(func.calc_value, Params((ParamOption(option_3)))), properties=frozenset({'normal'}), children=[option_5]) +option_4 = ConvertDynOptionDescription(name='dyn', doc='dyn', properties=frozenset({'normal'}), suffixes=Calculation(func.calc_value, Params((ParamOption(option_3)))), children=[option_5]) option_7 = StrOption(properties=frozenset({'normal'}), name='newvar', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamDynOption(option_5, '1', option_4, notraisepropertyerror=False, todict=False)), kwargs={}))) option_6 = OptionDescription(name='new', doc='new', properties=frozenset({'normal'}), children=[option_7]) option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2, option_4, option_6]) diff --git a/tests/dictionaries/61extra_dyn/tiramisu/base.py b/tests/dictionaries/61extra_dyn/tiramisu/base.py index 3dec2b80..0efbe600 100644 --- a/tests/dictionaries/61extra_dyn/tiramisu/base.py +++ b/tests/dictionaries/61extra_dyn/tiramisu/base.py @@ -16,6 +16,6 @@ option_3 = StrOption(properties=frozenset({'mandatory', 'normal'}), name='varnam option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'normal'}), children=[option_3]) option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2]) option_6 = StrOption(properties=frozenset({'normal'}), name='mode', doc='mode', multi=False) -option_5 = ConvertDynOptionDescription(name='ejabberd', doc='ejabberd', suffixes=Calculation(func.calc_value, Params((ParamOption(option_3)))), properties=frozenset({'normal'}), children=[option_6]) +option_5 = ConvertDynOptionDescription(name='ejabberd', doc='ejabberd', properties=frozenset({'normal'}), suffixes=Calculation(func.calc_value, Params((ParamOption(option_3)))), children=[option_6]) option_4 = OptionDescription(name='extra', doc='extra', children=[option_5]) option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1, option_4]) diff --git a/tests/dictionaries/61extra_dyn_extra/tiramisu/base.py b/tests/dictionaries/61extra_dyn_extra/tiramisu/base.py index 75c88a32..c43c70f3 100644 --- a/tests/dictionaries/61extra_dyn_extra/tiramisu/base.py +++ b/tests/dictionaries/61extra_dyn_extra/tiramisu/base.py @@ -18,6 +18,6 @@ option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2]) option_6 = StrOption(properties=frozenset({'mandatory', 'normal'}), name='varname', doc='No change', multi=True, default=['a'], default_multi='a') option_5 = OptionDescription(name='general', doc='général', properties=frozenset({'normal'}), children=[option_6]) option_8 = StrOption(properties=frozenset({'normal'}), name='mode', doc='mode', multi=False) -option_7 = ConvertDynOptionDescription(name='ejabberd', doc='ejabberd', suffixes=Calculation(func.calc_value, Params((ParamOption(option_6)))), properties=frozenset({'normal'}), children=[option_8]) +option_7 = ConvertDynOptionDescription(name='ejabberd', doc='ejabberd', properties=frozenset({'normal'}), suffixes=Calculation(func.calc_value, Params((ParamOption(option_6)))), children=[option_8]) option_4 = OptionDescription(name='extra', doc='extra', children=[option_5, option_7]) option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1, option_4])