fix: black

This commit is contained in:
egarette@silique.fr 2025-11-06 21:33:24 +01:00
parent a68a52ad67
commit e674217b63
11 changed files with 150 additions and 90 deletions

View file

@ -147,12 +147,15 @@ class Annotator(Walk):
for tag in variable.tags: for tag in variable.tags:
self.check_tag(tag, variable.xmlfiles) self.check_tag(tag, variable.xmlfiles)
self.objectspace.properties.add(variable.path, tag, True) self.objectspace.properties.add(variable.path, tag, True)
self.objectspace.informations.add(variable.path, "tags", tuple(variable.tags)) self.objectspace.informations.add(
variable.path, "tags", tuple(variable.tags)
)
def check_tag(self, def check_tag(
tag: str, self,
xmlfiles: List[str], tag: str,
): xmlfiles: List[str],
):
match = NAME_REGEXP.search(tag) match = NAME_REGEXP.search(tag)
if not match: if not match:
msg = _( msg = _(

View file

@ -29,7 +29,13 @@ from tiramisu.error import display_list
from rougail.i18n import _ from rougail.i18n import _
from rougail.utils import calc_multi_for_type_variable from rougail.utils import calc_multi_for_type_variable
from rougail.error import DictConsistencyError from rougail.error import DictConsistencyError
from rougail.convert.object_model import Calculation, VariableCalculation, VariableParam, IndexCalculation, JinjaCalculation from rougail.convert.object_model import (
Calculation,
VariableCalculation,
VariableParam,
IndexCalculation,
JinjaCalculation,
)
from rougail.tiramisu import display_xmlfiles, RENAME_TYPE from rougail.tiramisu import display_xmlfiles, RENAME_TYPE
from warnings import warn from warnings import warn
@ -116,49 +122,54 @@ class Annotator(Walk): # pylint: disable=R0903
continue continue
if variable.type in RENAME_TYPE: if variable.type in RENAME_TYPE:
warning = f'the variable "{ variable.path }" has a depreciated type "{variable.type}", please use "{RENAME_TYPE[variable.type]}" instead in {display_xmlfiles(variable.xmlfiles)}' warning = f'the variable "{ variable.path }" has a depreciated type "{variable.type}", please use "{RENAME_TYPE[variable.type]}" instead in {display_xmlfiles(variable.xmlfiles)}'
warn(warning, warn(
DeprecationWarning, warning,
) DeprecationWarning,
)
variable.type = RENAME_TYPE[variable.type] variable.type = RENAME_TYPE[variable.type]
if variable.type == 'cidr': if variable.type == "cidr":
warning = f'the variable "{ variable.path }" has a depreciated type "{variable.type}", please use type "ip" with attribute cidr=True instead in {display_xmlfiles(variable.xmlfiles)}' warning = f'the variable "{ variable.path }" has a depreciated type "{variable.type}", please use type "ip" with attribute cidr=True instead in {display_xmlfiles(variable.xmlfiles)}'
warn(warning, warn(
DeprecationWarning, warning,
) DeprecationWarning,
if variable.type == 'network_cidr': )
if variable.type == "network_cidr":
warning = f'the variable "{ variable.path }" has a depreciated type "{variable.type}", please use type "network" with attribute cidr=True instead in {display_xmlfiles(variable.xmlfiles)}' warning = f'the variable "{ variable.path }" has a depreciated type "{variable.type}", please use type "network" with attribute cidr=True instead in {display_xmlfiles(variable.xmlfiles)}'
warn(warning, warn(
DeprecationWarning, warning,
) DeprecationWarning,
)
self.objectspace.informations.add( self.objectspace.informations.add(
variable.path, "ymlfiles", variable.xmlfiles variable.path, "ymlfiles", variable.xmlfiles
) )
if variable.version != "1.0" and variable.type is None: if variable.version != "1.0" and variable.type is None:
if isinstance( if isinstance(variable.default, IndexCalculation):
variable.default, IndexCalculation variable.type = "integer"
): elif isinstance(variable.default, VariableCalculation):
variable.type = 'integer'
elif isinstance(
variable.default, VariableCalculation
):
calculated_variable_path, calculated_variable, identifier = ( calculated_variable_path, calculated_variable, identifier = (
variable.default.get_variable(self.objectspace) variable.default.get_variable(self.objectspace)
) )
if calculated_variable is not None: if calculated_variable is not None:
self._default_variable_copy_informations(variable, calculated_variable) self._default_variable_copy_informations(
variable, calculated_variable
)
self._convert_variable(variable) self._convert_variable(variable)
if variable.multi and variable.params: if variable.multi and variable.params:
indexes_to_remove = [] indexes_to_remove = []
for idx, param in enumerate(variable.params): for idx, param in enumerate(variable.params):
if param.key == "multi_length": if param.key == "multi_length":
jinja = f'{{% if var | length != {param.value} %}}{_("{0} values needed, but there are {{{{ var | length }}}}").format(param.value)}{{% endif %}}' jinja = f'{{% if var | length != {param.value} %}}{_("{0} values needed, but there are {{{{ var | length }}}}").format(param.value)}{{% endif %}}'
description = _('needs exactly {0} values').format(param.value) description = _("needs exactly {0} values").format(param.value)
elif param.key == "multi_max_length": elif param.key == "multi_max_length":
jinja = f'{{% if var | length > {param.value} %}}{_("a maximum of {0} values are needed, but there are {{{{ var | length }}}}").format(param.value)}{{% endif %}}' jinja = f'{{% if var | length > {param.value} %}}{_("a maximum of {0} values are needed, but there are {{{{ var | length }}}}").format(param.value)}{{% endif %}}'
description = _('needs a maximum of {0} values').format(param.value) description = _("needs a maximum of {0} values").format(
param.value
)
elif param.key == "multi_min_length": elif param.key == "multi_min_length":
jinja = f'{{% if var | length < {param.value} %}}{_("a minimum of {0} values are needed, but there are {{{{ var | length }}}}").format(param.value)}{{% endif %}}' jinja = f'{{% if var | length < {param.value} %}}{_("a minimum of {0} values are needed, but there are {{{{ var | length }}}}").format(param.value)}{{% endif %}}'
description = _('needs a minimum of {0} values').format(param.value) description = _("needs a minimum of {0} values").format(
param.value
)
else: else:
continue continue
indexes_to_remove.append(idx) indexes_to_remove.append(idx)
@ -166,16 +177,29 @@ class Annotator(Walk): # pylint: disable=R0903
variable.validators = [] variable.validators = []
variable.validators.append( variable.validators.append(
JinjaCalculation(path=variable.path, JinjaCalculation(
inside_list=True, path=variable.path,
version=variable.version, inside_list=True,
xmlfiles=variable.xmlfiles, version=variable.version,
attribute_name="validators", xmlfiles=variable.xmlfiles,
namespace=variable.namespace, attribute_name="validators",
jinja=jinja, namespace=variable.namespace,
description=description, jinja=jinja,
params=[VariableParam(variable.path, "validators", False, variable.xmlfiles, key="var", namespace=variable.namespace, type="variable", variable=variable.path, whole=True)], description=description,
) params=[
VariableParam(
variable.path,
"validators",
False,
variable.xmlfiles,
key="var",
namespace=variable.namespace,
type="variable",
variable=variable.path,
whole=True,
)
],
)
) )
for idx in reversed(indexes_to_remove): for idx in reversed(indexes_to_remove):
variable.params.pop(idx) variable.params.pop(idx)
@ -221,9 +245,8 @@ class Annotator(Walk): # pylint: disable=R0903
and variable.path == calculated_variable.default.path and variable.path == calculated_variable.default.path
): ):
msg = _( msg = _(
'the "{0}" default value is a calculation with itself').format( 'the "{0}" default value is a calculation with itself'
variable.path ).format(variable.path)
)
raise DictConsistencyError(msg, 75, variable.xmlfiles) raise DictConsistencyError(msg, 75, variable.xmlfiles)
self._convert_variable_multi(calculated_variable) self._convert_variable_multi(calculated_variable)
variable.multi = calc_multi_for_type_variable( variable.multi = calc_multi_for_type_variable(

View file

@ -25,6 +25,7 @@ details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
from pathlib import Path from pathlib import Path
from tiramisu import Config from tiramisu import Config
from ruamel.yaml import YAML from ruamel.yaml import YAML
@ -165,7 +166,8 @@ class _RougailConfig:
return ret return ret
def __contains__( def __contains__(
self, key, self,
key,
) -> None: ) -> None:
try: try:
self.__getitem__(key) self.__getitem__(key)
@ -204,7 +206,7 @@ class _RougailConfig:
return values return values
class RConfigLeadership(): class RConfigLeadership:
def __init__(self, config, option, leader, followers): def __init__(self, config, option, leader, followers):
self.config = config self.config = config
self.option = option self.option = option
@ -220,11 +222,11 @@ class RConfigLeadership():
value, value,
) -> None: ) -> None:
self.config.property.read_write() self.config.property.read_write()
names = self.option.option('names') names = self.option.option("names")
leader = names.value.get() leader = names.value.get()
leader.append(key) leader.append(key)
names.value.set(leader) names.value.set(leader)
directories = self.option.option('directories', len(leader) - 1) directories = self.option.option("directories", len(leader) - 1)
directories.value.set(value) directories.value.set(value)
self.leader.append(key) self.leader.append(key)
self.followers.append(value) self.followers.append(value)

View file

@ -161,7 +161,7 @@ class ParserVariable:
def load_config(self) -> None: def load_config(self) -> None:
rougailconfig = self.rougailconfig rougailconfig = self.rougailconfig
self.suffix = rougailconfig["suffix"] self.suffix = rougailconfig["suffix"]
self.default_structural_format_version= rougailconfig[ self.default_structural_format_version = rougailconfig[
"default_structural_format_version" "default_structural_format_version"
] ]
self.custom_types = rougailconfig["custom_types"] self.custom_types = rougailconfig["custom_types"]
@ -586,10 +586,11 @@ class ParserVariable:
del family["variable"] del family["variable"]
if self.version != "1.0": if self.version != "1.0":
warning = f'"variable" attribute in dynamic family "{ path }" is depreciated in {filename}' warning = f'"variable" attribute in dynamic family "{ path }" is depreciated in {filename}'
warn(warning, warn(
DeprecationWarning, warning,
stacklevel=2, DeprecationWarning,
) stacklevel=2,
)
if "variable" in family: if "variable" in family:
raise Exception( raise Exception(
f'dynamic family must not have "variable" attribute for "{family["path"]}" in {family["xmlfiles"]}' f'dynamic family must not have "variable" attribute for "{family["path"]}" in {family["xmlfiles"]}'

View file

@ -249,7 +249,9 @@ class Calculation(BaseModel):
def get_params(self, objectspace): def get_params(self, objectspace):
if self.warnings is not None and self.attribute_name != "validators": if self.warnings is not None and self.attribute_name != "validators":
msg = _('"warnings" are only available with attribute "{self.attribute_name}" for variable "{self.ori_path}"') msg = _(
'"warnings" are only available with attribute "{self.attribute_name}" for variable "{self.ori_path}"'
)
raise DictConsistencyError(msg, 83, xmlfiles) raise DictConsistencyError(msg, 83, xmlfiles)
if not self.params: if not self.params:
return {} return {}
@ -310,10 +312,11 @@ class JinjaCalculation(Calculation):
objectspace.jinja[jinja_path] = self.jinja objectspace.jinja[jinja_path] = self.jinja
if return_type in RENAME_TYPE: if return_type in RENAME_TYPE:
warning = f'the variable "{ self.path }" has a depreciated return_type "{return_type}", please use "{RENAME_TYPE[return_type]}" instead in {display_xmlfiles(variable.xmlfiles)}' warning = f'the variable "{ self.path }" has a depreciated return_type "{return_type}", please use "{RENAME_TYPE[return_type]}" instead in {display_xmlfiles(variable.xmlfiles)}'
warn(warning, warn(
DeprecationWarning, warning,
stacklevel=2, DeprecationWarning,
) stacklevel=2,
)
return_type = RENAME_TYPE[return_type] return_type = RENAME_TYPE[return_type]
default = { default = {
"function": function, "function": function,
@ -418,7 +421,11 @@ class JinjaCalculation(Calculation):
False, False,
objectspace, objectspace,
add_help=True, add_help=True,
params={None: [self.attribute_name, description], "when": True, "inverse": False}, params={
None: [self.attribute_name, description],
"when": True,
"inverse": False,
},
) )
elif self.attribute_name == "choices": elif self.attribute_name == "choices":
return_type = self.return_type return_type = self.return_type
@ -668,9 +675,13 @@ class _VariableCalculation(Calculation):
value_is_multi = isinstance(default, list) value_is_multi = isinstance(default, list)
if expected_multiple_value != value_is_multi: if expected_multiple_value != value_is_multi:
if self.attribute_name != "default" or expected_multiple_value: if self.attribute_name != "default" or expected_multiple_value:
msg = _('the variable "{0}" is waiting for a list as "{1}" but the attribute "default" is not a list ("{2}")') msg = _(
'the variable "{0}" is waiting for a list as "{1}" but the attribute "default" is not a list ("{2}")'
)
else: else:
msg = _('the variable "{0}" is not waiting for a list as "{1}" but the attribute "default" is a list ("{2}")') msg = _(
'the variable "{0}" is not waiting for a list as "{1}" but the attribute "default" is a list ("{2}")'
)
msg = msg.format(self.path, self.attribute_name, default) msg = msg.format(self.path, self.attribute_name, default)
raise DictConsistencyError(msg, 77, self.xmlfiles) raise DictConsistencyError(msg, 77, self.xmlfiles)
return default return default
@ -685,7 +696,11 @@ class VariableCalculation(_VariableCalculation):
self, self,
objectspace, objectspace,
) -> dict: ) -> dict:
if self.attribute_name != "default" and self.optional and self.default is undefined: if (
self.attribute_name != "default"
and self.optional
and self.default is undefined
):
msg = _( msg = _(
'"{0}" attribut shall not have an "optional" attribute without the "default" attribute for variable "{1}"' '"{0}" attribut shall not have an "optional" attribute without the "default" attribute for variable "{1}"'
).format(self.attribute_name, self.variable) ).format(self.attribute_name, self.variable)
@ -695,10 +710,8 @@ class VariableCalculation(_VariableCalculation):
variable_in_calculation, variable_in_calculation,
variable_in_calculation_identifier, variable_in_calculation_identifier,
) = self.get_variable(objectspace) ) = self.get_variable(objectspace)
if ( if not variable_in_calculation and (
not variable_in_calculation self.optional or objectspace.force_optional
and (self.optional
or objectspace.force_optional)
): ):
if self.default is not undefined: if self.default is not undefined:
return self.get_default_value_optional(objectspace, self.default) return self.get_default_value_optional(objectspace, self.default)
@ -743,17 +756,18 @@ class VariablePropertyCalculation(_VariableCalculation):
variable_in_calculation_identifier, variable_in_calculation_identifier,
) = self.get_variable(objectspace) ) = self.get_variable(objectspace)
if ( if (
# self.default is not undefined and # self.default is not undefined and
not variable_in_calculation not variable_in_calculation
and (self.optional and (self.optional or objectspace.force_optional)
or objectspace.force_optional)
): ):
if self.default is undefined: if self.default is undefined:
default = False default = False
else: else:
default = self.default default = self.default
if not isinstance(default, bool): if not isinstance(default, bool):
msg = _('the variable "{0}" is waiting for a boolean as "{1}" but the attribute "default" is not a boolean ("{2}")') msg = _(
'the variable "{0}" is waiting for a boolean as "{1}" but the attribute "default" is not a boolean ("{2}")'
)
msg = msg.format(self.path, self.attribute_name, default) msg = msg.format(self.path, self.attribute_name, default)
raise DictConsistencyError(msg, 79, self.xmlfiles) raise DictConsistencyError(msg, 79, self.xmlfiles)
return self.get_default_value_optional(objectspace, default) return self.get_default_value_optional(objectspace, default)
@ -762,7 +776,7 @@ class VariablePropertyCalculation(_VariableCalculation):
variable_in_calculation_path, variable_in_calculation_path,
variable_in_calculation, variable_in_calculation,
variable_in_calculation_identifier, variable_in_calculation_identifier,
key="value" key="value",
) )
params["prop"] = self.attribute_name params["prop"] = self.attribute_name
if objectspace.force_optional and ( if objectspace.force_optional and (

View file

@ -204,8 +204,8 @@ class Paths:
option = self._data[path] option = self._data[path]
option_namespace = option.namespace option_namespace = option.namespace
if ( if (
self.isolated_namespace and self.isolated_namespace
self.default_namespace not in [namespace, option_namespace] and self.default_namespace not in [namespace, option_namespace]
and namespace != option_namespace and namespace != option_namespace
): ):
msg = _( msg = _(

View file

@ -231,8 +231,10 @@ class Common:
elif ret is not None: elif ret is not None:
calc_properties.append(ret) calc_properties.append(ret)
if properties or calc_properties: if properties or calc_properties:
return "frozenset({" + ", ".join(sorted(properties) + calc_properties) + "})" return (
raise Exception('ca existe alors ...') "frozenset({" + ", ".join(sorted(properties) + calc_properties) + "})"
)
raise Exception("ca existe alors ...")
def calculation_property( def calculation_property(
self, self,
@ -245,7 +247,6 @@ class Common:
return None return None
return value return value
def calc_properties( def calc_properties(
self, self,
prop, prop,
@ -468,7 +469,7 @@ class Variable(Common):
keys["values"] = self.populate_calculation( keys["values"] = self.populate_calculation(
self.elt.choices, return_a_tuple=True self.elt.choices, return_a_tuple=True
) )
if keys["values"] == '(,)': if keys["values"] == "(,)":
keys["values"] = tuple() keys["values"] = tuple()
except VariableCalculationDependencyError: except VariableCalculationDependencyError:
keys["values"] = tuple() keys["values"] = tuple()

View file

@ -39,9 +39,10 @@ class Walker:
rougailconfig = self.convert.rougailconfig rougailconfig = self.convert.rougailconfig
self.sort_structural_files_all = rougailconfig["sort_structural_files_all"] self.sort_structural_files_all = rougailconfig["sort_structural_files_all"]
if rougailconfig["main_namespace"]: if rougailconfig["main_namespace"]:
self.convert.paths = Paths(rougailconfig["main_namespace"], self.convert.paths = Paths(
rougailconfig["isolated_namespace"], rougailconfig["main_namespace"],
) rougailconfig["isolated_namespace"],
)
self.load_with_extra( self.load_with_extra(
rougailconfig["extra_namespaces"], rougailconfig["extra_namespaces"],
rougailconfig["main_namespace"], rougailconfig["main_namespace"],

View file

@ -36,7 +36,12 @@ from unicodedata import normalize, combining
from jinja2 import StrictUndefined, DictLoader from jinja2 import StrictUndefined, DictLoader
from jinja2.sandbox import SandboxedEnvironment from jinja2.sandbox import SandboxedEnvironment
from re import findall from re import findall
from tiramisu import DynOptionDescription, calc_value, function_waiting_for_error, undefined from tiramisu import (
DynOptionDescription,
calc_value,
function_waiting_for_error,
undefined,
)
from tiramisu.error import ( from tiramisu.error import (
ValueWarning, ValueWarning,
ConfigError, ConfigError,
@ -134,7 +139,7 @@ CONVERT_OPTION = {
# #
"symlink": dict(opttype="SymLinkOption"), "symlink": dict(opttype="SymLinkOption"),
} }
RENAME_TYPE = {'number': 'integer'} RENAME_TYPE = {"number": "integer"}
def get_identifier_from_dynamic_family(true_name, name) -> str: def get_identifier_from_dynamic_family(true_name, name) -> str:
@ -372,14 +377,16 @@ def variable_to_property(*, prop, value=undefined, when, inverse, **kwargs):
@function_waiting_for_error @function_waiting_for_error
def jinja_to_property(prop, description, when, inverse, **kwargs): def jinja_to_property(prop, description, when, inverse, **kwargs):
value = func["jinja_to_function"](**kwargs) value = func["jinja_to_function"](**kwargs)
if kwargs["__internal_type"] == 'string': if kwargs["__internal_type"] == "string":
value = value is not None value = value is not None
return func["variable_to_property"](prop=prop, value=value, when=when, inverse=inverse) return func["variable_to_property"](
prop=prop, value=value, when=when, inverse=inverse
)
@function_waiting_for_error @function_waiting_for_error
def jinja_to_property_help(prop, description, **kwargs): def jinja_to_property_help(prop, description, **kwargs):
if kwargs["__internal_type"] == 'string': if kwargs["__internal_type"] == "string":
description = func["jinja_to_function"](**kwargs) description = func["jinja_to_function"](**kwargs)
return (prop, f'"{prop}" ({description})') return (prop, f'"{prop}" ({description})')
@ -408,6 +415,7 @@ class ConvertDynOptionDescription(DynOptionDescription):
"""Identifier could be an integer, we should convert it in str """Identifier could be an integer, we should convert it in str
Identifier could also contain invalid character, so we should "normalize" it Identifier could also contain invalid character, so we should "normalize" it
""" """
@staticmethod @staticmethod
def convert_identifier_to_path(identifier): def convert_identifier_to_path(identifier):
if identifier is None: if identifier is None:
@ -438,7 +446,9 @@ class ConvertDynOptionDescription(DynOptionDescription):
if "{{ identifier }}" in display: if "{{ identifier }}" in display:
return display.replace( return display.replace(
"{{ identifier }}", "{{ identifier }}",
self.convert_identifier_to_path(self.get_identifiers(subconfig, from_display_name=True)[-1]), self.convert_identifier_to_path(
self.get_identifiers(subconfig, from_display_name=True)[-1]
),
) )
return display return display

View file

@ -238,7 +238,7 @@ class UserDatas:
if index is not None: if index is not None:
if isinstance(value, tuple): if isinstance(value, tuple):
self.values[values_path]["values"] = [] self.values[values_path]["values"] = []
# for i in range(len(option.parent().leader().value.get())): # for i in range(len(option.parent().leader().value.get())):
for i in range(option.value.len()): for i in range(option.value.len()):
self.values[values_path]["values"].append(value) self.values[values_path]["values"].append(value)
value = self.values[values_path]["values"] value = self.values[values_path]["values"]
@ -256,7 +256,7 @@ class UserDatas:
option.value.pop(idx) option.value.pop(idx)
try: try:
self.set_value(option, value, options) self.set_value(option, value, options)
# option.value.set(value) # option.value.set(value)
value_is_set = True value_is_set = True
except Exception as err: except Exception as err:
if path != option.path(): if path != option.path():
@ -265,7 +265,9 @@ class UserDatas:
if "source" in self.values[values_path]: if "source" in self.values[values_path]:
option_without_index.information.set( option_without_index.information.set(
"loaded_from", "loaded_from",
_("loaded from {0}").format(self.values[values_path]["source"]), _("loaded from {0}").format(
self.values[values_path]["source"]
),
) )
# value is correctly set, remove variable to the set # value is correctly set, remove variable to the set
if index is not None: if index is not None:
@ -297,7 +299,7 @@ class UserDatas:
if "{{ identifier }}" in path: if "{{ identifier }}" in path:
continue continue
value = options["values"] value = options["values"]
if options.get('secret_manager'): if options.get("secret_manager"):
option = self.config.forcepermissive.option(path) option = self.config.forcepermissive.option(path)
else: else:
option = self.config.option(path) option = self.config.option(path)
@ -355,7 +357,9 @@ class UserDatas:
self.set_value(option, value, options.get("options", {})) self.set_value(option, value, options.get("options", {}))
except PropertiesOptionError as err: except PropertiesOptionError as err:
if err.code == "property-error": if err.code == "property-error":
properties = display_list([_(prop) for prop in err.proptype], add_quote=False) properties = display_list(
[_(prop) for prop in err.proptype], add_quote=False
)
err_path = err._subconfig.path err_path = err._subconfig.path
display_name = option.description(with_quote=True) display_name = option.description(with_quote=True)
if index is not None: if index is not None:
@ -446,7 +450,9 @@ class UserDatas:
is_secret_manager = options.get("secret_manager", False) is_secret_manager = options.get("secret_manager", False)
if is_secret_manager and isinstance(value, tuple): if is_secret_manager and isinstance(value, tuple):
# it's a function # it's a function
value = value[0](*value[1:], option=option, warnings=self.warnings, errors=self.errors) value = value[0](
*value[1:], option=option, warnings=self.warnings, errors=self.errors
)
option.value.set(value) option.value.set(value)

View file

@ -217,5 +217,4 @@ def get_properties_to_string():
] ]
undefined = Undefined() undefined = Undefined()