reorganize tiramisureflector

This commit is contained in:
2021-01-23 21:15:26 +01:00
parent 04e9706a1b
commit f5c7220930
200 changed files with 807 additions and 859 deletions

View File

@ -4,7 +4,8 @@ from .group import GroupAnnotator
from .service import ServiceAnnotator, ERASED_ATTRIBUTES
from .variable import VariableAnnotator, CONVERT_OPTION
from .check import CheckAnnotator
from .condition import Conditionnnotator
from .value import ValueAnnotator
from .condition import ConditionAnnotator
from .fill import FillAnnotator
from .family import FamilyAnnotator, modes
from .property import PropertyAnnotator
@ -20,12 +21,13 @@ class SpaceAnnotator: # pylint: disable=R0903
CheckAnnotator(objectspace,
eosfunc_file,
)
Conditionnnotator(objectspace)
ConditionAnnotator(objectspace)
FillAnnotator(objectspace,
eosfunc_file,
)
FamilyAnnotator(objectspace)
PropertyAnnotator(objectspace)
ValueAnnotator(objectspace)
__all__ = ('SpaceAnnotator', 'ERASED_ATTRIBUTES', 'CONVERT_OPTION', 'modes')

View File

@ -129,7 +129,7 @@ class CheckAnnotator:
# value for choice's variable is mandatory
variable.mandatory = True
# build choice
variable.choice = []
variable.values = []
variable_type = variable.type
variable.type = 'choice'
@ -182,7 +182,7 @@ class CheckAnnotator:
choice = self.objectspace.choice(variable.xmlfiles)
choice.name = value
choice.type = param_type
variable.choice.append(choice)
variable.values.append(choice)
if has_variable:
return None
@ -223,7 +223,7 @@ class CheckAnnotator:
msg = _(f'unknown parameter "{param.name}" in check "valid_entier" '
f'for variable "{check.target.name}" in {xmlfiles}')
raise DictConsistencyError(msg, 19)
else:
if not hasattr(check.target, 'check'):
check.target.check = []
check.target.check.append(check)
continue
if not hasattr(check.target, 'validators'):
check.target.validators = []
check.target.validators.append(check)

View File

