feat: upgrade is not in formatter

This commit is contained in:
egarette@silique.fr 2025-01-02 21:06:13 +01:00
parent 6c1df5578f
commit 3849c42cba
30 changed files with 447 additions and 1674 deletions

View file

@ -5,8 +5,8 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2024-11-25 09:10+0100\n"
"PO-Revision-Date: 2024-11-25 09:11+0100\n"
"POT-Creation-Date: 2024-12-15 16:50+0100\n"
"PO-Revision-Date: 2024-12-15 16:55+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: fr\n"
@ -16,31 +16,31 @@ msgstr ""
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 3.5\n"
#: src/rougail/annotator/family.py:141
#: src/rougail/annotator/family.py:143
msgid "default variable mode \"{0}\" is not a valid mode, valid modes are {1}"
msgstr ""
"le mode d'une variable par défaut \"{0}\" n'est pas un mode valide, les "
"modes valides sont {1}"
#: src/rougail/annotator/family.py:147
#: src/rougail/annotator/family.py:149
msgid "default family mode \"{0}\" is not a valid mode, valid modes are {1}"
msgstr ""
"le mode d'une famille par défaut \"{0}\" n'est pas un mode valide, les modes "
"valides sont {1}"
#: src/rougail/annotator/family.py:179
#: src/rougail/annotator/family.py:181
msgid "mode \"{0}\" for \"{1}\" is not a valid mode, valid modes are {2}"
msgstr ""
"le mode \"{0}\" pour \"{1}\" n'est pas un mode valide, les modes valides "
"sont {2}"
#: src/rougail/annotator/family.py:183
#: src/rougail/annotator/family.py:185
msgid "mode \"{0}\" for \"{1}\" is not a valid mode, no modes are available"
msgstr ""
"le mode \"{0}\" pour \"{1}\" n'est pas un mode valide, aucun mode ne sont "
"définis"
#: src/rougail/annotator/family.py:247
#: src/rougail/annotator/family.py:249
msgid ""
"the variable \"{0}\" is mandatory so in \"{1}\" mode but family has the "
"higher family mode \"{2}\""
@ -48,7 +48,7 @@ msgstr ""
"la variable \"{0}\" est obligatoire donc dans le mode \"{1}\" mais la "
"famille a un mode supérieur \"{2}\""
#: src/rougail/annotator/family.py:285
#: src/rougail/annotator/family.py:287
msgid ""
"the follower \"{0}\" is in \"{1}\" mode but leader have the higher mode "
"\"{2}\""
@ -56,7 +56,7 @@ msgstr ""
"la variable suiveuse \"{0}\" a le mode \"{1}\" mais la variable leader a un "
"mode supérieur \"{2}\""
#: src/rougail/annotator/family.py:318
#: src/rougail/annotator/family.py:320
msgid ""
"the family \"{0}\" is in \"{1}\" mode but variables and families inside have "
"the higher modes \"{2}\""
@ -64,7 +64,7 @@ msgstr ""
"la famille \"{0}\" a le mode \"{1}\" mais les variables et les familles à "
"l'intérieur ont des modes supérieurs \"{2}\""
#: src/rougail/annotator/family.py:336
#: src/rougail/annotator/family.py:338
msgid ""
"the variable \"{0}\" is in \"{1}\" mode but family has the higher family "
"mode \"{2}\""
@ -102,6 +102,64 @@ msgid ""
msgstr ""
"la variable \"{0}\" a la valeur par défaut invalide \"{1}\" devrait être {2}"
#: src/rougail/config.py:216
msgid "Directories where dictionary files are placed"
msgstr "Répertoires où sont placés les fichiers de structure"
#: src/rougail/config.py:227
msgid "Sort dictionaries from differents directories"
msgstr "Trier les fichiers de structure à partir de différents répertoires"
#: src/rougail/config.py:232
msgid "Main namespace name"
msgstr "Nom de l'espace de nom principal"
#: src/rougail/config.py:238
msgid "Extra namespaces"
msgstr "Espaces de nom supplémentaires"
#: src/rougail/config.py:245
msgid "Extra namespace name"
msgstr "Nom de l'espace de nom supplémentaire"
#: src/rougail/config.py:251
msgid "Directories where extra dictionary files are placed"
msgstr ""
"Répertoires où sont placés les fichiers de structure de l'espace de nom "
"supplémentaire"
#: src/rougail/config.py:262
msgid "Update dictionaries to newest Rougail format version"
msgstr ""
"Mettre à jour le fichier de structure vers la dernière version du format de "
"Rougail"
#: src/rougail/config.py:263
msgid "Do not update dictionaries to newest Rougail format version"
msgstr ""
"Ne pas mettre à jour le fichier de structure vers la dernière version du "
"format de Rougail"
#: src/rougail/config.py:267
msgid "Update informations"
msgstr "Mise à jour des informations"
#: src/rougail/config.py:273
msgid "Directories where dictionary files will be placed"
msgstr "Répertoires où sont placés les fichiers de structure"
#: src/rougail/config.py:278
msgid "Directories where extra files will be placed"
msgstr "Répertoires où sont placés les fichiers de structure supplémentaire"
#: src/rougail/config.py:290
msgid "File with functions"
msgstr "Fichier avec les fonctions"
#: src/rougail/config.py:302
msgid "All modes level available"
msgstr "Tous les niveaux de modes valides"
#: src/rougail/convert.py:281
msgid ""
"A variable or a family located in the \"{0}\" namespace shall not be used in "
@ -110,15 +168,19 @@ msgstr ""
"Une variable ou une famille localisé dans l'espace de nom \"{0}\" ne devrait "
"pas être utilisé dans l'espace de nom \"{1}\""
#: src/rougail/convert.py:477
#: src/rougail/convert.py:480
msgid "unknown type {0} for {1}"
msgstr "type {0} inconnu pour {1}"
#: src/rougail/convert.py:1347
#: src/rougail/convert.py:613
msgid "The family \"{0}\" already exists and it is not redefined"
msgstr "La famille \"{0}\" existe déjà et n'est pas redéfinie"
#: src/rougail/convert.py:1356
msgid "duplicate dictionary file name {0}"
msgstr "nom de fichier {0} de dictionnaire dupliqué"
#: src/rougail/convert.py:1394
#: src/rougail/convert.py:1403
msgid "Cannot execute annotate multiple time"
msgstr "Ne peut exécuter l'annotation plusieurs fois"

View file

