fix: black

This commit is contained in:
egarette@silique.fr 2026-06-21 17:05:44 +02:00
parent 324bc49255
commit 7ae6a70166
10 changed files with 307 additions and 146 deletions

View file

@ -1,7 +1,7 @@
""" """
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2024-2026 Copyright (C) 2024-2026
This program is free software: you can redistribute it and/or modify it This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the under the terms of the GNU Lesser General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your Free Software Foundation, either version 3 of the License, or (at your

View file

@ -64,7 +64,9 @@ class Annotator(Walk):
else: else:
self.default_values = self.objectspace.rougailconfig["doc.default_values"] self.default_values = self.objectspace.rougailconfig["doc.default_values"]
if "force_display_unknown_optional_variable" in kwargs: if "force_display_unknown_optional_variable" in kwargs:
self.display_unknown_optional_variable = kwargs["force_display_unknown_optional_variable"] self.display_unknown_optional_variable = kwargs[
"force_display_unknown_optional_variable"
]
else: else:
self.display_unknown_optional_variable = False self.display_unknown_optional_variable = False
self.regexp_description_get_paths = None self.regexp_description_get_paths = None
@ -264,16 +266,19 @@ class Annotator(Walk):
values.xmlfiles, values.xmlfiles,
) )
if variable: if variable:
val_description = val_description.replace(f'"{r_path}"', f'{{{index}}}') val_description = val_description.replace(
f'"{r_path}"', f"{{{index}}}"
)
v = {"path": variable.path, "description": variable.description} v = {"path": variable.path, "description": variable.description}
if identifiers: if identifiers:
v["identifiers"] = [identifiers] v["identifiers"] = [identifiers]
v["identifier_type"] = "many" v["identifier_type"] = "many"
variables.append(v) variables.append(v)
index += 1 index += 1
description = {"description": True, description = {
"value": val_description, "description": True,
} "value": val_description,
}
if variables: if variables:
description["variables"] = variables description["variables"] = variables
else: else:

View file

