This commit is contained in:
Emmanuel Garette 2021-01-11 22:34:16 +01:00
parent 46807533f3
commit 712175d56b
14 changed files with 113 additions and 68 deletions

View file

@ -268,13 +268,17 @@ class ConstrainteAnnotator:
):
if target.type == 'variable':
variable = self.objectspace.paths.get_variable_obj(target.name)
family = self.objectspace.paths.get_family_obj(target.name.rsplit('.', 1)[0])
family = self.objectspace.paths.get_family(target.name.rsplit('.', 1)[0],
variable.namespace,
)
# it's a leader, so apply property to leadership
if isinstance(family, self.objectspace.leadership) and family.name == variable.name:
if isinstance(family, self.objectspace.leadership) and family.variable[0].name == variable.name:
return family, family.variable
return variable, [variable]
# it's a family
variable = self.objectspace.paths.get_family_obj(target.name)
variable = self.objectspace.paths.get_family(target.name,
None,
)
return variable, list(variable.variable.values())
def convert_condition_target(self):
@ -302,14 +306,13 @@ class ConstrainteAnnotator:
if not target.optional or err.errno != 42:
raise err
elif target.type == 'family':
target_names = '.'.join([normalize_family(name) \
target_path = '.'.join([normalize_family(name) \
for name in target.name.split('.')])
try:
target.name = self.objectspace.paths.get_family_path(target_names,
if not self.objectspace.paths.family_is_defined(target_path,
condition.namespace,
)
except KeyError:
):
raise DictConsistencyError(_(f'cannot found family {target.name}'), 12)
target.name = target_path
elif target.type.endswith('list') and \
condition.name not in ['disabled_if_in', 'disabled_if_not_in']:
xmlfiles = self.objectspace.display_xmlfiles(target.xmlfiles)

View file

@ -169,14 +169,10 @@ class FamilyAnnotator:
for family in families.family.values():
if 'dynamic' not in vars(family):
continue
namespace = self.objectspace.paths.get_variable_namespace(family.dynamic)
varpath = self.objectspace.paths.get_variable_path(family.dynamic,
namespace,
)
obj = self.objectspace.paths.get_variable_obj(varpath)
obj = self.objectspace.paths.get_variable_obj(family.dynamic)
if not obj.multi:
xmlfiles = self.objectspace.display_xmlfiles(family.xmlfiles)
msg = _(f'dynamic family "{family.name}" must be linked '
f'to multi variable in {xmlfiles}')
raise DictConsistencyError(msg, 16)
family.dynamic = varpath
family.dynamic = obj.path

View file

@ -3,6 +3,7 @@
from typing import List
from ..i18n import _
from ..config import Config
from ..error import DictConsistencyError
@ -23,15 +24,16 @@ class GroupAnnotator:
"""
for group in self.objectspace.space.constraints.group:
leader_fullname = group.leader
leader = self.objectspace.paths.get_variable_obj(leader_fullname)
leader_family_name = self.objectspace.paths.get_variable_family_name(leader_fullname)
leader_name = self.objectspace.paths.get_variable_name(leader_fullname)
namespace = self.objectspace.paths.get_variable_namespace(leader_fullname)
if '.' not in leader_fullname:
leader_fullname = '.'.join([namespace, leader_family_name, leader_fullname])
leader_fullname = '.'.join([leader.namespace, leader_family_name, leader_fullname])
follower_names = list(group.follower.keys())
has_a_leader = False
leader_family = leader_fullname.rsplit('.', 1)[0]
ori_leader_family = self.objectspace.paths.get_family_obj(leader_family)
ori_leader_family = self.objectspace.paths.get_family(leader_family,
leader.namespace,
)
has_a_leader = False
for variable in list(ori_leader_family.variable.values()):
if has_a_leader:
# it's a follower
@ -48,7 +50,7 @@ class GroupAnnotator:
if follower_names == []:
# no more follower
break
elif variable.name == leader_name:
elif variable.name == leader.name:
# it's a leader
if isinstance(variable, self.objectspace.leadership):
# append follower to an existed leadership
@ -60,11 +62,11 @@ class GroupAnnotator:
if hasattr(group, 'name'):
leadership_name = group.name
else:
leadership_name = leader_name
leadership_name = leader.name
leader_is_hidden = self.manage_leader(leader_space,
leader_family_name,
leadership_name,
leader_name,
leader.name,
variable,
group,
)
@ -104,13 +106,13 @@ class GroupAnnotator:
variable.hidden = None
if hasattr(group, 'description'):
leader_space.doc = group.description
elif hasattr(variable, 'description'):
elif variable.name == leadership_name and hasattr(variable, 'description'):
leader_space.doc = variable.description
else:
leader_space.doc = variable.name
leader_space.doc = leadership_name
namespace = variable.namespace
leadership_path = namespace + '.' + leader_family_name + '.' + leadership_name
self.objectspace.paths.add_family(namespace,
self.objectspace.paths.add_leadership(namespace,
leadership_path,
leader_space,
)

View file

@ -146,7 +146,7 @@ class ServiceAnnotator:
if idx:
c_name += f'_{idx}'
subpath = '{}.{}'.format(path, c_name)
if not self.objectspace.paths.family_is_defined(subpath):
if not self.objectspace.paths.family_is_defined(subpath, 'services'):
return c_name, subpath
idx += 1
@ -187,6 +187,7 @@ class ServiceAnnotator:
val.type = type_
val.name = value
variable.value = [val]
variable.namespace = 'services'
self.objectspace.paths.add_variable('services',
path,
'service',

View file

@ -312,9 +312,7 @@ class RougailObjSpace:
name = space.path + '.' + name
if not self.paths.path_is_defined(name):
return None
old_family_name = self.paths.get_variable_family_name(name)
if namespace != Config['variable_namespace']:
old_family_name = namespace + '.' + old_family_name
old_family_name = namespace + '.' + self.paths.get_variable_family_name(name)
if space.path != old_family_name:
xmlfiles = self.display_xmlfiles(space.xmlfiles)
msg = _(f'Variable was previously create in family "{old_family_name}", '
@ -451,7 +449,6 @@ class RougailObjSpace:
family_name,
variableobj,
)
variableobj.path = self.paths.get_family_path(family_name, namespace)
@staticmethod
def add_to_tree_structure(variableobj,

View file

@ -21,17 +21,30 @@ class Path:
name: str,
variableobj: str,
) -> str: # pylint: disable=C0111
if '.' not in name and namespace == Config['variable_namespace']:
if namespace == Config['variable_namespace']:
full_name = '.'.join([namespace, name])
self.full_paths_families[name] = full_name
else:
full_name = name
if full_name in self.families and self.families[full_name]['variableobj'] != variableobj: # pragma: no cover
if full_name in self.families and \
self.families[full_name]['variableobj'] != variableobj: # pragma: no cover
raise DictConsistencyError(_(f'Duplicate family name "{name}"'), 37)
self.families[full_name] = dict(name=name,
namespace=namespace,
variableobj=variableobj,
)
variableobj.path = full_name
def add_leadership(self,
namespace: str,
path: str,
variableobj: str,
) -> str: # pylint: disable=C0111
self.families[path] = dict(name=path,
namespace=namespace,
variableobj=variableobj,
)
variableobj.path = path
def _get_family(self,
name: str,
@ -45,24 +58,18 @@ class Path:
raise DictConsistencyError(_(f'A family located in the "{dico["namespace"]}" namespace shall not be used in the "{namespace}" namespace'), 38)
return dico
def get_family_path(self,
def get_family(self,
name: str,
namespace: str,
) -> str: # pylint: disable=C0111
return self._get_family(name,
namespace,
)['name']
def get_family_obj(self,
name: str,
) -> 'Family': # pylint: disable=C0111
return self._get_family(name)['variableobj']
return self._get_family(name, namespace)['variableobj']
def family_is_defined(self,
name: str,
namespace: str,
) -> str: # pylint: disable=C0111
try:
self._get_family(name)
self._get_family(name, namespace)
return True
except KeyError:
return False
@ -109,11 +116,6 @@ class Path:
variableobj=variableobj,
)
def get_variable_name(self,
name: str,
): # pylint: disable=C0111
return self._get_variable(name)['name']
def get_variable_obj(self,
name: str,
) -> 'Variable': # pylint: disable=C0111
@ -124,11 +126,6 @@ class Path:
) -> str: # pylint: disable=C0111
return self._get_variable(name)['family']
def get_variable_namespace(self,
name: str,
) -> str: # pylint: disable=C0111
return self._get_variable(name)['namespace']
def get_variable_path(self,
name: str,
current_namespace: str,

View file

@ -1,9 +1,10 @@
# coding: utf-8
"""load XML file from directory
"""
from typing import List
from os.path import join, isfile
from os import listdir
from lxml.etree import DTD, parse, XMLSyntaxError
from lxml.etree import DTD, parse, XMLSyntaxError # pylint: disable=E0611
from .i18n import _
from .error import DictConsistencyError
@ -39,18 +40,20 @@ class XMLReflector:
except XMLSyntaxError as err:
raise DictConsistencyError(_(f'{xmlfile} is not an XML file: {err}'), 52)
if not self.dtd.validate(document):
raise DictConsistencyError(_(f'"{xmlfile}" not a valid XML file: {self.dtd.error_log.filter_from_errors()[0]}'), 43)
dtd_error = self.dtd.error_log.filter_from_errors()[0]
msg = _(f'"{xmlfile}" not a valid XML file: {dtd_error}')
raise DictConsistencyError(msg, 43)
return document.getroot()
def load_xml_from_folders(self,
xmlfolders: List[str],
):
@staticmethod
def load_xml_from_folders(xmlfolders: List[str]):
"""Loads all the XML files located in the xmlfolders' list
:param xmlfolders: list of full folder's name
"""
for xmlfolder in xmlfolders:
filenames = [join(xmlfolder, filename) for filename in listdir(xmlfolder) if filename.endswith('.xml')]
filenames = [join(xmlfolder, filename) for filename in listdir(xmlfolder) if \
filename.endswith('.xml')]
filenames.sort()
for xmlfile in filenames:
yield xmlfile

View file

@ -0,0 +1,26 @@
<?xml version='1.0' encoding='UTF-8'?>
<rougail>
<variables>
<family name="general" mode="expert">
<variable name="mode_conteneur_actif" type="string" description="No change">
<value>non</value>
</variable>
</family>
<family name="leadermode">
<variable name="leader" type="string" description="leader" multi="True"/>
<variable name="follower1" type="string" description="follower1"/>
<variable name="follower2" type="string" description="follower2"/>
</family>
</variables>
<constraints>
<group leader="leader" name="other">
<follower>follower1</follower>
<follower>follower2</follower>
</group>
<condition name="hidden_if_in" source="mode_conteneur_actif">
<param>non</param>
<target type="variable">leader</target>
</condition>
</constraints>
</rougail>

View file

@ -0,0 +1 @@
{"rougail.general.mode_conteneur_actif": "non", "rougail.leadermode.other.leader": []}

View file

@ -0,0 +1,19 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try:
from tiramisu3 import *
except:
from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription
option_3 = StrOption(properties=frozenset({'expert', 'mandatory'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non')
option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'expert'}), children=[option_3])
option_6 = StrOption(properties=frozenset({Calculation(calc_value, Params(ParamValue('frozen'), kwargs={'condition': ParamOption(option_3, todict=True), 'expected': ParamValue('non')})), Calculation(calc_value, Params(ParamValue('force_default_on_freeze'), kwargs={'condition': ParamOption(option_3, todict=True), 'expected': ParamValue('non')}))}), name='leader', doc='leader', multi=True)
option_7 = StrOption(properties=frozenset({'normal', Calculation(calc_value, Params(ParamValue('frozen'), kwargs={'condition': ParamOption(option_3, todict=True), 'expected': ParamValue('non')})), Calculation(calc_value, Params(ParamValue('force_default_on_freeze'), kwargs={'condition': ParamOption(option_3, todict=True), 'expected': ParamValue('non')}))}), name='follower1', doc='follower1', multi=True)
option_8 = StrOption(properties=frozenset({'normal', Calculation(calc_value, Params(ParamValue('frozen'), kwargs={'condition': ParamOption(option_3, todict=True), 'expected': ParamValue('non')})), Calculation(calc_value, Params(ParamValue('force_default_on_freeze'), kwargs={'condition': ParamOption(option_3, todict=True), 'expected': ParamValue('non')}))}), name='follower2', doc='follower2', multi=True)
option_5 = Leadership(name='other', doc='other', properties=frozenset({'normal', Calculation(calc_value, Params(ParamValue('hidden'), kwargs={'condition': ParamOption(option_3, todict=True), 'expected': ParamValue('non')}))}), children=[option_6, option_7, option_8])
option_4 = OptionDescription(name='leadermode', doc='leadermode', properties=frozenset({'normal'}), 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])

View file

@ -1 +1 @@
{"rougail.general.mode_conteneur_actif": "non", "rougail.general1.leader.leader": []}
{"rougail.general.mode_conteneur_actif": "non", "rougail.general1.other_name.leader": []}

View file

@ -13,7 +13,7 @@ option_2 = OptionDescription(name='general', doc='general', properties=frozenset
option_6 = StrOption(name='leader', doc='leader', multi=True)
option_7 = StrOption(properties=frozenset({'normal'}), name='follower1', doc='follower1', multi=True, default=Calculation(func.calc_val, Params((), kwargs={'valeur': ParamValue("valfill")})))
option_8 = StrOption(properties=frozenset({'normal'}), name='follower2', doc='follower2', multi=True, default=Calculation(func.calc_val, Params((ParamOption(option_7, notraisepropertyerror=False, todict=False)), kwargs={})))
option_5 = Leadership(name='other_name', doc='leader', properties=frozenset({'normal'}), children=[option_6, option_7, option_8])
option_5 = Leadership(name='other_name', doc='other_name', properties=frozenset({'normal'}), children=[option_6, option_7, option_8])
option_4 = OptionDescription(name='general1', doc='general1', properties=frozenset({'normal'}), 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])