@ -5,7 +5,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2024-11-25 09:10+0100\n"
"POT-Creation-Date: 2024-12-15 16:57+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -15,35 +15,35 @@ msgstr ""
"Generated-By: pygettext.py 1.5\n"
#: src/rougail/annotator/family.py:141
#: src/rougail/annotator/family.py:143
msgid "default variable mode \"{0}\" is not a valid mode, valid modes are {1}"
msgstr ""
#: src/rougail/annotator/family.py:147
#: src/rougail/annotator/family.py:149
msgid "default family mode \"{0}\" is not a valid mode, valid modes are {1}"
msgstr ""
#: src/rougail/annotator/family.py:179
#: src/rougail/annotator/family.py:181
msgid "mode \"{0}\" for \"{1}\" is not a valid mode, valid modes are {2}"
msgstr ""
#: src/rougail/annotator/family.py:183
#: src/rougail/annotator/family.py:185
msgid "mode \"{0}\" for \"{1}\" is not a valid mode, no modes are available"
msgstr ""
#: src/rougail/annotator/family.py:247
#: src/rougail/annotator/family.py:249
msgid "the variable \"{0}\" is mandatory so in \"{1}\" mode but family has the higher family mode \"{2}\""
msgstr ""
#: src/rougail/annotator/family.py:285
#: src/rougail/annotator/family.py:287
msgid "the follower \"{0}\" is in \"{1}\" mode but leader have the higher mode \"{2}\""
msgstr ""
#: src/rougail/annotator/family.py:318
#: src/rougail/annotator/family.py:320
msgid "the family \"{0}\" is in \"{1}\" mode but variables and families inside have the higher modes \"{2}\""
msgstr ""
#: src/rougail/annotator/family.py:336
#: src/rougail/annotator/family.py:338
msgid "the variable \"{0}\" is in \"{1}\" mode but family has the higher family mode \"{2}\""
msgstr ""
@ -67,19 +67,75 @@ msgstr ""
msgid "the variable \"{0}\" has an unvalid default value \"{1}\" should be in {2}"
msgstr ""
#: src/rougail/config.py:216
msgid "Directories where dictionary files are placed"
msgstr ""
#: src/rougail/config.py:227
msgid "Sort dictionaries from differents directories"
msgstr ""
#: src/rougail/config.py:232
msgid "Main namespace name"
msgstr ""
#: src/rougail/config.py:238
msgid "Extra namespaces"
msgstr ""
#: src/rougail/config.py:245
msgid "Extra namespace name"
msgstr ""
#: src/rougail/config.py:251
msgid "Directories where extra dictionary files are placed"
msgstr ""
#: src/rougail/config.py:262
msgid "Update dictionaries to newest Rougail format version"
msgstr ""
#: src/rougail/config.py:263
msgid "Do not update dictionaries to newest Rougail format version"
msgstr ""
#: src/rougail/config.py:267
msgid "Update informations"
msgstr ""
#: src/rougail/config.py:273
msgid "Directories where dictionary files will be placed"
msgstr ""
#: src/rougail/config.py:278
msgid "Directories where extra files will be placed"
msgstr ""
#: src/rougail/config.py:290
msgid "File with functions"
msgstr ""
#: src/rougail/config.py:302
msgid "All modes level available"
msgstr ""
#: src/rougail/convert.py:281
msgid "A variable or a family located in the \"{0}\" namespace shall not be used in the \"{1}\" namespace"
msgstr ""
#: src/rougail/convert.py:477
#: src/rougail/convert.py:480
msgid "unknown type {0} for {1}"
msgstr ""
#: src/rougail/convert.py:1347
#: src/rougail/convert.py:613
msgid "The family \"{0}\" already exists and it is not redefined"
msgstr ""
#: src/rougail/convert.py:1356
msgid "duplicate dictionary file name {0}"
msgstr ""
#: src/rougail/convert.py:1394
#: src/rougail/convert.py:1403
msgid "Cannot execute annotate multiple time"
msgstr ""

View file

@ -71,30 +71,38 @@ class SpaceAnnotator: # pylint: disable=R0903
if extra_annotator in ANNOTATORS:
continue
get_annotators(ANNOTATORS, extra_annotator)
if objectspace.output:
for structural in objectspace.structurals:
try:
get_annotators(ANNOTATORS, f"rougail.output_{objectspace.output}", "annotator")
get_annotators(
ANNOTATORS, f"rougail.structural_{structural}", "annotator"
)
except ModuleNotFoundError:
pass
for user_data in objectspace.user_datas:
try:
get_annotators(ANNOTATORS, f"rougail.user_data_{user_data}", "annotator")
get_annotators(
ANNOTATORS, f"rougail.user_data_{user_data}", "annotator"
)
except ModuleNotFoundError:
pass
for plugin in objectspace.plugins:
if objectspace.output:
try:
get_annotators(ANNOTATORS, f"rougail.{plugin}", "annotator")
get_annotators(
ANNOTATORS, f"rougail.output_{objectspace.output}", "annotator"
)
except ModuleNotFoundError:
pass
annotators = ANNOTATORS["rougail.annotator"].copy()
for extra_annotator in objectspace.extra_annotators:
annotators.extend(ANNOTATORS[extra_annotator])
for plugin in objectspace.plugins:
annotators.extend(ANNOTATORS[f"rougail.{plugin}.annotator"])
for structural in objectspace.structurals:
annotators.extend(ANNOTATORS[f"rougail.structural_{structural}.annotator"])
for user_data in objectspace.user_datas:
annotators.extend(ANNOTATORS[f"rougail.user_data_{user_data}.annotator"])
if objectspace.output:
annotators.extend(ANNOTATORS[f"rougail.output_{objectspace.output}.annotator"])
annotators.extend(
ANNOTATORS[f"rougail.output_{objectspace.output}.annotator"]
)
annotators = sorted(annotators, key=get_level)
functions = {}
functions_files = objectspace.functions_files

View file

@ -126,12 +126,15 @@ class Annotator(Walk):
family.dynamic, VariableCalculation
):
path = family.dynamic.variable
if family.version != "1.0" and self.objectspace.paths.regexp_relative.search(path):
if (
family.version != "1.0"
and self.objectspace.paths.regexp_relative.search(path)
):
path = self.objectspace.paths.get_full_path(
family.dynamic.variable,
family.path,
)
if family.version == '1.0' and "{{ suffix }}" in path:
if family.version == "1.0" and "{{ suffix }}" in path:
path = path.replace("{{ suffix }}", "{{ identifier }}")
self.objectspace.informations.add(family.path, "dynamic_variable", path)

View file

@ -64,7 +64,11 @@ def get_sub_modules():
def get_level(module):
return module["level"]
return float(module["level"]) + {
"structural": 0.1,
"user data": 0.2,
"output": 0.3,
}.get(module["process"])
class _RougailConfig:
@ -187,10 +191,12 @@ class FakeRougailConvert(RougailConvert):
self.export_with_import = True
self.internal_functions = []
self.force_optional = False
self.plugins = ["structural_commandline"]
self.structurals = ["commandline"]
self.user_datas = []
self.output = None
self.add_extra_options = self.add_extra_options
self.tiramisu_cache = False
self.load_unexist_redefine = False
def get_rougail_config(
@ -198,10 +204,6 @@ def get_rougail_config(
backward_compatibility: bool = True,
add_extra_options: bool = True,
) -> _RougailConfig:
if backward_compatibility:
main_namespace_default = "rougail"
else:
main_namespace_default = "null"
rougail_options = f"""default_dictionary_format_version:
description: Dictionary format version by default, if not specified in dictionary file
alternative_name: v
@ -210,82 +212,8 @@ def get_rougail_config(
- '1.1'
mandatory: false
main_dictionaries:
description: 'Directories where dictionary files are placed'
type: unix_filename
alternative_name: m
params:
allow_relative: True
test_existence: True
types:
- directory
multi: true
sort_dictionaries_all:
description: Sort dictionaries from differents directories
negative_description: Sort dictionaries directory by directory
default: false
main_namespace:
description: Main namespace name
default: {main_namespace_default}
alternative_name: s
mandatory: false
extra_dictionaries:
description: Extra namespaces
type: leadership
disabled:
variable: main_namespace
when: null
names:
description: 'Extra namespace name'
alternative_name: xn
multi: true
mandatory: false
directories:
description: Directories where extra dictionary files are placed
alternative_name: xd
type: unix_filename
params:
allow_relative: true
test_existence: true
types:
- directory
multi: true
upgrade:
description: Update dictionaries to newest Rougail format version
negative_description: Do not update dictionaries to newest Rougail format version
default: false
upgrade_options:
description: Update informations
disabled:
variable: upgrade
when: false
main_dictionaries:
description: 'Directories where dictionary files will be placed'
default:
variable: __.main_dictionaries
extra_dictionary:
description: 'Directories where extra files will be placed'
type: unix_filename
params:
allow_relative: true
test_existence: true
types:
- directory
disabled:
variable: __.main_namespace
when: null
functions_files:
description: File with functions
description: {_("File with functions")}
alternative_name: c
type: unix_filename
params:
@ -297,74 +225,73 @@ functions_files:
mandatory: false
modes_level:
description: All modes level available
description: {_("All modes level available")}
multi: true
mandatory: false
"""
if backward_compatibility:
rougail_options += """
default:
rougail_options += """ default:
- basic
- standard
- advanced
"""
rougail_options += """
rougail_options += f"""
default_family_mode:
description: Default mode for a family
description: {_("Default mode for a family")}
default:
jinja: |
{% if modes_level %}
{{ modes_level[0] }}
{% endif %}
{{% if modes_level %}}
{{{{ modes_level[0] }}}}
{{% endif %}}
disabled:
jinja: |
{% if not modes_level %}
{{% if not modes_level %}}
No mode
{% endif %}
{{% endif %}}
validators:
- type: jinja
jinja: |
{% if default_family_mode not in modes_level %}
not in modes_level ({modes_level})
{% endif %}
{{% if default_family_mode not in modes_level %}}
not in modes_level ({{modes_level}})
{{% endif %}}
commandline: false
default_variable_mode:
description: Default mode for a variable
description: {_("Default mode for a variable")}
default:
jinja: |
{% if modes_level %}
{% if modes_level | length == 1 %}
{{ modes_level[0] }}
{% else %}
{{ modes_level[1] }}
{% endif %}
{% endif %}
{{% if modes_level %}}
{{% if modes_level | length == 1 %}}
{{{{ modes_level[0] }}}}
{{% else %}}
{{{{ modes_level[1] }}}}
{{% endif %}}
{{% endif %}}
disabled:
jinja: |
{% if not modes_level %}
{{% if not modes_level %}}
No mode
{% endif %}
{{% endif %}}
validators:
- type: jinja
jinja: |
{% if default_variable_mode not in modes_level %}
not in modes_level ({modes_level})
{% endif %}
{{% if default_variable_mode not in modes_level %}}
not in modes_level ({{modes_level}})
{{% endif %}}
commandline: false
base_option_name:
description: Option name for the base option
description: {_("Option name for the base option")}
default: baseoption
commandline: false
not_export_with_import:
description: In cache file, do not importation of Tiramisu and other dependencies
description: {_("In cache file, do not importation of Tiramisu and other dependencies")}
default: false
commandline: false
tiramisu_cache:
description: Tiramisu cache filename
description: {_("Tiramisu cache filename")}
alternative_name: t
type: unix_filename
mandatory: false
@ -372,52 +299,52 @@ tiramisu_cache:
allow_relative: true
internal_functions:
description: Name of internal functions that we can use as a function
description: {_("Name of internal functions that we can use as a function")}
multi: true
mandatory: false
commandline: false
extra_annotators:
description: Name of extra annotators
multi: true
mandatory: false
commandline: false
plugins:
description: Name of Rougail plugins
description: {_("Name of extra annotators")}
multi: true
mandatory: false
commandline: false
suffix:
description: Suffix add to generated option name
description: {_("Suffix add to generated option name")}
default: ''
mandatory: false
commandline: false
force_optional:
description: Every variable in calculation are optional
negative_description: Variable in calculation are not optional by default
description: {_("Every variable in calculation are optional")}
negative_description: {_("Variable in calculation are not optional by default")}
default: False
load_unexist_redefine:
description: {_("Load redefine variable even if there don't already exists")}
negative_description: {_("Load redefine variable even if there don't already exists")}
commandline: false
default: False
"""
processes = {
"structural": [],
"output": [],
"user data": [],
"output": [],
}
for module in get_sub_modules().values():
data = module.get_rougail_config()
data = module.get_rougail_config(backward_compatibility=backward_compatibility)
processes[data["process"]].append(data)
# reorder
for process in processes:
processes[process] = list(sorted(processes[process], key=get_level))
rougail_process = """step: # Load and exporter steps
disabled:
variable: upgrade"""
rougail_process = "step: # Load and exporter steps"
for process in processes:
if processes[process]:
objects = processes[process]
rougail_process += """
{NAME}:
description: Select for {NAME}
alternative_name: {NAME[0]}
@ -428,26 +355,29 @@ force_optional:
for obj in objects:
rougail_process += f" - {obj['name']}\n"
if process == "structural":
rougail_process += " commandline: false"
rougail_process += """ commandline: false
multi: true
default:
- directory
"""
elif process == "user data":
rougail_process += """ multi: true
mandatory: false
"""
mandatory: false"""
hidden_outputs = [
process["name"]
for process in processes["output"]
if not process.get("allow_user_data", True)
]
if hidden_outputs:
rougail_process += """ hidden:
rougail_process += """
hidden:
type: jinja
jinja: |
"""
for hidden_output in hidden_outputs:
rougail_process += """ {% if _.output == 'NAME' %}
Cannot load user data for NAME output
{% endif %}
""".replace(
{% endif %}""".replace(
"NAME", hidden_output
)
elif objects:
@ -455,10 +385,10 @@ force_optional:
DEFAULT=objects[0]["name"]
)
else:
if process == 'output':
prop = 'hidden'
if process == "output":
prop = "hidden"
else:
prop = 'disabled'
prop = "disabled"
rougail_process += """
{NAME}:
description: Select for {NAME}
@ -473,8 +403,9 @@ force_optional:
PROP=prop,
)
rougail_options += rougail_process
# print(rougail_options)
convert = FakeRougailConvert(add_extra_options)
convert._init()
convert.init()
convert.namespace = None
convert.parse_root_file(
"rougail.config",
@ -483,25 +414,27 @@ force_optional:
YAML().load(rougail_options),
)
extra_vars = {}
for process in processes:
for obj in processes[process]:
if "extra_vars" in obj:
extra_vars |= obj["extra_vars"]
if not "options" in obj:
continue
if not isinstance(obj["options"], list):
options = [obj["options"]]
else:
options = obj["options"]
for option in options:
convert.parse_root_file(
f'rougail.config.{obj["name"]}',
"",
"1.1",
YAML().load(option),
)
objects = []
for obj in sorted(
[obj for objects in processes.values() for obj in objects], key=get_level
):
if "extra_vars" in obj:
extra_vars |= obj["extra_vars"]
if not "options" in obj:
continue
if not isinstance(obj["options"], list):
options = [obj["options"]]
else:
options = obj["options"]
for option in options:
convert.parse_root_file(
f'rougail.config.{obj["name"]}',
"",
"1.1",
YAML().load(option),
)
tiram_obj = convert.save(None)
tiram_obj = convert.save()
optiondescription = {}
exec(tiram_obj, {}, optiondescription) # pylint: disable=W0122
return _RougailConfig(

View file

@ -69,10 +69,6 @@ class DictConsistencyError(Exception):
self.errno = errno
class UpgradeError(Exception):
"""Error during XML upgrade"""
## ---- generic exceptions ----

View file

@ -27,7 +27,7 @@ from pydantic import (
ConfigDict,
)
from tiramisu import undefined
from .utils import get_jinja_variable_to_param, get_realpath
from .utils import get_jinja_variable_to_param
from .error import DictConsistencyError, VariableCalculationDependencyError
BASETYPE = Union[StrictBool, StrictInt, StrictFloat, StrictStr, None]
@ -178,7 +178,6 @@ PARAM_TYPES = {
class Calculation(BaseModel):
path_prefix: Optional[str]
path: str
inside_list: bool
version: str
@ -189,12 +188,6 @@ class Calculation(BaseModel):
model_config = ConfigDict(extra="forbid")
def get_realpath(
self,
path: str,
) -> str:
return get_realpath(path, self.path_prefix)
def get_params(self, objectspace):
if not self.params:
return {}
@ -208,7 +201,6 @@ class Calculation(BaseModel):
path = self.ori_path
variable, identifier = objectspace.paths.get_with_dynamic(
param["variable"],
self.path_prefix,
path,
self.version,
self.namespace,
@ -220,7 +212,12 @@ class Calculation(BaseModel):
raise DictConsistencyError(msg, 22, self.xmlfiles)
continue
if not isinstance(variable, objectspace.variable):
raise Exception("pfff it's a family")
if isinstance(variable, objectspace.family):
msg = f'the variable "{variable["name"]}" is in fact a family in attribute "{self.attribute_name}" for "{self.path}"'
raise DictConsistencyError(msg, 42, self.xmlfiles)
else:
msg = f'unknown object "{variable}" in attribute "{self.attribute_name}" for "{self.path}"'
raise DictConsistencyError(msg, 44, self.xmlfiles)
param["variable"] = variable
if identifier:
param["identifier"] = identifier
@ -232,7 +229,6 @@ class Calculation(BaseModel):
path = self.ori_path
variable, identifier = objectspace.paths.get_with_dynamic(
param["variable"],
self.path_prefix,
path,
self.version,
self.namespace,
@ -314,7 +310,6 @@ class JinjaCalculation(Calculation):
objectspace,
variable.xmlfiles,
objectspace.functions,
self.path_prefix,
self.version,
self.namespace,
):
@ -413,15 +408,18 @@ class _VariableCalculation(Calculation):
path = self.ori_path
variable, identifier = objectspace.paths.get_with_dynamic(
self.variable,
self.path_prefix,
path,
self.version,
self.namespace,
self.xmlfiles,
)
if variable and not isinstance(variable, objectspace.variable):
# FIXME remove the pfff
raise Exception("pfff it's a family")
if isinstance(variable, objectspace.family):
msg = f'the variable "{variable.path}" is in fact a family in attribute "{self.attribute_name}" for "{self.path}"'
raise DictConsistencyError(msg, 47, self.xmlfiles)
else:
msg = f'unknown object "{variable}" in attribute "{self.attribute_name}" for "{self.path}"'
raise DictConsistencyError(msg, 48, self.xmlfiles)
return variable, identifier
def get_params(
@ -434,9 +432,13 @@ class _VariableCalculation(Calculation):
):
if not variable:
if not objectspace.force_optional:
msg = f'Variable not found "{self.variable}" for attribut "{self.attribute_name}" for variable "{self.path}"'
if self.ori_path is None:
path = self.path
else:
path = self.ori_path
msg = f'Variable not found "{self.variable}" for attribut "{self.attribute_name}" in variable "{path}"'
raise DictConsistencyError(msg, 88, self.xmlfiles)
return {None: [['example']]}
return {None: [["example"]]}
param = {
"type": "variable",
"variable": variable,
@ -497,7 +499,7 @@ class _VariableCalculation(Calculation):
multi = objectspace.multis[self.path] == "submulti"
else:
multi = self.path in objectspace.multis
if multi:
if multi and not self.inside_list:
params["__internal_multi"] = True
return params
@ -514,7 +516,11 @@ class VariableCalculation(_VariableCalculation):
msg = f'"{self.attribute_name}" variable shall not have an "optional" attribute for variable "{self.variable}"'
raise DictConsistencyError(msg, 33, self.xmlfiles)
variable, identifier = self.get_variable(objectspace)
if not variable and self.optional or (objectspace.force_optional and self.attribute_name == "default"):
if (
not variable
and self.optional
or (objectspace.force_optional and self.attribute_name == "default")
):
raise VariableCalculationDependencyError()
params = self.get_params(
objectspace,
@ -600,7 +606,6 @@ class InformationCalculation(Calculation):
path = self.ori_path
variable, identifier = objectspace.paths.get_with_dynamic(
self.variable,
self.path_prefix,
path,
self.version,
self.namespace,
@ -704,16 +709,16 @@ class IndexCalculation(Calculation):
CALCULATION_TYPES = {
"jinja": JinjaCalculation,
"variable": VariableCalculation,
"information": InformationCalculation,
"variable": VariableCalculation,
"identifier": IdentifierCalculation,
"suffix": IdentifierCalculation,
"index": IndexCalculation,
}
CALCULATION_PROPERTY_TYPES = {
"jinja": JinjaCalculation,
"variable": VariablePropertyCalculation,
"information": InformationCalculation,
"variable": VariablePropertyCalculation,
"identifier": IdentifierPropertyCalculation,
"index": IndexCalculation,
}
@ -722,14 +727,18 @@ BASETYPE_CALC = Union[StrictBool, StrictInt, StrictFloat, StrictStr, Calculation
class Family(BaseModel):
name: str
# informations
description: Optional[str] = None
type: Literal["family", "leadership", "dynamic"] = "family"
path: str
help: Optional[str] = None
mode: Optional[str] = None
# validation
type: Literal["family", "leadership", "dynamic"] = "family"
# properties
hidden: Union[bool, Calculation] = False
disabled: Union[bool, Calculation] = False
# others
namespace: Optional[str]
path: str
version: str
xmlfiles: List[str] = []
@ -743,30 +752,34 @@ class Dynamic(Family):
class Variable(BaseModel):
# type will be set dynamically in `annotator/value.py`, default is None
type: str = None
name: str
# user informations
description: Optional[str] = None
default: Union[List[BASETYPE_CALC], BASETYPE_CALC] = None
choices: Optional[Union[List[BASETYPE_CALC], Calculation]] = None
regexp: Optional[str] = None
params: Optional[List[Param]] = None
validators: Optional[List[Calculation]] = None
multi: Optional[bool] = None
unique: Optional[bool] = None
help: Optional[str] = None
hidden: Union[bool, Calculation] = False
disabled: Union[bool, Calculation] = False
mode: Optional[str] = None
examples: Optional[list] = None
test: Optional[list] = None
# validations
## type will be set dynamically in `annotator/value.py`, default is None
type: str = None
params: Optional[List[Param]] = None
regexp: Optional[str] = None
choices: Optional[Union[List[BASETYPE_CALC], Calculation]] = None
multi: Optional[bool] = None
validators: Optional[List[Calculation]] = None
# value
default: Union[List[BASETYPE_CALC], BASETYPE_CALC] = None
# properties
auto_save: bool = False
mandatory: Union[None, bool, Calculation] = None
empty: Union[None, bool, Calculation] = True
auto_save: bool = False
mode: Optional[str] = None
test: Optional[list] = None
examples: Optional[list] = None
unique: Optional[bool] = None
hidden: Union[bool, Calculation] = False
disabled: Union[bool, Calculation] = False
# others
path: str
namespace: Optional[str]
version: str
path_prefix: Optional[str]
xmlfiles: List[str] = []
model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True)
@ -779,7 +792,6 @@ class SymLink(BaseModel):
opt: Variable
namespace: Optional[str]
version: str
path_prefix: Optional[str]
xmlfiles: List[str] = []
model_config = ConfigDict(extra="forbid")

View file

@ -0,0 +1,22 @@
"""
Silique (https://www.silique.fr)
Copyright (C) 2024
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
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from .object_model import Variable, Family
__all__ = ("Variable", "Family")

View file

@ -27,12 +27,13 @@ def get_rougail_config(
structural_commandline:
description: Configuration rougail-structural_commandline
commandline: false
add_extra_options:
description: Add extra options to tiramisu-cmdline-parser
default: true
"""
return {
"name": "exporter",
"name": "cmdline",
"process": "structural",
"options": options,
"level": 20,

View file

@ -29,6 +29,3 @@ class Variable(BaseModel):
class Family(BaseModel):
commandline: bool = True
__all__ = ("Variable", "Family")

View file

@ -127,7 +127,9 @@ def jinja_to_function(
c_kw = kw
path, var = key.rsplit(".", 1)
if isinstance(value, CancelParam):
count_o_path = value.origin_path.count('.') - value.current_path.count('.')
count_o_path = value.origin_path.count(".") - value.current_path.count(
"."
)
path = path.rsplit(".", count_o_path)[0]
for subkey in path.split("."):
c_kw = c_kw.setdefault(subkey, {})

View file

@ -87,7 +87,7 @@ class TiramisuReflector:
continue
self.text["header"].append(f"load_functions('{funcs_path}')")
if self.objectspace.export_with_import:
if objectspace.main_namespace:
if self.objectspace.has_namespace:
self.text["header"].extend(
[
"try:",
@ -372,6 +372,11 @@ class Common:
)
params = [f"{option_name}"]
if identifier is not None:
if not self.objectspace.paths.is_dynamic(variable.path):
msg = _("internal error, {0} is not a dynamic variable").format(
variable.path
)
raise DictConsistencyError(msg, 49, self.elt.xmlfiles)
param_type = "ParamDynOption"
identifiers = []
for ident in identifier:

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
"""
Silique (https://www.silique.fr)
Copyright (C) 2024
Copyright (C) 2022-2024
distribued with GPL-2 or later license
@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
from typing import List
from re import findall
@ -76,8 +77,7 @@ class UserDatas:
self._not_found_is_dynamic(self.config, path, cache, added)
def _not_found_is_dynamic(self, config, path, cache, added):
"""if path is not found, check if parent is a dynamic family
"""
"""if path is not found, check if parent is a dynamic family"""
current_path = ""
identifiers = []
# get parent
@ -102,9 +102,7 @@ class UserDatas:
if not tconfig.isdynamic(only_self=True):
# it's not a dynamic variable
continue
identifier = self._get_identifier(
tconfig.name(), name
)
identifier = self._get_identifier(tconfig.name(), name)
if identifier is None:
# it's a dynamic variable but doesn't match the current name
continue
@ -116,11 +114,13 @@ class UserDatas:
# it's the good dynamic variable but it's not linked to a variable
# so cannot change the variable
continue
option_type = self.config.option(
dynamic_variable
).information.get("type")
dyn_options_values = self.config.option(dynamic_variable).get().impl_getdefault()
if "{{ identifier }}" in dynamic_variable:
option_type = self.config.option(dynamic_variable).information.get(
"type"
)
dyn_options_values = (
self.config.option(dynamic_variable).get().impl_getdefault()
)
if "{{ identifier }}" in dynamic_variable:
for s in identifiers:
dynamic_variable = dynamic_variable.replace(
"{{ identifier }}", str(s), 1
@ -132,18 +132,11 @@ class UserDatas:
continue
config = tconfig
identifiers.append(identifier)
typ = CONVERT_OPTION.get(option_type, {}).get(
"func"
)
typ = CONVERT_OPTION.get(option_type, {}).get("func")
if typ:
identifier = typ(identifier)
if (
identifier
not in self.values[dynamic_variable]["values"]
):
self.values[dynamic_variable]["values"].append(
identifier
)
if identifier not in self.values[dynamic_variable]["values"]:
self.values[dynamic_variable]["values"].append(identifier)
cache[current_path] = config, identifier
break
@ -211,6 +204,11 @@ class UserDatas:
for path, data in self.values.items():
try:
option = self.config.option(path)
if option.isoptiondescription():
self.errors.append(
f'the option "{option.path()}" is an option description'
)
continue
value = data["values"]
if option.isfollower():
for index, val in enumerate(value):
@ -231,7 +229,7 @@ def convert_value(option, value):
if value == "":
return None
option_type = option.information.get("type")
if option_type == 'choice':
if option_type == "choice":
choices = option.value.list()
if value not in choices and isinstance(value, str):
# FIXME add other tests (boolean, float, ...)

View file

@ -11,6 +11,6 @@ ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_2 = StrOption(name="my_variable", doc="my_variable", default="val1", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_3 = StrOption(name="my_calculated_variable", doc="my_calculated_variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamOption(option_2)), kwargs={'__internal_multi': ParamValue(True)}))], default_multi=Calculation(func['calc_value'], Params((ParamOption(option_2)), kwargs={'__internal_multi': ParamValue(True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_3 = StrOption(name="my_calculated_variable", doc="my_calculated_variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamOption(option_2))))], default_multi=Calculation(func['calc_value'], Params((ParamOption(option_2)))), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2, option_3], properties=frozenset({"standard"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])

View file

@ -7,5 +7,5 @@ ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_1 = StrOption(name="my_variable", doc="my_variable", default="val1", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_2 = StrOption(name="my_calculated_variable", doc="my_calculated_variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamOption(option_1)), kwargs={'__internal_multi': ParamValue(True)}))], default_multi=Calculation(func['calc_value'], Params((ParamOption(option_1)), kwargs={'__internal_multi': ParamValue(True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_2 = StrOption(name="my_calculated_variable", doc="my_calculated_variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamOption(option_1))))], default_multi=Calculation(func['calc_value'], Params((ParamOption(option_1)))), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_2])

