diff --git a/src/rougail/annotator/family.py b/src/rougail/annotator/family.py
index bd29ee433..0bd0b3e32 100644
--- a/src/rougail/annotator/family.py
+++ b/src/rougail/annotator/family.py
@@ -79,7 +79,7 @@ class Annotator(Walk):
def check_sequence(self) -> None:
"""No subfamily in a sequence"""
for family in self.get_families():
- if family.type == 'leadership':
+ if family.type == "leadership":
family.type = "sequence"
if family.type != "sequence":
continue
@@ -113,7 +113,9 @@ class Annotator(Walk):
)
self.objectspace.informations.add(family.path, "dynamic_variable", path)
if family.xmlfiles:
- self.objectspace.informations.add(family.path, "ymlfiles", family.xmlfiles)
+ self.objectspace.informations.add(
+ family.path, "ymlfiles", family.xmlfiles
+ )
def set_modes(self):
if self.objectspace.modes_level:
@@ -130,8 +132,12 @@ class Annotator(Walk):
modes = self.modes = {
name: Mode(idx) for idx, name in enumerate(self.objectspace.modes_level)
}
- default_variable_mode = self.default_variable_mode = self.objectspace.default_variable_mode
- default_family_mode = self.default_family_mode = self.objectspace.default_family_mode
+ default_variable_mode = self.default_variable_mode = (
+ self.objectspace.default_variable_mode
+ )
+ default_family_mode = self.default_family_mode = (
+ self.objectspace.default_family_mode
+ )
list_modes = list(modes)
if default_variable_mode not in list_modes:
msg = _(
@@ -177,7 +183,9 @@ class Annotator(Walk):
if self.has_mode(obj):
msg = _(
'mode "{0}" for "{1}" is not a valid mode, valid modes are {2}'
- ).format(obj.mode, obj.name, display_list(list(self.modes), add_quote=True))
+ ).format(
+ obj.mode, obj.name, display_list(list(self.modes), add_quote=True)
+ )
raise DictConsistencyError(msg, 71, obj.xmlfiles)
elif self.has_mode(obj) and obj.mode not in self.modes:
msg = _(
diff --git a/src/rougail/annotator/property.py b/src/rougail/annotator/property.py
index c72d1c19c..e3f1d46b5 100644
--- a/src/rougail/annotator/property.py
+++ b/src/rougail/annotator/property.py
@@ -173,9 +173,7 @@ 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,
diff --git a/src/rougail/annotator/variable.py b/src/rougail/annotator/variable.py
index 04a49060b..6e3a7b8c7 100644
--- a/src/rougail/annotator/variable.py
+++ b/src/rougail/annotator/variable.py
@@ -106,9 +106,7 @@ class Annotator(Walk): # pylint: disable=R0903
'the variable "{0}" has attribute "secret_manager" so must not have default value'
)
raise DictConsistencyError(msg.format(path), 59, variable.xmlfiles)
- self.objectspace.informations.add(
- path, "secret_manager", True
- )
+ self.objectspace.informations.add(path, "secret_manager", True)
def convert_variable(self):
"""convert variable"""
@@ -214,9 +212,9 @@ class Annotator(Walk): # pylint: disable=R0903
if variable.type is not None:
return
## choice type inference from the `choices` attribute
- #if variable.choices is not None:
+ # if variable.choices is not None:
# variable.type = "choice"
- #elif variable.regexp is not None:
+ # elif variable.regexp is not None:
# variable.type = "regexp"
if variable.default not in [None, []]:
if isinstance(variable.default, list):
@@ -253,7 +251,9 @@ class Annotator(Walk): # pylint: disable=R0903
self._convert_variable_multi(calculated_variable)
identifier_is_a_calculation = False
if isinstance(variable.default, Calculation):
- identifier_is_a_calculation = isinstance(variable.default.identifier, Calculation)
+ identifier_is_a_calculation = isinstance(
+ variable.default.identifier, Calculation
+ )
variable.multi = calc_multi_for_type_variable(
variable,
calculated_variable_path,
@@ -317,11 +317,11 @@ class Annotator(Walk): # pylint: disable=R0903
self.objectspace.multis[variable.path] = "submulti"
elif variable.multi:
self.objectspace.multis[variable.path] = True
-# if variable.regexp is not None and variable.type != "regexp":
-# msg = _(
-# 'the variable "{0}" has regexp attribut but has not the "regexp" type'
-# ).format(variable.path)
-# raise DictConsistencyError(msg, 37, variable.xmlfiles)
+ # if variable.regexp is not None and variable.type != "regexp":
+ # msg = _(
+ # 'the variable "{0}" has regexp attribut but has not the "regexp" type'
+ # ).format(variable.path)
+ # raise DictConsistencyError(msg, 37, variable.xmlfiles)
if variable.mandatory is None:
variable.mandatory = True
@@ -358,9 +358,9 @@ class Annotator(Walk): # pylint: disable=R0903
def verify_choices(self):
for variable in self.get_variables():
# FIXME
-# if variable.type is None and variable.choices:
-# # choice type inference from the `choices` attribute
-# variable.type = "choice"
+ # if variable.type is None and variable.choices:
+ # # choice type inference from the `choices` attribute
+ # variable.type = "choice"
if variable.type != "choice":
continue
if variable.default is None:
diff --git a/src/rougail/config/__init__.py b/src/rougail/config/__init__.py
index d0105cbd6..dcc775a93 100644
--- a/src/rougail/config/__init__.py
+++ b/src/rougail/config/__init__.py
@@ -82,9 +82,7 @@ class _RougailConfig:
self.generate_config()
config = self.config.config.copy()
config.value.importation(self.config.value.exportation())
- config.property.importation(
- self.config.property.exportation()
- )
+ config.property.importation(self.config.property.exportation())
config.property.read_only()
if backward_compatibility is None:
backward_compatibility = self.backward_compatibility
@@ -250,7 +248,7 @@ class StaticRougailConvert(RougailConvert):
def __init__(
self,
add_extra_options: bool,
- rougailconfig: dict={},
+ rougailconfig: dict = {},
) -> None:
self.add_extra_options = add_extra_options
super().__init__(rougailconfig)
@@ -434,10 +432,11 @@ secret_manager: # {_("The secret manager")}
"user data": [],
"output": [],
}
- processes_tr = {"structural": _("structural"),
- "user data": _("user data"),
- "output": _("output"),
- }
+ processes_tr = {
+ "structural": _("structural"),
+ "user data": _("user data"),
+ "output": _("output"),
+ }
processes_empty = []
for module in get_sub_modules().values():
data = module.get_rougail_config(backward_compatibility=backward_compatibility)
@@ -495,7 +494,9 @@ secret_manager: # {_("The secret manager")}
"NAME", hidden_output
)
rougail_process += f""" description: {_('outputs {0} did not allow user data')}
-""".format(display_list(hidden_outputs, add_quote=True, separator="or"))
+""".format(
+ display_list(hidden_outputs, add_quote=True, separator="or")
+ )
elif objects:
rougail_process += " default: {DEFAULT}".format(
DEFAULT=objects[0]["name"]
@@ -557,7 +558,9 @@ def _rougail_config(
backward_compatibility: bool = True,
add_extra_options: bool = True,
) -> "OptionDescription":
- processes, processes_empty, rougail_options = get_common_rougail_config(backward_compatibility=backward_compatibility)
+ processes, processes_empty, rougail_options = get_common_rougail_config(
+ backward_compatibility=backward_compatibility
+ )
convert = StaticRougailConvert(add_extra_options)
convert.init()
convert.namespace = None
diff --git a/src/rougail/convert/__init__.py b/src/rougail/convert/__init__.py
index edbe10dec..23b988498 100644
--- a/src/rougail/convert/__init__.py
+++ b/src/rougail/convert/__init__.py
@@ -32,13 +32,16 @@ class Rougail(UserData):
def __init__(
self,
- rougailconfig: Optional[RougailConfig]=None,
- load_from_tiramisu_cache: bool=False,
+ rougailconfig: Optional[RougailConfig] = None,
+ load_from_tiramisu_cache: bool = False,
) -> None:
if rougailconfig is None:
rougailconfig = RougailConfig
self.rougailconfig = rougailconfig
- self.load_from_tiramisu_cache = load_from_tiramisu_cache and Path(self.rougailconfig["tiramisu_cache"]).is_file()
+ self.load_from_tiramisu_cache = (
+ load_from_tiramisu_cache
+ and Path(self.rougailconfig["tiramisu_cache"]).is_file()
+ )
types = rougail_type(self.rougailconfig)
if not self.load_from_tiramisu_cache:
self.converted = RougailConvert(self.rougailconfig, **types)
diff --git a/src/rougail/convert/collect.py b/src/rougail/convert/collect.py
index c4980477d..ed481dacb 100644
--- a/src/rougail/convert/collect.py
+++ b/src/rougail/convert/collect.py
@@ -17,6 +17,7 @@ details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see .
"""
+
import logging
from warnings import warn
from pydantic import ValidationError
@@ -104,10 +105,16 @@ class CollectFamily:
new_parameters = {}
children = self.parameters
# when an attribute starts with "_", the variable name without this "_" is a variable
- sub_variables = [key[1:] for key in self.parameters if key.startswith('_') and key[1:] in self.parameters]
+ sub_variables = [
+ key[1:]
+ for key in self.parameters
+ if key.startswith("_") and key[1:] in self.parameters
+ ]
# and known variables
if self.test_exists and self.path in self.objectspace.paths:
- sub_variables.extend([p.rsplit('.', 1)[-1] for p in self.objectspace.parents[self.path]])
+ sub_variables.extend(
+ [p.rsplit(".", 1)[-1] for p in self.objectspace.parents[self.path]]
+ )
attributes = self.object["attrs"]
attributes_types = self.object["attributes_types"]
if self.types:
@@ -127,10 +134,12 @@ class CollectFamily:
children.pop(key)
else:
new_parameters[key[1:]] = children.pop(key)
- elif key in types_children or \
- key not in attributes or \
- key in sub_variables or \
- not self.parameter_is_an_attributes(key, value, attributes_types):
+ elif (
+ key in types_children
+ or key not in attributes
+ or key in sub_variables
+ or not self.parameter_is_an_attributes(key, value, attributes_types)
+ ):
if key == "type" and self.types and key not in types_children:
children.pop(key)
else:
@@ -227,6 +236,7 @@ class CollectVariable:
secret_manager,
)
+
class CollectType:
"""Determine the option type
1/ self.option_type must be "variable" or "family" option type
@@ -250,7 +260,12 @@ class CollectType:
self.variable_in_sequence()
self.family_or_variable()
if self.user_type:
- logging.info("family_or_variable: %s is a %s (%s)", self.path, self.option_type, self.user_type)
+ logging.info(
+ "family_or_variable: %s is a %s (%s)",
+ self.path,
+ self.option_type,
+ self.user_type,
+ )
else:
logging.info("family_or_variable: %s is a %s", self.path, self.option_type)
@@ -259,18 +274,24 @@ class CollectType:
) -> None:
"""Check 'type' attributes and determine the option type"""
for type_name in ["_type", "type"]:
- if type_name not in self.parameters or not isinstance(self.parameters[type_name], str):
+ if type_name not in self.parameters or not isinstance(
+ self.parameters[type_name], str
+ ):
continue
self.user_type = self.parameters[type_name]
if self.user_type in self.objectspace.custom_family_types:
- self.set_custom_type(self.objectspace.custom_family_types[self.user_type])
+ self.set_custom_type(
+ self.objectspace.custom_family_types[self.user_type]
+ )
if self.user_type is None:
self.object = self.objectspace.family_objects[-1]
else:
self.set_object_user_type_family()
break
elif self.user_type in self.objectspace.custom_variable_types:
- self.set_custom_type(self.objectspace.custom_variable_types[self.user_type])
+ self.set_custom_type(
+ self.objectspace.custom_variable_types[self.user_type]
+ )
if self.user_type is None:
self.object = self.objectspace.variable_objects[0]
else:
@@ -281,11 +302,13 @@ class CollectType:
if not self.object:
self.set_object_user_type_variable()
if self.raises and not self.object:
- msg = _('cannot determine the type of the {0} "{1}"').format(self.user_type, self.path)
+ msg = _('cannot determine the type of the {0} "{1}"').format(
+ self.user_type, self.path
+ )
raise DictConsistencyError(msg, 43, self.sources)
break
- def set_custom_type(self, custom: dict, from_parent: bool=False) -> None:
+ def set_custom_type(self, custom: dict, from_parent: bool = False) -> None:
if self.raises and self.test_exists and self.path in self.objectspace.paths:
msg = f'cannot redefine "{self.path}" object to a custom type'
raise DictConsistencyError(msg, 64, self.sources)
@@ -302,7 +325,11 @@ class CollectType:
self.user_type = self.types.user_type
self.sources = self.types.sources + self.sources
self.object = self.types.object
- if not from_parent and self.option_type == "variable" and "type" in self.parameters:
+ if (
+ not from_parent
+ and self.option_type == "variable"
+ and "type" in self.parameters
+ ):
self.parameters.pop("type")
def set_object_user_type_family(self):
@@ -323,7 +350,9 @@ class CollectType:
if self.user_type:
return
for type_name in ["_dynamic", "dynamic"]:
- if type_name in self.parameters and isinstance(self.parameters[type_name], (list, dict)):
+ if type_name in self.parameters and isinstance(
+ self.parameters[type_name], (list, dict)
+ ):
self.user_type = "dynamic"
self.option_type = "family"
break
@@ -333,7 +362,9 @@ class CollectType:
return
# it's already a variable or a family
old_option_type = self.option_type if self.user_type else None
- self.option_type = "family" if self.path in self.objectspace.families else "variable"
+ self.option_type = (
+ "family" if self.path in self.objectspace.families else "variable"
+ )
if self.raises and old_option_type and self.option_type != old_option_type:
msg = f'the {old_option_type} "{self.path}" is redefine as a {self.option_type}, which is not allowed'
raise DictConsistencyError(msg, 11, self.sources)
@@ -382,7 +413,9 @@ class CollectType:
def find_variable_object(self) -> bool:
attrs = set(self.parameters)
for variable in self.objectspace.variable_objects:
- if not attrs - variable["attrs"] and self.check_variable_parameters(variable):
+ if not attrs - variable["attrs"] and self.check_variable_parameters(
+ variable
+ ):
self.option_type = "variable"
self.check_no_extra_keys = True
self.object = variable
@@ -399,22 +432,39 @@ class CollectType:
return False
return True
- def parameter_is_an_attributes(self, key: str, value: Any, attributes_types: dict) -> bool:
+ def parameter_is_an_attributes(
+ self, key: str, value: Any, attributes_types: dict
+ ) -> bool:
if value is None:
return True
- if key in attributes_types["literals"] and value in attributes_types["literals"][key]:
+ if (
+ key in attributes_types["literals"]
+ and value in attributes_types["literals"][key]
+ ):
return True
- for k, typ in [("strings", str), ("booleans", bool), ("integers", int), ("floats", float)]:
+ for k, typ in [
+ ("strings", str),
+ ("booleans", bool),
+ ("integers", int),
+ ("floats", float),
+ ]:
if key in attributes_types[k] and isinstance(value, typ):
return True
if isinstance(value, dict):
if key in attributes_types["calculation"]:
- return self.is_calculation(key, value, attributes_types=attributes_types)
+ return self.is_calculation(
+ key, value, attributes_types=attributes_types
+ )
if key in attributes_types["params"]:
return True
if isinstance(value, list):
current_value = value.copy()
- for k, typ in [("strings", str), ("booleans", bool), ("integers", int), ("floats", float)]:
+ for k, typ in [
+ ("strings", str),
+ ("booleans", bool),
+ ("integers", int),
+ ("floats", float),
+ ]:
if key in attributes_types["lists"][k]:
for idx, val in reversed(list(enumerate(current_value))):
if val is not None and not isinstance(val, typ):
@@ -424,7 +474,9 @@ class CollectType:
return True
if key in attributes_types["lists"]["calculation"]:
for val in current_value:
- if isinstance(val, dict) and not self.is_calculation(key, val, inside_list=True, attributes_types=attributes_types):
+ if isinstance(val, dict) and not self.is_calculation(
+ key, val, inside_list=True, attributes_types=attributes_types
+ ):
return False
return True
return False
@@ -440,8 +492,8 @@ class Collect(CollectType, CollectFamily, CollectVariable):
comment: Optional[str],
parent_option: Optional["Collect"],
*,
- raises: bool=True,
- test_exists: bool=True,
+ raises: bool = True,
+ test_exists: bool = True,
) -> None:
self.sources_types = None
self.types = None
@@ -464,14 +516,23 @@ class Collect(CollectType, CollectFamily, CollectVariable):
self.sources = objectspace.sources.copy()
self.user_type = None
self.option_type = None
- if parent_option is not None and parent_option.types is not None and self.name in parent_option.types.children:
- self.set_custom_type(parent_option.types.children[self.name], from_parent=True)
+ if (
+ parent_option is not None
+ and parent_option.types is not None
+ and self.name in parent_option.types.children
+ ):
+ self.set_custom_type(
+ parent_option.types.children[self.name], from_parent=True
+ )
self.check_no_extra_keys = False
if self.test_exists and path in objectspace.paths:
for source in reversed(self.objectspace.paths[path].xmlfiles):
self.sources.insert(0, source)
if parent_option:
- self.family_is_sequence = parent_option.user_type in ["leadership", "sequence"]
+ self.family_is_sequence = parent_option.user_type in [
+ "leadership",
+ "sequence",
+ ]
self.family_is_dynamic = parent_option.family_is_dynamic
self.parent_dynamic = parent_option.parent_dynamic
else:
@@ -509,7 +570,9 @@ class Collect(CollectType, CollectFamily, CollectVariable):
except ValidationError as err:
if self.raises:
raise DictConsistencyError(
- _('the {0} "{1}" has an invalid "{2}": {3}').format(self.option_type, self.path, key, err),
+ _('the {0} "{1}" has an invalid "{2}": {3}').format(
+ self.option_type, self.path, key, err
+ ),
84,
self.sources,
) from err
@@ -536,17 +599,21 @@ class Collect(CollectType, CollectFamily, CollectVariable):
f"at index {idx}: {err}"
) from err
- def is_dict(self, key: str, value: Any, *, attributes_types: Optional[dict]=None) -> bool:
+ def is_dict(
+ self, key: str, value: Any, *, attributes_types: Optional[dict] = None
+ ) -> bool:
"""it's a dict, so it's a new variables!"""
- return isinstance(value, dict) and not self.is_calculation(key, value, attributes_types=attributes_types)
+ return isinstance(value, dict) and not self.is_calculation(
+ key, value, attributes_types=attributes_types
+ )
def is_calculation(
self,
attribute: str,
value: dict,
*,
- attributes_types: Optional[dict]=None,
- inside_list: bool=False,
+ attributes_types: Optional[dict] = None,
+ inside_list: bool = False,
):
"""Check if it's a calculation"""
if not isinstance(value, dict):
@@ -603,11 +670,16 @@ class Collect(CollectType, CollectFamily, CollectVariable):
calculation_object["namespace"] = namespace
calculation_object["xmlfiles"] = self.sources
#
- self.set_identifier_calculation_in_default_attribut(attribute, calculation_object, inside_list, index)
+ self.set_identifier_calculation_in_default_attribut(
+ attribute, calculation_object, inside_list, index
+ )
self.set_params_calculation(calculation_object, attribute)
#
return_type = calculation_object.get("return_type")
- if return_type and return_type not in self.objectspace.variable_objects[0]["types"]:
+ if (
+ return_type
+ and return_type not in self.objectspace.variable_objects[0]["types"]
+ ):
raise Exception(
f'unknown "return_type" in {attribute} of variable "{self.path}"'
)
@@ -624,7 +696,13 @@ class Collect(CollectType, CollectFamily, CollectVariable):
else:
obj[attribute][index] = calc
- def set_identifier_calculation_in_default_attribut(self, attribute: str, calculation_object: dict, inside_list: bool, index: Optional[int]) -> None:
+ def set_identifier_calculation_in_default_attribut(
+ self,
+ attribute: str,
+ calculation_object: dict,
+ inside_list: bool,
+ index: Optional[int],
+ ) -> None:
if attribute != "default" or "identifier" not in calculation_object:
return
identifier = calculation_object["identifier"]
@@ -634,7 +712,13 @@ class Collect(CollectType, CollectFamily, CollectVariable):
attributes_types=self.objectspace.variable_objects[0]["attributes_types"],
inside_list=inside_list,
):
- self.set_calculation("identifier", identifier, obj=calculation_object, inside_list=inside_list, index=index)
+ self.set_calculation(
+ "identifier",
+ identifier,
+ obj=calculation_object,
+ inside_list=inside_list,
+ index=index,
+ )
def set_params_calculation(self, calculation_object: dict, attribute: str) -> None:
if "params" not in calculation_object:
@@ -686,12 +770,18 @@ class Collect(CollectType, CollectFamily, CollectVariable):
val["type"] = list(param_typ)[0]
def is_redefine(self):
- if self.path in self.objectspace.paths and self.option_type == "family" and not self.parameters:
+ if (
+ self.path in self.objectspace.paths
+ and self.option_type == "family"
+ and not self.parameters
+ ):
# allow loading family with no attribute loaded
return True
if self.types:
return True
- return self.parameters.pop("redefine", False) or (self.types and list(self.parameters) in [[], ["default"]])
+ return self.parameters.pop("redefine", False) or (
+ self.types and list(self.parameters) in [[], ["default"]]
+ )
def is_exists(self):
if self.version == "1.0" and self.option_type == "family":
diff --git a/src/rougail/convert/convert.py b/src/rougail/convert/convert.py
index a5f7d83f1..d377df00a 100644
--- a/src/rougail/convert/convert.py
+++ b/src/rougail/convert/convert.py
@@ -188,7 +188,10 @@ class ParserVariable:
self.load_unexist_redefine = rougailconfig["load_unexist_redefine"]
self.secret_pattern = rougailconfig["secret_manager.pattern"]
# change default initkwargs in CONVERT_OPTION
- if hasattr(rougailconfig, "config") and rougailconfig.config.option('define_default_params').value.get():
+ if (
+ hasattr(rougailconfig, "config")
+ and rougailconfig.config.option("define_default_params").value.get()
+ ):
for sub_od in rougailconfig.config.option("default_params"):
for option in sub_od:
if option.owner.isdefault():
@@ -219,7 +222,9 @@ class ParserVariable:
)
if "Family" in module.__all__:
self.family = type(
- self.family.__name__ + "_" + structural, (self.family, module.Family), {}
+ self.family.__name__ + "_" + structural,
+ (self.family, module.Family),
+ {},
)
if not self.walker and "Walker" in module.__all__:
self.walker = module.Walker
@@ -230,8 +235,19 @@ class ParserVariable:
variable_types.remove("choice")
variable_types.remove("regexp")
variable_types.remove("symlink")
- self.variable_objects = [self.get_variable_object(obj, is_variable=True) for obj in [(self.variable, variable_types), SymLink, self.choices, self.regexp]]
- self.family_objects = [self.get_variable_object(obj, is_variable=False) for obj in [self.dynamic, self.family]]
+ self.variable_objects = [
+ self.get_variable_object(obj, is_variable=True)
+ for obj in [
+ (self.variable, variable_types),
+ SymLink,
+ self.choices,
+ self.regexp,
+ ]
+ ]
+ self.family_objects = [
+ self.get_variable_object(obj, is_variable=False)
+ for obj in [self.dynamic, self.family]
+ ]
self.is_init = True
def get_variable_object(self, obj, *, is_variable: bool) -> dict:
@@ -241,11 +257,12 @@ class ParserVariable:
else:
hint = get_type_hints(obj)
types = self.get_types(hint)
- return {"object": obj,
- "types": types,
- "attrs": self.get_option_attrs(hint),
- "attributes_types": self.get_attributes_types(hint, variable=is_variable),
- }
+ return {
+ "object": obj,
+ "types": types,
+ "attrs": self.get_option_attrs(hint),
+ "attributes_types": self.get_attributes_types(hint, variable=is_variable),
+ }
def get_types(self, hint):
return hint["type"].__args__
@@ -298,12 +315,13 @@ class ParserVariable:
path = option.path
redefine = option.redefine
exists = option.exists
-# if not redefine and not exists and option.user_type in self.custom_family_types:
+ # if not redefine and not exists and option.user_type in self.custom_family_types:
types = option.types
if types:
- self.add_family(types,
- custom_type=True,
- )
+ self.add_family(
+ types,
+ custom_type=True,
+ )
if path not in self.paths:
if not self.load_unexist_redefine and exists is None and redefine:
raise Exception(
@@ -319,9 +337,7 @@ class ParserVariable:
else:
if exists in [None, True] and not redefine:
msg = _('family "{0}" define multiple time').format(path)
- raise DictConsistencyError(
- msg, 32, option.sources
- )
+ raise DictConsistencyError(msg, 32, option.sources)
if self.load_unexist_redefine or exists in [None, True]:
objects = option.parameters.copy()
objects["xmlfiles"] = option.sources
@@ -329,7 +345,7 @@ class ParserVariable:
option,
self.paths[path].model_copy(update=objects),
force=True,
- )
+ )
force_not_first = types == None
children = option.children
for idx, key in enumerate(self.list_children(option, types)):
@@ -394,7 +410,7 @@ class ParserVariable:
self,
option: Collect,
*,
- custom_type: bool=False,
+ custom_type: bool = False,
) -> None:
"""Add a new family"""
path = option.path
@@ -415,12 +431,15 @@ class ParserVariable:
try:
self.paths.add(
option,
- family_obj(name=option.name,
- **data,
- ),
+ family_obj(
+ name=option.name,
+ **data,
+ ),
)
except ValidationError as err:
- raise Exception(f'invalid family "{path}" in "{display_list(option.sources)}": {err}') from err
+ raise Exception(
+ f'invalid family "{path}" in "{display_list(option.sources)}": {err}'
+ ) from err
self.set_name(
self.paths[path],
"optiondescription_",
@@ -448,10 +467,11 @@ class ParserVariable:
path = option.path
if option.types:
redefine = True
- self.add_variable(option.types,
- first_variable=first_variable,
- custom_type=True,
- )
+ self.add_variable(
+ option.types,
+ first_variable=first_variable,
+ custom_type=True,
+ )
if path not in self.paths:
if not self.load_unexist_redefine and exists is True:
# this variable must exist
@@ -461,19 +481,18 @@ class ParserVariable:
if not self.load_unexist_redefine and redefine:
msg = f'cannot redefine the inexisting variable "{path}"'
raise DictConsistencyError(msg, 46, option.sources)
- self.add_variable(option,
- first_variable,
- custom_type,
- )
+ self.add_variable(
+ option,
+ first_variable,
+ custom_type,
+ )
else:
if not self.load_unexist_redefine:
if exists is False:
return
if not redefine:
msg = _('variable "{0}" define multiple time').format(path)
- raise DictConsistencyError(
- msg, 45, option.sources
- )
+ raise DictConsistencyError(msg, 45, option.sources)
objects = option.parameters.copy()
objects["xmlfiles"] = option.sources
self.paths.add(
@@ -499,9 +518,10 @@ class ParserVariable:
data["path"] = path
data["version"] = option.version
try:
- variable_obj = option.object["object"](name=option.name,
- **data,
- )
+ variable_obj = option.object["object"](
+ name=option.name,
+ **data,
+ )
except ValidationError as err:
raise Exception(
f'invalid variable "{path}" in "{display_list(option.sources)}": {err}'
@@ -572,12 +592,13 @@ class ParserVariable:
class RougailConvert(ParserVariable):
"""Main Rougail conversion"""
- def __init__(self,
- rougailconfig,
- *,
- custom_variable_types: dict={},
- custom_family_types: dict={},
- ) -> None:
+ def __init__(
+ self,
+ rougailconfig,
+ *,
+ custom_variable_types: dict = {},
+ custom_family_types: dict = {},
+ ) -> None:
self.annotator = False
self.has_namespace = False
self.custom_variable_types = custom_variable_types
@@ -588,14 +609,16 @@ class RougailConvert(ParserVariable):
def get_attributes_types(
self,
hint: dict,
- variable: bool=False,
+ variable: bool = False,
) -> dict:
"""attribute is calculated if typing is like: Union[Calculation, xxx]"""
- lists = {"strings": [],
- "booleans": [],
- "integers": [],
- "floats": [],
- "calculation": []}
+ lists = {
+ "strings": [],
+ "booleans": [],
+ "integers": [],
+ "floats": [],
+ "calculation": [],
+ }
if variable:
lists["calculation"].append("identifier")
calculation = ["identifier"]
@@ -647,18 +670,21 @@ class RougailConvert(ParserVariable):
booleans.append(key)
elif "Literal" in value.__class__.__name__:
literals[key] = value.__args__
- return {"strings": strings,
- "integers": integers,
- "booleans": booleans,
- "floats": floats,
- "literals": literals,
- "calculation": calculation,
- "lists": lists,
- "params": params,
- }
+ return {
+ "strings": strings,
+ "integers": integers,
+ "booleans": booleans,
+ "floats": floats,
+ "literals": literals,
+ "calculation": calculation,
+ "lists": lists,
+ "params": params,
+ }
def create_namespace(
- self, namespace_description: str, isolated_namespace: bool=True,
+ self,
+ namespace_description: str,
+ isolated_namespace: bool = True,
) -> None:
namespace_path = normalize_family(namespace_description)
self.has_namespace = True
@@ -687,9 +713,7 @@ class RougailConvert(ParserVariable):
None,
None,
)
- self.parse_family(
- option
- )
+ self.parse_family(option)
def get_comment(
self,
diff --git a/src/rougail/convert/object_model.py b/src/rougail/convert/object_model.py
index 49261fc9e..620208008 100644
--- a/src/rougail/convert/object_model.py
+++ b/src/rougail/convert/object_model.py
@@ -35,7 +35,11 @@ from ..utils import (
PROPERTY_ATTRIBUTE,
)
from ..i18n import _
-from ..error import DictConsistencyError, VariableCalculationDependencyError, RougailWarning
+from ..error import (
+ DictConsistencyError,
+ VariableCalculationDependencyError,
+ RougailWarning,
+)
from ..tiramisu import CONVERT_OPTION, RENAME_TYPE, display_xmlfiles, convert_boolean
BASETYPE = Union[StrictBool, StrictInt, StrictFloat, StrictStr, None]
@@ -60,7 +64,7 @@ def get_convert_option_types():
if key.startswith("_"):
continue
if "params" in datas and key in datas["params"]:
- multi = datas["params"][key].get('multi', False)
+ multi = datas["params"][key].get("multi", False)
description = datas["params"][key]["description"]
choices = datas["params"][key].get("choices")
else:
@@ -111,7 +115,7 @@ class VariableParam(Param):
variable: StrictStr
propertyerror: bool = True
whole: bool = False
-# dynamic: bool = True
+ # dynamic: bool = True
optional: bool = False
def to_param(
@@ -324,9 +328,16 @@ class JinjaCalculation(Calculation):
variable = objectspace.paths[path]
objectspace.jinja[jinja_path] = self.jinja
if return_type in RENAME_TYPE:
- warning = _('the variable "{0}" has a depreciated return_type "{1}", please use "{2}" instead in {3}')
+ warning = _(
+ 'the variable "{0}" has a depreciated return_type "{1}", please use "{2}" instead in {3}'
+ )
warn(
- warning.format(path, return_type, RENAME_TYPE[return_type], display_xmlfiles(self.xmlfiles)),
+ warning.format(
+ path,
+ return_type,
+ RENAME_TYPE[return_type],
+ display_xmlfiles(self.xmlfiles),
+ ),
DeprecationWarning,
stacklevel=2,
)
@@ -416,19 +427,26 @@ class JinjaCalculation(Calculation):
'variable "{0}" has a calculating "{1}" with an invalid return_type, should be boolean or string, not "{2}"'
).format(path, self.attribute_name, return_type)
raise DictConsistencyError(msg, 81, self.xmlfiles)
- if return_type == 'boolean':
+ if return_type == "boolean":
description = self.description
if description is None:
if self.ori_path is not None:
opath = self.ori_path
else:
opath = path
- warning = _('the variable "{0}" has a return_type "{1}", for attribute "{2}" but has not description in {3}')
+ warning = _(
+ 'the variable "{0}" has a return_type "{1}", for attribute "{2}" but has not description in {3}'
+ )
warn(
- warning.format(opath, return_type, self.attribute_name, display_xmlfiles(self.xmlfiles)),
+ warning.format(
+ opath,
+ return_type,
+ self.attribute_name,
+ display_xmlfiles(self.xmlfiles),
+ ),
RougailWarning,
)
- self.description = _('value is invalid')
+ self.description = _("value is invalid")
else:
description = None
return self._jinja_to_function(
@@ -437,7 +455,7 @@ class JinjaCalculation(Calculation):
False,
objectspace,
path,
- params={'description': description},
+ params={"description": description},
)
elif self.attribute_name in PROPERTY_ATTRIBUTE:
return_type = self.return_type
@@ -491,7 +509,7 @@ class JinjaCalculation(Calculation):
class _VariableCalculation(Calculation):
variable: StrictStr
- propertyerror: bool = True,
+ propertyerror: bool = (True,)
allow_none: bool = False
optional: bool = False
# FIXME identifier is not available for Properties!
@@ -522,7 +540,9 @@ class _VariableCalculation(Calculation):
self.namespace,
self.xmlfiles,
)
- if variable and not isinstance(variable, objectspace.variable_objects[0]["object"]):
+ if variable and not isinstance(
+ variable, objectspace.variable_objects[0]["object"]
+ ):
if isinstance(variable, objectspace.family):
msg = _(
'a variable "{0}" is needs in attribute "{1}" for "{2}" but it\'s a family'
@@ -549,7 +569,13 @@ class _VariableCalculation(Calculation):
if variable_in_calculation_identifier:
msg = _(
'variable "{0}" has an attribute "{1}" with an identifier "{2}" but the path has also the identifier "{3}"'
- ).format(path, self.attribute_name, self.variable, self.identifier, variable_in_calculation_identifier)
+ ).format(
+ path,
+ self.attribute_name,
+ self.variable,
+ self.identifier,
+ variable_in_calculation_identifier,
+ )
raise DictConsistencyError(msg, 89, self.xmlfiles)
variable_in_calculation_identifier = self.identifier
identifier_is_a_calculation = True
@@ -578,7 +604,11 @@ class _VariableCalculation(Calculation):
if self.allow_none:
params["allow_none"] = True
self.check_multi(
- objectspace, path, variable_in_calculation_path, variable_in_calculation, identifier_is_a_calculation,
+ objectspace,
+ path,
+ variable_in_calculation_path,
+ variable_in_calculation,
+ identifier_is_a_calculation,
)
if path in objectspace.followers:
multi = objectspace.multis[path] == "submulti"
@@ -589,7 +619,12 @@ class _VariableCalculation(Calculation):
return params
def check_multi(
- self, objectspace, path, variable_in_calculation_path, variable_in_calculation, identifier_is_a_calculation,
+ self,
+ objectspace,
+ path,
+ variable_in_calculation_path,
+ variable_in_calculation,
+ identifier_is_a_calculation,
):
local_variable = objectspace.paths[path]
local_variable_multi, variable_in_calculation_multi = (
@@ -1075,8 +1110,8 @@ class Family(BaseModel):
class Dynamic(BaseModel):
type: Literal["dynamic"] = "dynamic"
-# # None only for format 1.0
-# variable: StrictStr = None
+ # # None only for format 1.0
+ # variable: StrictStr = None
dynamic: Union[List[Union[StrictStr, Calculation]], Calculation]
diff --git a/src/rougail/convert/tiramisureflector.py b/src/rougail/convert/tiramisureflector.py
index ebf0b5e56..8b2e0ec4c 100644
--- a/src/rougail/convert/tiramisureflector.py
+++ b/src/rougail/convert/tiramisureflector.py
@@ -82,7 +82,7 @@ class TiramisuReflector:
continue
self.text["header"].append(f"load_functions('{funcs_path}')")
if self.objectspace.export_with_import:
-# if self.objectspace.has_namespace:
+ # if self.objectspace.has_namespace:
self.text["header"].extend(
[
"try:",
@@ -343,12 +343,16 @@ class Common:
ret = f"ParamSelfOption(whole={whole}"
if not dynamic:
ret += ", dynamic=False"
- return ret + ')'
+ return ret + ")"
if whole:
- msg = _('variable param "{0}" has whole attribute but it\'s not allowed for external variable')
+ msg = _(
+ 'variable param "{0}" has whole attribute but it\'s not allowed for external variable'
+ )
raise DictConsistencyError(msg.format(variable.path), 34, self.elt.xmlfiles)
if not dynamic:
- msg = _('variable param "{0}" has dynamic attribute but it\'s not allowed for external variable')
+ msg = _(
+ 'variable param "{0}" has dynamic attribute but it\'s not allowed for external variable'
+ )
raise DictConsistencyError(msg.format(variable.path), 34, self.elt.xmlfiles)
option_name = self.tiramisu.reflector_objects[variable.path].get(
self.calls, self.elt.path
diff --git a/src/rougail/error.py b/src/rougail/error.py
index ac0de0dfa..158d1659a 100644
--- a/src/rougail/error.py
+++ b/src/rougail/error.py
@@ -68,6 +68,7 @@ class DictConsistencyError(Exception):
class NotFoundError(Exception):
"not found error"
+
pass
diff --git a/src/rougail/structural_commandline/annotator.py b/src/rougail/structural_commandline/annotator.py
index 6339ce55b..7f0790361 100644
--- a/src/rougail/structural_commandline/annotator.py
+++ b/src/rougail/structural_commandline/annotator.py
@@ -60,7 +60,9 @@ class Annotator(Walk):
return
alternative_name = variable.alternative_name
variable_path = variable.path
- self.objectspace.informations.add(variable_path, "alternative_name", alternative_name)
+ self.objectspace.informations.add(
+ variable_path, "alternative_name", alternative_name
+ )
all_letters = ""
for letter in alternative_name:
all_letters += letter
diff --git a/src/rougail/structural_string/__init__.py b/src/rougail/structural_string/__init__.py
index ea94f1e2a..a7bdf46e7 100644
--- a/src/rougail/structural_string/__init__.py
+++ b/src/rougail/structural_string/__init__.py
@@ -16,15 +16,15 @@ You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see .
"""
-
from typing import List, Optional
from itertools import chain
from ruamel.yaml import YAML
from ..tiramisu import normalize_family
from ..convert.path import Paths
-#from ..error import DictConsistencyError
-#from ..i18n import _
+
+# from ..error import DictConsistencyError
+# from ..i18n import _
class Walker:
@@ -85,9 +85,9 @@ class Walker:
return
path = self.convert.namespace
if path:
- name = f'yaml file for {path}'
+ name = f"yaml file for {path}"
else:
- name = 'yaml file'
+ name = "yaml file"
version = self.convert.validate_file_version(
objects,
name,
@@ -101,4 +101,3 @@ class Walker:
__all__ = ("Walker",)
-
diff --git a/src/rougail/structural_string/config.py b/src/rougail/structural_string/config.py
index a2e5f85d7..e28c3d5d8 100644
--- a/src/rougail/structural_string/config.py
+++ b/src/rougail/structural_string/config.py
@@ -66,4 +66,3 @@ extra_namespaces:
__all__ = "get_rougail_config"
-
diff --git a/src/rougail/tiramisu.py b/src/rougail/tiramisu.py
index 12feb728f..b7556979e 100644
--- a/src/rougail/tiramisu.py
+++ b/src/rougail/tiramisu.py
@@ -87,90 +87,139 @@ def convert_boolean(value: str) -> bool:
return None
raise Exception(_('unknown boolean value "{0}"').format(value))
+
_ip_params = {
- "cidr": {"description": _("IP must be in CIDR format")},
- "private_only": {"description": _("private IP are allowed")},
- "allow_reserved": {"description": _("reserved IP are allowed")},
- }
+ "cidr": {"description": _("IP must be in CIDR format")},
+ "private_only": {"description": _("private IP are allowed")},
+ "allow_reserved": {"description": _("reserved IP are allowed")},
+}
_network_params = {
- "cidr": {"description": _("network must be in CIDR format")},
- "private_only": {"description": _("private network are allowed")},
- "allow_reserved": {"description": _("reserved network are allowed")},
- }
+ "cidr": {"description": _("network must be in CIDR format")},
+ "private_only": {"description": _("private network are allowed")},
+ "allow_reserved": {"description": _("reserved network are allowed")},
+}
_port_params = {
- "allow_range": {"description": _("can be range of port")},
- "allow_protocol": {"description": _("can have the protocol")},
- "allow_zero": {"description": _("port 0 is allowed")},
- "allow_wellknown": {"description": _("well-known ports (1 to 1023) are allowed")},
- "allow_registred": {"description": _("registred ports (1024 to 49151) are allowed")},
- "allow_private": {"description": _("private ports (greater than 49152) are allowed")},
- }
+ "allow_range": {"description": _("can be range of port")},
+ "allow_protocol": {"description": _("can have the protocol")},
+ "allow_zero": {"description": _("port 0 is allowed")},
+ "allow_wellknown": {"description": _("well-known ports (1 to 1023) are allowed")},
+ "allow_registred": {
+ "description": _("registred ports (1024 to 49151) are allowed")
+ },
+ "allow_private": {
+ "description": _("private ports (greater than 49152) are allowed")
+ },
+}
_domain_params = {
- "type": {"description": _("type of domainname"), "choices": ('domainname', 'netbios', 'hostname'), 'doc': _("type {0}")},
- "allow_startswith_dot": {"description": _("the domain name can starts by a dot")},
- "allow_without_dot": {"description": _("the domain name can be a hostname")},
- "allow_ip": {"description": _("the domain name can be an IP")},
- "allow_cidr_network": {"description": _("the domain name can be network in CIDR format")},
- "test_existence": {"description": _("the domain name must exist")},
- }
+ "type": {
+ "description": _("type of domainname"),
+ "choices": ("domainname", "netbios", "hostname"),
+ "doc": _("type {0}"),
+ },
+ "allow_startswith_dot": {"description": _("the domain name can starts by a dot")},
+ "allow_without_dot": {"description": _("the domain name can be a hostname")},
+ "allow_ip": {"description": _("the domain name can be an IP")},
+ "allow_cidr_network": {
+ "description": _("the domain name can be network in CIDR format")
+ },
+ "test_existence": {"description": _("the domain name must exist")},
+}
_web_params = _port_params | _domain_params
CONVERT_OPTION = {
"string": dict(opttype="StrOption", example="example"),
- "number": dict(opttype="IntOption",
- func=int,
- params={
- "min_number": {"description": _("the minimum value"), 'doc': _("the minimum value is {0}")},
- "max_number": {"description": _("the maximum value"), 'doc': _("the maximum value is {0}")},
- },
- example=42),
- "integer": dict(opttype="IntOption",
- params={
- "min_integer": {"description": _("the minimum value"), 'doc': _("the minimum value is {0}")},
- "max_integer": {"description": _("the maximum value"), 'doc': _("the maximum value is {0}")},
- },
- func=int,
- example=42,
- ),
+ "number": dict(
+ opttype="IntOption",
+ func=int,
+ params={
+ "min_number": {
+ "description": _("the minimum value"),
+ "doc": _("the minimum value is {0}"),
+ },
+ "max_number": {
+ "description": _("the maximum value"),
+ "doc": _("the maximum value is {0}"),
+ },
+ },
+ example=42,
+ ),
+ "integer": dict(
+ opttype="IntOption",
+ params={
+ "min_integer": {
+ "description": _("the minimum value"),
+ "doc": _("the minimum value is {0}"),
+ },
+ "max_integer": {
+ "description": _("the maximum value"),
+ "doc": _("the maximum value is {0}"),
+ },
+ },
+ func=int,
+ example=42,
+ ),
"float": dict(opttype="FloatOption", func=float, example=1.42),
"boolean": dict(opttype="BoolOption", func=convert_boolean, example=True),
- "secret": dict(opttype="PasswordOption",
- params={
- "min_len": {"description": _("minimum characters length for the secret"), "doc": _("minimum length for the secret is {0} characters")},
- "max_len": {"description": _("maximum characters length for the secret"), "doc": _("maximum length for the secret is {0} characters")},
- "forbidden_char": {"description": _("forbidden characters"), "doc": _("forbidden characters: {0}")},
- },
- example="secrets"),
+ "secret": dict(
+ opttype="PasswordOption",
+ params={
+ "min_len": {
+ "description": _("minimum characters length for the secret"),
+ "doc": _("minimum length for the secret is {0} characters"),
+ },
+ "max_len": {
+ "description": _("maximum characters length for the secret"),
+ "doc": _("maximum length for the secret is {0} characters"),
+ },
+ "forbidden_char": {
+ "description": _("forbidden characters"),
+ "doc": _("forbidden characters: {0}"),
+ },
+ },
+ example="secrets",
+ ),
"mail": dict(opttype="EmailOption", example="user@example.net"),
- "unix_filename": dict(opttype="FilenameOption",
- msg="UNIX filename",
- params={
- "allow_relative": {"description": _("this filename could be a relative path")},
- "test_existence": {"description": _("this file must exist")},
- "types": {"description": _("file type allowed"), "doc": _("file type allowed: {0}"), "choices": ("file", "directory"), "multi": True},
- },
- example="/tmp/myfile.txt"),
+ "unix_filename": dict(
+ opttype="FilenameOption",
+ msg="UNIX filename",
+ params={
+ "allow_relative": {
+ "description": _("this filename could be a relative path")
+ },
+ "test_existence": {"description": _("this file must exist")},
+ "types": {
+ "description": _("file type allowed"),
+ "doc": _("file type allowed: {0}"),
+ "choices": ("file", "directory"),
+ "multi": True,
+ },
+ },
+ example="/tmp/myfile.txt",
+ ),
"date": dict(opttype="DateOption", example="2000-01-01"),
- "unix_user": dict(opttype="UsernameOption", example="username",
- msg="UNIX user"
- ),
+ "unix_user": dict(opttype="UsernameOption", example="username", msg="UNIX user"),
"ip": dict(
- opttype="IPOption", initkwargs={"allow_reserved": True},
+ opttype="IPOption",
+ initkwargs={"allow_reserved": True},
msg="IP",
params=_ip_params,
- example="1.1.1.1"
+ example="1.1.1.1",
+ ),
+ "cidr": dict(
+ opttype="IPOption",
+ msg="CIDR",
+ initkwargs={"cidr": True},
+ params=_ip_params,
+ example="1.1.1.0/24",
),
- "cidr": dict(opttype="IPOption", msg="CIDR", initkwargs={"cidr": True},
- params=_ip_params,
- example="1.1.1.0/24"),
"netmask": dict(opttype="NetmaskOption", example="255.255.255.0"),
- "network": dict(opttype="NetworkOption",
- params=_network_params,
- example="1.1.1.0"),
+ "network": dict(opttype="NetworkOption", params=_network_params, example="1.1.1.0"),
"network_cidr": dict(
- opttype="NetworkOption", initkwargs={"cidr": True}, example="1.1.1.0/24",
- params=_network_params,
+ opttype="NetworkOption",
+ initkwargs={"cidr": True},
+ example="1.1.1.0/24",
+ params=_network_params,
msg="network CIDR",
),
"broadcast": dict(opttype="BroadcastOption", example="1.1.1.255"),
@@ -200,9 +249,11 @@ CONVERT_OPTION = {
example="https://example.net",
),
"port": dict(
- opttype="PortOption", initkwargs={"allow_private": True},
+ opttype="PortOption",
+ initkwargs={"allow_private": True},
params=_port_params,
- example="111", func=str,
+ example="111",
+ func=str,
),
"mac": dict(opttype="MACOption", example="00:00:00:00:00"),
"unix_permissions": dict(
@@ -218,9 +269,10 @@ CONVERT_OPTION = {
"symlink": dict(opttype="SymLinkOption"),
}
# only version 1.1
-RENAME_TYPE = {"number": "integer",
- "leadership": "sequence",
- }
+RENAME_TYPE = {
+ "number": "integer",
+ "leadership": "sequence",
+}
def get_identifier_from_dynamic_family(true_name, name) -> str:
@@ -240,7 +292,9 @@ def raise_carry_out_calculation_error(subconfig, *args, **kwargs):
ymlfiles = subconfig.config_bag.context.get_values().get_information(
subconfig, "ymlfiles", []
)
- raise ConfigError(_("{0} in {1}").format(err, display_xmlfiles(ymlfiles)), subconfig=subconfig)
+ raise ConfigError(
+ _("{0} in {1}").format(err, display_xmlfiles(ymlfiles)), subconfig=subconfig
+ )
errors.raise_carry_out_calculation_error = raise_carry_out_calculation_error
@@ -249,7 +303,7 @@ errors.raise_carry_out_calculation_error = raise_carry_out_calculation_error
global func
dict_env = {}
ENV = SandboxedEnvironment(loader=DictLoader(dict_env), undefined=StrictUndefined)
-ENV.add_extension('jinja2.ext.do')
+ENV.add_extension("jinja2.ext.do")
func = ENV.filters
TMP_TEMPLATE = mkdtemp()
@@ -258,6 +312,7 @@ ENV.compile_templates(TMP_TEMPLATE, zip=None)
atexit.register(rmtree, TMP_TEMPLATE)
+
class JinjaError:
__slot__ = ("_err",)
@@ -327,6 +382,7 @@ def tiramisu_display_name(
with_quote: bool = False,
) -> str:
"""Replace the Tiramisu display_name function to display path + description"""
+
def get_path():
if description_type in ["description", "name", "name_and_description"]:
path = kls.impl_getname()
@@ -337,6 +393,7 @@ def tiramisu_display_name(
"{{ identifier }}", normalize_family(str(subconfig.identifiers[-1]))
)
return path
+
config_bag = subconfig.config_bag
context = config_bag.context
values = context.get_values()
@@ -344,12 +401,23 @@ def tiramisu_display_name(
description_type = values.get_information(
context_subconfig, "description_type", "name_and_description"
)
- if description_type in ["description", "name_and_description", "path_and_description"]:
+ if description_type in [
+ "description",
+ "name_and_description",
+ "path_and_description",
+ ]:
doc = values.get_information(subconfig, "doc", None)
description = doc if doc and doc != kls.impl_getname() else ""
if "{{ identifier }}" in description and subconfig.identifiers:
- description = description.replace("{{ identifier }}", str(subconfig.identifiers[-1]))
- if description_type in ["name", "path", "name_and_description", "path_and_description"]:
+ description = description.replace(
+ "{{ identifier }}", str(subconfig.identifiers[-1])
+ )
+ if description_type in [
+ "name",
+ "path",
+ "name_and_description",
+ "path_and_description",
+ ]:
path = get_path()
if description_type in ["name_and_description", "path_and_description"]:
if description:
@@ -414,15 +482,15 @@ def jinja_to_function(
for v in value:
if isinstance(v, PropertiesOptionError):
v = JinjaError(v)
-# if v is None:
-# v = ''
+ # if v is None:
+ # v = ''
val.append(v)
value = val
else:
if isinstance(value, PropertiesOptionError):
value = JinjaError(value)
-# if value is None:
-# value = ''
+ # if value is None:
+ # value = ''
if "." in key:
c_kw = kw
path, var = key.rsplit(".", 1)
@@ -446,12 +514,14 @@ def jinja_to_function(
except Exception as err:
kw_str = ", ".join(kw_to_string(kw))
prefix = _('cannot calculate the variable "{0}"').format(__internal_variable)
- msg = _('the attribute "{0}" in {1} with the parameters "{2}" causes the error: {3}').format(
- __internal_attribute,
- display_xmlfiles(__internal_files),
- kw_str,
- err,
- )
+ msg = _(
+ 'the attribute "{0}" in {1} with the parameters "{2}" causes the error: {3}'
+ ).format(
+ __internal_attribute,
+ display_xmlfiles(__internal_files),
+ kw_str,
+ err,
+ )
raise ConfigError(msg, prefix=prefix) from err
convert = CONVERT_OPTION[__internal_type].get("func", str)
if __internal_multi:
@@ -468,10 +538,10 @@ def jinja_to_function(
msg = _('"{0}" is an invalid {1}').format(values, __internal_type)
if __internal_attribute != "default":
msg = _('the attribute "{0}" in {1} causes the error: {2}').format(
- __internal_attribute,
- display_xmlfiles(__internal_files),
- msg,
- )
+ __internal_attribute,
+ display_xmlfiles(__internal_files),
+ msg,
+ )
raise ConfigError(msg, prefix=prefix) from err
values = values if values != "" and values != "None" else None
if values is None and __default_value is not None:
diff --git a/src/rougail/types.py b/src/rougail/types.py
index 41d55b25d..d61cabfcc 100644
--- a/src/rougail/types.py
+++ b/src/rougail/types.py
@@ -15,6 +15,7 @@ details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see .
"""
+
from .config import StaticRougailConvert
from .i18n import _
from .error import DictConsistencyError
@@ -27,17 +28,21 @@ class TypeRougailConvert(StaticRougailConvert):
secret_pattern: str,
default_structural_format_version: str,
) -> None:
- super().__init__(False, {"sort_structural_files_all": True,
- "main_namespace": None,
- "main_structural_directories": main_structural_directories,
- })
+ super().__init__(
+ False,
+ {
+ "sort_structural_files_all": True,
+ "main_namespace": None,
+ "main_structural_directories": main_structural_directories,
+ },
+ )
self.default_structural_format_version = default_structural_format_version
self.secret_pattern = secret_pattern
self.loaded_custom_types = {}
def load_config(self) -> None:
super().load_config()
-# self.add_extra_options = self.add_extra_options
+ # self.add_extra_options = self.add_extra_options
self.sort_structural_files_all = False
self.structurals = ["directory"]
@@ -46,10 +51,11 @@ def rougail_type(rougailconfig):
types = rougailconfig["types"]
if not types:
return {"custom_variable_types": {}, "custom_family_types": {}}
- convert = TypeRougailConvert(types,
- rougailconfig["secret_manager.pattern"],
- rougailconfig["default_structural_format_version"],
- )
+ convert = TypeRougailConvert(
+ types,
+ rougailconfig["secret_manager.pattern"],
+ rougailconfig["default_structural_format_version"],
+ )
convert.init()
convert.parse_directories()
loaded_custom_types_keys = list(convert.loaded_custom_types)
@@ -68,10 +74,11 @@ def rougail_type(rougailconfig):
custom_variable_types = {}
custom_family_types = {}
for typ, data in convert.loaded_custom_types.items():
- if data.option_type == 'variable':
+ if data.option_type == "variable":
custom_variable_types[typ] = data
else:
custom_family_types[typ] = data
- return {"custom_variable_types": custom_variable_types,
- "custom_family_types": custom_family_types,
- }
+ return {
+ "custom_variable_types": custom_variable_types,
+ "custom_family_types": custom_family_types,
+ }
diff --git a/src/rougail/user_data.py b/src/rougail/user_data.py
index 993059786..b4cfa0ff4 100644
--- a/src/rougail/user_data.py
+++ b/src/rougail/user_data.py
@@ -82,11 +82,12 @@ class UserData:
source = datas["source"]
for name, data in datas.get("values", {}).items():
self.values.setdefault(name, []).append(
- {
- "source": source,
- "values": data,
- "options": options.copy(),
- })
+ {
+ "source": source,
+ "values": data,
+ "options": options.copy(),
+ }
+ )
self.errors.extend(datas.get("errors", []))
self.warnings.extend(datas.get("warnings", []))
@@ -102,7 +103,7 @@ class UserData:
if self.invalid_user_data_error:
msg = str(err)
else:
- msg = _('{0}, it will be ignored').format(err)
+ msg = _("{0}, it will be ignored").format(err)
self.invalids.append({msg: err.subconfig})
def _auto_configure_dynamics(self):
@@ -211,7 +212,9 @@ class UserData:
if option.issubmulti():
for idx, val in enumerate(value):
if isinstance(val, list):
- value[idx] = [convert_value(option, v, needs_convert) for v in val]
+ value[idx] = [
+ convert_value(option, v, needs_convert) for v in val
+ ]
elif isinstance(value, list):
value = [convert_value(option, val, needs_convert) for val in value]
if needs_convert:
@@ -236,21 +239,26 @@ class UserData:
if option.type() == "password":
one_is_in_error = False
for values in self.values[values_path]:
- if values.get("options", {}).get("allow_secrets_variables", True) is False:
+ if (
+ values.get("options", {}).get(
+ "allow_secrets_variables", True
+ )
+ is False
+ ):
one_is_in_error = True
- self.errors.append({
- _(
- 'the variable contains secrets and should not be defined in {0}'
- ).format(values["source"]): option._subconfig}
+ self.errors.append(
+ {
+ _(
+ "the variable contains secrets and should not be defined in {0}"
+ ).format(values["source"]): option._subconfig
+ }
)
if one_is_in_error:
self.values.pop(values_path)
continue
values = self.values[values_path][-1]
options = values.get("options", {})
- value = self.convert_value(
- path, option, options, values["values"]
- )
+ value = self.convert_value(path, option, options, values["values"])
index = option.index()
if index is not None:
if isinstance(value, tuple):
@@ -278,8 +286,8 @@ class UserData:
value_is_set = True
except Exception as err:
pass
-# if path != option.path():
-# self.values[option.path()] = self.values.pop(values_path)
+ # if path != option.path():
+ # self.values[option.path()] = self.values.pop(values_path)
else:
# value is correctly set, remove variable to the set
if index is not None:
@@ -326,34 +334,51 @@ class UserData:
if value:
if self.invalid_user_data_error:
msg = _(
- 'it\'s a family so we cannot set the value {0}, it has been loading from {1}'
- )
+ "it's a family so we cannot set the value {0}, it has been loading from {1}"
+ )
else:
msg = _(
- 'it\'s a family so we cannot set the value {0}, it will be ignored when loading from {1}'
- )
- self.invalids.append({msg.format(
- self._display_value(option, value),
- options["source"],
- ): option._subconfig}
+ "it's a family so we cannot set the value {0}, it will be ignored when loading from {1}"
+ )
+ self.invalids.append(
+ {
+ msg.format(
+ self._display_value(option, value),
+ options["source"],
+ ): option._subconfig
+ }
)
continue
if option.issymlinkoption():
- err = _('it\'s a symlink option so we cannot set the value {0}').format(self._display_value(option, value))
+ err = _(
+ "it's a symlink option so we cannot set the value {0}"
+ ).format(self._display_value(option, value))
if self.invalid_user_data_error:
- msg = _('{0}, it has been loading from {1}').format(err, options["source"])
+ msg = _("{0}, it has been loading from {1}").format(
+ err, options["source"]
+ )
else:
- msg = _('{0}, it will be ignored when loading from {1}').format(err, options["source"])
+ msg = _("{0}, it will be ignored when loading from {1}").format(
+ err, options["source"]
+ )
self.unknowns.append({msg: option._subconfig})
continue
except ConfigError as err:
- self.invalids.append({
- _("{0}, it has been loaded from {1}").format(err, options["source"]): option._subconfig}
+ self.invalids.append(
+ {
+ _("{0}, it has been loaded from {1}").format(
+ err, options["source"]
+ ): option._subconfig
+ }
)
continue
except PropertiesOptionError as err:
- self.unknowns.append({
- _("{0}, it has been loaded from {1}").format(err, options["source"]): option._subconfig}
+ self.unknowns.append(
+ {
+ _("{0}, it has been loaded from {1}").format(
+ err, options["source"]
+ ): option._subconfig
+ }
)
continue
@@ -364,20 +389,16 @@ class UserData:
subconfig = None
child_name = err_path
else:
- parent_path, child_name = err_path.rsplit('.', 1)
+ parent_path, child_name = err_path.rsplit(".", 1)
subconfig = self.config.option(parent_path)
subconfig._set_subconfig()
err_msg = _(
'variable or family "{0}" does not exist so cannot load "{1}"'
- ).format(child_name, path)
+ ).format(child_name, path)
if self.unknown_user_data_error:
- msg = _(
- '{0}, it has been loading from {1}'
- )
+ msg = _("{0}, it has been loading from {1}")
else:
- msg = _(
- '{0}, it will be ignored when loading from {1}'
- )
+ msg = _("{0}, it will be ignored when loading from {1}")
msg = msg.format(err_msg, options["source"])
if subconfig is not None:
msg = {msg: subconfig._subconfig}
@@ -385,13 +406,19 @@ class UserData:
elif err.code == "option-dynamic":
if self.invalid_user_data_error:
msg = _(
- '"{0}" is the name of a dynamic family, it has been loading from {1}'
+ '"{0}" is the name of a dynamic family, it has been loading from {1}'
)
else:
msg = _(
- '"{0}" is the name of a dynamic family, it will be ignored when loading from {1}'
+ '"{0}" is the name of a dynamic family, it will be ignored when loading from {1}'
)
- self.invalids.append({msg.format(option.description(with_quote=True), options["source"]): option._subconfig})
+ self.invalids.append(
+ {
+ msg.format(
+ option.description(with_quote=True), options["source"]
+ ): option._subconfig
+ }
+ )
else:
self.invalids.append(
_("{0} loaded from {1}").format(err, options["source"])
@@ -430,7 +457,9 @@ class UserData:
[_(prop) for prop in err.proptype], add_quote=False
)
err_path = err.subconfig.path
- err_description = err.subconfig.option.impl_get_display_name(err.subconfig, with_quote=True)
+ err_description = err.subconfig.option.impl_get_display_name(
+ err.subconfig, with_quote=True
+ )
display_name = option.description(with_quote=True)
if index is not None:
if path == err_path:
@@ -442,13 +471,15 @@ class UserData:
msg = _(
'variable {0} at index "{1}" is {2}, it will be ignored when loading from {3}'
)
- self.unknowns.append({
- msg.format(
- display_name,
- index,
- properties,
- options["source"],
- ): option._subconfig}
+ self.unknowns.append(
+ {
+ msg.format(
+ display_name,
+ index,
+ properties,
+ options["source"],
+ ): option._subconfig
+ }
)
else:
if self.unknown_user_data_error:
@@ -459,14 +490,16 @@ class UserData:
msg = _(
'family {0} is {1}, {2} at index "{3}", it will be ignored when loading from {4}'
)
- self.unknowns.append({
- msg.format(
- err_description,
- properties,
- display_name,
- index,
- options["source"],
- ): option._subconfig}
+ self.unknowns.append(
+ {
+ msg.format(
+ err_description,
+ properties,
+ display_name,
+ index,
+ options["source"],
+ ): option._subconfig
+ }
)
else:
if path == err_path:
@@ -478,13 +511,17 @@ class UserData:
msg = _(
"variable has property {0}, it will be ignored when loading from {1}"
)
- self.unknowns.append({
- msg.format(
- properties, options["source"]
- ): option._subconfig}
+ self.unknowns.append(
+ {
+ msg.format(
+ properties, options["source"]
+ ): option._subconfig
+ }
)
else:
- if not options.get("options", {}).get("secret_manager", False):
+ if not options.get("options", {}).get(
+ "secret_manager", False
+ ):
if self.unknown_user_data_error:
msg = _(
"family {0} has property {1}, so cannot access to {2}, it has been loading from {3}"
@@ -493,57 +530,59 @@ class UserData:
msg = _(
"family {0} has property {1}, so cannot access to {2}, it will be ignored when loading from {3}"
)
- self.unknowns.append({
- msg.format(
- err_description,
- properties,
- display_name,
- options["source"],
- ): option._subconfig}
+ self.unknowns.append(
+ {
+ msg.format(
+ err_description,
+ properties,
+ display_name,
+ options["source"],
+ ): option._subconfig
+ }
)
else:
if self.unknown_user_data_error:
- msg = _(
- "{0}, it has been loading from {1}"
- )
+ msg = _("{0}, it has been loading from {1}")
else:
- msg = _(
- "{0}, it will be ignored when loading from {1}"
- )
- self.unknowns.append({
- msg.format(err, options["source"]): option._subconfig}
+ msg = _("{0}, it will be ignored when loading from {1}")
+ self.unknowns.append(
+ {msg.format(err, options["source"]): option._subconfig}
)
except LeadershipError as err:
if self.unknown_user_data_error:
- msg = _(
- "{0}, it has been loading from {1}"
- )
+ msg = _("{0}, it has been loading from {1}")
else:
- msg = _(
- "{0}, it will be ignored when loading from {1}"
- )
- self.unknowns.append({
- msg.format(err, options["source"]): option._subconfig}
+ msg = _("{0}, it will be ignored when loading from {1}")
+ self.unknowns.append(
+ {msg.format(err, options["source"]): option._subconfig}
)
except ConfigError as err:
err.prefix = ""
if self.invalid_user_data_error:
- msg = _('{0}, it has been loading from {1}').format(err, options["source"])
+ msg = _("{0}, it has been loading from {1}").format(
+ err, options["source"]
+ )
else:
- msg = _('{0}, it will be ignored when loading from {1}').format(err, options["source"])
+ msg = _("{0}, it will be ignored when loading from {1}").format(
+ err, options["source"]
+ )
self.invalids.append({msg: option._subconfig})
except ValueError as err:
err.prefix = ""
type_ = option.type(translation=True)
- msg = _('the value {0} is an invalid {1}, {2}').format(
- self._display_value(option, value),
- type_,
- err,
- )
+ msg = _("the value {0} is an invalid {1}, {2}").format(
+ self._display_value(option, value),
+ type_,
+ err,
+ )
if self.invalid_user_data_error:
- msg += _(', it has been loading from {0}').format(options["source"])
+ msg += _(", it has been loading from {0}").format(
+ options["source"]
+ )
else:
- msg += _(', it will be ignored when loading from {0}').format(options["source"])
+ msg += _(", it will be ignored when loading from {0}").format(
+ options["source"]
+ )
self.invalids.append({msg: option._subconfig})
except AttributeOptionError as err:
err.prefix = ""
@@ -557,10 +596,12 @@ class UserData:
if is_secret_manager and isinstance(value, tuple):
# it's a function
params = tuple([ParamValue(val) for val in value[1:]])
- option.information.set('secret_manager', True)
+ option.information.set("secret_manager", True)
if index is not None:
option = option.forcepermissive.index(index)
- value = Calculation(value[0], Params(params, kwargs={"option": ParamValue(option)}))
+ value = Calculation(
+ value[0], Params(params, kwargs={"option": ParamValue(option)})
+ )
option = option.forcepermissive
add_validation = True
else:
@@ -586,9 +627,7 @@ class UserData:
key = f"loaded_from_{index}"
else:
key = "loaded_from"
- value = _("loaded from {0}").format(
- self.values[path][-1]["source"]
- )
+ value = _("loaded from {0}").format(self.values[path][-1]["source"])
if options.get("secret_manager"):
# FIXME (true_config ???)
default = option.value.default()
@@ -658,12 +697,18 @@ def _populate_mandatory(option, errors: list) -> None:
if index is None:
msg = _("mandatory variable but has no value")
else:
- msg = _('mandatory variable at index "{0}" but has no value').format(index)
+ msg = _('mandatory variable at index "{0}" but has no value').format(
+ index
+ )
else:
if index is None:
- msg = _("mandatory variable but is inaccessible and has no value or has null in value")
+ msg = _(
+ "mandatory variable but is inaccessible and has no value or has null in value"
+ )
else:
- msg = _('mandatory variable at index "{0}" but is inaccessible and has no value or has null in value').format(index)
+ msg = _(
+ 'mandatory variable at index "{0}" but is inaccessible and has no value or has null in value'
+ ).format(index)
else:
proptype = option.value.mandatory(return_type=True)
if proptype == "empty":
diff --git a/src/rougail/utils.py b/src/rougail/utils.py
index 6e287b8f1..97c281a9a 100644
--- a/src/rougail/utils.py
+++ b/src/rougail/utils.py
@@ -85,7 +85,7 @@ def get_jinja_variable_to_param(
):
try:
env = SandboxedEnvironment(loader=DictLoader({"tmpl": jinja_text}))
- env.add_extension('jinja2.ext.do')
+ env.add_extension("jinja2.ext.do")
env.filters = functions
parsed_content = Parser(env, jinja_text, "", "").parse()