fameio 3.2.0__py3-none-any.whl → 3.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fameio/cli/convert_results.py +4 -6
- fameio/cli/make_config.py +3 -5
- fameio/cli/options.py +6 -4
- fameio/cli/parser.py +53 -29
- fameio/cli/reformat.py +58 -0
- fameio/input/__init__.py +4 -4
- fameio/input/loader/__init__.py +4 -6
- fameio/input/loader/controller.py +11 -16
- fameio/input/loader/loader.py +11 -9
- fameio/input/metadata.py +26 -29
- fameio/input/resolver.py +4 -6
- fameio/input/scenario/agent.py +18 -16
- fameio/input/scenario/attribute.py +85 -31
- fameio/input/scenario/contract.py +78 -38
- fameio/input/scenario/exception.py +3 -6
- fameio/input/scenario/fameiofactory.py +7 -12
- fameio/input/scenario/generalproperties.py +7 -8
- fameio/input/scenario/scenario.py +14 -18
- fameio/input/scenario/stringset.py +5 -6
- fameio/input/schema/agenttype.py +8 -10
- fameio/input/schema/attribute.py +30 -36
- fameio/input/schema/java_packages.py +6 -7
- fameio/input/schema/schema.py +9 -11
- fameio/input/validator.py +178 -41
- fameio/input/writer.py +20 -29
- fameio/logs.py +28 -19
- fameio/output/agent_type.py +14 -16
- fameio/output/conversion.py +9 -12
- fameio/output/csv_writer.py +33 -23
- fameio/output/data_transformer.py +11 -11
- fameio/output/execution_dao.py +170 -0
- fameio/output/input_dao.py +16 -19
- fameio/output/output_dao.py +7 -7
- fameio/output/reader.py +8 -10
- fameio/output/yaml_writer.py +2 -3
- fameio/scripts/__init__.py +15 -4
- fameio/scripts/convert_results.py +18 -17
- fameio/scripts/exception.py +1 -1
- fameio/scripts/make_config.py +3 -4
- fameio/scripts/reformat.py +71 -0
- fameio/scripts/reformat.py.license +3 -0
- fameio/series.py +78 -47
- fameio/time.py +56 -18
- fameio/tools.py +42 -4
- {fameio-3.2.0.dist-info → fameio-3.4.0.dist-info}/METADATA +64 -40
- fameio-3.4.0.dist-info/RECORD +60 -0
- {fameio-3.2.0.dist-info → fameio-3.4.0.dist-info}/entry_points.txt +1 -0
- fameio-3.2.0.dist-info/RECORD +0 -56
- {fameio-3.2.0.dist-info → fameio-3.4.0.dist-info}/LICENSE.txt +0 -0
- {fameio-3.2.0.dist-info → fameio-3.4.0.dist-info}/LICENSES/Apache-2.0.txt +0 -0
- {fameio-3.2.0.dist-info → fameio-3.4.0.dist-info}/LICENSES/CC-BY-4.0.txt +0 -0
- {fameio-3.2.0.dist-info → fameio-3.4.0.dist-info}/LICENSES/CC0-1.0.txt +0 -0
- {fameio-3.2.0.dist-info → fameio-3.4.0.dist-info}/WHEEL +0 -0
fameio/cli/convert_results.py
CHANGED
@@ -26,8 +26,8 @@ CLI_DEFAULTS = {
|
|
26
26
|
Options.FILE: None,
|
27
27
|
Options.LOG_LEVEL: "WARN",
|
28
28
|
Options.LOG_FILE: None,
|
29
|
-
Options.AGENT_LIST: None,
|
30
29
|
Options.OUTPUT: None,
|
30
|
+
Options.AGENT_LIST: None,
|
31
31
|
Options.SINGLE_AGENT_EXPORT: False,
|
32
32
|
Options.MEMORY_SAVING: False,
|
33
33
|
Options.RESOLVE_COMPLEX_FIELD: ResolveOptions.SPLIT,
|
@@ -41,8 +41,7 @@ _OUTFILE_PATH_HELP = "Provide path to folder to store output .csv files"
|
|
41
41
|
|
42
42
|
|
43
43
|
def handle_args(args: list[str], defaults: dict[Options, Any] | None = None) -> dict[Options, Any]:
|
44
|
-
"""
|
45
|
-
Handles command line arguments and returns `run_config` for convert_results script
|
44
|
+
"""Handles command line arguments and returns `run_config` for convert_results script.
|
46
45
|
|
47
46
|
Args:
|
48
47
|
args: list of (command line) arguments, e.g., ['-f', 'my_file']; arg values take precedence over defaults
|
@@ -57,8 +56,7 @@ def handle_args(args: list[str], defaults: dict[Options, Any] | None = None) ->
|
|
57
56
|
|
58
57
|
|
59
58
|
def _prepare_parser(defaults: dict[Options, Any] | None) -> argparse.ArgumentParser:
|
60
|
-
"""
|
61
|
-
Creates a parser with given defaults to handle `make_config` configuration arguments
|
59
|
+
"""Creates a parser with given defaults to handle `make_config` configuration arguments.
|
62
60
|
|
63
61
|
Returns:
|
64
62
|
new parser using given defaults for its arguments; if a default is not specified, hard-coded defaults are used
|
@@ -82,5 +80,5 @@ def _prepare_parser(defaults: dict[Options, Any] | None) -> argparse.ArgumentPar
|
|
82
80
|
|
83
81
|
|
84
82
|
def _get_default(defaults: dict, option: Options) -> Any:
|
85
|
-
"""Returns default for given `option` or its cli default"""
|
83
|
+
"""Returns default for given `option` or its cli default."""
|
86
84
|
return defaults.get(option, CLI_DEFAULTS[option])
|
fameio/cli/make_config.py
CHANGED
@@ -34,8 +34,7 @@ _ENCODING_HELP = (
|
|
34
34
|
|
35
35
|
|
36
36
|
def handle_args(args: list[str], defaults: dict[Options, Any] | None = None) -> dict[Options, Any]:
|
37
|
-
"""
|
38
|
-
Converts given `arguments` and returns a configuration for the make_config script
|
37
|
+
"""Converts given `args` and returns a configuration for the make_config script.
|
39
38
|
|
40
39
|
Args:
|
41
40
|
args: list of (command line) arguments, e.g., ['-f', 'my_file']; arg values take precedence over defaults
|
@@ -50,8 +49,7 @@ def handle_args(args: list[str], defaults: dict[Options, Any] | None = None) ->
|
|
50
49
|
|
51
50
|
|
52
51
|
def _prepare_parser(defaults: dict[Options, Any] | None) -> argparse.ArgumentParser:
|
53
|
-
"""
|
54
|
-
Creates a parser with given defaults to handle `make_config` configuration arguments
|
52
|
+
"""Creates a parser with given defaults to handle `make_config` configuration arguments.
|
55
53
|
|
56
54
|
Returns:
|
57
55
|
new parser using given defaults for its arguments; if a default is not specified, hard-coded defaults are used
|
@@ -67,5 +65,5 @@ def _prepare_parser(defaults: dict[Options, Any] | None) -> argparse.ArgumentPar
|
|
67
65
|
|
68
66
|
|
69
67
|
def _get_default(defaults: dict, option: Options) -> Any:
|
70
|
-
"""Returns default for given `option` or, if missing, its cli default"""
|
68
|
+
"""Returns default for given `option` or, if missing, its cli default."""
|
71
69
|
return defaults.get(option, CLI_DEFAULTS[option])
|
fameio/cli/options.py
CHANGED
@@ -6,7 +6,7 @@ from enum import Enum, auto
|
|
6
6
|
|
7
7
|
|
8
8
|
class ParsableEnum(Enum):
|
9
|
-
"""Extend this to create an enum that can be parsed with argparse"""
|
9
|
+
"""Extend this to create an enum that can be parsed with argparse."""
|
10
10
|
|
11
11
|
@classmethod
|
12
12
|
def instantiate(cls, name: str) -> Enum:
|
@@ -20,7 +20,7 @@ class ParsableEnum(Enum):
|
|
20
20
|
|
21
21
|
|
22
22
|
class Options(Enum):
|
23
|
-
"""Specifies command line configuration options"""
|
23
|
+
"""Specifies command line configuration options."""
|
24
24
|
|
25
25
|
FILE = auto()
|
26
26
|
LOG_LEVEL = auto()
|
@@ -34,10 +34,12 @@ class Options(Enum):
|
|
34
34
|
TIME_MERGING = auto()
|
35
35
|
INPUT_RECOVERY = auto()
|
36
36
|
INPUT_ENCODING = auto()
|
37
|
+
FILE_PATTERN = auto()
|
38
|
+
REPLACE = auto()
|
37
39
|
|
38
40
|
|
39
41
|
class TimeOptions(ParsableEnum, Enum):
|
40
|
-
"""Specifies options for conversion of time in output"""
|
42
|
+
"""Specifies options for conversion of time in output."""
|
41
43
|
|
42
44
|
INT = auto()
|
43
45
|
UTC = auto()
|
@@ -45,7 +47,7 @@ class TimeOptions(ParsableEnum, Enum):
|
|
45
47
|
|
46
48
|
|
47
49
|
class ResolveOptions(ParsableEnum, Enum):
|
48
|
-
"""Specifies options for resolving complex fields in output files"""
|
50
|
+
"""Specifies options for resolving complex fields in output files."""
|
49
51
|
|
50
52
|
IGNORE = auto()
|
51
53
|
SPLIT = auto()
|
fameio/cli/parser.py
CHANGED
@@ -26,13 +26,15 @@ _OPTION_ARGUMENT_NAME: dict[str, Options] = {
|
|
26
26
|
"input_recovery": Options.INPUT_RECOVERY,
|
27
27
|
"complex_column": Options.RESOLVE_COMPLEX_FIELD,
|
28
28
|
"merge_times": Options.TIME_MERGING,
|
29
|
+
"file_pattern": Options.FILE_PATTERN,
|
30
|
+
"replace": Options.REPLACE,
|
29
31
|
}
|
30
32
|
|
31
33
|
|
32
34
|
def add_file_argument(parser: ArgumentParser, default: Path | None, help_text: str) -> None:
|
33
|
-
"""
|
34
|
-
|
35
|
-
If a default is not specified, the argument is required (optional otherwise)
|
35
|
+
"""Adds 'file' argument to the provided `parser` with the provided `help_text`.
|
36
|
+
|
37
|
+
If a default is not specified, the argument is required (optional otherwise).
|
36
38
|
|
37
39
|
Args:
|
38
40
|
parser: to add the argument to
|
@@ -46,24 +48,24 @@ def add_file_argument(parser: ArgumentParser, default: Path | None, help_text: s
|
|
46
48
|
|
47
49
|
|
48
50
|
def add_select_agents_argument(parser: ArgumentParser, default_value: list[str] | None) -> None:
|
49
|
-
"""Adds optional repeatable string argument 'agent' to given `parser
|
51
|
+
"""Adds optional repeatable string argument 'agent' to given `parser`."""
|
50
52
|
help_text = f"Provide list of agents to extract (default={default_value})"
|
51
53
|
parser.add_argument("-a", "--agents", nargs="*", type=str, default=default_value, help=help_text)
|
52
54
|
|
53
55
|
|
54
56
|
def add_logfile_argument(parser: ArgumentParser, default_value: Path | None) -> None:
|
55
|
-
"""Adds optional argument 'logfile' to given `parser
|
57
|
+
"""Adds optional argument 'logfile' to given `parser`."""
|
56
58
|
help_text = f"provide logging file (default={default_value})"
|
57
59
|
parser.add_argument("-lf", "--logfile", type=Path, default=default_value, help=help_text)
|
58
60
|
|
59
61
|
|
60
62
|
def add_output_argument(parser: ArgumentParser, default_value, help_text: str) -> None:
|
61
|
-
"""Adds optional argument 'output' to given `parser` using the given `help_text` and `default_value
|
63
|
+
"""Adds optional argument 'output' to given `parser` using the given `help_text` and `default_value`."""
|
62
64
|
parser.add_argument("-o", "--output", type=Path, default=default_value, help=help_text)
|
63
65
|
|
64
66
|
|
65
67
|
def add_log_level_argument(parser: ArgumentParser, default_value: str) -> None:
|
66
|
-
"""Adds optional argument 'log' to given `parser
|
68
|
+
"""Adds optional argument 'log' to given `parser`."""
|
67
69
|
help_text = f"choose logging level (default={default_value})"
|
68
70
|
# noinspection PyTypeChecker
|
69
71
|
parser.add_argument(
|
@@ -82,7 +84,7 @@ def add_encoding_argument(parser: ArgumentParser, default_value: str | None, hel
|
|
82
84
|
|
83
85
|
|
84
86
|
def add_single_export_argument(parser: ArgumentParser, default_value: bool) -> None:
|
85
|
-
"""Adds optional repeatable string argument 'agent' to given `parser
|
87
|
+
"""Adds optional repeatable string argument 'agent' to given `parser`."""
|
86
88
|
help_text = f"Enable export of single agents (default={default_value})"
|
87
89
|
parser.add_argument(
|
88
90
|
"-se",
|
@@ -94,7 +96,7 @@ def add_single_export_argument(parser: ArgumentParser, default_value: bool) -> N
|
|
94
96
|
|
95
97
|
|
96
98
|
def add_memory_saving_argument(parser: ArgumentParser, default_value: bool) -> None:
|
97
|
-
"""Adds optional bool argument to given `parser` to enable memory saving mode"""
|
99
|
+
"""Adds optional bool argument to given `parser` to enable memory saving mode."""
|
98
100
|
help_text = f"Reduces memory usage profile at the cost of runtime (default={default_value})"
|
99
101
|
parser.add_argument(
|
100
102
|
"-m",
|
@@ -106,7 +108,7 @@ def add_memory_saving_argument(parser: ArgumentParser, default_value: bool) -> N
|
|
106
108
|
|
107
109
|
|
108
110
|
def add_resolve_complex_argument(parser: ArgumentParser, default_value: ResolveOptions | str):
|
109
|
-
"""Instructs given `parser` how to deal with complex field outputs"""
|
111
|
+
"""Instructs given `parser` how to deal with complex field outputs."""
|
110
112
|
default_value = default_value if isinstance(default_value, ResolveOptions) else ResolveOptions[default_value]
|
111
113
|
help_text = f"How to deal with complex index columns? (default={default_value.name})"
|
112
114
|
parser.add_argument(
|
@@ -120,7 +122,7 @@ def add_resolve_complex_argument(parser: ArgumentParser, default_value: ResolveO
|
|
120
122
|
|
121
123
|
|
122
124
|
def add_time_argument(parser: ArgumentParser, default_value: TimeOptions | str) -> None:
|
123
|
-
"""Adds optional argument to given `parser` to define conversion of TimeSteps"""
|
125
|
+
"""Adds optional argument to given `parser` to define conversion of TimeSteps."""
|
124
126
|
default_value = default_value if isinstance(default_value, TimeOptions) else TimeOptions[default_value]
|
125
127
|
help_text = f"Apply conversion of time steps to given format (default={default_value.name})"
|
126
128
|
parser.add_argument(
|
@@ -134,7 +136,7 @@ def add_time_argument(parser: ArgumentParser, default_value: TimeOptions | str)
|
|
134
136
|
|
135
137
|
|
136
138
|
def add_merge_time_argument(parser: ArgumentParser, defaults: list[int] | None = None) -> None:
|
137
|
-
"""Adds optional three-fold argument for merging of TimeSteps to given `parser
|
139
|
+
"""Adds optional three-fold argument for merging of TimeSteps to given `parser`."""
|
138
140
|
if defaults is None:
|
139
141
|
defaults = []
|
140
142
|
if (
|
@@ -152,21 +154,43 @@ def add_merge_time_argument(parser: ArgumentParser, defaults: list[int] | None =
|
|
152
154
|
|
153
155
|
|
154
156
|
def add_inputs_recovery_argument(parser: ArgumentParser, default_value: bool) -> None:
|
155
|
-
"""Adds optional bool argument to given `parser` to recover inputs"""
|
156
|
-
|
157
|
-
|
158
|
-
help_text = f"If --(no-)input-recovery is specified, (no) inputs will be recovered (default={default_str})"
|
159
|
-
parser.add_argument(
|
160
|
-
f"--{arg_name}",
|
161
|
-
action=BooleanOptionalAction,
|
162
|
-
default=default_value,
|
163
|
-
help=help_text,
|
164
|
-
)
|
157
|
+
"""Adds optional bool argument to given `parser` to recover inputs."""
|
158
|
+
description = "(no) inputs will be recovered"
|
159
|
+
_add_optional_boolean_argument(parser, default_value, "input-recovery", description)
|
165
160
|
|
166
161
|
|
167
|
-
def
|
162
|
+
def _add_optional_boolean_argument(parser: ArgumentParser, default: bool, arg_name: str, description: str) -> None:
|
163
|
+
"""Adds optional boolean argument to parser.
|
164
|
+
|
165
|
+
Argument named `arg_name` is added to given `parser` overwriting the provided default.
|
166
|
+
Help from argument `description` is added as help text.
|
167
|
+
|
168
|
+
Args:
|
169
|
+
parser: to add the argument to
|
170
|
+
default: of the argument
|
171
|
+
arg_name: long name of the argument, no short name allowed; will be prepended with 'no-' for negation
|
172
|
+
description: to create the help text from: "If --(no-)<arg_name> is specified, <description> (default=X)'
|
168
173
|
"""
|
169
|
-
|
174
|
+
default_str = "--" + ("no-" if not default else "") + arg_name
|
175
|
+
help_text = f"If --(no-){arg_name} is specified, {description} (default={default_str})"
|
176
|
+
parser.add_argument(f"--{arg_name}", action=BooleanOptionalAction, default=default, help=help_text)
|
177
|
+
|
178
|
+
|
179
|
+
def add_file_pattern_argument(parser: ArgumentParser, default_value: str | None) -> None:
|
180
|
+
"""Adds argument to given `parser` to specify a file pattern; if no default provided, the argument is mandatory."""
|
181
|
+
help_text = f"Path to csv file(s) that are to be converted (default='{default_value}')"
|
182
|
+
required = not bool(default_value)
|
183
|
+
parser.add_argument("--file-pattern", "-fp", required=required, type=str, default=default_value, help=help_text)
|
184
|
+
|
185
|
+
|
186
|
+
def add_replace_argument(parser: ArgumentParser, default_value: bool) -> None:
|
187
|
+
"""Adds optional bool argument to given `parser` to replace converted files."""
|
188
|
+
description = "original files will (not) be replaced"
|
189
|
+
_add_optional_boolean_argument(parser, default_value, "replace", description)
|
190
|
+
|
191
|
+
|
192
|
+
def update_default_config(overrides: dict[Options, Any] | None, defaults: dict[Options, Any]) -> dict[Options, Any]:
|
193
|
+
"""Returns `defaults` with updated fields received from `overrides`.
|
170
194
|
|
171
195
|
Args:
|
172
196
|
overrides: updates to be applied to `defaults`
|
@@ -183,8 +207,7 @@ def update_default_config(overrides: dict[Options, Any] | None, defaults: dict[O
|
|
183
207
|
|
184
208
|
|
185
209
|
def map_namespace_to_options_dict(parsed: Namespace) -> dict[Options, Any]:
|
186
|
-
"""
|
187
|
-
Maps given parsing results to their corresponding configuration option
|
210
|
+
"""Maps given parsing results to their corresponding configuration option.
|
188
211
|
|
189
212
|
Args:
|
190
213
|
parsed: result of a parsing
|
@@ -196,9 +219,10 @@ def map_namespace_to_options_dict(parsed: Namespace) -> dict[Options, Any]:
|
|
196
219
|
|
197
220
|
|
198
221
|
def _map_namespace_to_options(parsed: Namespace, names_to_options: dict[str, Options]) -> dict[Options, Any]:
|
199
|
-
"""
|
200
|
-
|
201
|
-
|
222
|
+
"""Maps given parsing results to their corresponding configuration option.
|
223
|
+
|
224
|
+
Elements that cannot be mapped are ignored.
|
225
|
+
If a configuration option has inner elements, these will be also read and added as inner dictionary.
|
202
226
|
|
203
227
|
Args:
|
204
228
|
parsed: result of a parsing
|
fameio/cli/reformat.py
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 German Aerospace Center <fame@dlr.de>
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
4
|
+
from __future__ import annotations
|
5
|
+
|
6
|
+
import argparse
|
7
|
+
from typing import Any
|
8
|
+
|
9
|
+
from fameio.cli.options import Options
|
10
|
+
from fameio.cli.parser import (
|
11
|
+
map_namespace_to_options_dict,
|
12
|
+
add_logfile_argument,
|
13
|
+
add_log_level_argument,
|
14
|
+
add_file_pattern_argument,
|
15
|
+
add_replace_argument,
|
16
|
+
)
|
17
|
+
|
18
|
+
CLI_DEFAULTS = {
|
19
|
+
Options.LOG_LEVEL: "WARN",
|
20
|
+
Options.LOG_FILE: None,
|
21
|
+
Options.FILE_PATTERN: None,
|
22
|
+
Options.REPLACE: False,
|
23
|
+
}
|
24
|
+
|
25
|
+
|
26
|
+
def handle_args(args: list[str], defaults: dict[Options, Any] | None = None) -> dict[Options, Any]:
|
27
|
+
"""Converts given `args` and returns a configuration for the transform script.
|
28
|
+
|
29
|
+
Args:
|
30
|
+
args: list of (command line) arguments, e.g., ['-fp', 'my_file']; arg values take precedence over defaults
|
31
|
+
defaults: optional default values used for unspecified parameters; missing defaults are replaced by CLI defaults
|
32
|
+
|
33
|
+
Returns:
|
34
|
+
final configuration compiled from (given) `defaults` and given `args`
|
35
|
+
"""
|
36
|
+
parser = _prepare_parser(defaults)
|
37
|
+
parsed = parser.parse_args(args)
|
38
|
+
return map_namespace_to_options_dict(parsed)
|
39
|
+
|
40
|
+
|
41
|
+
def _prepare_parser(defaults: dict[Options, Any] | None) -> argparse.ArgumentParser:
|
42
|
+
"""Creates a parser with given defaults to handle `reformat` configuration arguments.
|
43
|
+
|
44
|
+
Returns:
|
45
|
+
new parser using given defaults for its arguments; if a default is not specified, hard-coded defaults are used
|
46
|
+
"""
|
47
|
+
defaults = defaults if (defaults is not None) else {}
|
48
|
+
parser = argparse.ArgumentParser()
|
49
|
+
add_log_level_argument(parser, _get_default(defaults, Options.LOG_LEVEL))
|
50
|
+
add_logfile_argument(parser, _get_default(defaults, Options.LOG_FILE))
|
51
|
+
add_file_pattern_argument(parser, _get_default(defaults, Options.FILE_PATTERN))
|
52
|
+
add_replace_argument(parser, _get_default(defaults, Options.REPLACE))
|
53
|
+
return parser
|
54
|
+
|
55
|
+
|
56
|
+
def _get_default(defaults: dict, option: Options) -> Any:
|
57
|
+
"""Returns default for given `option` or its cli default."""
|
58
|
+
return defaults.get(option, CLI_DEFAULTS[option])
|
fameio/input/__init__.py
CHANGED
@@ -4,16 +4,16 @@
|
|
4
4
|
|
5
5
|
|
6
6
|
class InputError(Exception):
|
7
|
-
"""An error that occurred while preparing a fame input file"""
|
7
|
+
"""An error that occurred while preparing a fame input file."""
|
8
8
|
|
9
9
|
|
10
10
|
class SchemaError(InputError):
|
11
|
-
"""An error that occurred while parsing a Schema"""
|
11
|
+
"""An error that occurred while parsing a Schema."""
|
12
12
|
|
13
13
|
|
14
14
|
class ScenarioError(InputError):
|
15
|
-
"""An error that occurred while parsing a Scenario"""
|
15
|
+
"""An error that occurred while parsing a Scenario."""
|
16
16
|
|
17
17
|
|
18
18
|
class YamlLoaderError(InputError):
|
19
|
-
"""An error that occurred while parsing a YAML file"""
|
19
|
+
"""An error that occurred while parsing a YAML file."""
|
fameio/input/loader/__init__.py
CHANGED
@@ -32,8 +32,7 @@ FameYamlLoader.add_constructor(FameYamlLoader.INCLUDE_COMMAND, _include_callback
|
|
32
32
|
|
33
33
|
|
34
34
|
def load_yaml(yaml_file_path: Path, path_resolver: PathResolver = PathResolver(), encoding: str | None = None) -> dict:
|
35
|
-
"""
|
36
|
-
Loads the YAML file from given and returns its content as a dict
|
35
|
+
"""Loads the YAML file from given `yaml_file_path` and returns its content as a dict.
|
37
36
|
|
38
37
|
Args:
|
39
38
|
yaml_file_path: Path to the YAML file that is to be read
|
@@ -52,19 +51,18 @@ def load_yaml(yaml_file_path: Path, path_resolver: PathResolver = PathResolver()
|
|
52
51
|
|
53
52
|
|
54
53
|
def _update_current_controller(path_resolver: PathResolver, encoding: str | None) -> None:
|
55
|
-
"""Updates the current LoaderController to use the given `path_resolver` and `encoding
|
54
|
+
"""Updates the current LoaderController to use the given `path_resolver` and `encoding`."""
|
56
55
|
__CONTROLLERS[0] = LoaderController(path_resolver, encoding)
|
57
56
|
|
58
57
|
|
59
58
|
def validate_yaml_file_suffix(yaml_file: Path) -> None:
|
60
|
-
"""
|
61
|
-
Ensures that given file has a file suffix compatible with YAML
|
59
|
+
"""Ensures that given file has a file suffix compatible with YAML.
|
62
60
|
|
63
61
|
Args:
|
64
62
|
yaml_file: that is to be checked for suffix correctness
|
65
63
|
|
66
64
|
Raises:
|
67
|
-
YamlLoaderError: if given file has no YAML-associated file suffix
|
65
|
+
YamlLoaderError: if given file has no YAML-associated file suffix, logged with level "CRITICAL"
|
68
66
|
"""
|
69
67
|
if yaml_file.suffix.lower() not in ALLOWED_SUFFIXES:
|
70
68
|
raise log_critical(YamlLoaderError(_ERR_NO_YAML_SUFFIX.format(ALLOWED_SUFFIXES, yaml_file)))
|
@@ -16,9 +16,9 @@ from fameio.logs import log, log_critical
|
|
16
16
|
|
17
17
|
|
18
18
|
class LoaderController:
|
19
|
-
"""
|
20
|
-
|
21
|
-
Uses same PathResolver and encoding for all files
|
19
|
+
"""Controls loading of YAML files by spawning one FameYamlLoader per file.
|
20
|
+
|
21
|
+
Uses same PathResolver and encoding for all files.
|
22
22
|
"""
|
23
23
|
|
24
24
|
DISABLING_YAML_FILE_PREFIX: Final[str] = "IGNORE_"
|
@@ -40,8 +40,7 @@ class LoaderController:
|
|
40
40
|
self._encoding: str | None = encoding
|
41
41
|
|
42
42
|
def load(self, yaml_file_path: Path) -> dict:
|
43
|
-
"""
|
44
|
-
Spawns a new FameYamlLoader, loads the given `yaml_file_path` and returns its content
|
43
|
+
"""Spawns a new FameYamlLoader, loads the given `yaml_file_path` and returns its content.
|
45
44
|
|
46
45
|
Args:
|
47
46
|
yaml_file_path: path to YAML file that is to be loaded
|
@@ -65,13 +64,12 @@ class LoaderController:
|
|
65
64
|
|
66
65
|
@staticmethod
|
67
66
|
def _spawn_loader_builder() -> Callable[[IO], FameYamlLoader]:
|
68
|
-
"""Returns a new Callable that instantiates a new FameYamlLoader with an IO-stream"""
|
67
|
+
"""Returns a new Callable that instantiates a new FameYamlLoader with an IO-stream."""
|
69
68
|
return lambda stream: FameYamlLoader(stream) # pylint: disable=unnecessary-lambda
|
70
69
|
|
71
70
|
@staticmethod
|
72
71
|
def _get_problem_position(exception: yaml.YAMLError) -> tuple[str, str]:
|
73
|
-
"""
|
74
|
-
Returns problematic line and column from given error (if available)
|
72
|
+
"""Returns problematic line and column from given error (if available).
|
75
73
|
|
76
74
|
Args:
|
77
75
|
exception: error thrown by yaml.load()
|
@@ -85,8 +83,7 @@ class LoaderController:
|
|
85
83
|
return "?", "?"
|
86
84
|
|
87
85
|
def include(self, loader: FameYamlLoader, include_args: yaml.Node) -> Any:
|
88
|
-
"""
|
89
|
-
Returns content loaded from the specified `include_args`
|
86
|
+
"""Returns content loaded from the specified `include_args`.
|
90
87
|
|
91
88
|
Args:
|
92
89
|
loader: the YAML loader to be used to load the file(s) that are to be included
|
@@ -113,8 +110,8 @@ class LoaderController:
|
|
113
110
|
return joined_data
|
114
111
|
|
115
112
|
def _resolve_imported_path(self, root_path: str, include_pattern: str) -> list[str]:
|
116
|
-
"""
|
117
|
-
|
113
|
+
"""Returns a list of file paths matching the given `include_pattern` relative to the `root_path`.
|
114
|
+
|
118
115
|
Ignores files starting with the `DISABLING_YAML_FILE_PREFIX`
|
119
116
|
"""
|
120
117
|
file_list = self._path_resolver.resolve_file_pattern(root_path, include_pattern)
|
@@ -133,8 +130,7 @@ class LoaderController:
|
|
133
130
|
|
134
131
|
@staticmethod
|
135
132
|
def _extract_node(file_name: str, data: dict, node_address: list[str]) -> Any:
|
136
|
-
"""
|
137
|
-
Returns only the part of the data that is at the specified node address
|
133
|
+
"""Returns only the part of the data that is at the specified node address.
|
138
134
|
|
139
135
|
Args:
|
140
136
|
file_name: name of the file from which the data were read - used to enrich logging messages
|
@@ -158,8 +154,7 @@ class LoaderController:
|
|
158
154
|
|
159
155
|
@staticmethod
|
160
156
|
def _join_data(new_data: list, previous_data: list | None) -> list:
|
161
|
-
"""
|
162
|
-
Joins two lists with data to a larger list
|
157
|
+
"""Joins two lists with data to a larger list.
|
163
158
|
|
164
159
|
Args:
|
165
160
|
new_data: list of any data
|
fameio/input/loader/loader.py
CHANGED
@@ -11,7 +11,7 @@ from fameio.logs import log, log_critical
|
|
11
11
|
|
12
12
|
|
13
13
|
class FameYamlLoader(yaml.SafeLoader):
|
14
|
-
"""Custom YAML Loader for `!include` constructor"""
|
14
|
+
"""Custom YAML Loader for `!include` constructor."""
|
15
15
|
|
16
16
|
INCLUDE_COMMAND: Final[str] = "!include"
|
17
17
|
|
@@ -29,8 +29,7 @@ class FameYamlLoader(yaml.SafeLoader):
|
|
29
29
|
super().__init__(stream)
|
30
30
|
|
31
31
|
def digest_include(self, node: yaml.Node) -> tuple[str, str, str]:
|
32
|
-
"""
|
33
|
-
Reads arguments in an !include statement and returns information which files to include
|
32
|
+
"""Reads arguments in an !include statement and returns information which files to include.
|
34
33
|
|
35
34
|
Args:
|
36
35
|
node: the current node that is to be deconstructed; could be a file-pattern to load;
|
@@ -58,8 +57,9 @@ class FameYamlLoader(yaml.SafeLoader):
|
|
58
57
|
return self._root_path, file_pattern, node_string
|
59
58
|
|
60
59
|
def _read_scalar_node(self, args: yaml.nodes.ScalarNode) -> tuple[str, str]:
|
61
|
-
"""
|
62
|
-
|
60
|
+
"""Reads and returns content of a scalar !include statement.
|
61
|
+
|
62
|
+
Example: !include "file".
|
63
63
|
|
64
64
|
Args:
|
65
65
|
args: argument assigned to the !include statement
|
@@ -72,8 +72,9 @@ class FameYamlLoader(yaml.SafeLoader):
|
|
72
72
|
return str(file_pattern), ""
|
73
73
|
|
74
74
|
def _read_sequence_node(self, args: yaml.nodes.SequenceNode) -> tuple[str, str]:
|
75
|
-
"""
|
76
|
-
|
75
|
+
"""Reads and returns content of a sequence !include statement.
|
76
|
+
|
77
|
+
Example: !include ["file", Path:to:Node].
|
77
78
|
|
78
79
|
Args:
|
79
80
|
args: argument assigned to the !include statement
|
@@ -94,8 +95,9 @@ class FameYamlLoader(yaml.SafeLoader):
|
|
94
95
|
return file_pattern, node_string
|
95
96
|
|
96
97
|
def _read_mapping_node(self, args: yaml.nodes.MappingNode) -> tuple[str, str]:
|
97
|
-
"""
|
98
|
-
|
98
|
+
"""Reads and returns content of a mapping !include statement.
|
99
|
+
|
100
|
+
Example: !include {file="file", node="Path:to:Node"}
|
99
101
|
|
100
102
|
Args:
|
101
103
|
args: argument assigned to the !include statement
|