View file

@ -11,6 +11,6 @@ ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_2 = StrOption(name="my_variable", doc="my_variable", default="val1", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_3 = StrOption(name="my_calculated_variable", doc="my_calculated_variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamOption(option_2)), kwargs={'__internal_multi': ParamValue(True)}))], properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_3 = StrOption(name="my_calculated_variable", doc="my_calculated_variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamOption(option_2))))], properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2, option_3], properties=frozenset({"standard"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])

View file

@ -7,5 +7,5 @@ ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_1 = StrOption(name="my_variable", doc="my_variable", default="val1", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_2 = StrOption(name="my_calculated_variable", doc="my_calculated_variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamOption(option_1)), kwargs={'__internal_multi': ParamValue(True)}))], properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_2 = StrOption(name="my_calculated_variable", doc="my_calculated_variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamOption(option_1))))], properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_2])

View file

@ -18,12 +18,16 @@
"owner": "default",
"value": null
},
"rougail.family2.var3": {
"owner": "default",
"value": "string4"
},
"rougail.family2.subfamily.variable": {
"owner": "default",
"value": [
null,
null,
null
"string4"
]
}
}

View file

@ -6,9 +6,10 @@
null
],
"rougail.family2.var2": null,
"rougail.family2.var3": "string4",
"rougail.family2.subfamily.variable": [
null,
null,
null
"string4"
]
}