@ -1,7 +1,7 @@
""" """
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2025-2026 Copyright (C) 2025-2026
This program is free software: you can redistribute it and/or modify it This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the under the terms of the GNU Lesser General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your Free Software Foundation, either version 3 of the License, or (at your
@ -178,7 +178,9 @@ class Changelog: # pylint: disable=no-member,too-few-public-methods
else: else:
title = _("Deleted variables") title = _("Deleted variables")
lst.append(self.formatter.title(title, self.level)) lst.append(self.formatter.title(title, self.level))
lst.append(self.formatter.list(self._removed_variables, inside_tabular=False)) lst.append(
self.formatter.list(self._removed_variables, inside_tabular=False)
)
end = self.formatter.end_family(self.level) end = self.formatter.end_family(self.level)
if end: if end:
lst.append(end) lst.append(end)

View file

@ -24,7 +24,11 @@ from tiramisu.error import display_list, PropertiesOptionError
from tiramisu.config import get_common_path from tiramisu.config import get_common_path
from rougail.tiramisu import display_xmlfiles from rougail.tiramisu import display_xmlfiles
from rougail.utils import PROPERTY_ATTRIBUTE from rougail.utils import PROPERTY_ATTRIBUTE
from rougail.error import VariableCalculationDependencyError, RougailWarning, ExtensionError from rougail.error import (
VariableCalculationDependencyError,
RougailWarning,
ExtensionError,
)
from .utils import dump, to_phrase, calc_path, add_dot, doc_path from .utils import dump, to_phrase, calc_path, add_dot, doc_path
from .i18n import _ from .i18n import _
@ -67,7 +71,9 @@ class _ToString:
return ret[0] return ret[0]
return ret return ret
def _calculation_to_string(self, child, calculation, attribute_type, inside_list=True): def _calculation_to_string(
self, child, calculation, attribute_type, inside_list=True
):
if calculation.get("description", False): if calculation.get("description", False):
values = calculation.copy() values = calculation.copy()
if self.document_a_type and "variables" in values: if self.document_a_type and "variables" in values:
@ -110,7 +116,9 @@ class _ToString:
if not inside_list: if not inside_list:
msg = add_dot(msg) msg = add_dot(msg)
variable = self.true_config.unrestraint.option(calculation["path"]) variable = self.true_config.unrestraint.option(calculation["path"])
values = self._calculation_with_variable(child, variable, calculation, msg) values = self._calculation_with_variable(
child, variable, calculation, msg
)
else: else:
values = _('the value of the global information "{0}"').format( values = _('the value of the global information "{0}"').format(
calculation["information"] calculation["information"]
@ -164,7 +172,7 @@ class _ToString:
child, option, condition.get("identifiers") child, option, condition.get("identifiers")
) )
else: else:
# option = self.true_config.option(variable_path) # option = self.true_config.option(variable_path)
try: try:
is_inaccessible = self.is_inaccessible_user_data(option) is_inaccessible = self.is_inaccessible_user_data(option)
except AttributeError as err: except AttributeError as err:
@ -231,7 +239,7 @@ class _ToString:
submsg = display_list( submsg = display_list(
[_("is {0}").format(prop), submsg], separator="or", sort=False [_("is {0}").format(prop), submsg], separator="or", sort=False
) )
msg = _('when the variable {{0}} {0}.').format(submsg) msg = _("when the variable {{0}} {0}.").format(submsg)
path_obj = { path_obj = {
"path": doc_path(variable_path, self.document_a_type), "path": doc_path(variable_path, self.document_a_type),
} }
@ -262,11 +270,13 @@ class _ToString:
variable.get() variable.get()
except AttributeError: except AttributeError:
defined = False defined = False
true_msg = _('the value of the variable {0} if it is defined') true_msg = _("the value of the variable {0} if it is defined")
else: else:
true_msg = _('the value of the variable {0}') true_msg = _("the value of the variable {0}")
if defined: if defined:
return self._calculation_with_variable(child, variable, calculation["value"], true_msg) return self._calculation_with_variable(
child, variable, calculation["value"], true_msg
)
return { return {
"message": true_msg, "message": true_msg,
"path": calculation["value"], "path": calculation["value"],
@ -280,9 +290,7 @@ class _ToString:
func = self._calculation_dynamic_variable_with_variable func = self._calculation_dynamic_variable_with_variable
return func(child, variable, calculation, msg) return func(child, variable, calculation, msg)
def _calculation_normal_with_variable( def _calculation_normal_with_variable(self, child, variable, obj, msg):
self, child, variable, obj, msg
):
isfollower = not variable.isoptiondescription() and variable.isfollower() isfollower = not variable.isoptiondescription() and variable.isfollower()
if not isfollower and self.is_inaccessible_user_data(variable): if not isfollower and self.is_inaccessible_user_data(variable):
uncalculated = variable.unrestraint.value.default(uncalculated=True) uncalculated = variable.unrestraint.value.default(uncalculated=True)
@ -295,9 +303,7 @@ class _ToString:
else: else:
if not isinstance(uncalculated, str): if not isinstance(uncalculated, str):
uncalculated = dump(uncalculated) uncalculated = dump(uncalculated)
msg = _("{0} (from an undocumented variable)").format( msg = _("{0} (from an undocumented variable)").format(uncalculated)
uncalculated
)
else: else:
msg = _("the value of an undocumented variable") msg = _("the value of an undocumented variable")
try: try:
@ -310,13 +316,14 @@ class _ToString:
"description": description, "description": description,
} }
def _calculation_dynamic_variable_with_variable( def _calculation_dynamic_variable_with_variable(self, child, variable, obj, msg):
self, child, variable, obj, msg
):
values = [] values = []
for path, description, identifiers, identifier_type in self._get_annotation_variable( for (
child, variable, obj.get("identifiers") path,
): description,
identifiers,
identifier_type,
) in self._get_annotation_variable(child, variable, obj.get("identifiers")):
variable = self.true_config.option(path) variable = self.true_config.option(path)
path_obj = { path_obj = {
"path": doc_path(path, self.document_a_type), "path": doc_path(path, self.document_a_type),
@ -325,9 +332,7 @@ class _ToString:
path_obj["identifiers"] = identifiers path_obj["identifiers"] = identifiers
path_obj["identifier_type"] = identifier_type path_obj["identifier_type"] = identifier_type
values.append( values.append(
self._calculation_normal_with_variable( self._calculation_normal_with_variable(child, variable, path_obj, msg)
child, variable, path_obj, msg
)
) )
return values return values
@ -350,13 +355,13 @@ class _ToString:
if ori_identifiers: if ori_identifiers:
if path.count("{{ identifier }}") == len(ori_identifiers): if path.count("{{ identifier }}") == len(ori_identifiers):
identifier_type = "one" identifier_type = "one"
elif "{{ identifier }}" in path[len(get_common_path(child_path, path)):]: elif "{{ identifier }}" in path[len(get_common_path(child_path, path)) :]:
identifier_type = "outside" identifier_type = "outside"
else: else:
identifier_type = "inside" identifier_type = "inside"
else: else:
common_path = get_common_path(child_path, path) common_path = get_common_path(child_path, path)
if common_path and "{{ identifier }}" in path[len(common_path):]: if common_path and "{{ identifier }}" in path[len(common_path) :]:
identifier_type = "outside" identifier_type = "outside"
else: else:
identifier_type = "inside" identifier_type = "inside"
@ -640,7 +645,11 @@ class Collect(_ToString):
annotation = False annotation = False
if child.information.get(f"{prop}_calculation", False): if child.information.get(f"{prop}_calculation", False):
annotation = self._to_string(child, prop) annotation = self._to_string(child, prop)
if not self.only_disabled and annotation is None and prop in HIDDEN_PROPERTIES: if (
not self.only_disabled
and annotation is None
and prop in HIDDEN_PROPERTIES
):
return False, [] return False, []
if annotation is True and prop in DISABLED_PROPERTIES: if annotation is True and prop in DISABLED_PROPERTIES:
return False, [] return False, []
@ -697,9 +706,7 @@ class Collect(_ToString):
) )
return None return None
var_type = "variable" if family_type is None else "family" var_type = "variable" if family_type is None else "family"
return self._convert_description( return self._convert_description(child.description(uncalculated=True), var_type)
child.description(uncalculated=True), var_type
)
def _convert_description(self, description, type_): def _convert_description(self, description, type_):
return to_phrase(description, type_) return to_phrase(description, type_)
@ -733,9 +740,7 @@ class Collect(_ToString):
variable.value.get() variable.value.get()
except AttributeError: except AttributeError:
variable = None variable = None
if variable and self.is_inaccessible_user_data( if variable and self.is_inaccessible_user_data(variable):
variable
):
try: try:
variable_value = self._get_unmodified_default_value( variable_value = self._get_unmodified_default_value(
variable variable

View file

@ -87,7 +87,9 @@ class RougailOutputDoc(Collect, Examples, Changelog):
def load_formatter(self) -> str: def load_formatter(self) -> str:
output_format = self.rougailconfig["doc.output_format"] output_format = self.rougailconfig["doc.output_format"]
self.formatter = self.outputs[output_format]( self.formatter = self.outputs[output_format](
self.rougailconfig, support_namespace=self.support_namespace, document_a_type=self.document_a_type self.rougailconfig,
support_namespace=self.support_namespace,
document_a_type=self.document_a_type,
) )
def print(self) -> None: def print(self) -> None:
@ -115,8 +117,8 @@ class RougailOutputDoc(Collect, Examples, Changelog):
self.dynamic_paths = {} self.dynamic_paths = {}
if self.config.isoptiondescription(): if self.config.isoptiondescription():
informations = self.collect_families(self.config.unrestraint) informations = self.collect_families(self.config.unrestraint)
# from pprint import pprint # from pprint import pprint
# pprint(informations) # pprint(informations)
else: else:
informations = {} informations = {}
self.collect_variable(self.config, informations) self.collect_variable(self.config, informations)

View file

@ -82,7 +82,13 @@ class Examples: # pylint: disable=no-member,too-few-public-methods
self._set_mandatories(config) self._set_mandatories(config)
return config return config
def _gen_doc_examples(self, config, only_modified: bool, with_secret_manager: bool=True, with_calculated_value: bool=True) -> dict: def _gen_doc_examples(
self,
config,
only_modified: bool,
with_secret_manager: bool = True,
with_calculated_value: bool = True,
) -> dict:
if not only_modified: if not only_modified:
self._set_examples(config) self._set_examples(config)
results = CommentedMap() results = CommentedMap()
@ -107,18 +113,26 @@ class Examples: # pylint: disable=no-member,too-few-public-methods
n_results = n_results[name] n_results = n_results[name]
if only_modified: if only_modified:
if with_calculated_value: if with_calculated_value:
dump_type = 'modified' dump_type = "modified"
else: else:
dump_type = "empty" dump_type = "empty"
else: else:
dump_type = 'all' dump_type = "all"
if root_config.isoptiondescription(): if root_config.isoptiondescription():
self._example_parse_family( self._example_parse_family(
root_config.value.get(), results, dump_type, with_secret_manager=with_secret_manager root_config.value.get(),
results,
dump_type,
with_secret_manager=with_secret_manager,
) )
else: else:
self._set_example_value( self._set_example_value(
results, root_config, root_config.value.get(), dump_type, with_secret_manager, False results,
root_config,
root_config.value.get(),
dump_type,
with_secret_manager,
False,
) )
if true_results and results: if true_results and results:
n_results.update(results) n_results.update(results)
@ -203,26 +217,51 @@ class Examples: # pylint: disable=no-member,too-few-public-methods
return option.issubmulti() return option.issubmulti()
return option.ismulti() return option.ismulti()
def _example_parse_family(self, config, results, dump_type, *, with_secret_manager: bool=True, with_true_path: bool=False) -> None: def _example_parse_family(
self,
config,
results,
dump_type,
*,
with_secret_manager: bool = True,
with_true_path: bool = False,
) -> None:
for option, values in config.items(): for option, values in config.items():
if option.isoptiondescription(): if option.isoptiondescription():
if option.isleadership(): if option.isleadership():
subresults = self._example_parse_sequence(values, dump_type, with_secret_manager, with_true_path) subresults = self._example_parse_sequence(
values, dump_type, with_secret_manager, with_true_path
)
if subresults: if subresults:
name = option.name(uncalculated=with_true_path) name = option.name(uncalculated=with_true_path)
results[name] = subresults results[name] = subresults
self._set_description(results, name, option) self._set_description(results, name, option)
else: else:
subresults = CommentedMap() subresults = CommentedMap()
self._example_parse_family(values, subresults, dump_type, with_secret_manager=with_secret_manager, with_true_path=with_true_path) self._example_parse_family(
values,
subresults,
dump_type,
with_secret_manager=with_secret_manager,
with_true_path=with_true_path,
)
if subresults: if subresults:
name = option.name(uncalculated=with_true_path) name = option.name(uncalculated=with_true_path)
results[name] = subresults results[name] = subresults
self._set_description(results, name, option) self._set_description(results, name, option)
else: else:
self._set_example_value(results, option, values, dump_type, with_secret_manager, with_true_path) self._set_example_value(
results,
option,
values,
dump_type,
with_secret_manager,
with_true_path,
)
def _set_example_value(self, results, option, values, dump_type, with_secret_manager, with_true_path): def _set_example_value(
self, results, option, values, dump_type, with_secret_manager, with_true_path
):
if not self._is_valid_owner(option, dump_type): if not self._is_valid_owner(option, dump_type):
return return
if not with_secret_manager and option.information.get("secret_manager", False): if not with_secret_manager and option.information.get("secret_manager", False):
@ -242,22 +281,50 @@ class Examples: # pylint: disable=no-member,too-few-public-methods
return "hidden" in option.property.get() return "hidden" in option.property.get()
is_default = option.owner.isdefault() is_default = option.owner.isdefault()
return ( return (
(dump_type == 'modified' and not is_default and option.owner.get() != owners.forced) (
or (dump_type == "empty" and "hidden" in option.property.get() and not option.information.get("default_calculation", None) and (option.value.default(uncalculated=True) in [None, []] or not option.information.get("default_value_makes_sense", True))) dump_type == "modified"
or (dump_type == 'default' and is_default) and not is_default
and option.owner.get() != owners.forced
)
or (
dump_type == "empty"
and "hidden" in option.property.get()
and not option.information.get("default_calculation", None)
and (
option.value.default(uncalculated=True) in [None, []]
or not option.information.get("default_value_makes_sense", True)
)
)
or (dump_type == "default" and is_default)
) )
def _example_parse_sequence(self, values, dump_type, with_secret_manager, with_true_path): def _example_parse_sequence(
self, values, dump_type, with_secret_manager, with_true_path
):
sequence_iter = iter(values.items()) sequence_iter = iter(values.items())
leader, leader_values = next(sequence_iter) leader, leader_values = next(sequence_iter)
if not self._is_valid_owner(leader, dump_type): if not self._is_valid_owner(leader, dump_type):
return None return None
sequence = [CommentedMap() for idx in range(len(leader_values))] sequence = [CommentedMap() for idx in range(len(leader_values))]
for idx, value in enumerate(leader_values): for idx, value in enumerate(leader_values):
self._set_example_value(sequence[idx], leader, value, dump_type, with_secret_manager, with_true_path) self._set_example_value(
sequence[idx],
leader,
value,
dump_type,
with_secret_manager,
with_true_path,
)
for option, value in sequence_iter: for option, value in sequence_iter:
idx = option.index() idx = option.index()
self._set_example_value(sequence[idx], option, value, dump_type, with_secret_manager, with_true_path) self._set_example_value(
sequence[idx],
option,
value,
dump_type,
with_secret_manager,
with_true_path,
)
return sequence return sequence
def _set_description(self, results, name, option): def _set_description(self, results, name, option):

View file

@ -21,6 +21,7 @@ from typing import List
from ..i18n import _ from ..i18n import _
from rougail.error import ExtensionError from rougail.error import ExtensionError
from ..utils import dump, CommonFormatter from ..utils import dump, CommonFormatter
try: try:
from rich.jupyter import JupyterMixin from rich.jupyter import JupyterMixin
from rich.segment import Segment from rich.segment import Segment
@ -34,6 +35,7 @@ except ModuleNotFoundError:
if Console: if Console:
class BlockQuote(JupyterMixin): class BlockQuote(JupyterMixin):
def __init__( def __init__(
self, self,
@ -72,7 +74,9 @@ class Formatter(CommonFormatter):
def __init__(self, rougailconfig, **kwargs) -> None: def __init__(self, rougailconfig, **kwargs) -> None:
if not Console: if not Console:
raise ExtensionError(_("cannot find Python module Rich, please install it!")) raise ExtensionError(
_("cannot find Python module Rich, please install it!")
)
self.custom_theme = Theme(self.titles_color) self.custom_theme = Theme(self.titles_color)
self.max_line = 0 self.max_line = 0
super().__init__(rougailconfig, **kwargs) super().__init__(rougailconfig, **kwargs)
@ -87,9 +91,7 @@ class Formatter(CommonFormatter):
force_terminal = "xterm-256color" force_terminal = "xterm-256color"
else: else:
force_terminal = None force_terminal = None
console = Console( console = Console(theme=self.custom_theme, force_terminal=force_terminal)
theme=self.custom_theme, force_terminal=force_terminal
)
with console.capture() as capture: with console.capture() as capture:
for data in dico: for data in dico:
console.print(data) console.print(data)
@ -100,7 +102,7 @@ class Formatter(CommonFormatter):
self, self,
title: str, title: str,
level: int, level: int,
collapse: bool=True, collapse: bool = True,
) -> str: ) -> str:
"""Display family name as a title""" """Display family name as a title"""
space = " " * (2 * (level - 1)) space = " " * (2 * (level - 1))

View file

@ -1,7 +1,7 @@
""" """
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2024-2026 Copyright (C) 2024-2026
This program is free software: you can redistribute it and/or modify it This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the under the terms of the GNU Lesser General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your Free Software Foundation, either version 3 of the License, or (at your
@ -45,7 +45,7 @@ class Formatter(CommonFormatter):
self, self,
title: str, title: str,
level: int, level: int,
collapse: bool=True, collapse: bool = True,
) -> str: ) -> str:
"""Display family name as a title""" """Display family name as a title"""
char = "#" char = "#"

View file

@ -1,7 +1,7 @@
""" """
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2025-2026 Copyright (C) 2025-2026
This program is free software: you can redistribute it and/or modify it This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the under the terms of the GNU Lesser General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your Free Software Foundation, either version 3 of the License, or (at your
@ -29,16 +29,17 @@ class Formatter(GithubFormatter):
level = 51 level = 51
format_in_title = False format_in_title = False
def title(self, def title(
title: str, self,
level: int, title: str,
collapse: bool=True, level: int,
) -> str: collapse: bool = True,
) -> str:
if collapse: if collapse:
return "<details><summary>" + title + "</summary>" return "<details><summary>" + title + "</summary>"
return super().title(title, level, collapse) return super().title(title, level, collapse)
def end_family(self, level, collapse: bool=True): def end_family(self, level, collapse: bool = True):
if collapse: if collapse:
return "</details>" return "</details>"
return None return None
@ -61,8 +62,9 @@ class Formatter(GithubFormatter):
def family_informations_starts_line(self) -> str: def family_informations_starts_line(self) -> str:
return "\n> " return "\n> "
# def list(self, *args, **kwargs):
# return super().list(*args, **kwargs) + "\n" # def list(self, *args, **kwargs):
# return super().list(*args, **kwargs) + "\n"
def family_informations_starts_list_first(self): def family_informations_starts_list_first(self):
return "" return ""

View file

@ -286,11 +286,11 @@ class CommonFormatter:
if not self.rougailconfig["main_namespace"] and self.with_environment: if not self.rougailconfig["main_namespace"] and self.with_environment:
environment_prefix = self.rougailconfig["doc.tabulars.environment_prefix"] environment_prefix = self.rougailconfig["doc.tabulars.environment_prefix"]
if environment_prefix: if environment_prefix:
self.prefix = ( self.prefix = environment_prefix + "_"
environment_prefix + "_"
)
self.with_family = not self.rougailconfig["doc.tabulars.without_family"] self.with_family = not self.rougailconfig["doc.tabulars.without_family"]
self.other_root_filenames = dict(self.rougailconfig["doc.other_root_filenames"].items()) self.other_root_filenames = dict(
self.rougailconfig["doc.other_root_filenames"].items()
)
tabular_template = self.rougailconfig["doc.tabular_template"] tabular_template = self.rougailconfig["doc.tabular_template"]
self.tabular_datas = Tabulars().get()[tabular_template](self) self.tabular_datas = Tabulars().get()[tabular_template](self)
@ -302,7 +302,7 @@ class CommonFormatter:
self, self,
title: str, title: str,
level: int, level: int,
collapse: bool=True, collapse: bool = True,
) -> str: ) -> str:
"""Display family name as a title""" """Display family name as a title"""
raise NotImplementedError() raise NotImplementedError()
@ -385,10 +385,10 @@ class CommonFormatter:
"""Add a link""" """Add a link"""
raise NotImplementedError() raise NotImplementedError()
def yaml(self, _dump: str, yaml_version: str="1.1"): def yaml(self, _dump: str, yaml_version: str = "1.1"):
output = f"---\n{_dump}" output = f"---\n{_dump}"
if yaml_version == "1.2": if yaml_version == "1.2":
output = f'%YAML 1.2\n{output}\n...' output = f"%YAML 1.2\n{output}\n..."
return self._yaml(output) return self._yaml(output)
################## ##################
@ -414,6 +414,7 @@ class CommonFormatter:
def anchor(path, true_path): def anchor(path, true_path):
return path return path
ret_paths = [] ret_paths = []
path = informations["path"] path = informations["path"]
if not path: if not path:
@ -537,7 +538,8 @@ class CommonFormatter:
else: else:
ret = [ ret = [
self.title( self.title(
self.get_description(informations, {}, title=True), level, self.get_description(informations, {}, title=True),
level,
) )
] ]
msg = [] msg = []
@ -567,7 +569,10 @@ class CommonFormatter:
full_path = informations["path"] full_path = informations["path"]
msg.append( msg.append(
self.section( self.section(
full_path, _("Identifiers"), informations["identifier"], type_="family" full_path,
_("Identifiers"),
informations["identifier"],
type_="family",
) )
) )
if msg: if msg:
@ -593,7 +598,7 @@ class CommonFormatter:
def family_informations_ends_line(self) -> str: def family_informations_ends_line(self) -> str:
return "" return ""
def end_family(self, level: int, collapse: bool=True) -> str: def end_family(self, level: int, collapse: bool = True) -> str:
return None return None
def convert_list_to_string( def convert_list_to_string(
@ -627,12 +632,21 @@ class CommonFormatter:
informations: dict, informations: dict,
modified_attributes: dict, modified_attributes: dict,
*, *,
force_identifiers: Optional[list]=None, force_identifiers: Optional[list] = None,
with_to_phrase: bool=True, with_to_phrase: bool = True,
title: bool=False, title: bool = False,
) -> str: ) -> str:
add_new_description = True add_new_description = True
def _get_description(description, identifiers, delete=False, new=[], previous_identifiers=[], new_identifiers=[], its_a_name=False):
def _get_description(
description,
identifiers,
delete=False,
new=[],
previous_identifiers=[],
new_identifiers=[],
its_a_name=False,
):
if identifiers and "{{ identifier }}" in description: if identifiers and "{{ identifier }}" in description:
if its_a_name: if its_a_name:
information_type = "name" information_type = "name"
@ -653,14 +667,15 @@ class CommonFormatter:
formatter = self formatter = self
else: else:
formatter = None formatter = None
description = get_path_from_identifiers(description, description = get_path_from_identifiers(
identifiers, description,
previous_identifiers, identifiers,
new_identifiers, previous_identifiers,
identifier_type, new_identifiers,
formatter=formatter, identifier_type,
information_type=information_type, formatter=formatter,
) information_type=information_type,
)
elif with_to_phrase: elif with_to_phrase:
description = self.to_phrase(description) description = self.to_phrase(description)
if description in new: if description in new:
@ -685,15 +700,25 @@ class CommonFormatter:
) )
else: else:
modified_description = None modified_description = None
elif "identifiers" in modified_attributes and "{{ identifier }}" in informations["description"]: elif (
"identifiers" in modified_attributes
and "{{ identifier }}" in informations["description"]
):
# FIXME aussi au dessus ! # FIXME aussi au dessus !
name, previous, new = modified_attributes["identifiers"] name, previous, new = modified_attributes["identifiers"]
previous_identifiers = previous[-1] if previous else [] previous_identifiers = previous[-1] if previous else []
new_identifiers = new[-1] if new else [] new_identifiers = new[-1] if new else []
if new_identifiers: if new_identifiers:
all_identifiers = [identifier for identifier in all_identifiers if identifier != new_identifiers] all_identifiers = [
identifier
for identifier in all_identifiers
if identifier != new_identifiers
]
modified_description = _get_description( modified_description = _get_description(
informations["description"], all_identifiers, previous_identifiers=previous_identifiers, new_identifiers=new_identifiers informations["description"],
all_identifiers,
previous_identifiers=previous_identifiers,
new_identifiers=new_identifiers,
) )
add_new_description = False add_new_description = False
else: else:
@ -706,7 +731,10 @@ class CommonFormatter:
) )
else: else:
description = _get_description( description = _get_description(
informations["name"], all_identifiers, new=new, its_a_name=True, informations["name"],
all_identifiers,
new=new,
its_a_name=True,
) )
else: else:
description = None description = None
@ -752,7 +780,9 @@ class CommonFormatter:
submessage, m = self.message_to_string(full_path, p, submessage) submessage, m = self.message_to_string(full_path, p, submessage)
values.append(self.delete(m)) values.append(self.delete(m))
else: else:
submessage, old_values = self.message_to_string(full_path, previous, submessage) submessage, old_values = self.message_to_string(
full_path, previous, submessage
)
values.append(self.delete(old_values)) values.append(self.delete(old_values))
else: else:
new = [] new = []
@ -761,11 +791,15 @@ class CommonFormatter:
name = old["name"] name = old["name"]
if isinstance(old["values"], list): if isinstance(old["values"], list):
for value in old["values"]: for value in old["values"]:
if "identifiers" in informations and (not isinstance(value, dict) or "identifiers" not in value): if "identifiers" in informations and (
not isinstance(value, dict) or "identifiers" not in value
):
identifiers = informations["identifiers"] identifiers = informations["identifiers"]
else: else:
identifiers = [] identifiers = []
submessage, old_value = self.message_to_string(full_path, value, submessage, force_identifiers=identifiers) submessage, old_value = self.message_to_string(
full_path, value, submessage, force_identifiers=identifiers
)
if value in new: if value in new:
old_value = self.underline(old_value) old_value = self.underline(old_value)
values.append(old_value) values.append(old_value)
@ -775,18 +809,24 @@ class CommonFormatter:
values = self.join(values) values = self.join(values)
elif values: elif values:
old_values = old["values"] old_values = old["values"]
submessage, old_values = self.message_to_string(full_path, old_values, submessage) submessage, old_values = self.message_to_string(
full_path, old_values, submessage
)
if old["values"] in new: if old["values"] in new:
old_values = self.underline(old_values) old_values = self.underline(old_values)
values.append(old_values) values.append(old_values)
values = self.join(values) values = self.join(values)
else: else:
old_values = old["values"] old_values = old["values"]
if "identifiers" in informations and (not isinstance(old_values, dict) or "identifiers" not in old_values): if "identifiers" in informations and (
not isinstance(old_values, dict) or "identifiers" not in old_values
):
identifiers = informations["identifiers"] identifiers = informations["identifiers"]
else: else:
identifiers = [] identifiers = []
submessage, values = self.message_to_string(full_path, old_values, submessage, force_identifiers=identifiers) submessage, values = self.message_to_string(
full_path, old_values, submessage, force_identifiers=identifiers
)
if old["values"] in new: if old["values"] in new:
values = self.underline(values) values = self.underline(values)
if values != []: if values != []:
@ -820,7 +860,9 @@ class CommonFormatter:
full_path = informations["path"] full_path = informations["path"]
for idx, choice in enumerate(choices_values.copy()): for idx, choice in enumerate(choices_values.copy()):
if isinstance(choice, dict): if isinstance(choice, dict):
choices_values[idx] = self.message_to_string(full_path, choice, None)[1] choices_values[idx] = self.message_to_string(
full_path, choice, None
)[1]
if "default" in modified_attributes: if "default" in modified_attributes:
name, old_default, new_default = modified_attributes["default"] name, old_default, new_default = modified_attributes["default"]
if not old_default: if not old_default:
@ -909,7 +951,9 @@ class CommonFormatter:
# if old value and new value is a list, display a list # if old value and new value is a list, display a list
if not default_is_a_list and len(choices_values) == 1: if not default_is_a_list and len(choices_values) == 1:
choices_values = choices_values[0] choices_values = choices_values[0]
return default_is_already_set, self.section(full_path, choices["name"], choices_values) return default_is_already_set, self.section(
full_path, choices["name"], choices_values
)
return default_is_already_set, None return default_is_already_set, None
# OTHERs # OTHERs
@ -937,13 +981,20 @@ class CommonFormatter:
) )
) )
if "multiple" in modified_attributes: if "multiple" in modified_attributes:
if modified_attributes["multiple"][1] and modified_attributes["multiple"][1][0]: if (
modified_attributes["multiple"][1]
and modified_attributes["multiple"][1][0]
):
properties.append( properties.append(
self.prop("multiple", italic=False, delete=True, underline=False) self.prop(
"multiple", italic=False, delete=True, underline=False
)
) )
else: else:
properties.append( properties.append(
self.prop("multiple", italic=False, delete=False, underline=True) self.prop(
"multiple", italic=False, delete=False, underline=True
)
) )
if "properties" not in contents and "properties" in modified_attributes: if "properties" not in contents and "properties" in modified_attributes:
for prop in modified_attributes["properties"]: for prop in modified_attributes["properties"]:
@ -1086,7 +1137,9 @@ class CommonFormatter:
) in local_calculated_properties.items(): ) in local_calculated_properties.items():
data = [] data = []
for calc in calculated_property: for calc in calculated_property:
annotation = self.message_to_string(full_path, calc["annotation"], None)[1] annotation = self.message_to_string(
full_path, calc["annotation"], None
)[1]
if calc.get("underline", False): if calc.get("underline", False):
annotation = self.underline(annotation) annotation = self.underline(annotation)
if calc.get("delete", False): if calc.get("delete", False):
@ -1098,7 +1151,9 @@ class CommonFormatter:
calculated_property = data[0] calculated_property = data[0]
calculated_properties.append( calculated_properties.append(
self.section( self.section(
full_path, calculated_property_name.capitalize(), calculated_property full_path,
calculated_property_name.capitalize(),
calculated_property,
) )
) )
if not properties: if not properties:
@ -1126,12 +1181,10 @@ class CommonFormatter:
headers = self.tabular_header(self.tabular_datas.headers()) headers = self.tabular_header(self.tabular_datas.headers())
else: else:
headers = () headers = ()
msg = ( msg = tabulate(
tabulate( self.tabular_datas.get(),
self.tabular_datas.get(), headers=headers,
headers=headers, tablefmt=self._tabular_name,
tablefmt=self._tabular_name,
)
) )
return msg return msg
@ -1153,18 +1206,32 @@ class CommonFormatter:
filename = self.other_root_filenames["."] filename = self.other_root_filenames["."]
if "identifiers" in msg["path"]: if "identifiers" in msg["path"]:
msg["identifiers"] = msg["path"]["identifiers"] msg["identifiers"] = msg["path"]["identifiers"]
calculated_paths = calc_path(msg["path"], formatter=self, identifiers=force_identifiers) calculated_paths = calc_path(
msg["path"], formatter=self, identifiers=force_identifiers
)
if self.support_namespace and self.document_a_type: if self.support_namespace and self.document_a_type:
namespace = full_path.split(".", 1)[0] namespace = full_path.split(".", 1)[0]
else: else:
namespace = None namespace = None
if isinstance(calculated_paths, list): if isinstance(calculated_paths, list):
msgs = [msg["message"].format(self.link_variable( msgs = [
doc_path(calculated_path, self.document_a_type, namespace), msg["message"].format(
msg["path"]["path"], self.link_variable(
self.get_description(msg, {}, force_identifiers=[msg["path"]["identifiers"][idx]], with_to_phrase=False), doc_path(
filename=filename, calculated_path, self.document_a_type, namespace
)) for idx, calculated_path in enumerate(calculated_paths)] ),
msg["path"]["path"],
self.get_description(
msg,
{},
force_identifiers=[msg["path"]["identifiers"][idx]],
with_to_phrase=False,
),
filename=filename,
)
)
for idx, calculated_path in enumerate(calculated_paths)
]
msg = self.list(msgs) msg = self.list(msgs)
else: else:
path = self.link_variable( path = self.link_variable(
@ -1265,10 +1332,18 @@ def calc_path(path, *, formatter=None, identifiers: List[str] = None) -> str:
if formatter: if formatter:
identifier = formatter.italic(identifier) identifier = formatter.italic(identifier)
return path.replace("{{ identifier }}", identifier, 1) return path.replace("{{ identifier }}", identifier, 1)
if isinstance(path, dict): if isinstance(path, dict):
path_ = path["path"] path_ = path["path"]
if "identifiers" in path: if "identifiers" in path:
path_ = get_path_from_identifiers(path["path"], path["identifiers"], [], [], path["identifier_type"], formatter) path_ = get_path_from_identifiers(
path["path"],
path["identifiers"],
[],
[],
path["identifier_type"],
formatter,
)
elif identifiers: elif identifiers:
for identifier in identifiers[0]: for identifier in identifiers[0]:
path_ = _path_with_identifier(path_, identifier) path_ = _path_with_identifier(path_, identifier)
@ -1282,34 +1357,36 @@ def calc_path(path, *, formatter=None, identifiers: List[str] = None) -> str:
return path_ return path_
def doc_path(path, document_a_type, namespace: Optional[str]=None) -> str: def doc_path(path, document_a_type, namespace: Optional[str] = None) -> str:
if document_a_type: if document_a_type:
if "." not in path: if "." not in path:
return None return None
if not namespace or path.startswith(namespace + '.'): if not namespace or path.startswith(namespace + "."):
return path.split(".", 1)[-1] return path.split(".", 1)[-1]
return path return path
def get_path_from_identifiers(text: str, def get_path_from_identifiers(
all_identifiers: list, text: str,
previous_identifiers: list, all_identifiers: list,
new_identifiers: list, previous_identifiers: list,
identifier_type: str, new_identifiers: list,
formatter: Optional[object]=None, identifier_type: str,
information_type="path", formatter: Optional[object] = None,
) -> str: information_type="path",
) -> str:
if not isinstance(all_identifiers, list): if not isinstance(all_identifiers, list):
raise Exception('hu1?') raise Exception("hu1?")
if all_identifiers: if all_identifiers:
for i in all_identifiers: for i in all_identifiers:
if not isinstance(i, list): if not isinstance(i, list):
raise Exception('hu2?') raise Exception("hu2?")
for j in i: for j in i:
if isinstance(j, list): if isinstance(j, list):
raise Exception('hu3?') raise Exception("hu3?")
if not isinstance(new_identifiers, list): if not isinstance(new_identifiers, list):
raise Exception('hu?') raise Exception("hu?")
def _text_with_identifier(information, identifier, delete=False, underline=False): def _text_with_identifier(information, identifier, delete=False, underline=False):
if identifier is None: if identifier is None:
identifier = "{{ __identifier__ }}" identifier = "{{ __identifier__ }}"
@ -1324,6 +1401,7 @@ def get_path_from_identifiers(text: str,
identifier = formatter.underline(identifier) identifier = formatter.underline(identifier)
identifier = formatter.italic(identifier) identifier = formatter.italic(identifier)
return information.replace("{{ identifier }}", identifier, 1) return information.replace("{{ identifier }}", identifier, 1)
if identifier_type == "outside": if identifier_type == "outside":
separator = "and" separator = "and"
else: else:
@ -1364,9 +1442,7 @@ def get_path_from_identifiers(text: str,
separator=separator, separator=separator,
sort=False, sort=False,
) )
return text.replace( return text.replace("{{ identifier }}", identifiers_text)
"{{ identifier }}", identifiers_text if identifier_type == "outside":
)
if identifier_type == 'outside':
return paths return paths
return display_list(paths, separator=separator, sort=False) return display_list(paths, separator=separator, sort=False)