WIP: Expand the developer documentation #27

Draft
gremond wants to merge 62 commits from develop into developer_docs
4 changed files with 41 additions and 22 deletions
Showing only changes of commit 04bf6a1d38 - Show all commits

View file

@ -83,11 +83,4 @@ class NotFoundError(Exception):
## ---- specific exceptions ----
class VariableCalculationDependencyError(Exception):
"""When an attribute is set, and
the target of this attribute doesn't exists.
"""
def __init__(self, msg, errno, xmlfiles):
if xmlfiles:
msg = _(f"{msg} in {display_xmlfiles(xmlfiles)}")
super().__init__(msg)
self.errno = errno
pass

View file

@ -293,6 +293,9 @@ class JinjaCalculation(Calculation):
"__internal_jinja": jinja_path,
"__internal_type": return_type,
"__internal_multi": multi,
"__internal_files": self.xmlfiles,
"__internal_attribute": self.attribute_name,
"__internal_variable": self.path,
},
}
if self.default_values:
@ -461,6 +464,8 @@ class _VariableCalculation(Calculation):
calc_variable_is_multi = True
else:
calc_variable_is_multi = True
elif suffix and '{{ suffix }}' in suffix:
calc_variable_is_multi = True
if needs_multi:
if calc_variable_is_multi:
if self.inside_list:
@ -473,8 +478,12 @@ class _VariableCalculation(Calculation):
msg = f'the variable "{self.path}" has an invalid attribute "{self.attribute_name}", it\'s a list'
raise DictConsistencyError(msg, 23, self.xmlfiles)
elif calc_variable_is_multi:
msg = f'the variable "{self.path}" has an invalid attribute "{self.attribute_name}", the variable "{variable.path}" is a multi'
raise DictConsistencyError(msg, 21, self.xmlfiles)
if variable.multi or variable.path.rsplit('.', 1)[0] != self.path.rsplit('.', 1)[0]:
# it's not a follower or not in same leadership
msg = f'the variable "{self.path}" has an invalid attribute "{self.attribute_name}", the variable "{variable.path}" is a multi'
raise DictConsistencyError(msg, 21, self.xmlfiles)
else:
params[None][0]['index'] = {'index': {'type': 'index'}}
return params
@ -486,13 +495,12 @@ class VariableCalculation(_VariableCalculation):
self,
objectspace,
) -> dict:
if self.attribute_name != "default" and self.optional is True:
if self.attribute_name != "default" and self.optional:
msg = f'"{self.attribute_name}" variable shall not have an "optional" attribute for variable "{self.variable}"'
raise DictConsistencyError(msg, 33, self.xmlfiles)
variable, suffix = self.get_variable(objectspace)
if not variable and self.optional:
msg = f'the dependent variable was not found "{self.optional}" for attribute "{self.attribute_name}" in variable "{self.path}"'
raise VariableCalculationDependencyError(msg, 90, self.xmlfiles)
raise VariableCalculationDependencyError()
params = self.get_params(objectspace,
variable,
suffix,
@ -728,6 +736,7 @@ class Variable(BaseModel):
path: str
namespace: Optional[str]
version: str
path_prefix: Optional[str]
xmlfiles: List[str] = []
model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True)
@ -740,6 +749,7 @@ class SymLink(BaseModel):
opt: Variable
namespace: Optional[str]
version: str
path_prefix: Optional[str]
xmlfiles: List[str] = []
model_config = ConfigDict(extra="forbid")

View file

@ -36,7 +36,8 @@ from importlib.util import spec_from_loader as _spec_from_loader, module_from_sp
from jinja2 import StrictUndefined, DictLoader
from jinja2.sandbox import SandboxedEnvironment
from rougail.object_model import CONVERT_OPTION
from tiramisu.error import ValueWarning
from rougail.error import display_xmlfiles
from tiramisu.error import ValueWarning, ConfigError
from .utils import normalize_family
@ -66,7 +67,7 @@ def rougail_calc_value(*args, __default_value=None, **kwargs):
return values
def jinja_to_function(__internal_jinja, __internal_type, __internal_multi, __default_value=None, **kwargs):
def jinja_to_function(__internal_variable, __internal_attribute, __internal_jinja, __internal_type, __internal_multi, __internal_files, __default_value=None, **kwargs):
global ENV, CONVERT_OPTION
kw = {}
for key, value in kwargs.items():
@ -77,15 +78,23 @@ def jinja_to_function(__internal_jinja, __internal_type, __internal_multi, __def
c_kw = c_kw.setdefault(subkey, {})
c_kw[var] = value
else:
if key in kw:
raise ConfigError(f'internal error, multi key for "{key}" in jinja_to_function')
kw[key] = value
values = ENV.get_template(__internal_jinja).render(kw, **func).strip()
try:
values = ENV.get_template(__internal_jinja).render(kw, **func).strip()
except Exception as err:
raise ConfigError(f'cannot calculating "{__internal_attribute}" attribute for variable "{__internal_variable}" in {display_xmlfiles(__internal_files)}: {err}') from err
convert = CONVERT_OPTION[__internal_type].get('func', str)
if __internal_multi:
values = [convert(val) for val in values.split()]
values = [convert(val) for val in values.split('\n') if val != ""]
if not values and __default_value is not None:
return __default_value
return values
values = convert(values)
try:
values = convert(values)
except Exception as err:
raise ConfigError(f'cannot converting "{__internal_attribute}" attribute for variable "{__internal_variable}" in {display_xmlfiles(__internal_files)}: {err}') from err
values = values if values != '' and values != 'None' else None
if values is None and __default_value is not None:
return __default_value

View file

@ -30,6 +30,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
from typing import List, Union
from unicodedata import normalize, combining
import re
from itertools import chain
from importlib.machinery import SourceFileLoader
from importlib.util import spec_from_loader, module_from_spec
@ -116,10 +117,10 @@ def get_jinja_variable_to_param(
for g in parsed_content.find_all(Getattr):
variables.add(recurse_getattr(g))
except TemplateSyntaxError as err:
msg = _(f'error in jinja "{jinja_text}": {err}')
raise Exception(msg) from err
msg = _(f'error in jinja "{jinja_text}" for the variable "{ current_path }": {err}')
raise DictConsistencyError(msg, 39, xmlfiles) from err
variables = list(variables)
variables.sort()
variables.sort(reverse=True)
founded_variables = {}
unknown_variables = []
for variable_path in variables:
@ -134,7 +135,13 @@ def get_jinja_variable_to_param(
if variable and variable.path in objectspace.variables:
founded_variables[variable_path] = (suffix, variable)
else:
unknown_variables.append(variable_path)
sub_family = variable_path + '.'
for founded_variable in chain(founded_variables, unknown_variables):
if founded_variable.startswith(sub_family):
break
else:
unknown_variables.append(variable_path)
for variable_path in unknown_variables:
for v in founded_variables:
if get_common_path(v, variable_path) == v: