Compare commits
2 Commits
7191bbbcb3
...
17e09354fa
Author | SHA1 | Date |
---|---|---|
Emmanuel Garette | 17e09354fa | |
Emmanuel Garette | 05ca7ed578 |
|
@ -10,8 +10,9 @@ import imp
|
||||||
|
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
from .utils import normalize_family
|
from .utils import normalize_family
|
||||||
from .error import CreoleDictConsistencyError
|
from .error import DictConsistencyError
|
||||||
from .xmlreflector import HIGH_COMPATIBILITY
|
from .xmlreflector import HIGH_COMPATIBILITY
|
||||||
|
from .config import variable_namespace
|
||||||
|
|
||||||
#mode order is important
|
#mode order is important
|
||||||
modes_level = ('basic', 'normal', 'expert')
|
modes_level = ('basic', 'normal', 'expert')
|
||||||
|
@ -39,7 +40,7 @@ modes = mode_factory()
|
||||||
# that shall not be present in the exported (flatened) XML
|
# that shall not be present in the exported (flatened) XML
|
||||||
ERASED_ATTRIBUTES = ('redefine', 'exists', 'fallback', 'optional', 'remove_check', 'namespace',
|
ERASED_ATTRIBUTES = ('redefine', 'exists', 'fallback', 'optional', 'remove_check', 'namespace',
|
||||||
'remove_condition', 'path', 'instance_mode', 'index', 'is_in_leadership',
|
'remove_condition', 'path', 'instance_mode', 'index', 'is_in_leadership',
|
||||||
'level', 'submulti') # , '_real_container')
|
'level') # , '_real_container')
|
||||||
ERASED_CONTAINER_ATTRIBUTES = ('id', 'container', 'group_id', 'group', 'container_group')
|
ERASED_CONTAINER_ATTRIBUTES = ('id', 'container', 'group_id', 'group', 'container_group')
|
||||||
|
|
||||||
FORCE_CHOICE = {'oui/non': ['oui', 'non'],
|
FORCE_CHOICE = {'oui/non': ['oui', 'non'],
|
||||||
|
@ -64,8 +65,6 @@ CONVERSION = {'number': int}
|
||||||
|
|
||||||
FREEZE_AUTOFREEZE_VARIABLE = 'module_instancie'
|
FREEZE_AUTOFREEZE_VARIABLE = 'module_instancie'
|
||||||
|
|
||||||
VARIABLE_NAMESPACE = 'rougail'
|
|
||||||
|
|
||||||
|
|
||||||
class ServiceAnnotator:
|
class ServiceAnnotator:
|
||||||
"""Manage service's object
|
"""Manage service's object
|
||||||
|
@ -215,9 +214,11 @@ class ServiceAnnotator:
|
||||||
variable.type = type_
|
variable.type = type_
|
||||||
if type_ == 'symlink':
|
if type_ == 'symlink':
|
||||||
variable.opt = value
|
variable.opt = value
|
||||||
|
variable.multi = None
|
||||||
else:
|
else:
|
||||||
variable.doc = key
|
variable.doc = key
|
||||||
val = self.objectspace.value()
|
val = self.objectspace.value()
|
||||||
|
val.type = type_
|
||||||
val.name = value
|
val.name = value
|
||||||
variable.value = [val]
|
variable.value = [val]
|
||||||
self.paths.add_variable('services',
|
self.paths.add_variable('services',
|
||||||
|
@ -274,7 +275,7 @@ class ServiceAnnotator:
|
||||||
if not hasattr(file_, 'source'):
|
if not hasattr(file_, 'source'):
|
||||||
file_.source = basename(file_.name)
|
file_.source = basename(file_.name)
|
||||||
elif not hasattr(file_, 'source'):
|
elif not hasattr(file_, 'source'):
|
||||||
raise CreoleDictConsistencyError(_('attribute source mandatory for file with variable name '
|
raise DictConsistencyError(_('attribute source mandatory for file with variable name '
|
||||||
'for {}').format(file_.name))
|
'for {}').format(file_.name))
|
||||||
|
|
||||||
|
|
||||||
|
@ -330,7 +331,7 @@ class SpaceAnnotator(object):
|
||||||
for variable in fam2.variable:
|
for variable in fam2.variable:
|
||||||
if variable.type == 'symlink' and '.' not in variable.name:
|
if variable.type == 'symlink' and '.' not in variable.name:
|
||||||
variable.opt = self.paths.get_variable_path(variable.opt,
|
variable.opt = self.paths.get_variable_path(variable.opt,
|
||||||
VARIABLE_NAMESPACE,
|
variable_namespace,
|
||||||
)
|
)
|
||||||
|
|
||||||
def convert_helps(self):
|
def convert_helps(self):
|
||||||
|
@ -359,7 +360,7 @@ class SpaceAnnotator(object):
|
||||||
) -> None:
|
) -> None:
|
||||||
# manage leader's variable
|
# manage leader's variable
|
||||||
if variable.multi is not True:
|
if variable.multi is not True:
|
||||||
raise CreoleDictConsistencyError(_('the variable {} in a group must be multi').format(variable.name))
|
raise DictConsistencyError(_('the variable {} in a group must be multi').format(variable.name))
|
||||||
leader_space.variable = []
|
leader_space.variable = []
|
||||||
leader_space.name = leader_name
|
leader_space.name = leader_name
|
||||||
leader_space.hidden = variable.hidden
|
leader_space.hidden = variable.hidden
|
||||||
|
@ -400,14 +401,11 @@ class SpaceAnnotator(object):
|
||||||
leader_is_hidden: bool,
|
leader_is_hidden: bool,
|
||||||
) -> None:
|
) -> None:
|
||||||
if variable.name != follower_names[0]:
|
if variable.name != follower_names[0]:
|
||||||
raise CreoleDictConsistencyError(_('cannot found this follower {}').format(follower_names[0]))
|
raise DictConsistencyError(_('cannot found this follower {}').format(follower_names[0]))
|
||||||
follower_names.remove(variable.name)
|
follower_names.remove(variable.name)
|
||||||
if leader_is_hidden:
|
if leader_is_hidden:
|
||||||
variable.frozen = True
|
variable.frozen = True
|
||||||
variable.force_default_on_freeze = True
|
variable.force_default_on_freeze = True
|
||||||
# followers are multi
|
|
||||||
if not variable.multi:
|
|
||||||
raise CreoleDictConsistencyError(_('the variable {} in a group must be multi or submulti').format(variable.name))
|
|
||||||
leader_space.variable.append(variable) # pylint: disable=E1101
|
leader_space.variable.append(variable) # pylint: disable=E1101
|
||||||
self.paths.set_leader(namespace,
|
self.paths.set_leader(namespace,
|
||||||
leader_family_name,
|
leader_family_name,
|
||||||
|
@ -459,7 +457,7 @@ class SpaceAnnotator(object):
|
||||||
)
|
)
|
||||||
has_a_leader = True
|
has_a_leader = True
|
||||||
else:
|
else:
|
||||||
raise CreoleDictConsistencyError(_('cannot found followers {}').format(follower_names))
|
raise DictConsistencyError(_('cannot found followers {}').format(follower_names))
|
||||||
del self.space.constraints.group
|
del self.space.constraints.group
|
||||||
|
|
||||||
def remove_empty_families(self): # pylint: disable=C0111,R0201
|
def remove_empty_families(self): # pylint: disable=C0111,R0201
|
||||||
|
@ -534,8 +532,10 @@ class SpaceAnnotator(object):
|
||||||
variable.type = 'string'
|
variable.type = 'string'
|
||||||
if variable.type != 'symlink' and not hasattr(variable, 'description'):
|
if variable.type != 'symlink' and not hasattr(variable, 'description'):
|
||||||
variable.description = variable.name
|
variable.description = variable.name
|
||||||
if variable.submulti:
|
if hasattr(variable, 'value'):
|
||||||
variable.multi = 'submulti'
|
for value in variable.value:
|
||||||
|
if not hasattr(value, 'type'):
|
||||||
|
value.type = variable.type
|
||||||
|
|
||||||
def convert_auto_freeze(self): # pylint: disable=C0111
|
def convert_auto_freeze(self): # pylint: disable=C0111
|
||||||
if hasattr(self.space, 'variables'):
|
if hasattr(self.space, 'variables'):
|
||||||
|
@ -554,7 +554,7 @@ class SpaceAnnotator(object):
|
||||||
new_condition.param = [new_param]
|
new_condition.param = [new_param]
|
||||||
new_target = self.objectspace.target()
|
new_target = self.objectspace.target()
|
||||||
new_target.type = 'variable'
|
new_target.type = 'variable'
|
||||||
if variables.name == VARIABLE_NAMESPACE:
|
if variables.name == variable_namespace:
|
||||||
path = variable.name
|
path = variable.name
|
||||||
else:
|
else:
|
||||||
path = variable.namespace + '.' + family.name + '.' + variable.name
|
path = variable.namespace + '.' + family.name + '.' + variable.name
|
||||||
|
@ -576,12 +576,12 @@ class SpaceAnnotator(object):
|
||||||
else:
|
else:
|
||||||
choice.name = str(value)
|
choice.name = str(value)
|
||||||
except:
|
except:
|
||||||
raise CreoleDictConsistencyError(_(f'unable to change type of a valid_enum entry "{value}" is not a valid "{type_}" for "{variable.name}"'))
|
raise DictConsistencyError(_(f'unable to change type of a valid_enum entry "{value}" is not a valid "{type_}" for "{variable.name}"'))
|
||||||
choices.append(choice.name)
|
choices.append(choice.name)
|
||||||
choice.type = type_
|
choice.type = type_
|
||||||
variable.choice.append(choice)
|
variable.choice.append(choice)
|
||||||
if not variable.choice:
|
if not variable.choice:
|
||||||
raise CreoleDictConsistencyError(_('empty valid enum is not allowed for variable {}').format(variable.name))
|
raise DictConsistencyError(_('empty valid enum is not allowed for variable {}').format(variable.name))
|
||||||
if hasattr(variable, 'value'):
|
if hasattr(variable, 'value'):
|
||||||
for value in variable.value:
|
for value in variable.value:
|
||||||
value.type = type_
|
value.type = type_
|
||||||
|
@ -590,7 +590,7 @@ class SpaceAnnotator(object):
|
||||||
else:
|
else:
|
||||||
cvalue = value.name
|
cvalue = value.name
|
||||||
if cvalue not in choices:
|
if cvalue not in choices:
|
||||||
raise CreoleDictConsistencyError(_('value "{}" of variable "{}" is not in list of all expected values ({})').format(value.name, variable.name, choices))
|
raise DictConsistencyError(_('value "{}" of variable "{}" is not in list of all expected values ({})').format(value.name, variable.name, choices))
|
||||||
else:
|
else:
|
||||||
new_value = self.objectspace.value()
|
new_value = self.objectspace.value()
|
||||||
new_value.name = values[0]
|
new_value.name = values[0]
|
||||||
|
@ -601,7 +601,7 @@ class SpaceAnnotator(object):
|
||||||
def _convert_valid_enum(self, variable, path):
|
def _convert_valid_enum(self, variable, path):
|
||||||
if variable.type in FORCE_CHOICE:
|
if variable.type in FORCE_CHOICE:
|
||||||
if path in self.valid_enums:
|
if path in self.valid_enums:
|
||||||
raise CreoleDictConsistencyError(_('cannot set valid enum for variable with type {}').format(variable.type))
|
raise DictConsistencyError(_('cannot set valid enum for variable with type {}').format(variable.type))
|
||||||
self._set_valid_enum(variable, FORCE_CHOICE[variable.type], 'string')
|
self._set_valid_enum(variable, FORCE_CHOICE[variable.type], 'string')
|
||||||
if path in self.valid_enums:
|
if path in self.valid_enums:
|
||||||
values = self.valid_enums[path]['values']
|
values = self.valid_enums[path]['values']
|
||||||
|
@ -610,6 +610,7 @@ class SpaceAnnotator(object):
|
||||||
if path in self.force_value:
|
if path in self.force_value:
|
||||||
new_value = self.objectspace.value()
|
new_value = self.objectspace.value()
|
||||||
new_value.name = self.force_value[path]
|
new_value.name = self.force_value[path]
|
||||||
|
new_value.type = variable.type
|
||||||
variable.value = [new_value]
|
variable.value = [new_value]
|
||||||
del self.force_value[path]
|
del self.force_value[path]
|
||||||
|
|
||||||
|
@ -631,7 +632,7 @@ class SpaceAnnotator(object):
|
||||||
self._convert_valid_enum(variable, path)
|
self._convert_valid_enum(variable, path)
|
||||||
# valid_enums must be empty now (all information are store in objects)
|
# valid_enums must be empty now (all information are store in objects)
|
||||||
if self.valid_enums:
|
if self.valid_enums:
|
||||||
raise CreoleDictConsistencyError(_('valid_enum sets for unknown variables {}').format(self.valid_enums.keys()))
|
raise DictConsistencyError(_('valid_enum sets for unknown variables {}').format(self.valid_enums.keys()))
|
||||||
|
|
||||||
def change_variable_mode(self): # pylint: disable=C0111
|
def change_variable_mode(self): # pylint: disable=C0111
|
||||||
if not hasattr(self.space, 'variables'):
|
if not hasattr(self.space, 'variables'):
|
||||||
|
@ -647,11 +648,11 @@ class SpaceAnnotator(object):
|
||||||
mode = modes_level[-1]
|
mode = modes_level[-1]
|
||||||
for follower in variable.variable:
|
for follower in variable.variable:
|
||||||
if follower.auto_save is True:
|
if follower.auto_save is True:
|
||||||
raise CreoleDictConsistencyError(_('leader/followers {} '
|
raise DictConsistencyError(_('leader/followers {} '
|
||||||
'could not be '
|
'could not be '
|
||||||
'auto_save').format(follower.name))
|
'auto_save').format(follower.name))
|
||||||
if follower.auto_freeze is True:
|
if follower.auto_freeze is True:
|
||||||
raise CreoleDictConsistencyError(_('leader/followers {} '
|
raise DictConsistencyError(_('leader/followers {} '
|
||||||
'could not be '
|
'could not be '
|
||||||
'auto_freeze').format(follower.name))
|
'auto_freeze').format(follower.name))
|
||||||
if HIGH_COMPATIBILITY and variable.name != follower.name: # and variable.variable[0].mode != modes_level[0]:
|
if HIGH_COMPATIBILITY and variable.name != follower.name: # and variable.variable[0].mode != modes_level[0]:
|
||||||
|
@ -687,11 +688,11 @@ class SpaceAnnotator(object):
|
||||||
fill = fills[idx]
|
fill = fills[idx]
|
||||||
# test if it's redefined calculation
|
# test if it's redefined calculation
|
||||||
if fill.target in targets and not fill.redefine:
|
if fill.target in targets and not fill.redefine:
|
||||||
raise CreoleDictConsistencyError(_(f"A fill already exists for the target: {fill.target}"))
|
raise DictConsistencyError(_(f"A fill already exists for the target: {fill.target}"))
|
||||||
targets.append(fill.target)
|
targets.append(fill.target)
|
||||||
#
|
#
|
||||||
if not fill.name in eosfunc:
|
if not fill.name in eosfunc:
|
||||||
raise CreoleDictConsistencyError(_('cannot find fill function {}').format(fill.name))
|
raise DictConsistencyError(_('cannot find fill function {}').format(fill.name))
|
||||||
|
|
||||||
namespace = fill.namespace
|
namespace = fill.namespace
|
||||||
# let's replace the target by the path
|
# let's replace the target by the path
|
||||||
|
@ -705,9 +706,9 @@ class SpaceAnnotator(object):
|
||||||
param_to_delete = []
|
param_to_delete = []
|
||||||
for fill_idx, param in enumerate(fill.param):
|
for fill_idx, param in enumerate(fill.param):
|
||||||
if param.type not in TYPE_PARAM_FILL:
|
if param.type not in TYPE_PARAM_FILL:
|
||||||
raise CreoleDictConsistencyError(_(f'cannot use {param.type} type as a param in a fill/auto'))
|
raise DictConsistencyError(_(f'cannot use {param.type} type as a param in a fill/auto'))
|
||||||
if param.type != 'string' and not hasattr(param, 'text'):
|
if param.type != 'string' and not hasattr(param, 'text'):
|
||||||
raise CreoleDictConsistencyError(_(f"All '{param.type}' variables shall have a value in order to calculate {fill.target}"))
|
raise DictConsistencyError(_(f"All '{param.type}' variables shall have a value in order to calculate {fill.target}"))
|
||||||
if param.type == 'variable':
|
if param.type == 'variable':
|
||||||
try:
|
try:
|
||||||
param.text, suffix = self.paths.get_variable_path(param.text,
|
param.text, suffix = self.paths.get_variable_path(param.text,
|
||||||
|
@ -715,14 +716,13 @@ class SpaceAnnotator(object):
|
||||||
with_suffix=True)
|
with_suffix=True)
|
||||||
if suffix:
|
if suffix:
|
||||||
param.suffix = suffix
|
param.suffix = suffix
|
||||||
except CreoleDictConsistencyError as err:
|
except DictConsistencyError as err:
|
||||||
if param.optional is False:
|
if param.optional is False:
|
||||||
raise err
|
raise err
|
||||||
param_to_delete.append(fill_idx)
|
param_to_delete.append(fill_idx)
|
||||||
continue
|
continue
|
||||||
if param.hidden is True:
|
else:
|
||||||
param.transitive = False
|
param.notraisepropertyerror = None
|
||||||
param.hidden = None
|
|
||||||
param_to_delete.sort(reverse=True)
|
param_to_delete.sort(reverse=True)
|
||||||
for param_idx in param_to_delete:
|
for param_idx in param_to_delete:
|
||||||
fill.param.pop(param_idx)
|
fill.param.pop(param_idx)
|
||||||
|
@ -732,39 +732,39 @@ class SpaceAnnotator(object):
|
||||||
del self.space.constraints.fill
|
del self.space.constraints.fill
|
||||||
|
|
||||||
def filter_separators(self): # pylint: disable=C0111,R0201
|
def filter_separators(self): # pylint: disable=C0111,R0201
|
||||||
# FIXME devrait etre dans la variable
|
|
||||||
if not hasattr(self.space, 'variables'):
|
if not hasattr(self.space, 'variables'):
|
||||||
return
|
return
|
||||||
for family in self.space.variables.values():
|
for family in self.space.variables.values():
|
||||||
if (hasattr(family, 'separators') and hasattr(family.separators, 'separator')):
|
if not hasattr(family, 'separators'):
|
||||||
space = family.separators.separator
|
continue
|
||||||
names = []
|
if hasattr(family.separators, 'separator'):
|
||||||
for idx, separator in enumerate(space):
|
for idx, separator in enumerate(family.separators.separator):
|
||||||
namespace = self.paths.get_variable_namespace(separator.name)
|
option = self.paths.get_variable_obj(separator.name)
|
||||||
subpath = self.paths.get_variable_path(separator.name, namespace)
|
if hasattr(option, 'separator'):
|
||||||
separator.name = subpath
|
subpath = self.paths.get_variable_path(separator.name,
|
||||||
if separator.name in names:
|
separator.namespace,
|
||||||
raise CreoleDictConsistencyError(_('{} already has a separator').format(separator.name))
|
)
|
||||||
names.append(separator.name)
|
raise DictConsistencyError(_('{} already has a separator').format(subpath))
|
||||||
|
option.separator = separator.text
|
||||||
|
del family.separators
|
||||||
|
|
||||||
def load_params_in_validenum(self, param):
|
def load_params_in_validenum(self, param):
|
||||||
if param.type in ['string', 'python', 'number']:
|
if param.type in ['string', 'python', 'number']:
|
||||||
if not hasattr(param, 'text') and (param.type == 'python' or param.type == 'number'):
|
if not hasattr(param, 'text') and (param.type == 'python' or param.type == 'number'):
|
||||||
raise CreoleDictConsistencyError(_("All '{}' variables shall be set in order to calculate {}").format(param.type, 'valid_enum'))
|
raise DictConsistencyError(_("All '{}' variables shall be set in order to calculate {}").format(param.type, 'valid_enum'))
|
||||||
if param.type in ['string', 'number']:
|
if param.type in ['string', 'number']:
|
||||||
try:
|
try:
|
||||||
values = literal_eval(param.text)
|
values = literal_eval(param.text)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise CreoleDictConsistencyError(_('Cannot load {}').format(param.text))
|
raise DictConsistencyError(_('Cannot load {}').format(param.text))
|
||||||
elif param.type == 'python':
|
elif param.type == 'python':
|
||||||
try:
|
try:
|
||||||
#values = eval(param.text, {'eosfunc': self.eosfunc, '__builtins__': {'range': range, 'str': str}})
|
#values = eval(param.text, {'eosfunc': self.eosfunc, '__builtins__': {'range': range, 'str': str}})
|
||||||
values = eval(param.text, {'eosfunc': self.eosfunc, '__builtins__': {'range': range, 'str': str}})
|
values = eval(param.text, {'eosfunc': self.eosfunc, '__builtins__': {'range': range, 'str': str}})
|
||||||
except NameError:
|
except NameError:
|
||||||
raise CreoleDictConsistencyError(_('The function {} is unknown').format(param.text))
|
raise DictConsistencyError(_('The function {} is unknown').format(param.text))
|
||||||
if not isinstance(values, list):
|
if not isinstance(values, list):
|
||||||
raise CreoleDictConsistencyError(_('Function {} shall return a list').format(param.text))
|
raise DictConsistencyError(_('Function {} shall return a list').format(param.text))
|
||||||
new_values = []
|
new_values = []
|
||||||
for val in values:
|
for val in values:
|
||||||
new_values.append(val)
|
new_values.append(val)
|
||||||
|
@ -779,17 +779,19 @@ class SpaceAnnotator(object):
|
||||||
functions.extend(['valid_enum', 'valid_in_network', 'valid_differ'])
|
functions.extend(['valid_enum', 'valid_in_network', 'valid_differ'])
|
||||||
for check_idx, check in enumerate(self.space.constraints.check):
|
for check_idx, check in enumerate(self.space.constraints.check):
|
||||||
if not check.name in functions:
|
if not check.name in functions:
|
||||||
raise CreoleDictConsistencyError(_('cannot find check function {}').format(check.name))
|
raise DictConsistencyError(_('cannot find check function {}').format(check.name))
|
||||||
if hasattr(check, 'param'):
|
if hasattr(check, 'param'):
|
||||||
param_option_indexes = []
|
param_option_indexes = []
|
||||||
for idx, param in enumerate(check.param):
|
for idx, param in enumerate(check.param):
|
||||||
if param.type not in TYPE_PARAM_CHECK:
|
if param.type not in TYPE_PARAM_CHECK:
|
||||||
raise CreoleDictConsistencyError(_('cannot use {} type as a param in check for {}').format(param.type, check.target))
|
raise DictConsistencyError(_('cannot use {} type as a param in check for {}').format(param.type, check.target))
|
||||||
if param.type == 'variable' and not self.paths.path_is_defined(param.text):
|
if param.type == 'variable' and not self.paths.path_is_defined(param.text):
|
||||||
if param.optional is True:
|
if param.optional is True:
|
||||||
param_option_indexes.append(idx)
|
param_option_indexes.append(idx)
|
||||||
else:
|
else:
|
||||||
raise CreoleDictConsistencyError(_(f'unknown param {param.text} in check'))
|
raise DictConsistencyError(_(f'unknown param {param.text} in check'))
|
||||||
|
if param.type != 'variable':
|
||||||
|
param.notraisepropertyerror = None
|
||||||
param_option_indexes = list(set(param_option_indexes))
|
param_option_indexes = list(set(param_option_indexes))
|
||||||
param_option_indexes.sort(reverse=True)
|
param_option_indexes.sort(reverse=True)
|
||||||
for idx in param_option_indexes:
|
for idx in param_option_indexes:
|
||||||
|
@ -823,27 +825,27 @@ class SpaceAnnotator(object):
|
||||||
proposed_value_type = self.objectspace.convert_boolean(param.text) == False
|
proposed_value_type = self.objectspace.convert_boolean(param.text) == False
|
||||||
remove_params.append(param_idx)
|
remove_params.append(param_idx)
|
||||||
except TypeError as err:
|
except TypeError as err:
|
||||||
raise CreoleDictConsistencyError(_('cannot load checkval value for variable {}: {}').format(check.target, err))
|
raise DictConsistencyError(_('cannot load checkval value for variable {}: {}').format(check.target, err))
|
||||||
if proposed_value_type:
|
if proposed_value_type:
|
||||||
# no more supported
|
# no more supported
|
||||||
raise CreoleDictConsistencyError(_('cannot load checkval value for variable {}, no more supported').format(check.target))
|
raise DictConsistencyError(_('cannot load checkval value for variable {}, no more supported').format(check.target))
|
||||||
remove_params.sort(reverse=True)
|
remove_params.sort(reverse=True)
|
||||||
for param_idx in remove_params:
|
for param_idx in remove_params:
|
||||||
del check.param[param_idx]
|
del check.param[param_idx]
|
||||||
if len(check.param) != 1:
|
if len(check.param) != 1:
|
||||||
raise CreoleDictConsistencyError(_('cannot set more than one param '
|
raise DictConsistencyError(_('cannot set more than one param '
|
||||||
'for valid_enum for variable {}'
|
'for valid_enum for variable {}'
|
||||||
'').format(check.target))
|
'').format(check.target))
|
||||||
param = check.param[0]
|
param = check.param[0]
|
||||||
if check.target in self.valid_enums:
|
if check.target in self.valid_enums:
|
||||||
raise CreoleDictConsistencyError(_('valid_enum already set for {}'
|
raise DictConsistencyError(_('valid_enum already set for {}'
|
||||||
'').format(check.target))
|
'').format(check.target))
|
||||||
if proposed_value_type:
|
if proposed_value_type:
|
||||||
if param.type == 'variable':
|
if param.type == 'variable':
|
||||||
try:
|
try:
|
||||||
values = self.load_params_in_validenum(param)
|
values = self.load_params_in_validenum(param)
|
||||||
except NameError as err:
|
except NameError as err:
|
||||||
raise CreoleDictConsistencyError(_('cannot load value for variable {}: {}').format(check.target, err))
|
raise DictConsistencyError(_('cannot load value for variable {}: {}').format(check.target, err))
|
||||||
add_default_value = not check.is_in_leadership
|
add_default_value = not check.is_in_leadership
|
||||||
if add_default_value and values:
|
if add_default_value and values:
|
||||||
self.force_value[check.target] = values[0]
|
self.force_value[check.target] = values[0]
|
||||||
|
@ -857,18 +859,13 @@ class SpaceAnnotator(object):
|
||||||
del self.space.constraints.check[idx]
|
del self.space.constraints.check[idx]
|
||||||
|
|
||||||
def check_change_warning(self):
|
def check_change_warning(self):
|
||||||
#convert level to "warnings_only" and hidden to "transitive"
|
#convert level to "warnings_only"
|
||||||
for check in self.space.constraints.check:
|
for check in self.space.constraints.check:
|
||||||
if check.level == 'warning':
|
if check.level == 'warning':
|
||||||
check.warnings_only = True
|
check.warnings_only = True
|
||||||
else:
|
else:
|
||||||
check.warnings_only = False
|
check.warnings_only = False
|
||||||
check.level = None
|
check.level = None
|
||||||
if hasattr(check, 'param'):
|
|
||||||
for param in check.param:
|
|
||||||
if not param.hidden is True:
|
|
||||||
check.transitive = False
|
|
||||||
param.hidden = None
|
|
||||||
|
|
||||||
def filter_check(self): # pylint: disable=C0111
|
def filter_check(self): # pylint: disable=C0111
|
||||||
# valid param in check
|
# valid param in check
|
||||||
|
@ -894,20 +891,20 @@ class SpaceAnnotator(object):
|
||||||
elif name == 'valid_network_netmask':
|
elif name == 'valid_network_netmask':
|
||||||
params_len = 1
|
params_len = 1
|
||||||
if len(check.param) != params_len:
|
if len(check.param) != params_len:
|
||||||
raise CreoleDictConsistencyError(_('{} must have {} param').format(name, params_len))
|
raise DictConsistencyError(_('{} must have {} param').format(name, params_len))
|
||||||
elif name == 'valid_ipnetmask':
|
elif name == 'valid_ipnetmask':
|
||||||
params_len = 1
|
params_len = 1
|
||||||
if len(check.param) != params_len:
|
if len(check.param) != params_len:
|
||||||
raise CreoleDictConsistencyError(_('{} must have {} param').format(name, params_len))
|
raise DictConsistencyError(_('{} must have {} param').format(name, params_len))
|
||||||
name = 'valid_ip_netmask'
|
name = 'valid_ip_netmask'
|
||||||
elif name == 'valid_broadcast':
|
elif name == 'valid_broadcast':
|
||||||
params_len = 2
|
params_len = 2
|
||||||
if len(check.param) != params_len:
|
if len(check.param) != params_len:
|
||||||
raise CreoleDictConsistencyError(_('{} must have {} param').format(name, params_len))
|
raise DictConsistencyError(_('{} must have {} param').format(name, params_len))
|
||||||
elif name == 'valid_in_network':
|
elif name == 'valid_in_network':
|
||||||
params_len = 2
|
params_len = 2
|
||||||
if len(check.param) != params_len:
|
if len(check.param) != params_len:
|
||||||
raise CreoleDictConsistencyError(_('{} must have {} param').format(name, params_len))
|
raise DictConsistencyError(_('{} must have {} param').format(name, params_len))
|
||||||
check_.name = name
|
check_.name = name
|
||||||
check_.warnings_only = check.warnings_only
|
check_.warnings_only = check.warnings_only
|
||||||
if hasattr(check, 'param'):
|
if hasattr(check, 'param'):
|
||||||
|
@ -923,13 +920,13 @@ class SpaceAnnotator(object):
|
||||||
for idx, target in enumerate(condition.target):
|
for idx, target in enumerate(condition.target):
|
||||||
if target.type == 'variable':
|
if target.type == 'variable':
|
||||||
if condition.source == target.name:
|
if condition.source == target.name:
|
||||||
raise CreoleDictConsistencyError(_('target name and source name must be different: {}').format(condition.source))
|
raise DictConsistencyError(_('target name and source name must be different: {}').format(condition.source))
|
||||||
target.name = self.paths.get_variable_path(target.name, namespace)
|
target.name = self.paths.get_variable_path(target.name, namespace)
|
||||||
elif target.type == 'family':
|
elif target.type == 'family':
|
||||||
try:
|
try:
|
||||||
target.name = self.paths.get_family_path(target.name, namespace)
|
target.name = self.paths.get_family_path(target.name, namespace)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise CreoleDictConsistencyError(_('cannot found family {}').format(target.name))
|
raise DictConsistencyError(_('cannot found family {}').format(target.name))
|
||||||
|
|
||||||
def convert_xxxlist_to_variable(self): # pylint: disable=C0111
|
def convert_xxxlist_to_variable(self): # pylint: disable=C0111
|
||||||
# transform *list to variable or family
|
# transform *list to variable or family
|
||||||
|
@ -963,21 +960,21 @@ class SpaceAnnotator(object):
|
||||||
for condition in self.space.constraints.condition:
|
for condition in self.space.constraints.condition:
|
||||||
if condition.name not in ['disabled_if_in', 'disabled_if_not_in', 'hidden_if_in', 'auto_hidden_if_not_in',
|
if condition.name not in ['disabled_if_in', 'disabled_if_not_in', 'hidden_if_in', 'auto_hidden_if_not_in',
|
||||||
'hidden_if_not_in', 'mandatory_if_in', 'mandatory_if_not_in']:
|
'hidden_if_not_in', 'mandatory_if_in', 'mandatory_if_not_in']:
|
||||||
raise CreoleDictConsistencyError(_(f'unknown condition {condition.name}'))
|
raise DictConsistencyError(_(f'unknown condition {condition.name}'))
|
||||||
|
|
||||||
def check_params(self):
|
def check_params(self):
|
||||||
for condition in self.space.constraints.condition:
|
for condition in self.space.constraints.condition:
|
||||||
for param in condition.param:
|
for param in condition.param:
|
||||||
if param.type not in TYPE_PARAM_CONDITION:
|
if param.type not in TYPE_PARAM_CONDITION:
|
||||||
raise CreoleDictConsistencyError(_(f'cannot use {param.type} type as a param in a condition'))
|
raise DictConsistencyError(_(f'cannot use {param.type} type as a param in a condition'))
|
||||||
|
|
||||||
def check_target(self):
|
def check_target(self):
|
||||||
for condition in self.space.constraints.condition:
|
for condition in self.space.constraints.condition:
|
||||||
if not hasattr(condition, 'target'):
|
if not hasattr(condition, 'target'):
|
||||||
raise CreoleDictConsistencyError(_('target is mandatory in condition'))
|
raise DictConsistencyError(_('target is mandatory in condition'))
|
||||||
for target in condition.target:
|
for target in condition.target:
|
||||||
if target.type.endswith('list') and condition.name not in ['disabled_if_in', 'disabled_if_not_in']:
|
if target.type.endswith('list') and condition.name not in ['disabled_if_in', 'disabled_if_not_in']:
|
||||||
raise CreoleDictConsistencyError(_(f'target in condition for {target.type} not allow in {condition.name}'))
|
raise DictConsistencyError(_(f'target in condition for {target.type} not allow in {condition.name}'))
|
||||||
|
|
||||||
def check_condition_fallback_optional(self):
|
def check_condition_fallback_optional(self):
|
||||||
# a condition with a fallback **and** the source variable doesn't exist
|
# a condition with a fallback **and** the source variable doesn't exist
|
||||||
|
@ -987,7 +984,7 @@ class SpaceAnnotator(object):
|
||||||
if condition.fallback is True and not self.paths.path_is_defined(condition.source):
|
if condition.fallback is True and not self.paths.path_is_defined(condition.source):
|
||||||
for target in condition.target:
|
for target in condition.target:
|
||||||
if target.type in ['variable', 'family']:
|
if target.type in ['variable', 'family']:
|
||||||
if target.name.startswith(VARIABLE_NAMESPACE + '.'):
|
if target.name.startswith(variable_namespace + '.'):
|
||||||
name = target.name.split('.')[-1]
|
name = target.name.split('.')[-1]
|
||||||
else:
|
else:
|
||||||
name = target.name
|
name = target.name
|
||||||
|
@ -1048,7 +1045,7 @@ class SpaceAnnotator(object):
|
||||||
if condition.param == []:
|
if condition.param == []:
|
||||||
remove_targets = []
|
remove_targets = []
|
||||||
for target in condition.target:
|
for target in condition.target:
|
||||||
if target.name.startswith(f'{VARIABLE_NAMESPACE}.'):
|
if target.name.startswith(f'{variable_namespace}.'):
|
||||||
name = target.name.split('.')[-1]
|
name = target.name.split('.')[-1]
|
||||||
else:
|
else:
|
||||||
name = target.name
|
name = target.name
|
||||||
|
@ -1076,7 +1073,7 @@ class SpaceAnnotator(object):
|
||||||
for condition in self.space.constraints.condition:
|
for condition in self.space.constraints.condition:
|
||||||
#parse each variable and family
|
#parse each variable and family
|
||||||
for target_idx, target in enumerate(condition.target):
|
for target_idx, target in enumerate(condition.target):
|
||||||
if target.name.startswith(f'{VARIABLE_NAMESPACE}.'):
|
if target.name.startswith(f'{variable_namespace}.'):
|
||||||
name = target.name.split('.')[-1]
|
name = target.name.split('.')[-1]
|
||||||
else:
|
else:
|
||||||
name = target.name
|
name = target.name
|
||||||
|
@ -1132,7 +1129,7 @@ class SpaceAnnotator(object):
|
||||||
else:
|
else:
|
||||||
param = None
|
param = None
|
||||||
for target in condition.target:
|
for target in condition.target:
|
||||||
if target.name.startswith(f'{VARIABLE_NAMESPACE}.'):
|
if target.name.startswith(f'{variable_namespace}.'):
|
||||||
name = target.name.split('.')[-1]
|
name = target.name.split('.')[-1]
|
||||||
else:
|
else:
|
||||||
name = target.name
|
name = target.name
|
||||||
|
|
|
@ -15,3 +15,5 @@ dtdfilename = join(dtddir, 'rougail.dtd')
|
||||||
|
|
||||||
# chemin du répertoire source des fichiers templates
|
# chemin du répertoire source des fichiers templates
|
||||||
patch_dir = '/srv/rougail/patch'
|
patch_dir = '/srv/rougail/patch'
|
||||||
|
|
||||||
|
variable_namespace = 'rougail'
|
||||||
|
|
|
@ -101,7 +101,6 @@
|
||||||
<!ATTLIST variable hidden (True|False) "False">
|
<!ATTLIST variable hidden (True|False) "False">
|
||||||
<!ATTLIST variable disabled (True|False) "False">
|
<!ATTLIST variable disabled (True|False) "False">
|
||||||
<!ATTLIST variable multi (True|False) "False">
|
<!ATTLIST variable multi (True|False) "False">
|
||||||
<!ATTLIST variable submulti (True|False) "False">
|
|
||||||
<!ATTLIST variable redefine (True|False) "False">
|
<!ATTLIST variable redefine (True|False) "False">
|
||||||
<!ATTLIST variable exists (True|False) "True">
|
<!ATTLIST variable exists (True|False) "True">
|
||||||
<!ATTLIST variable mandatory (True|False) "False">
|
<!ATTLIST variable mandatory (True|False) "False">
|
||||||
|
@ -141,7 +140,7 @@
|
||||||
<!ELEMENT param (#PCDATA)>
|
<!ELEMENT param (#PCDATA)>
|
||||||
<!ATTLIST param type (string|variable|number|python) "string">
|
<!ATTLIST param type (string|variable|number|python) "string">
|
||||||
<!ATTLIST param name CDATA #IMPLIED>
|
<!ATTLIST param name CDATA #IMPLIED>
|
||||||
<!ATTLIST param hidden (True|False) "True">
|
<!ATTLIST param notraisepropertyerror (True|False) "False">
|
||||||
<!ATTLIST param optional (True|False) "False">
|
<!ATTLIST param optional (True|False) "False">
|
||||||
|
|
||||||
<!ELEMENT target (#PCDATA)>
|
<!ELEMENT target (#PCDATA)>
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
|
||||||
Erreurs Creole
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigError(Exception):
|
class ConfigError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -19,7 +14,7 @@ class TemplateDisabled(TemplateError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class CreoleOperationError(Exception):
|
class OperationError(Exception):
|
||||||
"""Type error or value Error for Creole variable's type or values
|
"""Type error or value Error for Creole variable's type or values
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -30,11 +25,11 @@ class SpaceObjShallNotBeUpdated(Exception):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class CreoleDictConsistencyError(Exception):
|
class DictConsistencyError(Exception):
|
||||||
"""It's not only that the Creole XML is valid against the Creole DTD
|
"""It's not only that the Creole XML is valid against the Creole DTD
|
||||||
it's that it is not consistent.
|
it's that it is not consistent.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class CreoleLoaderError(Exception):
|
class LoaderError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,52 +1,34 @@
|
||||||
"""loader
|
"""loader
|
||||||
flattened XML specific
|
flattened XML specific
|
||||||
"""
|
"""
|
||||||
from os.path import join, isfile
|
from os.path import isfile
|
||||||
from lxml.etree import DTD
|
from lxml.etree import DTD
|
||||||
import imp
|
|
||||||
|
|
||||||
from tiramisu import (StrOption, OptionDescription, DynOptionDescription, PortOption,
|
from .config import dtdfilename, variable_namespace
|
||||||
IntOption, ChoiceOption, BoolOption, SymLinkOption, IPOption,
|
|
||||||
NetworkOption, NetmaskOption, DomainnameOption, BroadcastOption,
|
|
||||||
URLOption, EmailOption, FilenameOption, UsernameOption, DateOption,
|
|
||||||
PasswordOption, BoolOption, MACOption, Leadership, submulti,
|
|
||||||
Params, ParamSelfOption, ParamOption, ParamDynOption, ParamValue, Calculation, calc_value)
|
|
||||||
|
|
||||||
from .config import dtdfilename
|
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
from .utils import normalize_family
|
from .error import LoaderError
|
||||||
from .annotator import VARIABLE_NAMESPACE
|
|
||||||
from .error import CreoleLoaderError
|
|
||||||
|
|
||||||
|
|
||||||
FUNC_TO_DICT = ['valid_not_equal']
|
FUNC_TO_DICT = ['valid_not_equal']
|
||||||
KNOWN_TAGS = ['family', 'variable', 'separators', 'leader', 'property']
|
FORCE_INFORMATIONS = ['help', 'test', 'separator']
|
||||||
|
|
||||||
|
|
||||||
class ConvertDynOptionDescription(DynOptionDescription):
|
def convert_boolean(value):
|
||||||
def convert_suffix_to_path(self, suffix):
|
prop = {'True': True,
|
||||||
if not isinstance(suffix, str):
|
'False': False,
|
||||||
suffix = str(suffix)
|
'None': None}
|
||||||
return normalize_family(suffix,
|
if value not in prop:
|
||||||
check_name=False)
|
raise Exception('unknown value {} while trying to cast {} to boolean'.format(value, obj))
|
||||||
|
return prop[value]
|
||||||
|
|
||||||
|
|
||||||
def convert_tiramisu_value(value, obj):
|
def convert_tiramisu_value(value, type_):
|
||||||
"""
|
"""
|
||||||
convertit les variables dans le bon type si nécessaire
|
convertit les variables dans le bon type si nécessaire
|
||||||
"""
|
"""
|
||||||
def _convert_boolean(value):
|
|
||||||
prop = {'True': True,
|
|
||||||
'False': False,
|
|
||||||
'None': None}
|
|
||||||
if value not in prop:
|
|
||||||
raise Exception('unknown value {} while trying to cast {} to boolean'.format(value, obj))
|
|
||||||
return prop[value]
|
|
||||||
|
|
||||||
if value is None:
|
if value is None:
|
||||||
return value
|
return value
|
||||||
func = {IntOption: int,
|
func = CONVERT_OPTION[type_].get('func', None)
|
||||||
BoolOption: _convert_boolean}.get(obj, None)
|
|
||||||
if func is None:
|
if func is None:
|
||||||
return value
|
return value
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
|
@ -55,85 +37,71 @@ def convert_tiramisu_value(value, obj):
|
||||||
return func(value)
|
return func(value)
|
||||||
|
|
||||||
|
|
||||||
CONVERT_OPTION = {'number': dict(opttype=IntOption),
|
CONVERT_OPTION = {'number': dict(opttype="IntOption", func=int),
|
||||||
'choice': dict(opttype=ChoiceOption),
|
'choice': dict(opttype="ChoiceOption"),
|
||||||
'string': dict(opttype=StrOption),
|
'string': dict(opttype="StrOption"),
|
||||||
'password': dict(opttype=PasswordOption),
|
'password': dict(opttype="PasswordOption"),
|
||||||
'mail': dict(opttype=EmailOption),
|
'mail': dict(opttype="EmailOption"),
|
||||||
'boolean': dict(opttype=BoolOption, initkwargs={'default': True}),
|
'boolean': dict(opttype="BoolOption", initkwargs={'default': [True]}, func=convert_boolean),
|
||||||
'symlink': dict(opttype=SymLinkOption),
|
'symlink': dict(opttype="SymLinkOption"),
|
||||||
'filename': dict(opttype=FilenameOption),
|
'filename': dict(opttype="FilenameOption"),
|
||||||
'date': dict(opttype=DateOption),
|
'date': dict(opttype="DateOption"),
|
||||||
'unix_user': dict(opttype=UsernameOption),
|
'unix_user': dict(opttype="UsernameOption"),
|
||||||
'ip': dict(opttype=IPOption, initkwargs={'allow_reserved': True}),
|
'ip': dict(opttype="IPOption", initkwargs={'allow_reserved': True}),
|
||||||
'local_ip': dict(opttype=IPOption, initkwargs={'private_only': True, 'warnings_only': True}),
|
'local_ip': dict(opttype="IPOption", initkwargs={'private_only': True, 'warnings_only': True}),
|
||||||
'netmask': dict(opttype=NetmaskOption),
|
'netmask': dict(opttype="NetmaskOption"),
|
||||||
'network': dict(opttype=NetworkOption),
|
'network': dict(opttype="NetworkOption"),
|
||||||
'broadcast': dict(opttype=BroadcastOption),
|
'broadcast': dict(opttype="BroadcastOption"),
|
||||||
'netbios': dict(opttype=DomainnameOption, initkwargs={'type': 'netbios', 'warnings_only': True}),
|
'netbios': dict(opttype="DomainnameOption", initkwargs={'type': 'netbios', 'warnings_only': True}),
|
||||||
'domain': dict(opttype=DomainnameOption, initkwargs={'type': 'domainname', 'allow_ip': True, 'allow_without_dot': True}),
|
'domain': dict(opttype="DomainnameOption", initkwargs={'type': 'domainname', 'allow_ip': True, 'allow_without_dot': True}),
|
||||||
'domain_strict': dict(opttype=DomainnameOption, initkwargs={'type': 'domainname', 'allow_ip': False}),
|
'domain_strict': dict(opttype="DomainnameOption", initkwargs={'type': 'domainname', 'allow_ip': False}),
|
||||||
'hostname': dict(opttype=DomainnameOption, initkwargs={'type': 'hostname', 'allow_ip': True}),
|
'hostname': dict(opttype="DomainnameOption", initkwargs={'type': 'hostname', 'allow_ip': True}),
|
||||||
'hostname_strict': dict(opttype=DomainnameOption, initkwargs={'type': 'hostname', 'allow_ip': False}),
|
'hostname_strict': dict(opttype="DomainnameOption", initkwargs={'type': 'hostname', 'allow_ip': False}),
|
||||||
'web_address': dict(opttype=URLOption, initkwargs={'allow_ip': True, 'allow_without_dot': True}),
|
'web_address': dict(opttype="URLOption", initkwargs={'allow_ip': True, 'allow_without_dot': True}),
|
||||||
'port': dict(opttype=PortOption, initkwargs={'allow_private': True}),
|
'port': dict(opttype="PortOption", initkwargs={'allow_private': True}),
|
||||||
'mac': dict(opttype=MACOption),
|
'mac': dict(opttype="MACOption"),
|
||||||
'cidr': dict(opttype=IPOption, initkwargs={'cidr': True}),
|
'cidr': dict(opttype="IPOption", initkwargs={'cidr': True}),
|
||||||
'network_cidr': dict(opttype=NetworkOption, initkwargs={'cidr': True}),
|
'network_cidr': dict(opttype="NetworkOption", initkwargs={'cidr': True}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Elt:
|
|
||||||
def __init__(self, attrib):
|
|
||||||
self.attrib = attrib
|
|
||||||
|
|
||||||
|
|
||||||
class PopulateTiramisuObjects:
|
class PopulateTiramisuObjects:
|
||||||
def __init__(self):
|
def __init__(self,
|
||||||
self.storage = ElementStorage()
|
xmlroot,
|
||||||
self.booleans = []
|
funcs_path,
|
||||||
|
):
|
||||||
|
self.storage = ElementStorage(self.parse_dtd())
|
||||||
|
self.storage.text = ["from tiramisu import *",
|
||||||
|
"from rougail.tiramisu import ConvertDynOptionDescription",
|
||||||
|
"import imp",
|
||||||
|
f"func = imp.load_source('func', '{funcs_path}')",
|
||||||
|
]
|
||||||
|
self.make_tiramisu_objects(xmlroot)
|
||||||
|
# parse object
|
||||||
|
self.storage.get('.').get()
|
||||||
|
|
||||||
def parse_dtd(self, dtdfilename):
|
def parse_dtd(self):
|
||||||
"""Loads the Creole DTD
|
"""Loads the DTD
|
||||||
|
|
||||||
:raises IOError: if the DTD is not found
|
:raises IOError: if the DTD is not found
|
||||||
|
|
||||||
:param dtdfilename: the full filename of the Creole DTD
|
:param dtdfilename: the full filename of the DTD
|
||||||
"""
|
"""
|
||||||
if not isfile(dtdfilename):
|
if not isfile(dtdfilename):
|
||||||
raise IOError(_("no such DTD file: {}").format(dtdfilename))
|
raise IOError(_("no such DTD file: {}").format(dtdfilename))
|
||||||
|
booleans = []
|
||||||
with open(dtdfilename, 'r') as dtdfd:
|
with open(dtdfilename, 'r') as dtdfd:
|
||||||
dtd = DTD(dtdfd)
|
dtd = DTD(dtdfd)
|
||||||
for elt in dtd.iterelements():
|
for elt in dtd.iterelements():
|
||||||
if elt.name == 'variable':
|
if elt.name == 'variable':
|
||||||
for attr in elt.iterattributes():
|
for attr in elt.iterattributes():
|
||||||
if set(attr.itervalues()) == set(['True', 'False']):
|
if set(attr.itervalues()) == set(['True', 'False']):
|
||||||
self.booleans.append(attr.name)
|
booleans.append(attr.name)
|
||||||
|
return booleans
|
||||||
def get_root_family(self):
|
|
||||||
family = Family(Elt({'name': 'baseoption',
|
|
||||||
'doc': 'baseoption'}),
|
|
||||||
self.booleans,
|
|
||||||
self.storage,
|
|
||||||
self.eosfunc,
|
|
||||||
)
|
|
||||||
self.storage.add('.', family)
|
|
||||||
return family
|
|
||||||
|
|
||||||
def reorder_family(self, xmlroot):
|
|
||||||
xmlelts = []
|
|
||||||
for xmlelt in xmlroot:
|
|
||||||
# VARIABLE_NAMESPACE family has to be loaded before any other family
|
|
||||||
# because `extra` family could use `VARIABLE_NAMESPACE` variables.
|
|
||||||
if xmlelt.attrib['name'] == VARIABLE_NAMESPACE:
|
|
||||||
xmlelts.insert(0, xmlelt)
|
|
||||||
else:
|
|
||||||
xmlelts.append(xmlelt)
|
|
||||||
return xmlelts
|
|
||||||
|
|
||||||
def make_tiramisu_objects(self, xmlroot, eosfunc):
|
|
||||||
self.eosfunc = imp.load_source('eosfunc', eosfunc)
|
|
||||||
|
|
||||||
|
def make_tiramisu_objects(self,
|
||||||
|
xmlroot,
|
||||||
|
):
|
||||||
family = self.get_root_family()
|
family = self.get_root_family()
|
||||||
for xmlelt in self.reorder_family(xmlroot):
|
for xmlelt in self.reorder_family(xmlroot):
|
||||||
self.iter_family(xmlelt,
|
self.iter_family(xmlelt,
|
||||||
|
@ -141,26 +109,44 @@ class PopulateTiramisuObjects:
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_root_family(self):
|
||||||
|
family = Family(BaseElt({'name': 'baseoption',
|
||||||
|
'doc': 'baseoption'}),
|
||||||
|
self.storage,
|
||||||
|
False,
|
||||||
|
'.',
|
||||||
|
)
|
||||||
|
return family
|
||||||
|
|
||||||
|
def reorder_family(self, xmlroot):
|
||||||
|
xmlelts = []
|
||||||
|
for xmlelt in xmlroot:
|
||||||
|
# variable_namespace family has to be loaded before any other family
|
||||||
|
# because `extra` family could use `variable_namespace` variables.
|
||||||
|
if xmlelt.attrib['name'] == variable_namespace:
|
||||||
|
xmlelts.insert(0, xmlelt)
|
||||||
|
else:
|
||||||
|
xmlelts.append(xmlelt)
|
||||||
|
return xmlelts
|
||||||
|
|
||||||
def iter_family(self,
|
def iter_family(self,
|
||||||
child,
|
child,
|
||||||
family,
|
family,
|
||||||
subpath,
|
subpath,
|
||||||
):
|
):
|
||||||
if child.tag not in KNOWN_TAGS:
|
|
||||||
raise CreoleLoaderError(_('unknown tag {}').format(child.tag))
|
|
||||||
if child.tag in ['family', 'leader']:
|
if child.tag in ['family', 'leader']:
|
||||||
self.populate_family(family,
|
function = self.populate_family
|
||||||
child,
|
|
||||||
subpath,
|
|
||||||
)
|
|
||||||
elif child.tag == 'separators':
|
|
||||||
self.parse_separators(child)
|
|
||||||
elif child.tag == 'variable':
|
elif child.tag == 'variable':
|
||||||
self.populate_variable(child, subpath, family)
|
function = self.populate_variable
|
||||||
elif child.tag == 'property':
|
elif child.tag == 'property':
|
||||||
self.parse_properties(family, child)
|
# property already imported with family
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
raise Exception('unknown tag {}'.format(child.tag))
|
raise Exception('unknown tag {}'.format(child.tag))
|
||||||
|
function(family,
|
||||||
|
child,
|
||||||
|
subpath,
|
||||||
|
)
|
||||||
|
|
||||||
def populate_family(self,
|
def populate_family(self,
|
||||||
parent_family,
|
parent_family,
|
||||||
|
@ -171,13 +157,10 @@ class PopulateTiramisuObjects:
|
||||||
elt,
|
elt,
|
||||||
)
|
)
|
||||||
family = Family(elt,
|
family = Family(elt,
|
||||||
self.booleans,
|
|
||||||
self.storage,
|
self.storage,
|
||||||
self.eosfunc,
|
elt.tag == 'leader',
|
||||||
|
path,
|
||||||
)
|
)
|
||||||
self.storage.add(path, family)
|
|
||||||
if elt.tag == 'leader':
|
|
||||||
family.set_leader()
|
|
||||||
parent_family.add(family)
|
parent_family.add(family)
|
||||||
if len(elt) != 0:
|
if len(elt) != 0:
|
||||||
for child in elt:
|
for child in elt:
|
||||||
|
@ -186,43 +169,26 @@ class PopulateTiramisuObjects:
|
||||||
path,
|
path,
|
||||||
)
|
)
|
||||||
|
|
||||||
def parse_separators(self,
|
def populate_variable(self,
|
||||||
separators,
|
family,
|
||||||
):
|
elt,
|
||||||
for separator in separators:
|
subpath,
|
||||||
elt = self.storage.get(separator.attrib['name'])
|
):
|
||||||
elt.add_information('separator', separator.text)
|
|
||||||
|
|
||||||
def populate_variable(self, elt, subpath, family):
|
|
||||||
is_follower = False
|
is_follower = False
|
||||||
is_leader = False
|
is_leader = False
|
||||||
if family.is_leader:
|
if family.is_leader:
|
||||||
if elt.attrib['name'] != family.attrib['name']:
|
if elt.attrib['name'] != family.elt.attrib['name']:
|
||||||
is_follower = True
|
is_follower = True
|
||||||
else:
|
else:
|
||||||
is_leader = True
|
is_leader = True
|
||||||
path = self.build_path(subpath,
|
family.add(Variable(elt,
|
||||||
elt,
|
|
||||||
)
|
|
||||||
variable = Variable(elt,
|
|
||||||
self.booleans,
|
|
||||||
self.storage,
|
self.storage,
|
||||||
is_follower,
|
is_follower,
|
||||||
is_leader,
|
is_leader,
|
||||||
self.eosfunc,
|
self.build_path(subpath,
|
||||||
)
|
elt,
|
||||||
self.storage.add(path, variable)
|
)
|
||||||
family.add(variable)
|
))
|
||||||
|
|
||||||
def parse_properties(self, family, child):
|
|
||||||
if child.get('type') == 'calculation':
|
|
||||||
kwargs = {'condition': child.attrib['source'],
|
|
||||||
'expected': ParamValue(child.attrib.get('expected'))}
|
|
||||||
if child.attrib['inverse'] == 'True':
|
|
||||||
kwargs['reverse_condition'] = ParamValue(True)
|
|
||||||
family.attrib['properties'].append((ParamValue(child.text), kwargs))
|
|
||||||
else:
|
|
||||||
family.attrib['properties'].append(child.text)
|
|
||||||
|
|
||||||
def build_path(self,
|
def build_path(self,
|
||||||
subpath,
|
subpath,
|
||||||
|
@ -232,321 +198,299 @@ class PopulateTiramisuObjects:
|
||||||
return elt.attrib['name']
|
return elt.attrib['name']
|
||||||
return subpath + '.' + elt.attrib['name']
|
return subpath + '.' + elt.attrib['name']
|
||||||
|
|
||||||
|
def get_text(self):
|
||||||
|
return '\n'.join(self.storage.get('.').get_text())
|
||||||
|
|
||||||
|
|
||||||
|
class BaseElt:
|
||||||
|
def __init__(self, attrib):
|
||||||
|
self.attrib = attrib
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return iter([])
|
||||||
|
|
||||||
|
|
||||||
class ElementStorage:
|
class ElementStorage:
|
||||||
def __init__(self):
|
def __init__(self,
|
||||||
|
booleans,
|
||||||
|
):
|
||||||
self.paths = {}
|
self.paths = {}
|
||||||
|
self.text = []
|
||||||
|
self.index = 0
|
||||||
|
self.booleans = booleans
|
||||||
|
|
||||||
def add(self, path, elt):
|
def add(self, path, elt):
|
||||||
if path in self.paths:
|
self.paths[path] = (elt, self.index)
|
||||||
raise CreoleLoaderError(_('path already loaded {}').format(path))
|
self.index += 1
|
||||||
self.paths[path] = elt
|
|
||||||
|
|
||||||
def get(self, path):
|
def get(self, path):
|
||||||
|
if path not in self.paths or self.paths[path][0] is None:
|
||||||
|
raise LoaderError(_('there is no element for path {}').format(path))
|
||||||
|
return self.paths[path][0]
|
||||||
|
|
||||||
|
def get_name(self, path):
|
||||||
if path not in self.paths:
|
if path not in self.paths:
|
||||||
raise CreoleLoaderError(_('there is no element for path {}').format(path))
|
raise LoaderError(_('there is no element for index {}').format(path))
|
||||||
return self.paths[path]
|
return f'option_{self.paths[path][1]}'
|
||||||
|
|
||||||
|
|
||||||
class Common:
|
class Common:
|
||||||
def build_properties(self):
|
def __init__(self,
|
||||||
for index, prop in enumerate(self.attrib['properties']):
|
elt,
|
||||||
if isinstance(prop, tuple):
|
storage,
|
||||||
action, kwargs = prop
|
is_leader,
|
||||||
kwargs['condition'] = ParamOption(self.storage.get(kwargs['condition']).get(), todict=True)
|
path,
|
||||||
prop = Calculation(calc_value,
|
):
|
||||||
Params(action,
|
self.option_name = None
|
||||||
kwargs=kwargs))
|
self.path = path
|
||||||
self.attrib['properties'][index] = prop
|
self.attrib = {}
|
||||||
if self.attrib['properties']:
|
self.informations = {}
|
||||||
self.attrib['properties'] = tuple(self.attrib['properties'])
|
self.storage = storage
|
||||||
|
self.is_leader = is_leader
|
||||||
|
self.storage.add(self.path, self)
|
||||||
|
|
||||||
|
def populate_properties(self, child):
|
||||||
|
if child.get('type') == 'calculation':
|
||||||
|
action = f"ParamValue('{child.text}')"
|
||||||
|
option_name = self.storage.get(child.attrib['source']).get()
|
||||||
|
kwargs = f"'condition': ParamOption({option_name}, todict=True), 'expected': ParamValue('{child.attrib.get('expected')}')"
|
||||||
|
if child.attrib['inverse'] == 'True':
|
||||||
|
kwargs += ", 'reverse_condition': ParamValue(True)"
|
||||||
|
prop = 'Calculation(calc_value, Params(' + action + ', kwargs={' + kwargs + '}))'
|
||||||
else:
|
else:
|
||||||
|
prop = "'" + child.text + "'"
|
||||||
|
if self.attrib['properties']:
|
||||||
|
self.attrib['properties'] += ', '
|
||||||
|
self.attrib['properties'] += prop
|
||||||
|
if not self.attrib['properties']:
|
||||||
del self.attrib['properties']
|
del self.attrib['properties']
|
||||||
|
|
||||||
|
def get_attrib(self, attrib):
|
||||||
|
ret_list = []
|
||||||
|
for key, value in self.attrib.items():
|
||||||
|
if key == 'properties':
|
||||||
|
value = 'frozenset([' + self.attrib[key] + '])'
|
||||||
|
elif key in ['default', 'multi', 'suffixes', 'validators']:
|
||||||
|
value = self.attrib[key]
|
||||||
|
elif isinstance(value, str) and key != 'opt' and not value.startswith('['):
|
||||||
|
value = "'" + value.replace("'", "\\\'") + "'"
|
||||||
|
ret_list.append(f'{key}={value}')
|
||||||
|
return ', '.join(ret_list)
|
||||||
|
|
||||||
|
def populate_informations(self):
|
||||||
|
for key, value in self.informations.items():
|
||||||
|
value = value.replace('"', '\"')
|
||||||
|
self.storage.text.append(f'{self.option_name}.impl_set_information("{key}", "{value}")')
|
||||||
|
|
||||||
|
def get_text(self,
|
||||||
|
):
|
||||||
|
return self.storage.text
|
||||||
|
|
||||||
|
|
||||||
class Variable(Common):
|
class Variable(Common):
|
||||||
def __init__(self, elt, booleans, storage, is_follower, is_leader, eosfunc):
|
def __init__(self,
|
||||||
self.option = None
|
elt,
|
||||||
self.informations = {}
|
storage,
|
||||||
self.attrib = {}
|
is_follower,
|
||||||
convert_option = CONVERT_OPTION[elt.attrib['type']]
|
is_leader,
|
||||||
if 'initkwargs' in convert_option:
|
path,
|
||||||
self.attrib.update(convert_option['initkwargs'])
|
):
|
||||||
if elt.attrib['type'] != 'symlink':
|
super().__init__(elt,
|
||||||
self.attrib['properties'] = []
|
storage,
|
||||||
self.attrib['validators'] = []
|
is_leader,
|
||||||
self.eosfunc = eosfunc
|
path,
|
||||||
self.storage = storage
|
)
|
||||||
self.booleans = booleans
|
|
||||||
self.populate_attrib(elt)
|
|
||||||
self.is_follower = is_follower
|
self.is_follower = is_follower
|
||||||
self.is_leader = is_leader
|
convert_option = CONVERT_OPTION[elt.attrib['type']]
|
||||||
|
del elt.attrib['type']
|
||||||
self.object_type = convert_option['opttype']
|
self.object_type = convert_option['opttype']
|
||||||
self.populate_choice(elt)
|
self.attrib.update(convert_option.get('initkwargs', {}))
|
||||||
for child in elt:
|
if self.object_type != 'SymLinkOption':
|
||||||
self.populate_property(child)
|
self.attrib['properties'] = ''
|
||||||
self.populate_value(child)
|
self.attrib['validators'] = []
|
||||||
self.populate_check(child)
|
self.elt = elt
|
||||||
if elt.attrib['type'] == 'symlink':
|
|
||||||
self.attrib['opt'] = storage.get(self.attrib['opt'])
|
|
||||||
|
|
||||||
def populate_attrib(self,
|
|
||||||
elt,
|
|
||||||
):
|
|
||||||
for key, value in elt.attrib.items():
|
|
||||||
if key == 'multi' and elt.attrib['type'] == 'symlink':
|
|
||||||
continue
|
|
||||||
if key == 'multi' and value == 'submulti':
|
|
||||||
value = submulti
|
|
||||||
elif key in self.booleans:
|
|
||||||
if value == 'True':
|
|
||||||
value = True
|
|
||||||
elif value == 'False':
|
|
||||||
value = False
|
|
||||||
else:
|
|
||||||
raise CreoleLoaderError(_('unknown value {} for {}').format(value, key))
|
|
||||||
if key in ['help', 'test']:
|
|
||||||
self.add_information(key, value)
|
|
||||||
elif key != 'type':
|
|
||||||
self.attrib[key] = value
|
|
||||||
|
|
||||||
def populate_choice(self,
|
|
||||||
elt,
|
|
||||||
):
|
|
||||||
if elt.attrib['type'] == 'choice':
|
|
||||||
values = []
|
|
||||||
for child in elt:
|
|
||||||
if child.tag == 'choice':
|
|
||||||
value = child.text
|
|
||||||
if child.attrib['type'] == 'number':
|
|
||||||
value = int(value)
|
|
||||||
values.append(value)
|
|
||||||
self.attrib['values'] = tuple(values)
|
|
||||||
|
|
||||||
def populate_property(self, child):
|
|
||||||
if child.tag == 'property':
|
|
||||||
if child.get('type') == 'calculation':
|
|
||||||
kwargs = {'condition': child.attrib['source'],
|
|
||||||
'expected': ParamValue(child.attrib.get('expected'))}
|
|
||||||
if child.attrib['inverse'] == 'True':
|
|
||||||
kwargs['reverse_condition'] = ParamValue(True)
|
|
||||||
self.attrib['properties'].append((ParamValue(child.text), kwargs))
|
|
||||||
else:
|
|
||||||
self.attrib['properties'].append(child.text)
|
|
||||||
|
|
||||||
def populate_value(self, child):
|
|
||||||
if child.tag == 'value':
|
|
||||||
if child.attrib.get('type') == 'calculation':
|
|
||||||
if child.text is not None and child.text.strip():
|
|
||||||
self.attrib['default'] = (child.text.strip(),)
|
|
||||||
else:
|
|
||||||
params = []
|
|
||||||
for param in child:
|
|
||||||
params.append(self.parse_param(param))
|
|
||||||
self.attrib['default'] = (child.attrib['name'], params, False)
|
|
||||||
else:
|
|
||||||
if "type" in child.attrib:
|
|
||||||
type_ = CONVERT_OPTION[child.attrib['type']]['opttype']
|
|
||||||
else:
|
|
||||||
type_ = self.object_type
|
|
||||||
if self.attrib['multi'] is True and not self.is_follower:
|
|
||||||
if 'default' not in self.attrib:
|
|
||||||
self.attrib['default'] = []
|
|
||||||
value = convert_tiramisu_value(child.text, type_)
|
|
||||||
self.attrib['default'].append(value)
|
|
||||||
if 'default_multi' not in self.attrib and not self.is_leader:
|
|
||||||
self.attrib['default_multi'] = value
|
|
||||||
elif self.attrib['multi'] == submulti:
|
|
||||||
if 'default' not in self.attrib:
|
|
||||||
self.attrib['default'] = []
|
|
||||||
value = convert_tiramisu_value(child.text, type_)
|
|
||||||
if not self.is_follower:
|
|
||||||
if not isinstance(value, list):
|
|
||||||
dvalue = [value]
|
|
||||||
else:
|
|
||||||
dvalue = value
|
|
||||||
self.attrib['default'].append(dvalue)
|
|
||||||
if value and 'default_multi' not in self.attrib and not self.is_leader:
|
|
||||||
self.attrib['default_multi'] = []
|
|
||||||
if not self.is_leader:
|
|
||||||
self.attrib['default_multi'].append(value)
|
|
||||||
else:
|
|
||||||
value = convert_tiramisu_value(child.text, type_)
|
|
||||||
if self.is_follower:
|
|
||||||
self.attrib['default_multi'] = value
|
|
||||||
else:
|
|
||||||
self.attrib['default'] = value
|
|
||||||
|
|
||||||
def populate_check(self, child):
|
|
||||||
if child.tag == 'check':
|
|
||||||
params = []
|
|
||||||
for param in child:
|
|
||||||
params.append(self.parse_param(param))
|
|
||||||
#check.params = params
|
|
||||||
self.attrib['validators'].append((child.attrib['name'], params, child.attrib['warnings_only']))
|
|
||||||
|
|
||||||
def parse_param(self, param):
|
|
||||||
name = param.attrib.get('name', '')
|
|
||||||
if param.attrib['type'] == 'string':
|
|
||||||
value = param.text
|
|
||||||
elif param.attrib['type'] == 'variable':
|
|
||||||
transitive = param.attrib.get('transitive', 'False')
|
|
||||||
if transitive == 'True':
|
|
||||||
transitive = True
|
|
||||||
elif transitive == 'False':
|
|
||||||
transitive = False
|
|
||||||
else:
|
|
||||||
raise CreoleLoaderError(_('unknown transitive boolean {}').format(transitive))
|
|
||||||
value = [param.text, transitive, param.attrib.get('suffix')]
|
|
||||||
elif param.attrib['type'] == 'number':
|
|
||||||
value = int(param.text)
|
|
||||||
else:
|
|
||||||
raise CreoleLoaderError(_('unknown param type {}').format(param.attrib['type']))
|
|
||||||
return(name, value)
|
|
||||||
|
|
||||||
def add_information(self, key, value):
|
|
||||||
if key in self.informations:
|
|
||||||
raise CreoleLoaderError(_('key already exists in information {}').format(key))
|
|
||||||
self.informations[key] = value
|
|
||||||
|
|
||||||
def build_calculator(self, key):
|
|
||||||
if key in self.attrib:
|
|
||||||
values = self.attrib[key]
|
|
||||||
if isinstance(values, list):
|
|
||||||
is_list = True
|
|
||||||
else:
|
|
||||||
is_list = False
|
|
||||||
values = [values]
|
|
||||||
ret = []
|
|
||||||
for value in values:
|
|
||||||
if isinstance(value, tuple):
|
|
||||||
if key == 'validators':
|
|
||||||
args = [ParamSelfOption()]
|
|
||||||
else:
|
|
||||||
args = []
|
|
||||||
kwargs = {}
|
|
||||||
if len(value) == 3:
|
|
||||||
for param in value[1]:
|
|
||||||
if isinstance(param[1], list):
|
|
||||||
option = self.storage.get(param[1][0]).get()
|
|
||||||
param_kwargs = {'notraisepropertyerror': param[1][1]}
|
|
||||||
if value[0] in FUNC_TO_DICT:
|
|
||||||
param_kwargs['todict'] = True
|
|
||||||
if not param[1][2]:
|
|
||||||
param_value = ParamOption(option,
|
|
||||||
**param_kwargs,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
family = '.'.join(param[1][0].split('.', 3)[:2])
|
|
||||||
param_value = ParamDynOption(option,
|
|
||||||
param[1][2],
|
|
||||||
self.storage.get(family).get(),
|
|
||||||
**param_kwargs,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
param_value = ParamValue(param[1])
|
|
||||||
if not param[0]:
|
|
||||||
args.append(param_value)
|
|
||||||
else:
|
|
||||||
kwargs[param[0]] = param_value
|
|
||||||
|
|
||||||
ret.append(Calculation(getattr(self.eosfunc, value[0]),
|
|
||||||
Params(tuple(args),
|
|
||||||
kwargs=kwargs)))
|
|
||||||
else:
|
|
||||||
ret.append(value)
|
|
||||||
if not is_list:
|
|
||||||
self.attrib[key] = ret[0]
|
|
||||||
else:
|
|
||||||
self.attrib[key] = ret
|
|
||||||
|
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
if self.option is None:
|
if self.option_name is None:
|
||||||
if self.object_type is SymLinkOption:
|
self.populate_attrib()
|
||||||
self.attrib['opt'] = self.attrib['opt'].get()
|
if self.object_type == 'SymLinkOption':
|
||||||
|
self.attrib['opt'] = self.storage.get(self.attrib['opt']).get()
|
||||||
else:
|
else:
|
||||||
self.build_properties()
|
self.parse_multi()
|
||||||
self.build_calculator('default')
|
self.parse_children()
|
||||||
self.build_calculator('validators')
|
attrib = self.get_attrib(self.attrib)
|
||||||
if not self.attrib['validators']:
|
self.option_name = self.storage.get_name(self.path)
|
||||||
del self.attrib['validators']
|
self.storage.text.append(f'{self.option_name} = {self.object_type}({attrib})')
|
||||||
try:
|
self.populate_informations()
|
||||||
option = self.object_type(**self.attrib)
|
return self.option_name
|
||||||
except Exception as err:
|
|
||||||
import traceback
|
def populate_attrib(self):
|
||||||
traceback.print_exc()
|
for key, value in self.elt.attrib.items():
|
||||||
name = self.attrib['name']
|
if key in self.storage.booleans:
|
||||||
raise CreoleLoaderError(_('cannot create option "{}": {}').format(name, err))
|
value = convert_boolean(value)
|
||||||
for key, value in self.informations.items():
|
if key in FORCE_INFORMATIONS:
|
||||||
option.impl_set_information(key, value)
|
self.informations[key] = value
|
||||||
self.option = option
|
else:
|
||||||
return self.option
|
self.attrib[key] = value
|
||||||
|
|
||||||
|
def parse_children(self):
|
||||||
|
if not 'default' in self.attrib or self.attrib['multi']:
|
||||||
|
self.attrib['default'] = []
|
||||||
|
if self.attrib['multi'] == 'submulti' and self.is_follower:
|
||||||
|
self.attrib['default_multi'] = []
|
||||||
|
choices = []
|
||||||
|
for child in self.elt:
|
||||||
|
if child.tag == 'property':
|
||||||
|
self.populate_properties(child)
|
||||||
|
elif child.tag == 'value':
|
||||||
|
if child.attrib['type'] == 'calculation':
|
||||||
|
self.attrib['default'] = self.calculation_value(child, [])
|
||||||
|
else:
|
||||||
|
self.populate_value(child)
|
||||||
|
elif child.tag == 'check':
|
||||||
|
self.attrib['validators'].append(self.calculation_value(child, ['ParamSelfOption()']))
|
||||||
|
elif child.tag == 'choice':
|
||||||
|
choices.append(convert_tiramisu_value(child.text, child.attrib['type']))
|
||||||
|
if choices:
|
||||||
|
self.attrib['values'] = tuple(choices)
|
||||||
|
if 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 self.attrib['validators'] == []:
|
||||||
|
del self.attrib['validators']
|
||||||
|
else:
|
||||||
|
self.attrib['validators'] = '[' + ', '.join(self.attrib['validators']) + ']'
|
||||||
|
|
||||||
|
def parse_multi(self):
|
||||||
|
if self.is_follower:
|
||||||
|
if self.attrib['multi'] is True:
|
||||||
|
self.attrib['multi'] = 'submulti'
|
||||||
|
else:
|
||||||
|
self.attrib['multi'] = True
|
||||||
|
|
||||||
|
def calculation_value(self, child, args):
|
||||||
|
kwargs = []
|
||||||
|
if 'name' in child.attrib:
|
||||||
|
# has parameters
|
||||||
|
function = child.attrib['name']
|
||||||
|
for param in child:
|
||||||
|
value = self.populate_param(param)
|
||||||
|
if 'name' not in param.attrib:
|
||||||
|
args.append(str(value))
|
||||||
|
else:
|
||||||
|
kwargs.append(f"'{param.attrib['name']}': " + value)
|
||||||
|
else:
|
||||||
|
# function without any parameter
|
||||||
|
function = child.text.strip()
|
||||||
|
ret = f"Calculation(func.{function}, Params((" + ', '.join(args) + "), kwargs=" + "{" + ', '.join(kwargs) + "})"
|
||||||
|
if 'warnings_only' in child.attrib:
|
||||||
|
ret += f', warnings_only={child.attrib["warnings_only"]}'
|
||||||
|
return ret + ')'
|
||||||
|
|
||||||
|
def populate_param(self,
|
||||||
|
param,
|
||||||
|
):
|
||||||
|
if param.attrib['type'] == 'string':
|
||||||
|
return f'ParamValue("{param.text}")'
|
||||||
|
elif param.attrib['type'] == 'number':
|
||||||
|
return f'ParamValue({param.text})'
|
||||||
|
elif param.attrib['type'] == 'variable':
|
||||||
|
value = {'option': param.text,
|
||||||
|
'notraisepropertyerror': convert_boolean(param.attrib['notraisepropertyerror']),
|
||||||
|
'todict': param.text in FUNC_TO_DICT,
|
||||||
|
}
|
||||||
|
if 'suffix' in param.attrib:
|
||||||
|
value['suffix'] = param.attrib['suffix']
|
||||||
|
return self.build_param(value)
|
||||||
|
raise LoaderError(_('unknown param type {}').format(param.attrib['type']))
|
||||||
|
|
||||||
|
def populate_value(self,
|
||||||
|
child,
|
||||||
|
):
|
||||||
|
value = convert_tiramisu_value(child.text, child.attrib['type'])
|
||||||
|
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):
|
||||||
|
self.attrib['default'].append(value)
|
||||||
|
else:
|
||||||
|
self.attrib['default'].append("'" + value + "'")
|
||||||
|
|
||||||
|
def build_param(self,
|
||||||
|
param,
|
||||||
|
):
|
||||||
|
option_name = self.storage.get(param['option']).get()
|
||||||
|
if 'suffix' in param:
|
||||||
|
family = '.'.join(param['option'].split('.')[:-1])
|
||||||
|
family_option = self.storage.get_name(family)
|
||||||
|
return f"ParamDynOption({option_name}, '{param['suffix']}', {family_option}, notraisepropertyerror={param['notraisepropertyerror']}, todict={param['todict']})"
|
||||||
|
return f"ParamOption({option_name}, notraisepropertyerror={param['notraisepropertyerror']}, todict={param['todict']})"
|
||||||
|
|
||||||
|
|
||||||
class Family(Common):
|
class Family(Common):
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
elt,
|
elt,
|
||||||
booleans,
|
|
||||||
storage,
|
storage,
|
||||||
eosfunc,
|
is_leader,
|
||||||
|
path,
|
||||||
):
|
):
|
||||||
self.option = None
|
super().__init__(elt,
|
||||||
self.attrib = {}
|
storage,
|
||||||
self.is_leader = False
|
is_leader,
|
||||||
self.informations = {}
|
path,
|
||||||
|
)
|
||||||
self.children = []
|
self.children = []
|
||||||
self.storage = storage
|
self.elt = elt
|
||||||
self.eosfunc = eosfunc
|
|
||||||
self.attrib['properties'] = []
|
|
||||||
for key, value in elt.attrib.items():
|
|
||||||
if key == 'help':
|
|
||||||
self.add_information(key, value)
|
|
||||||
else:
|
|
||||||
self.attrib[key] = value
|
|
||||||
|
|
||||||
def add(self, child):
|
def add(self, child):
|
||||||
self.children.append(child)
|
self.children.append(child)
|
||||||
|
|
||||||
def add_information(self, key, value):
|
|
||||||
if key in self.informations and not (key == 'icon' and self.informations[key] is None):
|
|
||||||
raise CreoleLoaderError(_('key already exists in information {}').format(key))
|
|
||||||
self.informations[key] = value
|
|
||||||
|
|
||||||
def set_leader(self):
|
|
||||||
self.is_leader = True
|
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
if self.option is None:
|
if not self.option_name:
|
||||||
self.attrib['children'] = []
|
self.populate_attrib()
|
||||||
for child in self.children:
|
self.parse_children()
|
||||||
self.attrib['children'].append(child.get())
|
self.option_name = self.storage.get_name(self.path)
|
||||||
self.build_properties()
|
object_name = self.get_object_name()
|
||||||
try:
|
attrib = self.get_attrib(self.attrib) + ', children=[' + ', '.join([child.get() for child in self.children]) + ']'
|
||||||
if 'dynamic' in self.attrib:
|
self.storage.text.append(f'{self.option_name} = {object_name}({attrib})')
|
||||||
dynamic = self.storage.get(self.attrib['dynamic']).get()
|
self.populate_informations()
|
||||||
del self.attrib['dynamic']
|
return self.option_name
|
||||||
self.attrib['suffixes'] = Calculation(self.eosfunc.calc_value,
|
|
||||||
Params((ParamOption(dynamic),)))
|
def populate_attrib(self):
|
||||||
option = ConvertDynOptionDescription(**self.attrib)
|
for key, value in self.elt.attrib.items():
|
||||||
elif not self.is_leader:
|
if key == 'help':
|
||||||
option = OptionDescription(**self.attrib)
|
self.informations[key] = value
|
||||||
else:
|
elif key == 'dynamic':
|
||||||
option = Leadership(**self.attrib)
|
dynamic = self.storage.get(value).get()
|
||||||
except Exception as err:
|
self.attrib['suffixes'] = f"Calculation(func.calc_value, Params((ParamOption({dynamic}))))"
|
||||||
print(self.attrib)
|
else:
|
||||||
raise CreoleLoaderError(_('cannot create optiondescription "{}": {}').format(self.attrib['name'], err))
|
self.attrib[key] = value
|
||||||
for key, value in self.informations.items():
|
|
||||||
option.impl_set_information(key, value)
|
def parse_children(self):
|
||||||
self.option = option
|
self.attrib['properties'] = ''
|
||||||
return self.option
|
for child in self.elt:
|
||||||
|
if child.tag == 'property':
|
||||||
|
self.populate_properties(child)
|
||||||
|
if not self.attrib['properties']:
|
||||||
|
del self.attrib['properties']
|
||||||
|
|
||||||
|
def get_object_name(self):
|
||||||
|
if 'suffixes' in self.attrib:
|
||||||
|
return 'ConvertDynOptionDescription'
|
||||||
|
elif not self.is_leader:
|
||||||
|
return 'OptionDescription'
|
||||||
|
return 'Leadership'
|
||||||
|
|
||||||
|
|
||||||
def load(xmlroot: str,
|
def load(xmlroot: str,
|
||||||
dtd_path: str,
|
|
||||||
funcs_path: str):
|
funcs_path: str):
|
||||||
tiramisu_objects = PopulateTiramisuObjects()
|
tiramisu_objects = PopulateTiramisuObjects(xmlroot,
|
||||||
tiramisu_objects.parse_dtd(dtd_path)
|
funcs_path,
|
||||||
tiramisu_objects.make_tiramisu_objects(xmlroot,
|
)
|
||||||
funcs_path)
|
return tiramisu_objects.get_text()
|
||||||
return tiramisu_objects.storage.paths['.'].get()
|
|
||||||
|
|
|
@ -28,17 +28,18 @@ from lxml.etree import Element, SubElement # pylint: disable=E0611
|
||||||
|
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
from .xmlreflector import XMLReflector, HIGH_COMPATIBILITY
|
from .xmlreflector import XMLReflector, HIGH_COMPATIBILITY
|
||||||
from .annotator import ERASED_ATTRIBUTES, VARIABLE_NAMESPACE, ServiceAnnotator, SpaceAnnotator
|
from .annotator import ERASED_ATTRIBUTES, ServiceAnnotator, SpaceAnnotator
|
||||||
from .utils import normalize_family
|
from .utils import normalize_family
|
||||||
from .error import CreoleOperationError, SpaceObjShallNotBeUpdated, CreoleDictConsistencyError
|
from .error import OperationError, SpaceObjShallNotBeUpdated, DictConsistencyError
|
||||||
from .path import Path
|
from .path import Path
|
||||||
|
from .config import variable_namespace
|
||||||
|
|
||||||
# CreoleObjSpace's elements like 'family' or 'follower', that shall be forced to the Redefinable type
|
# CreoleObjSpace's elements like 'family' or 'follower', that shall be forced to the Redefinable type
|
||||||
FORCE_REDEFINABLES = ('family', 'follower', 'service', 'disknod', 'variables')
|
FORCE_REDEFINABLES = ('family', 'follower', 'service', 'disknod', 'variables')
|
||||||
# CreoleObjSpace's elements that shall be forced to the UnRedefinable type
|
# CreoleObjSpace's elements that shall be forced to the UnRedefinable type
|
||||||
FORCE_UNREDEFINABLES = ('value',)
|
FORCE_UNREDEFINABLES = ('value',)
|
||||||
# CreoleObjSpace's elements that shall be set to the UnRedefinable type
|
# CreoleObjSpace's elements that shall be set to the UnRedefinable type
|
||||||
UNREDEFINABLE = ('submulti', 'multi', 'type')
|
UNREDEFINABLE = ('multi', 'type')
|
||||||
|
|
||||||
PROPERTIES = ('hidden', 'frozen', 'auto_freeze', 'auto_save', 'force_default_on_freeze',
|
PROPERTIES = ('hidden', 'frozen', 'auto_freeze', 'auto_save', 'force_default_on_freeze',
|
||||||
'force_store_value', 'disabled', 'mandatory')
|
'force_store_value', 'disabled', 'mandatory')
|
||||||
|
@ -46,17 +47,14 @@ CONVERT_PROPERTIES = {'auto_save': ['force_store_value'], 'auto_freeze': ['force
|
||||||
|
|
||||||
RENAME_ATTIBUTES = {'description': 'doc'}
|
RENAME_ATTIBUTES = {'description': 'doc'}
|
||||||
|
|
||||||
INCOMPATIBLE_ATTRIBUTES = [['multi', 'submulti']]
|
|
||||||
FORCED_TEXT_ELTS_AS_NAME = ('choice', 'property', 'value', 'target')
|
FORCED_TEXT_ELTS_AS_NAME = ('choice', 'property', 'value', 'target')
|
||||||
|
|
||||||
CONVERT_EXPORT = {'Leadership': 'leader',
|
CONVERT_EXPORT = {'Leadership': 'leader',
|
||||||
'Separators': 'separators',
|
|
||||||
'Variable': 'variable',
|
'Variable': 'variable',
|
||||||
'Value': 'value',
|
'Value': 'value',
|
||||||
'Property': 'property',
|
'Property': 'property',
|
||||||
'Choice': 'choice',
|
'Choice': 'choice',
|
||||||
'Param': 'param',
|
'Param': 'param',
|
||||||
'Separator': 'separator',
|
|
||||||
'Check': 'check',
|
'Check': 'check',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +179,7 @@ class CreoleObjSpace:
|
||||||
continue
|
continue
|
||||||
if child.tag == 'family':
|
if child.tag == 'family':
|
||||||
if child.attrib['name'] in family_names:
|
if child.attrib['name'] in family_names:
|
||||||
raise CreoleDictConsistencyError(_('Family {} is set several times').format(child.attrib['name']))
|
raise DictConsistencyError(_('Family {} is set several times').format(child.attrib['name']))
|
||||||
family_names.append(child.attrib['name'])
|
family_names.append(child.attrib['name'])
|
||||||
if child.tag == 'variables':
|
if child.tag == 'variables':
|
||||||
child.attrib['name'] = namespace
|
child.attrib['name'] = namespace
|
||||||
|
@ -299,12 +297,12 @@ class CreoleObjSpace:
|
||||||
)
|
)
|
||||||
elif exists is False:
|
elif exists is False:
|
||||||
raise SpaceObjShallNotBeUpdated()
|
raise SpaceObjShallNotBeUpdated()
|
||||||
raise CreoleDictConsistencyError(_(f'Already present in another XML file, {name} cannot be re-created'))
|
raise DictConsistencyError(_(f'Already present in another XML file, {name} cannot be re-created'))
|
||||||
redefine = self.convert_boolean(subspace.get('redefine', False))
|
redefine = self.convert_boolean(subspace.get('redefine', False))
|
||||||
exists = self.convert_boolean(subspace.get('exists', False))
|
exists = self.convert_boolean(subspace.get('exists', False))
|
||||||
if redefine is False or exists is True:
|
if redefine is False or exists is True:
|
||||||
return getattr(self, child.tag)()
|
return getattr(self, child.tag)()
|
||||||
raise CreoleDictConsistencyError(_(f'Redefined object: {name} does not exist yet'))
|
raise DictConsistencyError(_(f'Redefined object: {name} does not exist yet'))
|
||||||
|
|
||||||
def create_tree_structure(self,
|
def create_tree_structure(self,
|
||||||
space,
|
space,
|
||||||
|
@ -328,12 +326,12 @@ class CreoleObjSpace:
|
||||||
elif isinstance(variableobj, self.UnRedefinable):
|
elif isinstance(variableobj, self.UnRedefinable):
|
||||||
setattr(space, child.tag, [])
|
setattr(space, child.tag, [])
|
||||||
elif not isinstance(variableobj, self.Atom): # pragma: no cover
|
elif not isinstance(variableobj, self.Atom): # pragma: no cover
|
||||||
raise CreoleOperationError(_("Creole object {} "
|
raise OperationError(_("Creole object {} "
|
||||||
"has a wrong type").format(type(variableobj)))
|
"has a wrong type").format(type(variableobj)))
|
||||||
|
|
||||||
def is_already_exists(self, name, space, child, namespace):
|
def is_already_exists(self, name, space, child, namespace):
|
||||||
if isinstance(space, self.family): # pylint: disable=E1101
|
if isinstance(space, self.family): # pylint: disable=E1101
|
||||||
if namespace != VARIABLE_NAMESPACE:
|
if namespace != variable_namespace:
|
||||||
name = space.path + '.' + name
|
name = space.path + '.' + name
|
||||||
return self.paths.path_is_defined(name)
|
return self.paths.path_is_defined(name)
|
||||||
if child.tag == 'family':
|
if child.tag == 'family':
|
||||||
|
@ -366,14 +364,14 @@ class CreoleObjSpace:
|
||||||
else:
|
else:
|
||||||
norm_name = name
|
norm_name = name
|
||||||
return getattr(family, variable.tag)[norm_name]
|
return getattr(family, variable.tag)[norm_name]
|
||||||
if namespace == VARIABLE_NAMESPACE:
|
if namespace == variable_namespace:
|
||||||
path = name
|
path = name
|
||||||
else:
|
else:
|
||||||
path = family.path + '.' + name
|
path = family.path + '.' + name
|
||||||
old_family_name = self.paths.get_variable_family_name(path)
|
old_family_name = self.paths.get_variable_family_name(path)
|
||||||
if normalize_family(family.name) == old_family_name:
|
if normalize_family(family.name) == old_family_name:
|
||||||
return getattr(family, variable.tag)[name]
|
return getattr(family, variable.tag)[name]
|
||||||
old_family = self.space.variables[VARIABLE_NAMESPACE].family[old_family_name] # pylint: disable=E1101
|
old_family = self.space.variables[variable_namespace].family[old_family_name] # pylint: disable=E1101
|
||||||
variable_obj = old_family.variable[name]
|
variable_obj = old_family.variable[name]
|
||||||
del old_family.variable[name]
|
del old_family.variable[name]
|
||||||
if 'variable' not in vars(family):
|
if 'variable' not in vars(family):
|
||||||
|
@ -455,19 +453,12 @@ class CreoleObjSpace:
|
||||||
# UNREDEFINABLE concerns only 'variable' node so we can fix name
|
# UNREDEFINABLE concerns only 'variable' node so we can fix name
|
||||||
# to child.attrib['name']
|
# to child.attrib['name']
|
||||||
name = child.attrib['name']
|
name = child.attrib['name']
|
||||||
raise CreoleDictConsistencyError(_(f'cannot redefine attribute {attr} for variable {name}'))
|
raise DictConsistencyError(_(f'cannot redefine attribute {attr} for variable {name}'))
|
||||||
if attr in self.booleans_attributs:
|
if attr in self.booleans_attributs:
|
||||||
val = self.convert_boolean(val)
|
val = self.convert_boolean(val)
|
||||||
if not (attr == 'name' and getattr(variableobj, 'name', None) != None):
|
if not (attr == 'name' and getattr(variableobj, 'name', None) != None):
|
||||||
setattr(variableobj, attr, val)
|
setattr(variableobj, attr, val)
|
||||||
keys = list(vars(variableobj).keys())
|
keys = list(vars(variableobj).keys())
|
||||||
for incompatible in INCOMPATIBLE_ATTRIBUTES:
|
|
||||||
found = False
|
|
||||||
for inc in incompatible:
|
|
||||||
if inc in keys:
|
|
||||||
if found:
|
|
||||||
raise CreoleDictConsistencyError(_('those attributes are incompatible {}').format(incompatible))
|
|
||||||
found = True
|
|
||||||
|
|
||||||
def variableobj_tree_visitor(self,
|
def variableobj_tree_visitor(self,
|
||||||
child,
|
child,
|
||||||
|
@ -514,7 +505,7 @@ class CreoleObjSpace:
|
||||||
document.attrib.get('dynamic') != None,
|
document.attrib.get('dynamic') != None,
|
||||||
variableobj)
|
variableobj)
|
||||||
if child.attrib.get('redefine', 'False') == 'True':
|
if child.attrib.get('redefine', 'False') == 'True':
|
||||||
if namespace == VARIABLE_NAMESPACE:
|
if namespace == variable_namespace:
|
||||||
self.redefine_variables.append(child.attrib['name'])
|
self.redefine_variables.append(child.attrib['name'])
|
||||||
else:
|
else:
|
||||||
self.redefine_variables.append(namespace + '.' + family_name + '.' +
|
self.redefine_variables.append(namespace + '.' + family_name + '.' +
|
||||||
|
@ -522,7 +513,7 @@ class CreoleObjSpace:
|
||||||
|
|
||||||
elif child.tag == 'family':
|
elif child.tag == 'family':
|
||||||
family_name = normalize_family(child.attrib['name'])
|
family_name = normalize_family(child.attrib['name'])
|
||||||
if namespace != VARIABLE_NAMESPACE:
|
if namespace != variable_namespace:
|
||||||
family_name = namespace + '.' + family_name
|
family_name = namespace + '.' + family_name
|
||||||
self.paths.add_family(namespace,
|
self.paths.add_family(namespace,
|
||||||
family_name,
|
family_name,
|
||||||
|
@ -600,7 +591,7 @@ class CreoleObjSpace:
|
||||||
def _xml_export(self,
|
def _xml_export(self,
|
||||||
node,
|
node,
|
||||||
space,
|
space,
|
||||||
node_name=VARIABLE_NAMESPACE,
|
node_name=variable_namespace,
|
||||||
):
|
):
|
||||||
for name in self.get_attributes(space):
|
for name in self.get_attributes(space):
|
||||||
subspace = getattr(space, name)
|
subspace = getattr(space, name)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
from .utils import normalize_family
|
from .utils import normalize_family
|
||||||
from .error import CreoleOperationError, CreoleDictConsistencyError
|
from .error import OperationError, DictConsistencyError
|
||||||
from .annotator import VARIABLE_NAMESPACE
|
from .config import variable_namespace
|
||||||
|
|
||||||
|
|
||||||
class Path:
|
class Path:
|
||||||
|
@ -30,13 +30,13 @@ class Path:
|
||||||
current_namespace: str,
|
current_namespace: str,
|
||||||
) -> str: # pylint: disable=C0111
|
) -> str: # pylint: disable=C0111
|
||||||
if current_namespace is None: # pragma: no cover
|
if current_namespace is None: # pragma: no cover
|
||||||
raise CreoleOperationError('current_namespace must not be None')
|
raise OperationError('current_namespace must not be None')
|
||||||
dico = self.families[normalize_family(name,
|
dico = self.families[normalize_family(name,
|
||||||
check_name=False,
|
check_name=False,
|
||||||
allow_dot=True,
|
allow_dot=True,
|
||||||
)]
|
)]
|
||||||
if dico['namespace'] != VARIABLE_NAMESPACE and current_namespace != dico['namespace']:
|
if dico['namespace'] != variable_namespace and current_namespace != dico['namespace']:
|
||||||
raise CreoleDictConsistencyError(_('A family located in the {} namespace '
|
raise DictConsistencyError(_('A family located in the {} namespace '
|
||||||
'shall not be used in the {} namespace').format(
|
'shall not be used in the {} namespace').format(
|
||||||
dico['namespace'], current_namespace))
|
dico['namespace'], current_namespace))
|
||||||
path = dico['name']
|
path = dico['name']
|
||||||
|
@ -48,7 +48,7 @@ class Path:
|
||||||
name: str,
|
name: str,
|
||||||
) -> 'Family': # pylint: disable=C0111
|
) -> 'Family': # pylint: disable=C0111
|
||||||
if name not in self.families:
|
if name not in self.families:
|
||||||
raise CreoleDictConsistencyError(_('unknown family {}').format(name))
|
raise DictConsistencyError(_('unknown family {}').format(name))
|
||||||
dico = self.families[name]
|
dico = self.families[name]
|
||||||
return dico['variableobj']
|
return dico['variableobj']
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ class Path:
|
||||||
name: str,
|
name: str,
|
||||||
leader_name: str,
|
leader_name: str,
|
||||||
) -> None: # pylint: disable=C0111
|
) -> None: # pylint: disable=C0111
|
||||||
if namespace != VARIABLE_NAMESPACE:
|
if namespace != variable_namespace:
|
||||||
# need rebuild path and move object in new path
|
# need rebuild path and move object in new path
|
||||||
old_path = namespace + '.' + leader_family_name + '.' + name
|
old_path = namespace + '.' + leader_family_name + '.' + name
|
||||||
dico = self._get_variable(old_path)
|
dico = self._get_variable(old_path)
|
||||||
|
@ -74,7 +74,7 @@ class Path:
|
||||||
name = new_path
|
name = new_path
|
||||||
dico = self._get_variable(name)
|
dico = self._get_variable(name)
|
||||||
if dico['leader'] != None:
|
if dico['leader'] != None:
|
||||||
raise CreoleDictConsistencyError(_('Already defined leader {} for variable'
|
raise DictConsistencyError(_('Already defined leader {} for variable'
|
||||||
' {}'.format(dico['leader'], name)))
|
' {}'.format(dico['leader'], name)))
|
||||||
dico['leader'] = leader_name
|
dico['leader'] = leader_name
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ class Path:
|
||||||
is_dynamic: bool,
|
is_dynamic: bool,
|
||||||
variableobj,
|
variableobj,
|
||||||
) -> str: # pylint: disable=C0111
|
) -> str: # pylint: disable=C0111
|
||||||
if namespace == VARIABLE_NAMESPACE or '.' in name:
|
if namespace == variable_namespace or '.' in name:
|
||||||
varname = name
|
varname = name
|
||||||
else:
|
else:
|
||||||
varname = '.'.join([namespace, family, name])
|
varname = '.'.join([namespace, family, name])
|
||||||
|
@ -127,7 +127,7 @@ class Path:
|
||||||
with_suffix: bool=False,
|
with_suffix: bool=False,
|
||||||
) -> str: # pylint: disable=C0111
|
) -> str: # pylint: disable=C0111
|
||||||
if current_namespace is None: # pragma: no cover
|
if current_namespace is None: # pragma: no cover
|
||||||
raise CreoleOperationError('current_namespace must not be None')
|
raise OperationError('current_namespace must not be None')
|
||||||
if with_suffix:
|
if with_suffix:
|
||||||
dico, suffix = self._get_variable(name,
|
dico, suffix = self._get_variable(name,
|
||||||
with_suffix=True,
|
with_suffix=True,
|
||||||
|
@ -135,8 +135,8 @@ class Path:
|
||||||
else:
|
else:
|
||||||
dico = self._get_variable(name)
|
dico = self._get_variable(name)
|
||||||
if not allow_source:
|
if not allow_source:
|
||||||
if dico['namespace'] not in [VARIABLE_NAMESPACE, 'services'] and current_namespace != dico['namespace']:
|
if dico['namespace'] not in [variable_namespace, 'services'] and current_namespace != dico['namespace']:
|
||||||
raise CreoleDictConsistencyError(_('A variable located in the {} namespace '
|
raise DictConsistencyError(_('A variable located in the {} namespace '
|
||||||
'shall not be used in the {} namespace').format(
|
'shall not be used in the {} namespace').format(
|
||||||
dico['namespace'], current_namespace))
|
dico['namespace'], current_namespace))
|
||||||
if '.' in dico['name']:
|
if '.' in dico['name']:
|
||||||
|
@ -161,13 +161,13 @@ class Path:
|
||||||
with_suffix: bool=False,
|
with_suffix: bool=False,
|
||||||
) -> str:
|
) -> str:
|
||||||
if name not in self.variables:
|
if name not in self.variables:
|
||||||
if name.startswith(f'{VARIABLE_NAMESPACE}.'):
|
if name.startswith(f'{variable_namespace}.'):
|
||||||
name = name.split('.')[-1]
|
name = name.split('.')[-1]
|
||||||
if name not in self.variables:
|
if name not in self.variables:
|
||||||
for var_name, variable in self.variables.items():
|
for var_name, variable in self.variables.items():
|
||||||
if variable['is_dynamic'] and name.startswith(var_name):
|
if variable['is_dynamic'] and name.startswith(var_name):
|
||||||
return variable, name[len(var_name):]
|
return variable, name[len(var_name):]
|
||||||
raise CreoleDictConsistencyError(_('unknown option {}').format(name))
|
raise DictConsistencyError(_('unknown option {}').format(name))
|
||||||
if with_suffix:
|
if with_suffix:
|
||||||
return self.variables[name], None
|
return self.variables[name], None
|
||||||
return self.variables[name]
|
return self.variables[name]
|
||||||
|
|
|
@ -18,8 +18,7 @@ from Cheetah.NameMapper import NotFound as CheetahNotFound
|
||||||
from tiramisu import Config
|
from tiramisu import Config
|
||||||
from tiramisu.error import PropertiesOptionError
|
from tiramisu.error import PropertiesOptionError
|
||||||
|
|
||||||
from .annotator import VARIABLE_NAMESPACE
|
from .config import patch_dir, variable_namespace
|
||||||
from .config import patch_dir
|
|
||||||
from .error import FileNotFound, TemplateError
|
from .error import FileNotFound, TemplateError
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
from .utils import normalize_family
|
from .utils import normalize_family
|
||||||
|
@ -373,7 +372,7 @@ class CreoleTemplateEngine:
|
||||||
"""
|
"""
|
||||||
for option in await self.config.option.list(type='all'):
|
for option in await self.config.option.list(type='all'):
|
||||||
namespace = await option.option.name()
|
namespace = await option.option.name()
|
||||||
if namespace == VARIABLE_NAMESPACE:
|
if namespace == variable_namespace:
|
||||||
await self.load_eole_variables_rougail(option)
|
await self.load_eole_variables_rougail(option)
|
||||||
else:
|
else:
|
||||||
families = await self.load_eole_variables(namespace,
|
families = await self.load_eole_variables(namespace,
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
from tiramisu import DynOptionDescription
|
||||||
|
from .utils import normalize_family
|
||||||
|
|
||||||
|
|
||||||
|
class ConvertDynOptionDescription(DynOptionDescription):
|
||||||
|
def convert_suffix_to_path(self, suffix):
|
||||||
|
if not isinstance(suffix, str):
|
||||||
|
suffix = str(suffix)
|
||||||
|
return normalize_family(suffix,
|
||||||
|
check_name=False)
|
|
@ -6,7 +6,7 @@ from os import listdir
|
||||||
from lxml.etree import DTD, parse, tostring # , XMLParser
|
from lxml.etree import DTD, parse, tostring # , XMLParser
|
||||||
|
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
from .error import CreoleDictConsistencyError
|
from .error import DictConsistencyError
|
||||||
|
|
||||||
HIGH_COMPATIBILITY = True
|
HIGH_COMPATIBILITY = True
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ class XMLReflector(object):
|
||||||
# document = parse(BytesIO(xmlfile), XMLParser(remove_blank_text=True))
|
# document = parse(BytesIO(xmlfile), XMLParser(remove_blank_text=True))
|
||||||
document = parse(xmlfile)
|
document = parse(xmlfile)
|
||||||
if not self.dtd.validate(document):
|
if not self.dtd.validate(document):
|
||||||
raise CreoleDictConsistencyError(_("not a valid xml file: {}").format(xmlfile))
|
raise DictConsistencyError(_("not a valid xml file: {}").format(xmlfile))
|
||||||
return document.getroot()
|
return document.getroot()
|
||||||
|
|
||||||
def load_xml_from_folders(self, xmlfolders):
|
def load_xml_from_folders(self, xmlfolders):
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_2 = OptionDescription(doc='tata', name='tata', children=[])
|
||||||
|
option_1 = OptionDescription(name='services', doc='services', properties=frozenset(['hidden']), children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -21,6 +21,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_4 = ChoiceOption(properties=frozenset(['mandatory', 'normal']), doc='No change', multi=False, name='module_instancie', default='non', values=('oui', 'non'))
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_store_value', 'auto_freeze', 'mandatory', 'basic', Calculation(calc_value, Params(ParamValue('auto_frozen'), kwargs={'condition': ParamOption(option_4, todict=True), 'expected': ParamValue('oui'), 'reverse_condition': ParamValue(True)}))]), doc='No change', multi=False, name='mode_conteneur_actif', default='non', values=('oui', 'non'))
|
||||||
|
option_2 = OptionDescription(doc='général', name='general', properties=frozenset(['basic']), children=[option_3, option_4])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -21,6 +21,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_4 = ChoiceOption(properties=frozenset(['mandatory', 'normal']), doc='No change', multi=False, name='module_instancie', default='non', values=('oui', 'non'))
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_store_value', 'auto_freeze', 'mandatory', 'expert', Calculation(calc_value, Params(ParamValue('auto_frozen'), kwargs={'condition': ParamOption(option_4, todict=True), 'expected': ParamValue('oui'), 'reverse_condition': ParamValue(True)}))]), doc='No change', multi=False, name='mode_conteneur_actif', default='non', values=('oui', 'non'))
|
||||||
|
option_2 = OptionDescription(doc='général', name='general', properties=frozenset(['normal']), children=[option_3, option_4])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -12,6 +12,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_store_value', 'mandatory', 'basic']), doc='No change', multi=False, name='mode_conteneur_actif', default='non', values=('oui', 'non'))
|
||||||
|
option_2 = OptionDescription(doc='général', name='general', properties=frozenset(['basic']), children=[option_3])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -12,6 +12,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_store_value', 'mandatory', 'expert']), doc='No change', multi=False, name='mode_conteneur_actif', default='non', values=('oui', 'non'))
|
||||||
|
option_2 = OptionDescription(doc='général', name='general', properties=frozenset(['expert']), children=[option_3])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -14,6 +14,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif', default='non', values=('oui', 'non'))
|
||||||
|
option_2 = OptionDescription(doc='général', name='general', properties=frozenset(['normal']), children=[option_3])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -16,9 +16,8 @@
|
||||||
<variable doc="without_type" multi="False" name="without_type" type="string">
|
<variable doc="without_type" multi="False" name="without_type" type="string">
|
||||||
<property>mandatory</property>
|
<property>mandatory</property>
|
||||||
<property>normal</property>
|
<property>normal</property>
|
||||||
<value>non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif', default='non', values=('oui', 'non'))
|
||||||
|
option_4 = StrOption(properties=frozenset(['mandatory', 'normal']), doc='without_type', multi=False, name='without_type', default='non')
|
||||||
|
option_2 = OptionDescription(doc='général', name='general', properties=frozenset(['normal']), children=[option_3, option_4])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -14,6 +14,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif', default='non', values=('oui', 'non'))
|
||||||
|
option_2 = OptionDescription(doc='général', name='general', properties=frozenset(['normal']), children=[option_3])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -24,6 +24,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif', default='non', values=('oui', 'non'))
|
||||||
|
option_4 = ChoiceOption(properties=frozenset(['force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif1', default='non', values=('oui', 'non'))
|
||||||
|
option_2 = OptionDescription(doc='général', name='general', properties=frozenset(['normal']), children=[option_3, option_4])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -12,7 +12,7 @@
|
||||||
<property>mandatory</property>
|
<property>mandatory</property>
|
||||||
<property>normal</property>
|
<property>normal</property>
|
||||||
<value name="calc_val" type="calculation">
|
<value name="calc_val" type="calculation">
|
||||||
<param transitive="False" type="variable">rougail.general.mode_conteneur_actif1</param>
|
<param notraisepropertyerror="False" type="variable">rougail.general.mode_conteneur_actif1</param>
|
||||||
</value>
|
</value>
|
||||||
</variable>
|
</variable>
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
||||||
|
@ -23,6 +23,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_4 = ChoiceOption(properties=frozenset(['mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif1', default='non', values=('oui', 'non'))
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif', default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non'))
|
||||||
|
option_2 = OptionDescription(doc='general', name='general', properties=frozenset(['normal']), children=[option_3, option_4])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -21,6 +21,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif', default=Calculation(func.calc_val, Params((), kwargs={})), values=('oui', 'non'))
|
||||||
|
option_4 = ChoiceOption(properties=frozenset(['mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif1', default='non', values=('oui', 'non'))
|
||||||
|
option_2 = OptionDescription(doc='general', name='general', properties=frozenset(['normal']), children=[option_3, option_4])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -14,6 +14,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal']), doc='Redefine description', multi=True, name='mode_conteneur_actif', default=['non'], default_multi='non', values=('oui', 'non'))
|
||||||
|
option_2 = OptionDescription(doc='general', name='general', properties=frozenset(['normal']), children=[option_3])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -1 +0,0 @@
|
||||||
{"rougail.general.mode_conteneur_actif": [["non"]]}
|
|
|
@ -1,19 +0,0 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<rougail>
|
|
||||||
<family doc="rougail" name="rougail">
|
|
||||||
<family doc="general" name="general">
|
|
||||||
<property>normal</property>
|
|
||||||
<variable doc="Redefine description" multi="submulti" name="mode_conteneur_actif" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>force_default_on_freeze</property>
|
|
||||||
<property>frozen</property>
|
|
||||||
<property>hidden</property>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
</family>
|
|
||||||
<separators/>
|
|
||||||
</family>
|
|
||||||
</rougail>
|
|
|
@ -12,7 +12,7 @@
|
||||||
<property>basic</property>
|
<property>basic</property>
|
||||||
<property expected="oui" inverse="True" source="rougail.general.module_instancie" type="calculation">auto_frozen</property>
|
<property expected="oui" inverse="True" source="rougail.general.module_instancie" type="calculation">auto_frozen</property>
|
||||||
<value name="calc_val" type="calculation">
|
<value name="calc_val" type="calculation">
|
||||||
<param transitive="False" type="variable">rougail.general.mode_conteneur_actif1</param>
|
<param notraisepropertyerror="False" type="variable">rougail.general.mode_conteneur_actif1</param>
|
||||||
</value>
|
</value>
|
||||||
</variable>
|
</variable>
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
||||||
|
@ -30,6 +30,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_5 = ChoiceOption(properties=frozenset(['mandatory', 'normal']), doc='No change', multi=False, name='module_instancie', default='non', values=('oui', 'non'))
|
||||||
|
option_4 = ChoiceOption(properties=frozenset(['mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif1', default='non', values=('oui', 'non'))
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_store_value', 'auto_freeze', 'mandatory', 'basic', Calculation(calc_value, Params(ParamValue('auto_frozen'), kwargs={'condition': ParamOption(option_5, todict=True), 'expected': ParamValue('oui'), 'reverse_condition': ParamValue(True)}))]), doc='No change', multi=False, name='mode_conteneur_actif', default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non'))
|
||||||
|
option_2 = OptionDescription(doc='general', name='general', properties=frozenset(['basic']), children=[option_3, option_4, option_5])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -10,7 +10,7 @@
|
||||||
<property>mandatory</property>
|
<property>mandatory</property>
|
||||||
<property>basic</property>
|
<property>basic</property>
|
||||||
<value name="calc_val" type="calculation">
|
<value name="calc_val" type="calculation">
|
||||||
<param transitive="False" type="variable">rougail.general.mode_conteneur_actif1</param>
|
<param notraisepropertyerror="False" type="variable">rougail.general.mode_conteneur_actif1</param>
|
||||||
</value>
|
</value>
|
||||||
</variable>
|
</variable>
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
||||||
|
@ -21,6 +21,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_4 = ChoiceOption(properties=frozenset(['mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif1', default='non', values=('oui', 'non'))
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_store_value', 'mandatory', 'basic']), doc='No change', multi=False, name='mode_conteneur_actif', default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non'))
|
||||||
|
option_2 = OptionDescription(doc='general', name='general', properties=frozenset(['basic']), children=[option_3, option_4])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -12,7 +12,7 @@
|
||||||
<property>mandatory</property>
|
<property>mandatory</property>
|
||||||
<property>normal</property>
|
<property>normal</property>
|
||||||
<value name="calc_val" type="calculation">
|
<value name="calc_val" type="calculation">
|
||||||
<param transitive="False" type="variable">rougail.general.mode_conteneur_actif1</param>
|
<param notraisepropertyerror="False" type="variable">rougail.general.mode_conteneur_actif1</param>
|
||||||
</value>
|
</value>
|
||||||
</variable>
|
</variable>
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
||||||
|
@ -23,6 +23,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_4 = ChoiceOption(properties=frozenset(['mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif1', default='non', values=('oui', 'non'))
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif', default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non'))
|
||||||
|
option_2 = OptionDescription(doc='general', name='general', properties=frozenset(['normal']), children=[option_3, option_4])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -12,7 +12,7 @@
|
||||||
<property>mandatory</property>
|
<property>mandatory</property>
|
||||||
<property>normal</property>
|
<property>normal</property>
|
||||||
<value name="calc_val" type="calculation">
|
<value name="calc_val" type="calculation">
|
||||||
<param transitive="False" type="variable">rougail.general.mode_conteneur_actif1</param>
|
<param notraisepropertyerror="False" type="variable">rougail.general.mode_conteneur_actif1</param>
|
||||||
</value>
|
</value>
|
||||||
</variable>
|
</variable>
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
||||||
|
@ -23,6 +23,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_4 = ChoiceOption(properties=frozenset(['mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif1', default='non', values=('oui', 'non'))
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif', default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non'))
|
||||||
|
option_2 = OptionDescription(doc='Général', name='general', properties=frozenset(['normal']), children=[option_3, option_4])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -7,7 +7,7 @@
|
||||||
<property>mandatory</property>
|
<property>mandatory</property>
|
||||||
<property>expert</property>
|
<property>expert</property>
|
||||||
<value name="calc_val" type="calculation">
|
<value name="calc_val" type="calculation">
|
||||||
<param transitive="False" type="variable">rougail.general.mode_conteneur_actif1</param>
|
<param notraisepropertyerror="False" type="variable">rougail.general.mode_conteneur_actif1</param>
|
||||||
</value>
|
</value>
|
||||||
</variable>
|
</variable>
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
||||||
|
@ -18,6 +18,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_4 = ChoiceOption(properties=frozenset(['mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif1', default='non', values=('oui', 'non'))
|
||||||
|
option_3 = DomainnameOption(type='domainname', allow_ip=True, allow_without_dot=True, properties=frozenset(['mandatory', 'expert']), doc='No change', multi=False, name='mode_conteneur_actif', default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})))
|
||||||
|
option_2 = OptionDescription(doc='general', name='general', properties=frozenset(['normal']), children=[option_3, option_4])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -10,7 +10,7 @@
|
||||||
<property>mandatory</property>
|
<property>mandatory</property>
|
||||||
<property>normal</property>
|
<property>normal</property>
|
||||||
<value name="calc_val" type="calculation">
|
<value name="calc_val" type="calculation">
|
||||||
<param transitive="False" type="number">3</param>
|
<param type="number">3</param>
|
||||||
</value>
|
</value>
|
||||||
</variable>
|
</variable>
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
||||||
|
@ -21,6 +21,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_3 = IntOption(properties=frozenset(['force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif', default=Calculation(func.calc_val, Params((ParamValue(3)), kwargs={})))
|
||||||
|
option_4 = ChoiceOption(properties=frozenset(['mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif1', default='non', values=('oui', 'non'))
|
||||||
|
option_2 = OptionDescription(doc='general', name='general', properties=frozenset(['normal']), children=[option_3, option_4])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -12,7 +12,7 @@
|
||||||
<property>mandatory</property>
|
<property>mandatory</property>
|
||||||
<property>normal</property>
|
<property>normal</property>
|
||||||
<value name="calc_val" type="calculation">
|
<value name="calc_val" type="calculation">
|
||||||
<param transitive="False" type="variable">rougail.general.mode_conteneur_actif1</param>
|
<param notraisepropertyerror="False" type="variable">rougail.general.mode_conteneur_actif1</param>
|
||||||
</value>
|
</value>
|
||||||
</variable>
|
</variable>
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
||||||
|
@ -23,6 +23,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_4 = ChoiceOption(properties=frozenset(['mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif1', default='non', values=('oui', 'non'))
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif', default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non'))
|
||||||
|
option_2 = OptionDescription(doc='general', name='general', properties=frozenset(['normal']), children=[option_3, option_4])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -3,7 +3,7 @@
|
||||||
<family doc="rougail" name="rougail">
|
<family doc="rougail" name="rougail">
|
||||||
<family doc="general" name="general">
|
<family doc="general" name="general">
|
||||||
<property>normal</property>
|
<property>normal</property>
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif" type="choice">
|
<variable doc="No change" multi="False" name="mode_conteneur_actif" separator="Établissement" type="choice">
|
||||||
<choice type="string">oui</choice>
|
<choice type="string">oui</choice>
|
||||||
<choice type="string">non</choice>
|
<choice type="string">non</choice>
|
||||||
<property>force_default_on_freeze</property>
|
<property>force_default_on_freeze</property>
|
||||||
|
@ -14,8 +14,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators>
|
|
||||||
<separator name="rougail.general.mode_conteneur_actif">Établissement</separator>
|
|
||||||
</separators>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif', default='non', values=('oui', 'non'))
|
||||||
|
option_3.impl_set_information("separator", "Établissement")
|
||||||
|
option_2 = OptionDescription(doc='general', name='general', properties=frozenset(['normal']), children=[option_3])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -3,7 +3,7 @@
|
||||||
<family doc="rougail" name="rougail">
|
<family doc="rougail" name="rougail">
|
||||||
<family doc="general" name="general">
|
<family doc="general" name="general">
|
||||||
<property>normal</property>
|
<property>normal</property>
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif" type="choice">
|
<variable doc="No change" multi="False" name="mode_conteneur_actif" separator="Établissement" type="choice">
|
||||||
<choice type="string">oui</choice>
|
<choice type="string">oui</choice>
|
||||||
<choice type="string">non</choice>
|
<choice type="string">non</choice>
|
||||||
<property>force_default_on_freeze</property>
|
<property>force_default_on_freeze</property>
|
||||||
|
@ -14,8 +14,5 @@
|
||||||
<value type="string">non</value>
|
<value type="string">non</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators>
|
|
||||||
<separator name="rougail.general.mode_conteneur_actif">Établissement</separator>
|
|
||||||
</separators>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif', default='non', values=('oui', 'non'))
|
||||||
|
option_3.impl_set_information("separator", "Établissement")
|
||||||
|
option_2 = OptionDescription(doc='general', name='general', properties=frozenset(['normal']), children=[option_3])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -20,10 +20,9 @@
|
||||||
<property>mandatory</property>
|
<property>mandatory</property>
|
||||||
<property>basic</property>
|
<property>basic</property>
|
||||||
<value name="calc_val" type="calculation">
|
<value name="calc_val" type="calculation">
|
||||||
<param transitive="False" type="string">oui</param>
|
<param type="string">oui</param>
|
||||||
</value>
|
</value>
|
||||||
</variable>
|
</variable>
|
||||||
</family>
|
</family>
|
||||||
<separators/>
|
|
||||||
</family>
|
</family>
|
||||||
</rougail>
|
</rougail>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_3 = ChoiceOption(properties=frozenset(['force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal']), doc='No change', multi=False, name='mode_conteneur_actif', default='non', values=('oui', 'non'))
|
||||||
|
option_4 = StrOption(properties=frozenset(['force_store_value', 'frozen', 'hidden', 'mandatory', 'basic']), doc='autosave variable', multi=False, name='autosavevar', default=Calculation(func.calc_val, Params((ParamValue("oui")), kwargs={})))
|
||||||
|
option_2 = OptionDescription(doc='général', name='general', properties=frozenset(['basic']), children=[option_3, option_4])
|
||||||
|
option_1 = OptionDescription(doc='rougail', name='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue