diff --git a/src/rougail/annotator/property.py b/src/rougail/annotator/property.py index ec4142ff4..c60ff2494 100644 --- a/src/rougail/annotator/property.py +++ b/src/rougail/annotator/property.py @@ -147,12 +147,15 @@ class Annotator(Walk): for tag in variable.tags: self.check_tag(tag, variable.xmlfiles) 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, - tag: str, - xmlfiles: List[str], - ): + def check_tag( + self, + tag: str, + xmlfiles: List[str], + ): match = NAME_REGEXP.search(tag) if not match: msg = _( diff --git a/src/rougail/annotator/variable.py b/src/rougail/annotator/variable.py index 0bc351624..baf945760 100644 --- a/src/rougail/annotator/variable.py +++ b/src/rougail/annotator/variable.py @@ -29,7 +29,13 @@ from tiramisu.error import display_list from rougail.i18n import _ from rougail.utils import calc_multi_for_type_variable 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 warnings import warn @@ -116,49 +122,54 @@ class Annotator(Walk): # pylint: disable=R0903 continue 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)}' - warn(warning, - DeprecationWarning, - ) + warn( + warning, + DeprecationWarning, + ) 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)}' - warn(warning, - DeprecationWarning, - ) - if variable.type == 'network_cidr': + warn( + warning, + DeprecationWarning, + ) + 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)}' - warn(warning, - DeprecationWarning, - ) + warn( + warning, + DeprecationWarning, + ) self.objectspace.informations.add( variable.path, "ymlfiles", variable.xmlfiles ) if variable.version != "1.0" and variable.type is None: - if isinstance( - variable.default, IndexCalculation - ): - variable.type = 'integer' - elif isinstance( - variable.default, VariableCalculation - ): + if isinstance(variable.default, IndexCalculation): + variable.type = "integer" + elif isinstance(variable.default, VariableCalculation): calculated_variable_path, calculated_variable, identifier = ( variable.default.get_variable(self.objectspace) ) 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) if variable.multi and variable.params: indexes_to_remove = [] for idx, param in enumerate(variable.params): if param.key == "multi_length": 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": 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": 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: continue indexes_to_remove.append(idx) @@ -166,16 +177,29 @@ class Annotator(Walk): # pylint: disable=R0903 variable.validators = [] variable.validators.append( - JinjaCalculation(path=variable.path, - inside_list=True, - version=variable.version, - xmlfiles=variable.xmlfiles, - attribute_name="validators", - namespace=variable.namespace, - jinja=jinja, - description=description, - params=[VariableParam(variable.path, "validators", False, variable.xmlfiles, key="var", namespace=variable.namespace, type="variable", variable=variable.path, whole=True)], - ) + JinjaCalculation( + path=variable.path, + inside_list=True, + version=variable.version, + xmlfiles=variable.xmlfiles, + attribute_name="validators", + namespace=variable.namespace, + jinja=jinja, + 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): variable.params.pop(idx) @@ -221,9 +245,8 @@ class Annotator(Walk): # pylint: disable=R0903 and variable.path == calculated_variable.default.path ): msg = _( - 'the "{0}" default value is a calculation with itself').format( - variable.path - ) + 'the "{0}" default value is a calculation with itself' + ).format(variable.path) raise DictConsistencyError(msg, 75, variable.xmlfiles) self._convert_variable_multi(calculated_variable) variable.multi = calc_multi_for_type_variable( diff --git a/src/rougail/config/__init__.py b/src/rougail/config/__init__.py index 9b575ba6d..d4889cc98 100644 --- a/src/rougail/config/__init__.py +++ b/src/rougail/config/__init__.py @@ -25,6 +25,7 @@ details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . """ + from pathlib import Path from tiramisu import Config from ruamel.yaml import YAML @@ -165,7 +166,8 @@ class _RougailConfig: return ret def __contains__( - self, key, + self, + key, ) -> None: try: self.__getitem__(key) @@ -204,7 +206,7 @@ class _RougailConfig: return values -class RConfigLeadership(): +class RConfigLeadership: def __init__(self, config, option, leader, followers): self.config = config self.option = option @@ -220,11 +222,11 @@ class RConfigLeadership(): value, ) -> None: self.config.property.read_write() - names = self.option.option('names') + names = self.option.option("names") leader = names.value.get() leader.append(key) names.value.set(leader) - directories = self.option.option('directories', len(leader) - 1) + directories = self.option.option("directories", len(leader) - 1) directories.value.set(value) self.leader.append(key) self.followers.append(value) diff --git a/src/rougail/convert/convert.py b/src/rougail/convert/convert.py index 310f17266..d59944725 100644 --- a/src/rougail/convert/convert.py +++ b/src/rougail/convert/convert.py @@ -161,7 +161,7 @@ class ParserVariable: def load_config(self) -> None: rougailconfig = self.rougailconfig self.suffix = rougailconfig["suffix"] - self.default_structural_format_version= rougailconfig[ + self.default_structural_format_version = rougailconfig[ "default_structural_format_version" ] self.custom_types = rougailconfig["custom_types"] @@ -586,10 +586,11 @@ class ParserVariable: del family["variable"] if self.version != "1.0": warning = f'"variable" attribute in dynamic family "{ path }" is depreciated in {filename}' - warn(warning, - DeprecationWarning, - stacklevel=2, - ) + warn( + warning, + DeprecationWarning, + stacklevel=2, + ) if "variable" in family: raise Exception( f'dynamic family must not have "variable" attribute for "{family["path"]}" in {family["xmlfiles"]}' diff --git a/src/rougail/convert/object_model.py b/src/rougail/convert/object_model.py index 63d43ee01..399944246 100644 --- a/src/rougail/convert/object_model.py +++ b/src/rougail/convert/object_model.py @@ -249,7 +249,9 @@ class Calculation(BaseModel): def get_params(self, objectspace): 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) if not self.params: return {} @@ -310,10 +312,11 @@ class JinjaCalculation(Calculation): objectspace.jinja[jinja_path] = self.jinja 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)}' - warn(warning, - DeprecationWarning, - stacklevel=2, - ) + warn( + warning, + DeprecationWarning, + stacklevel=2, + ) return_type = RENAME_TYPE[return_type] default = { "function": function, @@ -418,7 +421,11 @@ class JinjaCalculation(Calculation): False, objectspace, 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": return_type = self.return_type @@ -668,9 +675,13 @@ class _VariableCalculation(Calculation): value_is_multi = isinstance(default, list) if expected_multiple_value != value_is_multi: 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: - 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) raise DictConsistencyError(msg, 77, self.xmlfiles) return default @@ -685,7 +696,11 @@ class VariableCalculation(_VariableCalculation): self, objectspace, ) -> 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 = _( '"{0}" attribut shall not have an "optional" attribute without the "default" attribute for variable "{1}"' ).format(self.attribute_name, self.variable) @@ -695,10 +710,8 @@ class VariableCalculation(_VariableCalculation): variable_in_calculation, variable_in_calculation_identifier, ) = self.get_variable(objectspace) - if ( - not variable_in_calculation - and (self.optional - or objectspace.force_optional) + if not variable_in_calculation and ( + self.optional or objectspace.force_optional ): if self.default is not undefined: return self.get_default_value_optional(objectspace, self.default) @@ -743,17 +756,18 @@ class VariablePropertyCalculation(_VariableCalculation): variable_in_calculation_identifier, ) = self.get_variable(objectspace) if ( -# self.default is not undefined and + # self.default is not undefined and not variable_in_calculation - and (self.optional - or objectspace.force_optional) + and (self.optional or objectspace.force_optional) ): if self.default is undefined: default = False else: default = self.default 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) raise DictConsistencyError(msg, 79, self.xmlfiles) return self.get_default_value_optional(objectspace, default) @@ -762,7 +776,7 @@ class VariablePropertyCalculation(_VariableCalculation): variable_in_calculation_path, variable_in_calculation, variable_in_calculation_identifier, - key="value" + key="value", ) params["prop"] = self.attribute_name if objectspace.force_optional and ( diff --git a/src/rougail/convert/path.py b/src/rougail/convert/path.py index 740e4a9f6..4ea5581a3 100644 --- a/src/rougail/convert/path.py +++ b/src/rougail/convert/path.py @@ -204,8 +204,8 @@ class Paths: option = self._data[path] option_namespace = option.namespace if ( - self.isolated_namespace and - self.default_namespace not in [namespace, option_namespace] + self.isolated_namespace + and self.default_namespace not in [namespace, option_namespace] and namespace != option_namespace ): msg = _( diff --git a/src/rougail/convert/tiramisureflector.py b/src/rougail/convert/tiramisureflector.py index cc7bbb895..d95b90b0a 100644 --- a/src/rougail/convert/tiramisureflector.py +++ b/src/rougail/convert/tiramisureflector.py @@ -231,8 +231,10 @@ class Common: elif ret is not None: calc_properties.append(ret) if properties or calc_properties: - return "frozenset({" + ", ".join(sorted(properties) + calc_properties) + "})" - raise Exception('ca existe alors ...') + return ( + "frozenset({" + ", ".join(sorted(properties) + calc_properties) + "})" + ) + raise Exception("ca existe alors ...") def calculation_property( self, @@ -245,7 +247,6 @@ class Common: return None return value - def calc_properties( self, prop, @@ -468,7 +469,7 @@ class Variable(Common): keys["values"] = self.populate_calculation( self.elt.choices, return_a_tuple=True ) - if keys["values"] == '(,)': + if keys["values"] == "(,)": keys["values"] = tuple() except VariableCalculationDependencyError: keys["values"] = tuple() diff --git a/src/rougail/structural_directory/__init__.py b/src/rougail/structural_directory/__init__.py index 5f494daee..a7c62b156 100644 --- a/src/rougail/structural_directory/__init__.py +++ b/src/rougail/structural_directory/__init__.py @@ -39,9 +39,10 @@ class Walker: rougailconfig = self.convert.rougailconfig self.sort_structural_files_all = rougailconfig["sort_structural_files_all"] if rougailconfig["main_namespace"]: - self.convert.paths = Paths(rougailconfig["main_namespace"], - rougailconfig["isolated_namespace"], - ) + self.convert.paths = Paths( + rougailconfig["main_namespace"], + rougailconfig["isolated_namespace"], + ) self.load_with_extra( rougailconfig["extra_namespaces"], rougailconfig["main_namespace"], diff --git a/src/rougail/tiramisu.py b/src/rougail/tiramisu.py index 4b680479d..461b58402 100644 --- a/src/rougail/tiramisu.py +++ b/src/rougail/tiramisu.py @@ -36,7 +36,12 @@ from unicodedata import normalize, combining from jinja2 import StrictUndefined, DictLoader from jinja2.sandbox import SandboxedEnvironment 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 ( ValueWarning, ConfigError, @@ -134,7 +139,7 @@ CONVERT_OPTION = { # "symlink": dict(opttype="SymLinkOption"), } -RENAME_TYPE = {'number': 'integer'} +RENAME_TYPE = {"number": "integer"} 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 def jinja_to_property(prop, description, when, inverse, **kwargs): value = func["jinja_to_function"](**kwargs) - if kwargs["__internal_type"] == 'string': + if kwargs["__internal_type"] == "string": 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 def jinja_to_property_help(prop, description, **kwargs): - if kwargs["__internal_type"] == 'string': + if kwargs["__internal_type"] == "string": description = func["jinja_to_function"](**kwargs) 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 also contain invalid character, so we should "normalize" it """ + @staticmethod def convert_identifier_to_path(identifier): if identifier is None: @@ -438,7 +446,9 @@ class ConvertDynOptionDescription(DynOptionDescription): if "{{ identifier }}" in display: return display.replace( "{{ 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 diff --git a/src/rougail/user_datas.py b/src/rougail/user_datas.py index 8d040ab78..e5c09f500 100644 --- a/src/rougail/user_datas.py +++ b/src/rougail/user_datas.py @@ -238,7 +238,7 @@ class UserDatas: if index is not None: if isinstance(value, tuple): 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()): self.values[values_path]["values"].append(value) value = self.values[values_path]["values"] @@ -256,7 +256,7 @@ class UserDatas: option.value.pop(idx) try: self.set_value(option, value, options) -# option.value.set(value) + # option.value.set(value) value_is_set = True except Exception as err: if path != option.path(): @@ -265,7 +265,9 @@ class UserDatas: if "source" in self.values[values_path]: option_without_index.information.set( "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 if index is not None: @@ -297,7 +299,7 @@ class UserDatas: if "{{ identifier }}" in path: continue value = options["values"] - if options.get('secret_manager'): + if options.get("secret_manager"): option = self.config.forcepermissive.option(path) else: option = self.config.option(path) @@ -355,7 +357,9 @@ class UserDatas: self.set_value(option, value, options.get("options", {})) except PropertiesOptionError as err: 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 display_name = option.description(with_quote=True) if index is not None: @@ -446,7 +450,9 @@ class UserDatas: is_secret_manager = options.get("secret_manager", False) if is_secret_manager and isinstance(value, tuple): # 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) diff --git a/src/rougail/utils.py b/src/rougail/utils.py index 7d3a8b5c9..f03bf1872 100644 --- a/src/rougail/utils.py +++ b/src/rougail/utils.py @@ -217,5 +217,4 @@ def get_properties_to_string(): ] - undefined = Undefined()