rougail/src/rougail/annotator/param.py

155 lines
7.6 KiB
Python

"""Param annotator
Created by:
EOLE (http://eole.orion.education.fr)
Copyright (C) 2005-2018
Forked by:
Cadoles (http://www.cadoles.com)
Copyright (C) 2019-2021
distribued with GPL-2 or later license
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
try:
import tiramisu3 as tiramisu
except ModuleNotFoundError:
import tiramisu
from rougail.annotator.variable import CONVERT_OPTION
from rougail.i18n import _
from rougail.error import DictConsistencyError
class ParamAnnotator:
"""Param annotator
"""
objectspace = None
@staticmethod
def valid_type_validation(obj) -> None:
"""Function to valid type (redefine in fill/condition/check classes)
"""
return None
def convert_param(self, objects) -> None:
""" valid and convert param
"""
for obj in objects:
if not hasattr(obj, 'param'):
continue
param_to_delete = []
variable_type = self.valid_type_validation(obj)
for param_idx, param in enumerate(obj.param):
if hasattr(param, 'text'):
if param.type in ['suffix', 'index']:
msg = _(f'"{param.type}" parameter must not have a value')
raise DictConsistencyError(msg, 28, obj.xmlfiles)
if param.type in ['nil', 'space']:
if param.text is not None:
msg = _(f'"{param.type}" parameter must not have a value')
raise DictConsistencyError(msg, 40, obj.xmlfiles)
elif param.type == 'variable':
try:
path, suffix = self.objectspace.paths.get_variable_path(param.text,
obj.namespace,
param.xmlfiles,
)
param.text = self.objectspace.paths.get_variable(path)
if variable_type and param.text.type != variable_type:
msg = _(f'"{obj.name}" has type "{variable_type}" but param '
f'has type "{param.text.type}"')
raise DictConsistencyError(msg, 26, param.xmlfiles)
if suffix:
param.suffix = suffix
family_path = self.objectspace.paths.get_variable_family_path(path)
namespace = param.text.namespace
param.family = self.objectspace.paths.get_family(family_path,
namespace,
)
except DictConsistencyError as err:
if err.errno != 42 or not param.optional:
raise err
param_to_delete.append(param_idx)
elif param.type == 'function':
if not self.allow_function:
msg = _(f'cannot use "function" type')
raise DictConsistencyError(msg, 74, param.xmlfiles)
if not param.text in self.functions:
msg = _(f'cannot find function "{param.text}"')
raise DictConsistencyError(msg, 67, param.xmlfiles)
if param_idx != 0:
msg = _(f'function "{param.text}" must only set has first parameter')
raise DictConsistencyError(msg, 75, param.xmlfiles)
elif variable_type:
self._convert_with_variable_type(variable_type, param)
continue
# no param.text
if param.type == 'suffix':
for target in obj.target:
if not self.objectspace.paths.variable_is_dynamic(target.name.path):
target_name = target.name
if isinstance(target_name, self.objectspace.variable):
target_name = target_name.name
msg = _(f'"{param.type}" parameter cannot be set with target '
f'"{target_name}" which is not a dynamic variable')
raise DictConsistencyError(msg, 53, obj.xmlfiles)
elif param.type == 'index':
for target in obj.target:
if not self.objectspace.paths.is_follower(target.name.path):
msg = _(f'"{param.type}" parameter cannot be set with target '
f'"{target.name.name}" which is not a follower variable')
raise DictConsistencyError(msg, 60, obj.xmlfiles)
elif param.type == 'nil':
param.text = None
elif param.type == 'space':
param.type = 'string'
param.text = ' '
elif param.type == 'string':
param.text = ''
if variable_type:
self._convert_with_variable_type(variable_type, param)
else:
msg = _(f'"{param.type}" parameter must have a value')
raise DictConsistencyError(msg, 27, obj.xmlfiles)
param_to_delete.sort(reverse=True)
for param_idx in param_to_delete:
obj.param.pop(param_idx)
@staticmethod
def _convert_with_variable_type(variable_type: str,
param: 'self.objectspace.param',
) -> None:
if 'type' in vars(param) and variable_type != param.type:
msg = _(f'parameter has incompatible type "{param.type}" '
f'with type "{variable_type}"')
raise DictConsistencyError(msg, 7, param.xmlfiles)
if variable_type != 'choice':
try:
option = CONVERT_OPTION[variable_type]
param.text = option.get('func', str)(param.text)
getattr(tiramisu, option['opttype'])('test',
'Object to valid value',
param.text,
**option.get('initkwargs', {}),
)
except ValueError as err:
msg = _(f'unable to change type of value "{param.text}" '
f'is not a valid "{variable_type}"')
raise DictConsistencyError(msg, 13, param.xmlfiles) from err
param.type = variable_type