@ -10,7 +10,7 @@ from ..config import Config
FREEZE_AUTOFREEZE_VARIABLE = 'module_instancie'
class Conditionnnotator:
class ConditionAnnotator:
"""Annotate condition
"""
def __init__(self,
@ -290,6 +290,6 @@ class Conditionnnotator:
prop.source = condition.source
prop.expected = text
prop.name = action
if not hasattr(obj, 'property'):
obj.property = []
obj.property.append(prop)
if not hasattr(obj, 'properties'):
obj.properties = []
obj.properties.append(prop)

View File

@ -2,6 +2,8 @@
"""
from ..i18n import _
from ..error import DictConsistencyError
from ..utils import normalize_family
from .variable import RENAME_ATTIBUTES
#mode order is important
@ -34,14 +36,28 @@ class FamilyAnnotator:
objectspace,
):
self.objectspace = objectspace
if hasattr(self.objectspace.space, 'variables'):
self.remove_empty_families()
self.change_variable_mode()
self.change_family_mode()
self.dynamic_families()
self.convert_help()
if not hasattr(self.objectspace.space, 'variables'):
return
self.family_names()
self.remove_empty_families()
self.change_variable_mode()
self.change_family_mode()
self.dynamic_families()
self.convert_help()
def remove_empty_families(self):
def family_names(self) -> None:
for families in self.objectspace.space.variables.values():
families.doc = families.name
families.path = families.name
for family in families.family.values():
if not hasattr(family, 'description'):
family.description = family.name
for key, value in RENAME_ATTIBUTES.items():
setattr(family, value, getattr(family, key))
setattr(family, key, None)
family.name = normalize_family(family.name)
def remove_empty_families(self) -> None:
"""Remove all families without any variable
"""
for families in self.objectspace.space.variables.values():

View File

@ -26,25 +26,27 @@ class PropertyAnnotator:
) -> None:
"""convert properties
"""
properties = []
if not hasattr(variable, 'properties'):
variable.properties = []
for prop in PROPERTIES:
if hasattr(variable, prop):
if getattr(variable, prop) is True:
for subprop in CONVERT_PROPERTIES.get(prop, [prop]):
properties.append(subprop)
variable.properties.append(subprop)
setattr(variable, prop, None)
if hasattr(variable, 'mode') and variable.mode:
properties.append(variable.mode)
variable.properties.append(variable.mode)
variable.mode = None
if 'force_store_value' in properties and \
'force_default_on_freeze' in properties: # pragma: no cover
if 'force_store_value' in variable.properties and \
'force_default_on_freeze' in variable.properties: # pragma: no cover
# should not appened
xmlfiles = self.objectspace.display_xmlfiles(variable.xmlfiles)
msg = _('cannot have auto_freeze or auto_store with the hidden '
f'variable "{variable.name}" in {xmlfiles}')
raise DictConsistencyError(msg, 50)
if properties:
variable.properties = set(properties)
if not variable.properties:
del variable.properties
def convert_services(self) -> None:
"""convert services

View File

@ -183,10 +183,7 @@ class ServiceAnnotator:
variable.multi = None
else:
variable.doc = key
val = self.objectspace.value(xmlfiles)
val.type = type_
val.name = value
variable.value = [val]
variable.default = value
variable.namespace = 'services'
self.objectspace.paths.add_variable('services',
path,

View File

@ -0,0 +1,46 @@
class ValueAnnotator:
"""Annotate check
"""
def __init__(self,
objectspace,
) -> None:
if not hasattr(objectspace.space, 'variables'):
return
self.objectspace = objectspace
self.convert_value()
def convert_value(self) -> None:
for families in self.objectspace.space.variables.values():
for family in families.family.values():
for variable in family.variable.values():
if isinstance(variable, self.objectspace.leadership):
variable_type = 'leader'
for follower in variable.variable:
self._convert_value(follower,
variable_type,
)
variable_type = 'follower'
else:
self._convert_value(variable)
def _convert_value(self,
variable,
variable_type: str=None,
) -> None:
if not hasattr(variable, 'value'):
return
if variable.value[0].type == 'calculation':
variable.default = variable.value[0]
else:
if variable.multi:
if variable_type != 'follower':
variable.default = [value.name for value in variable.value]
if variable_type != 'leader':
if variable.multi == 'submulti':
variable.default_multi = [value.name for value in variable.value]
else:
#FIXME 0 ou -1 ?
variable.default_multi = variable.value[-1].name
else:
variable.default = variable.value[0].name
del variable.value

View File

@ -1,6 +1,5 @@
"""Annotate variable
"""
from ..utils import normalize_family
CONVERT_OPTION = {'number': dict(opttype="IntOption", func=int),
@ -60,15 +59,7 @@ class VariableAnnotator: # pylint: disable=R0903
"""convert variable
"""
for families in self.objectspace.space.variables.values():
families.doc = families.name
families.path = families.name
for family in families.family.values():
if not hasattr(family, 'description'):
family.description = family.name
for key, value in RENAME_ATTIBUTES.items():
setattr(family, value, getattr(family, key))
setattr(family, key, None)
family.name = normalize_family(family.name)
if not hasattr(family, 'variable'):
continue
for variable in family.variable.values():
@ -192,9 +183,8 @@ class VariableAnnotator: # pylint: disable=R0903
else:
self._convert_help(variable)
def _convert_help(self,
variable,
) -> None:
@staticmethod
def _convert_help(variable) -> None:
if hasattr(variable, 'help'):
variable.information.help = variable.help
del variable.help

View File

@ -7,7 +7,7 @@ from .objspace import RootRougailObject
FUNC_TO_DICT = []
ATTRIBUTES_ORDER = ('name', 'doc', 'default', 'multi', 'properties', 'min_number', 'max_number')
ATTRIBUTES_ORDER = ('name', 'doc', 'default', 'values', 'multi', 'default_multi', 'properties', 'validators', 'min_number', 'max_number')
class Root(): # pylint: disable=R0903
@ -127,6 +127,7 @@ class TiramisuReflector:
self.set_name(elt)
family.add(Variable(elt,
self.text,
self.objectspace,
is_follower,
is_leader,
))
@ -168,18 +169,19 @@ class Common:
f"'expected': ParamValue('{child.expected}')")
if child.inverse:
kwargs += ", 'reverse_condition': ParamValue(True)"
prop = 'Calculation(calc_value, Params(' + action + ', kwargs={' + kwargs + '}))'
if self.attrib['properties']:
self.attrib['properties'] += ', '
self.attrib['properties'] += prop
return 'Calculation(calc_value, Params(' + action + ', kwargs={' + kwargs + '}))'
def properties_to_string(self):
"""Change properties to string
"""
if not self.attrib['properties']:
self.attrib['properties'] = ''
else:
self.attrib['properties'] = "'" + "', '".join(sorted(self.attrib['properties'])) + "'"
properties = []
calc_properties = []
for property_ in self.attrib['properties']:
if not isinstance(property_, str):
calc_properties.append(self.populate_properties(property_))
else:
properties.append(f"'{property_}'")
return 'frozenset({' + ', '.join(sorted(properties) + calc_properties) + '})'
def get_attrib(self):
"""Get attributes
@ -189,13 +191,21 @@ class Common:
if value is None:
continue
if key == 'properties':
if not self.attrib[key]:
continue
value = "frozenset({" + self.attrib[key] + "})"
elif key in ['default', 'multi', 'suffixes', 'validators', 'values']:
value = self.attrib[key]
value = self.properties_to_string()
elif key == 'validators':
value = '[' + ', '.join([self.calculation_value(val, ['ParamSelfOption()']) for val in value]) + ']'
elif key == 'values':
if value[0].type == 'calculation':
value = value[0].name.reflector_object.get()
value = f"Calculation(func.calc_value, Params((ParamOption({value}))))"
else:
value = str(tuple([val.name for val in value]))
elif key in ['multi', 'suffixes']:
pass
elif isinstance(value, str) and key != 'opt' and not value.startswith('['):
value = "'" + value.replace("'", "\\\'") + "'"
elif isinstance(value, self.objectspace.value):
value = self.calculation_value(value, [])
ret_list.append(f'{key}={value}')
return ', '.join(ret_list)
@ -211,22 +221,12 @@ class Common:
value = '"' + value.replace('"', '\"') + '"'
self.text.append(f'{self.option_name}.impl_set_information("{key}", {value})')
@staticmethod
def get_attributes(space):
"""Get attributes
def populate_attrib(self):
"""Populate attributes
"""
for attr in ATTRIBUTES_ORDER:
if hasattr(space, attr):
yield attr
@staticmethod
def get_children(space):
"""Get children
"""
for attr in dir(space):
if not attr.startswith('_') and attr not in ERASED_ATTRIBUTES:
if isinstance(getattr(space, attr), list):
yield attr, getattr(space, attr)
if hasattr(self.elt, attr):
self.attrib[attr] = getattr(self.elt, attr)
class Variable(Common):
@ -235,18 +235,17 @@ class Variable(Common):
def __init__(self,
elt,
text,
objectspace,
is_follower,
is_leader,
):
super().__init__(elt, text)
self.objectspace = objectspace
self.is_leader = is_leader
self.is_follower = is_follower
convert_option = CONVERT_OPTION[elt.type]
self.object_type = convert_option['opttype']
self.attrib.update(convert_option.get('initkwargs', {}))
if self.object_type != 'SymLinkOption':
self.attrib['properties'] = []
self.attrib['validators'] = []
def get(self):
"""Get tiramisu's object
@ -255,79 +254,12 @@ class Variable(Common):
self.populate_attrib()
if self.object_type == 'SymLinkOption':
self.attrib['opt'] = self.elt.opt.reflector_object.get()
else:
self.parse_children()
attrib = self.get_attrib()
self.option_name = self.elt.reflector_name
self.text.append(f'{self.option_name} = {self.object_type}({attrib})')
self.populate_informations()
return self.option_name
def populate_attrib(self):
"""Populate attributes
"""
for key in self.get_attributes(self.elt):
self.attrib[key] = getattr(self.elt, key)
def parse_children(self):
"""Parse children
"""
if 'default' not in self.attrib or self.attrib['multi']:
self.attrib['default'] = []
if self.attrib['multi'] == 'submulti' and self.is_follower:
self.attrib['default_multi'] = []
choices = []
self.properties_to_string()
for tag, children in self.get_children(self.elt):
for child in children:
self.parse_child(tag,
child,
choices,
)
if choices:
self.attrib['values'] = str(tuple(choices))
if not self.attrib['default']:
del self.attrib['default']
elif not self.attrib['multi'] and isinstance(self.attrib['default'], list):
self.attrib['default'] = self.attrib['default'][-1]
if not self.attrib['validators']:
del self.attrib['validators']
else:
self.attrib['validators'] = '[' + ', '.join(self.attrib['validators']) + ']'
def parse_child(self,
tag,
child,
choices,
) -> None:
"""Parse child
"""
if tag == 'property':
self.populate_properties(child)
elif tag == 'value':
self.populate_value(child)
elif tag == 'check':
validator = self.calculation_value(child, ['ParamSelfOption()'])
self.attrib['validators'].append(validator)
elif tag == 'choice':
self.calculate_choice(child,
choices,
)
else: # pragma: no cover
raise Exception(f'unknown tag {tag}')
def calculate_choice(self,
child,
choices: list,
) -> None:
"""Calculating choice
"""
if child.type == 'calculation':
value = child.name.reflector_object.get()
self.attrib['values'] = f"Calculation(func.calc_value, Params((ParamOption({value}))))"
else:
choices.append(child.name)
def calculation_value(self,
child,
args,
@ -375,28 +307,6 @@ class Variable(Common):
return 'ParamSuffix()'
return '' # pragma: no cover
def populate_value(self,
child,
):
"""Populate variable's values
"""
if child.type == 'calculation':
self.attrib['default'] = self.calculation_value(child, [])
else:
value = child.name
if self.attrib['multi'] == 'submulti':
self.attrib['default_multi'].append(value)
elif self.is_follower:
self.attrib['default_multi'] = value
elif self.attrib['multi']:
self.attrib['default'].append(value)
if not self.is_leader:
self.attrib['default_multi'] = value
elif isinstance(value, (int, float)) or value is None:
self.attrib['default'].append(value)
else:
self.attrib['default'].append("'" + value + "'")
@staticmethod
def build_param(param) -> str:
"""build variable parameters
@ -431,7 +341,6 @@ class Family(Common):
"""
if not self.option_name:
self.populate_attrib()
self.parse_properties()
self.populate_dynamic()
self.option_name = self.elt.reflector_name
object_name = self.get_object_name()
@ -448,21 +357,6 @@ class Family(Common):
dyn = self.elt.dynamic.reflector_object.get()
self.attrib['suffixes'] = f"Calculation(func.calc_value, Params((ParamOption({dyn}))))"
def populate_attrib(self):
"""parse a populate attributes
"""
for key in self.get_attributes(self.elt):
self.attrib[key] = getattr(self.elt, key)
def parse_properties(self):
"""parse current children
"""
if 'properties' in self.attrib:
self.properties_to_string()
if hasattr(self.elt, 'property'):
for child in self.elt.property:
self.populate_properties(child)
def get_object_name(self):
"""Get family object's name
"""