View file

@ -18,12 +18,16 @@
"owner": "default",
"value": null
},
"rougail.family2.var3": {
"owner": "default",
"value": "string4"
},
"rougail.family2.subfamily.variable": {
"owner": "default",
"value": [
null,
null,
null
"string4"
]
}
}

View file

@ -7,12 +7,13 @@ ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_1 = StrOption(name="var1", doc="first variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
option_3 = StrOption(name="var2", doc="a second variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
option_5 = StrOption(name="variable", doc="third variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamOption(option_1)), kwargs={'__internal_multi': ParamValue(False)})), Calculation(func['calc_value'], Params((ParamOption(option_3)), kwargs={'__internal_multi': ParamValue(False)}))], default_multi=Calculation(func['calc_value'], Params((ParamOption(option_1)), kwargs={'__internal_multi': ParamValue(False)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_3 = StrOption(name="var2", doc="a second variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string', 'test': ('string6',)})
option_5 = StrOption(name="variable", doc="third variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamOption(option_1)))), Calculation(func['calc_value'], Params((ParamOption(option_3))))], default_multi=Calculation(func['calc_value'], Params((ParamOption(option_1)))), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
optiondescription_4 = OptionDescription(name="subfamily", doc="a sub family", children=[option_5], properties=frozenset({"standard"}))
optiondescription_2 = OptionDescription(name="family", doc="a family", children=[option_3, optiondescription_4], properties=frozenset({"basic"}))
option_7 = StrOption(name="var2", doc="var2", default=Calculation(func['calc_value'], Params((ParamOption(option_3)))), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_9 = StrOption(name="variable", doc="fourth variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamOption(option_1)), kwargs={'__internal_multi': ParamValue(False)})), Calculation(func['calc_value'], Params((ParamOption(option_3)), kwargs={'__internal_multi': ParamValue(False)})), Calculation(func['calc_value'], Params((ParamOption(option_7)), kwargs={'__internal_multi': ParamValue(False)}))], default_multi=Calculation(func['calc_value'], Params((ParamOption(option_1)), kwargs={'__internal_multi': ParamValue(False)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
optiondescription_8 = OptionDescription(name="subfamily", doc="a sub family", children=[option_9], properties=frozenset({"standard"}))
optiondescription_6 = OptionDescription(name="family2", doc="a family", children=[option_7, optiondescription_8], properties=frozenset({"standard"}))
option_7 = StrOption(name="var2", doc="a variable2", default=Calculation(func['calc_value'], Params((ParamOption(option_3)))), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_8 = StrOption(name="var3", doc="var3", default="string4", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string', 'test': ('string5',)})
option_10 = StrOption(name="variable", doc="fourth variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamOption(option_1)))), Calculation(func['calc_value'], Params((ParamOption(option_3)))), Calculation(func['calc_value'], Params((ParamOption(option_8))))], default_multi=Calculation(func['calc_value'], Params((ParamOption(option_1)))), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
optiondescription_9 = OptionDescription(name="subfamily", doc="a sub family", children=[option_10], properties=frozenset({"standard"}))
optiondescription_6 = OptionDescription(name="family2", doc="a family", children=[option_7, option_8, optiondescription_9], properties=frozenset({"standard"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, optiondescription_2, optiondescription_6])

View file

@ -1,18 +0,0 @@
from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_1 = StrOption(name="var1", doc="first variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
option_3 = StrOption(name="var2", doc="a second variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
option_5 = StrOption(name="variable", doc="third variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamOption(option_1)), kwargs={'__internal_multi': ParamValue(True)})), Calculation(func['calc_value'], Params((ParamOption(option_3)), kwargs={'__internal_multi': ParamValue(True)}))], default_multi=Calculation(func['calc_value'], Params((ParamOption(option_1)), kwargs={'__internal_multi': ParamValue(True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
optiondescription_4 = OptionDescription(name="subfamily", doc="a sub family", children=[option_5], properties=frozenset({"standard"}))
optiondescription_2 = OptionDescription(name="family", doc="a family", children=[option_3, optiondescription_4], properties=frozenset({"basic"}))
option_7 = StrOption(name="var2", doc="var2", default=Calculation(func['calc_value'], Params((ParamOption(option_3)))), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_9 = StrOption(name="variable", doc="fourth variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamOption(option_1)), kwargs={'__internal_multi': ParamValue(True)})), Calculation(func['calc_value'], Params((ParamOption(option_3)), kwargs={'__internal_multi': ParamValue(True)})), Calculation(func['calc_value'], Params((ParamOption(option_7)), kwargs={'__internal_multi': ParamValue(True)}))], default_multi=Calculation(func['calc_value'], Params((ParamOption(option_1)), kwargs={'__internal_multi': ParamValue(True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
optiondescription_8 = OptionDescription(name="subfamily", doc="a sub family", children=[option_9], properties=frozenset({"standard"}))
optiondescription_6 = OptionDescription(name="family2", doc="a family", children=[option_7, optiondescription_8], properties=frozenset({"standard"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, optiondescription_2, optiondescription_6])

View file

@ -12,6 +12,6 @@ ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_3 = StrOption(name="var2", doc="a second variable", default="no", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_4 = StrOption(name="var3", doc="a third variable", default="yes", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_2 = StrOption(name="var", doc="a first variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamOption(option_3)), kwargs={'__internal_multi': ParamValue(True)})), Calculation(func['calc_value'], Params((ParamOption(option_4)), kwargs={'__internal_multi': ParamValue(True)}))], default_multi=Calculation(func['calc_value'], Params((ParamOption(option_3)), kwargs={'__internal_multi': ParamValue(True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_2 = StrOption(name="var", doc="a first variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamOption(option_3)))), Calculation(func['calc_value'], Params((ParamOption(option_4))))], default_multi=Calculation(func['calc_value'], Params((ParamOption(option_3)))), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2, option_3, option_4], properties=frozenset({"standard"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])

View file

@ -8,5 +8,5 @@ ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_2 = StrOption(name="var2", doc="a second variable", default="no", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_3 = StrOption(name="var3", doc="a third variable", default="yes", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_1 = StrOption(name="var", doc="a first variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamOption(option_2)), kwargs={'__internal_multi': ParamValue(True)})), Calculation(func['calc_value'], Params((ParamOption(option_3)), kwargs={'__internal_multi': ParamValue(True)}))], default_multi=Calculation(func['calc_value'], Params((ParamOption(option_2)), kwargs={'__internal_multi': ParamValue(True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_1 = StrOption(name="var", doc="a first variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamOption(option_2)))), Calculation(func['calc_value'], Params((ParamOption(option_3))))], default_multi=Calculation(func['calc_value'], Params((ParamOption(option_2)))), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_2, option_3])

View file

@ -12,7 +12,7 @@
"default"
],
"value": [
"ne peut acc\u00e9der \u00e0 l'option \"a follower\" \u00e0 cause de la propri\u00e9t\u00e9 \"disabled\" (the value of \"leader\" is \"a\")",
"cannot access to option \"a follower\" because has property \"disabled\" (the value of \"leader\" is \"a\")",
"b"
]
}

View file

@ -12,7 +12,7 @@
"default"
],
"value": [
"ne peut acc\u00e9der \u00e0 l'option \"a follower\" \u00e0 cause de la propri\u00e9t\u00e9 \"disabled\" (the value of \"leader\" is \"a\")",
"cannot access to option \"a follower\" because has property \"disabled\" (the value of \"leader\" is \"a\")",
"b"
]
}

View file

@ -45,7 +45,7 @@ excludes = set([
])
test_ok -= excludes
test_raise -= excludes
#test_ok = ['00_9extra']
# test_ok = ['00_9default_calculation_multi_optional']
#test_ok = []
#test_raise = ['88valid_enum_invalid_default']
#test_raise = []
@ -124,7 +124,7 @@ def save(test_dir, eolobj, multi=False, namespace=False, error=False):
tiramisu_dir = dirname(tiramisu_file)
if not error:
if not isdir(tiramisu_dir):
raise Exception(f'creates {tiramisu_dir}')
raise Exception(f'please creates {tiramisu_dir}')
if not isfile(tiramisu_file) or debug:
copyfile(tiramisu_tmp, tiramisu_file)
with open(tiramisu_tmp, 'r') as fh:
@ -161,28 +161,32 @@ def test_dictionary_namespace(test_dir):
test_dir_ = join(dico_dirs, test_dir)
rougailconfig = RougailConfig.copy()
rougailconfig['main_namespace'] = 'Rougail'
if (dico_dirs / test_dir / 'force_no_namespace').is_file():
return
eolobj = load_rougail_object(test_dir_, rougailconfig, namespace=True)
if not eolobj:
return
save(test_dir_, eolobj, namespace=True)
assert getcwd() == ORI_DIR
def test_dictionary_multi(test_dir):
if not test_multi:
print('MULTI!')
return
assert getcwd() == ORI_DIR
test_dir_ = join(dico_dirs, test_dir)
rougailconfig = RougailConfig.copy()
rougailconfig['main_namespace'] = 'Rougail'
eolobj = load_rougail_object(test_dir_, rougailconfig, multi=True)
if not eolobj:
return
eolobj.add_path_prefix('1')
eolobj.add_path_prefix('2')
save(test_dir_, eolobj, multi=True)
assert getcwd() == ORI_DIR
#
#
#def test_dictionary_multi(test_dir):
# if not test_multi:
# print('MULTI!')
# return
# assert getcwd() == ORI_DIR
# test_dir_ = join(dico_dirs, test_dir)
# rougailconfig = RougailConfig.copy()
# rougailconfig['main_namespace'] = 'Rougail'
# if (dico_dirs / test_dir / 'force_no_namespace').is_file():
# return
# eolobj = load_rougail_object(test_dir_, rougailconfig, multi=True)
# if not eolobj:
# return
# eolobj.add_path_prefix('1')
# eolobj.add_path_prefix('2')
# save(test_dir_, eolobj, multi=True)
# assert getcwd() == ORI_DIR
def test_error_dictionary(test_dir_error):

View file

@ -85,6 +85,8 @@ def launch_flattener(test_dir,
mandatory_file = Path(makedict_dir) / 'mandatory.json'
modulepath = join(test_dir, 'tiramisu', filename + '.py')
if not isfile(modulepath):
return
with open(modulepath) as fh:
optiondescription = {}
exec(fh.read(), {'CustomOption': CustomOption}, optiondescription) # pylint: disable=W0122
@ -113,17 +115,20 @@ def launch_flattener(test_dir,
for root in ['1', '2']:
config.option(f'{root}.{key}').information.set('test_information', value)
#
if not isdir(makedict_dir):
mkdir(makedict_dir)
config_dict = dict(option_value(config.value.get()))
if filename == 'base':
if not isdir(makedict_dir):
mkdir(makedict_dir)
if not isfile(makedict_file) or debug:
with open(makedict_file, 'w') as fh:
dump(config_dict, fh, indent=4)
fh.write('\n')
elif filename == 'no_namespace':
config_dict = {f'rougail.{path}': value for path, value in config_dict.items()}
if not isfile(Path(test_dir) / 'tiramisu' / 'base.py'):
tconfig_dict = {f'rougail.{path}': value for path, value in config_dict.items()}
else:
tconfig_dict = config_dict
if not isfile(makedict_file) or debug:
with open(makedict_file, 'w') as fh:
dump(tconfig_dict, fh, indent=4)
fh.write('\n')
if filename == 'no_namespace':
config_dict = {f'rougail.{path}': value for path, value in config_dict.items()}
elif filename != 'base':
config_dict_prefix = {'1': {}, '2': {}}
for key, value in config_dict.items():
prefix, path = key.split('.', 1)
@ -142,9 +147,10 @@ def launch_flattener(test_dir,
if not isfile(makedict_file):
raise Exception('dict is not empty')
with open(makedict_file, 'r') as fh:
assert load(fh) == loads(dumps(config_dict)), f"error in file {makedict_file}"
loaded_config_dict = load(fh)
assert loaded_config_dict == loads(dumps(config_dict)), f"error in file {makedict_file}"
#
value_owner(makedict_before, config, filename)
value_owner(test_dir, makedict_before, config, filename)
# deploy
ro = config.property.default('read_only', 'append')
ro = frozenset(list(ro) + ['force_store_value'])
@ -154,12 +160,12 @@ def launch_flattener(test_dir,
config.property.setdefault(rw, 'read_write', 'append')
config.property.add('force_store_value')
#
value_owner(makedict_after, config, filename)
value_owner(test_dir, makedict_after, config, filename)
#
mandatory(mandatory_file, config.value.mandatory(), filename)
mandatory(test_dir, mandatory_file, config.value.mandatory(), filename)
def value_owner(makedict_value_owner, config, filename):
def value_owner(test_dir, makedict_value_owner, config, filename):
ret = {}
for key, value in option_value(config.value.get(), True):
path = key.path()
@ -182,14 +188,17 @@ def value_owner(makedict_value_owner, config, filename):
ret[path] = {'owner': owner,
'value': value,
}
if filename == 'base':
if not isfile(makedict_value_owner) or debug:
with open(makedict_value_owner, 'w') as fh:
dump(ret, fh, indent=4)
fh.write('\n')
elif filename == 'no_namespace':
ret = {f'rougail.{path}': value for path, value in ret.items()}
if not isfile(Path(test_dir) / 'tiramisu' / 'base.py'):
tret = {f'rougail.{path}': value for path, value in ret.items()}
else:
tret = ret
if not isfile(makedict_value_owner) or debug:
with open(makedict_value_owner, 'w') as fh:
dump(tret, fh, indent=4)
fh.write('\n')
if filename == 'no_namespace':
ret = {f'rougail.{path}': value for path, value in ret.items()}
elif filename != 'base':
ret_prefix = {'1': {}, '2': {}}
for key, value in ret.items():
prefix, path = key.split('.', 1)
@ -200,14 +209,15 @@ def value_owner(makedict_value_owner, config, filename):
assert load(fh) == loads(dumps(ret)), f"error in file {makedict_value_owner}"
def mandatory(mandatory_file, mandatories, filename):
ret = [opt.path() for opt in mandatories]
def mandatory(test_dir, mandatory_file, mandatories, filename):
if filename == 'no_namespace':
ret = [f'rougail.{opt.path()}' for opt in mandatories]
else:
ret = [opt.path() for opt in mandatories]
if not mandatory_file.is_file():
with mandatory_file.open('w') as fh:
dump(ret, fh)
if filename == 'no_namespace':
ret = [f'rougail.{path}' for path in ret]
elif filename == 'multi':
if filename == 'multi':
ret_prefix = {'1': [], '2': []}
for key in ret:
prefix, path = key.split('.', 1)
@ -223,12 +233,14 @@ def test_dictionary(test_dir):
print('FIXME')
return
test_dir = join(dico_dirs, test_dir)
if not (Path(test_dir) / 'tiramisu' / 'base.py').is_file():
return
launch_flattener(test_dir, 'base')
def test_dictionary_no_namespace(test_dir):
test_dir = join(dico_dirs, test_dir)
if not isfile(Path(test_dir) / 'tiramisu' / 'no_namespace.py'):
if not (Path(test_dir) / 'tiramisu' / 'no_namespace.py').is_file():
return
launch_flattener(test_dir, 'no_namespace')
@ -238,6 +250,6 @@ def test_dictionary_multi(test_dir):
print('FIXME')
return
test_dir = join(dico_dirs, test_dir)
if not isfile(Path(test_dir) / 'tiramisu' / 'multi.py'):
if not (Path(test_dir) / 'tiramisu' / 'multi.py').is_file():
return
launch_flattener(test_dir, 'multi')