the1conf 1.0.0__py3-none-any.whl → 1.3.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.
- the1conf/__init__.py +12 -2
- the1conf/app_config.py +276 -408
- the1conf/app_config_meta.py +202 -0
- the1conf/attr_dict.py +38 -25
- the1conf/auto_prolog.py +177 -0
- the1conf/click_option.py +62 -25
- the1conf/config_var.py +312 -396
- the1conf/flags.py +143 -0
- the1conf/solver.py +346 -0
- the1conf/utils.py +110 -0
- the1conf/var_substitution.py +59 -0
- the1conf-1.3.0.dist-info/METADATA +794 -0
- the1conf-1.3.0.dist-info/RECORD +16 -0
- the1conf-1.0.0.dist-info/METADATA +0 -516
- the1conf-1.0.0.dist-info/RECORD +0 -10
- {the1conf-1.0.0.dist-info → the1conf-1.3.0.dist-info}/WHEEL +0 -0
- {the1conf-1.0.0.dist-info → the1conf-1.3.0.dist-info}/licenses/LICENSE +0 -0
the1conf/config_var.py
CHANGED
|
@@ -1,213 +1,30 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
from collections.abc import Sequence, Callable
|
|
5
|
-
from dataclasses import dataclass
|
|
6
|
-
from enum import Enum, auto
|
|
3
|
+
from collections.abc import Callable, Sequence
|
|
7
4
|
from pathlib import Path
|
|
8
5
|
from typing import (
|
|
6
|
+
TYPE_CHECKING,
|
|
9
7
|
Any,
|
|
10
8
|
Generic,
|
|
11
9
|
Optional,
|
|
12
|
-
TypeAlias,
|
|
13
10
|
TypeVar,
|
|
14
11
|
Union,
|
|
12
|
+
cast,
|
|
13
|
+
dataclass_transform,
|
|
15
14
|
get_args,
|
|
16
15
|
get_origin,
|
|
17
16
|
get_type_hints,
|
|
18
|
-
dataclass_transform,
|
|
19
|
-
TYPE_CHECKING,
|
|
20
17
|
)
|
|
21
|
-
|
|
18
|
+
import inspect
|
|
19
|
+
from .utils import Undefined, _undef, PathType, is_sequence
|
|
20
|
+
from .flags import Flags
|
|
22
21
|
|
|
23
22
|
if TYPE_CHECKING:
|
|
24
23
|
from .app_config import AppConfig
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
class _UndefinedSentinel:
|
|
28
|
-
pass
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
Undefined: TypeAlias = _UndefinedSentinel
|
|
32
|
-
_undef: Undefined = _UndefinedSentinel()
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class PathType(Enum):
|
|
36
|
-
Dir = auto()
|
|
37
|
-
File = auto()
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
__NO_SEARCH__ = "__NOSEARCH__"
|
|
41
|
-
|
|
42
25
|
_T = TypeVar("_T")
|
|
43
26
|
|
|
44
27
|
|
|
45
|
-
class Flags:
|
|
46
|
-
"""
|
|
47
|
-
Flags that control how to search for variable values in AppConfig.
|
|
48
|
-
These flags can be set globally in the AppConfig object or locally when calling resolve_vars() or
|
|
49
|
-
per config variables.
|
|
50
|
-
|
|
51
|
-
Not None flag values override other values with the following precedence:
|
|
52
|
-
ConfigVariableDef > resolve_vars() parameters > AppConfig global flags.
|
|
53
|
-
Which means that a not None value in a ConfVarDef directive will overrride a global flag value defined in AppConfig. And also that a None value in a ConfVarDef directive
|
|
54
|
-
will not override the value set in resolve_vars() parameters or an AppConfig global flags.
|
|
55
|
-
|
|
56
|
-
Attributes:
|
|
57
|
-
no_env_search (bool|None): don't search values in the environment.
|
|
58
|
-
no_value_search (bool|None): don't search values in the values dict.
|
|
59
|
-
no_conffile_search (bool|None): don't search values in the configuration file.
|
|
60
|
-
no_search (bool|None): don't search values in any location.
|
|
61
|
-
click_key_conversion (bool|None): use the variable name converted to lower case and with dashes converted to underscores as
|
|
62
|
-
the key to search in values.
|
|
63
|
-
allow_override (bool|None): allow overriding variable in the configuration when calling resolve_vars.
|
|
64
|
-
no_exception (bool|None): don't raise exception when no value is found for a variable.
|
|
65
|
-
"""
|
|
66
|
-
|
|
67
|
-
_no_env_search: bool | None
|
|
68
|
-
_no_value_search: bool | None
|
|
69
|
-
_no_conffile_search: bool | None
|
|
70
|
-
_no_search: bool | None
|
|
71
|
-
_click_key_conversion: bool | None
|
|
72
|
-
_allow_override: bool | None
|
|
73
|
-
_no_exception: bool | None
|
|
74
|
-
|
|
75
|
-
def __init__(
|
|
76
|
-
self,
|
|
77
|
-
*,
|
|
78
|
-
no_env_search: Optional[bool] = None,
|
|
79
|
-
no_value_search: Optional[bool] = None,
|
|
80
|
-
no_conffile_search: Optional[bool] = None,
|
|
81
|
-
no_search: Optional[bool] = None,
|
|
82
|
-
click_key_conversion: Optional[bool] = None,
|
|
83
|
-
allow_override: Optional[bool] = None,
|
|
84
|
-
no_exception: Optional[bool] = None,
|
|
85
|
-
) -> None:
|
|
86
|
-
self._no_env_search = no_env_search
|
|
87
|
-
self._no_value_search = no_value_search
|
|
88
|
-
self._no_conffile_search = no_conffile_search
|
|
89
|
-
self._no_search = no_search
|
|
90
|
-
if self._no_search:
|
|
91
|
-
self._no_env_search = True
|
|
92
|
-
self._no_value_search = True
|
|
93
|
-
self._no_conffile_search = True
|
|
94
|
-
self._click_key_conversion = click_key_conversion
|
|
95
|
-
self._allow_override = allow_override
|
|
96
|
-
self._no_exception = no_exception
|
|
97
|
-
|
|
98
|
-
def merge(self, *, inplace: bool = False, other: Flags) -> Flags | None:
|
|
99
|
-
"""
|
|
100
|
-
Merge the current flags with the given flags.
|
|
101
|
-
If inplace is True then modify the current object, otherwise return a new Flags object.
|
|
102
|
-
|
|
103
|
-
Flags given as parameters have precedence over the current object values if they are not None.
|
|
104
|
-
"""
|
|
105
|
-
cur_no_search: Optional[bool]
|
|
106
|
-
cur_no_env_search: Optional[bool]
|
|
107
|
-
cur_no_value_search: Optional[bool]
|
|
108
|
-
cur_no_conffile_search: Optional[bool]
|
|
109
|
-
cur_click_key_conversion: Optional[bool]
|
|
110
|
-
cur_allow_override: Optional[bool]
|
|
111
|
-
cur_no_exception: Optional[bool]
|
|
112
|
-
|
|
113
|
-
cur_no_search = (
|
|
114
|
-
other._no_search if other._no_search is not None else self._no_search
|
|
115
|
-
)
|
|
116
|
-
if cur_no_search:
|
|
117
|
-
cur_no_env_search = True
|
|
118
|
-
cur_no_value_search = True
|
|
119
|
-
cur_no_conffile_search = True
|
|
120
|
-
else:
|
|
121
|
-
cur_no_env_search = (
|
|
122
|
-
other._no_env_search
|
|
123
|
-
if other._no_env_search is not None
|
|
124
|
-
else self._no_env_search
|
|
125
|
-
)
|
|
126
|
-
cur_no_value_search = (
|
|
127
|
-
other._no_value_search
|
|
128
|
-
if other._no_value_search is not None
|
|
129
|
-
else self._no_value_search
|
|
130
|
-
)
|
|
131
|
-
cur_no_conffile_search = (
|
|
132
|
-
other._no_conffile_search
|
|
133
|
-
if other._no_conffile_search is not None
|
|
134
|
-
else self._no_conffile_search
|
|
135
|
-
)
|
|
136
|
-
cur_click_key_conversion = (
|
|
137
|
-
other._click_key_conversion
|
|
138
|
-
if other._click_key_conversion is not None
|
|
139
|
-
else self._click_key_conversion
|
|
140
|
-
)
|
|
141
|
-
cur_allow_override = (
|
|
142
|
-
other._allow_override
|
|
143
|
-
if other._allow_override is not None
|
|
144
|
-
else self._allow_override
|
|
145
|
-
)
|
|
146
|
-
cur_no_exception = (
|
|
147
|
-
other._no_exception if other._no_exception is not None else self._no_exception
|
|
148
|
-
)
|
|
149
|
-
if not inplace:
|
|
150
|
-
return Flags(
|
|
151
|
-
no_env_search=cur_no_env_search,
|
|
152
|
-
no_value_search=cur_no_value_search,
|
|
153
|
-
no_conffile_search=cur_no_conffile_search,
|
|
154
|
-
no_search=cur_no_search,
|
|
155
|
-
click_key_conversion=cur_click_key_conversion,
|
|
156
|
-
allow_override=cur_allow_override,
|
|
157
|
-
no_exception=cur_no_exception,
|
|
158
|
-
)
|
|
159
|
-
else:
|
|
160
|
-
self._no_env_search = cur_no_env_search
|
|
161
|
-
self._no_value_search = cur_no_value_search
|
|
162
|
-
self._no_conffile_search = cur_no_conffile_search
|
|
163
|
-
self._no_search = cur_no_search
|
|
164
|
-
self._click_key_conversion = cur_click_key_conversion
|
|
165
|
-
self._allow_override = cur_allow_override
|
|
166
|
-
self._no_exception = cur_no_exception
|
|
167
|
-
return None
|
|
168
|
-
|
|
169
|
-
@property
|
|
170
|
-
def no_env_search(self) -> bool:
|
|
171
|
-
return (
|
|
172
|
-
False
|
|
173
|
-
if self._no_env_search is None or self._no_env_search == __NO_SEARCH__
|
|
174
|
-
else self._no_env_search
|
|
175
|
-
)
|
|
176
|
-
|
|
177
|
-
@property
|
|
178
|
-
def no_value_search(self) -> bool:
|
|
179
|
-
return (
|
|
180
|
-
False
|
|
181
|
-
if self._no_value_search is None or self._no_value_search == __NO_SEARCH__
|
|
182
|
-
else self._no_value_search
|
|
183
|
-
)
|
|
184
|
-
|
|
185
|
-
@property
|
|
186
|
-
def no_conffile_search(self) -> bool:
|
|
187
|
-
return (
|
|
188
|
-
False
|
|
189
|
-
if self._no_conffile_search is None
|
|
190
|
-
or self._no_conffile_search == __NO_SEARCH__
|
|
191
|
-
else self._no_conffile_search
|
|
192
|
-
)
|
|
193
|
-
|
|
194
|
-
@property
|
|
195
|
-
def no_search(self) -> bool:
|
|
196
|
-
return False if self._no_search is None else self._no_search
|
|
197
|
-
|
|
198
|
-
@property
|
|
199
|
-
def click_key_conversion(self) -> bool:
|
|
200
|
-
return False if self._click_key_conversion is None else self._click_key_conversion
|
|
201
|
-
|
|
202
|
-
@property
|
|
203
|
-
def allow_override(self) -> bool:
|
|
204
|
-
return False if self._allow_override is None else self._allow_override
|
|
205
|
-
|
|
206
|
-
@property
|
|
207
|
-
def no_exception(self) -> bool:
|
|
208
|
-
return False if self._no_exception is None else self._no_exception
|
|
209
|
-
|
|
210
|
-
|
|
211
28
|
@dataclass_transform()
|
|
212
29
|
class ConfigVarDef(Generic[_T]):
|
|
213
30
|
"""
|
|
@@ -217,15 +34,15 @@ class ConfigVarDef(Generic[_T]):
|
|
|
217
34
|
|
|
218
35
|
Configuration are used indirectly by defining attributes of an AppConfig subclass with the configvar() function that creates ConfigVarDef objects:
|
|
219
36
|
class MyAppConfig(AppConfig):
|
|
220
|
-
my_var: int = configvar(
|
|
37
|
+
my_var: int = configvar(default=1)
|
|
221
38
|
|
|
222
39
|
The method resolve_vars() of the AppConfig class uses these configuration variable definitions to look for the values of the variables as explained in its documentation.
|
|
223
40
|
Each configuration variable definition contains several directives to define how to look for the values of the variables in a dictionnarary that can be the CLI parameters,
|
|
224
41
|
or a configuration file, or an environment variables or a computation defined by a python Callable.
|
|
225
42
|
|
|
226
43
|
Two directive are not specified in the constructor of ConfigVarDef because they are inferred from the attribute name and type hint:
|
|
227
|
-
-
|
|
228
|
-
-
|
|
44
|
+
- name : the name of the variable, inferred from the attribute name.
|
|
45
|
+
- type_info : the type to which to cast the variable value, inferred from the attribute type hint. Must be a python builtin type or a class or a list of
|
|
229
46
|
builtin types.
|
|
230
47
|
Here how to get the list of python builtin types:
|
|
231
48
|
print([t.__name__ for t in __builtins__.__dict__.values() if isinstance(t, type)])
|
|
@@ -236,198 +53,242 @@ class ConfigVarDef(Generic[_T]):
|
|
|
236
53
|
|
|
237
54
|
The directives that can be specified in configvar() are:
|
|
238
55
|
|
|
239
|
-
-
|
|
240
|
-
-
|
|
56
|
+
- help [optional]: a help string that describes the variable.
|
|
57
|
+
- default [optional]: the default value, can be a value or an Eval Form (see below explanation on Eval forms) whose
|
|
241
58
|
returned value will be the value of the variable if no other value has been found.
|
|
242
59
|
See paragraph about None below for more information.
|
|
243
|
-
-
|
|
244
|
-
-
|
|
245
|
-
nested namespaces (see AppConfig documentation). By default search for
|
|
246
|
-
-
|
|
247
|
-
If the constructor parameter click_key_conversion flag (see below for flags) is true then the default value is the
|
|
248
|
-
-
|
|
249
|
-
of the variable before possible casting (like explain in
|
|
250
|
-
-
|
|
251
|
-
AppConfig.resolve_vars() matches
|
|
60
|
+
- env_name [optional ]: the name of the environment variable that can contain the value. By default search for name
|
|
61
|
+
- file_key [optional ]: the key to look for in the configuration file, key can be in the form a1.a2.a3 (attributes separated by dots) to indicate
|
|
62
|
+
nested namespaces (see AppConfig documentation). By default search for name.
|
|
63
|
+
- value_key [optional ]: the key to look for in the "Values" dict. by default search for name. None value are ignored.
|
|
64
|
+
If the constructor parameter click_key_conversion flag (see below for flags) is true then the default value is the name in lowercase and with '-' replaced by '_'
|
|
65
|
+
- transform : an Eval Form (see below explanation on Eval forms) that transform the value found for the variable and produce another value that will be the value
|
|
66
|
+
of the variable before possible casting (like explain in type_info).
|
|
67
|
+
- scopes [optional]: a list of names indicating in which scope the variable is valid. If one of the scope names passed at variable resolution to
|
|
68
|
+
AppConfig.resolve_vars() matches one of the scope names of the variable or if the variable has no scope directive then the variable is
|
|
252
69
|
considered for resolution.
|
|
253
|
-
-
|
|
254
|
-
|
|
70
|
+
- split_to_list [optional ]: Indicates that the value found must be split in order to produce a list of string. The value
|
|
71
|
+
|
|
72
|
+
of the directive is the list separator or True if the separator is a comma. Value in the string list will be casted to the type specified in type_info.
|
|
255
73
|
See the paragraph below about Lists that explain how list handled.
|
|
256
|
-
-
|
|
257
|
-
If
|
|
74
|
+
- can_be_relative_to [optional]: a directory path or the name of another key that resolves in a directory path.
|
|
75
|
+
If type_info is a Path and the retrieved value is not an empty string nor None nor an absolute path then
|
|
258
76
|
transform the value to an absolute path with the given directory as parent directory.
|
|
259
77
|
See details below on how Path are processed.
|
|
260
|
-
-
|
|
78
|
+
- make_dirs [optional ]: a PathType that indicates the type of Path for which directories are to be created if they do not exist yet.
|
|
261
79
|
if PathType is:
|
|
262
80
|
- Dir : create the hierarchy of directory necessary to contains this directory as well as the directory itself
|
|
263
81
|
- File: create the parent hierarchy of directory necessary to contains this file
|
|
264
82
|
See details below on how Path are processed.
|
|
83
|
+
- auto_prolog [optional]: mark the variable for automatic prolog processing - which means that the variable will be resolved at an early stage, before the configuration file
|
|
84
|
+
is resolved and before all other variables. If it has also the allow_override flag True then it can be processed again with all other variables in the regular resolution.
|
|
85
|
+
|
|
265
86
|
|
|
266
87
|
- Flag directives:
|
|
267
88
|
These directives can also be defined globally in the AppConfig object or when calling resolve_vars().Flags defined in a ConfigVarDef override
|
|
268
89
|
the other values if they are defined.
|
|
269
|
-
-
|
|
270
|
-
-
|
|
271
|
-
-
|
|
272
|
-
-
|
|
273
|
-
-
|
|
274
|
-
-
|
|
275
|
-
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
the
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
the
|
|
282
|
-
|
|
283
|
-
|
|
90
|
+
- no_dir_processing [optional ]: don't run specific Path processing for this variable.
|
|
91
|
+
- no_env_search [optional ]: boolean, False by default. If true the value of the variable is not searched in the Environment.
|
|
92
|
+
- no_value_search[optional ]: boolean, False by default. If true the value of the variable is not searched in the values dict.
|
|
93
|
+
- no_conffile_search [optional ]: boolean, False by default. If true the value of the variable is not searched in the configuration file.
|
|
94
|
+
- click_key_conversion [optional ]: boolean, False by default. If true the value of the variable is converted using Click key conversion.
|
|
95
|
+
- allow_override [optional ]: boolean, False by default. If true the variable value can be overridden by another context.
|
|
96
|
+
- mandatory [optional ]: boolean, True by default. If true an exception is thrown if the variable value is not found. Otherwise the variable is not set which means that accessing it
|
|
97
|
+
would raise an Exception.
|
|
98
|
+
- no_search [optional] : boolean, False by default. It true the value of the variable is not searched in the Environment, the values or the configuration
|
|
99
|
+
file. It's equivaleut to set the directives no_env_search, no_value_search, no_conffile_search to True. In this case the value of the variable should be defined by
|
|
100
|
+
the default directive.
|
|
101
|
+
|
|
102
|
+
For backward compatibilty the special value __NO_SEARCH__ for env_name, config_key, file_key and value_key are still supported but it's recommended to use
|
|
103
|
+
the no_env_search, no_value_search, no_conffile_search or no_search directives instead.
|
|
104
|
+
|
|
105
|
+
By default throw an exception if no value are found except if mandatory is False
|
|
284
106
|
|
|
285
107
|
Eval Forms:
|
|
286
108
|
-----------
|
|
287
109
|
|
|
288
|
-
an eval form is a callable that is evaluated to compute a value for a variable. Eval forms can be used in the
|
|
289
|
-
|
|
110
|
+
an eval form is a callable that is evaluated to compute a value for a variable. Eval forms can be used in the default directive or the
|
|
111
|
+
transform directive.
|
|
290
112
|
|
|
291
113
|
The callable receives three parameters: the variable name, this configuration object and the current value found for the variable if one has been found
|
|
292
|
-
in the case of a
|
|
114
|
+
in the case of a transform directive.
|
|
293
115
|
|
|
294
116
|
The expression can use value already defined in this application configuration object by using the first parameter of the callable which is the AppConfig object itself,
|
|
295
117
|
knowing that variables are evaluated in the order they are defined.
|
|
296
118
|
|
|
297
|
-
In the case of a
|
|
298
|
-
In the case of a
|
|
299
|
-
the '
|
|
119
|
+
In the case of a default directive the third parameter of the callable will be None.
|
|
120
|
+
In the case of a transform directive the third parameter of the callable may be None if no value have been found and
|
|
121
|
+
the 'mandatory' global flag is set to False, otherwise it will be the value found for the variable before transformation.
|
|
300
122
|
|
|
301
|
-
The returned value from the evaluation of the callable will be used to set the variable value before casting to
|
|
123
|
+
The returned value from the evaluation of the callable will be used to set the variable value before casting to type_info.
|
|
302
124
|
Note that the eventual type casting will be done after the Eval call.
|
|
303
125
|
It's up to the caller to deal with the returned value.
|
|
304
126
|
|
|
305
127
|
Note that the libraries used in Eval Forms must be imported in the module that defines the form.
|
|
306
128
|
|
|
307
|
-
!!Warning!!:
|
|
308
|
-
For example if a variable is declared as a class that accept a string in its constructor then the
|
|
129
|
+
!!Warning!!: default and transform directives should be set or return a value that must be 'castable' to the type defined by type_info.
|
|
130
|
+
For example if a variable is declared as a class that accept a string in its constructor then the default directive should be a string or an Eval
|
|
309
131
|
Form that returns a string not the class instance.
|
|
310
132
|
|
|
311
|
-
Path and Path list
|
|
133
|
+
Path and Path list type_info variables:
|
|
312
134
|
--------------------------------------
|
|
313
135
|
|
|
314
|
-
If a variable has a
|
|
136
|
+
If a variable has a type_info that is a Path or a list of Path there a dedicated processing that applies on the
|
|
315
137
|
value found for them.
|
|
316
138
|
This processing takes place at the end of the processing of normal variable and occurs when:
|
|
317
|
-
- the
|
|
139
|
+
- the type_info is a Path or a list of Path
|
|
318
140
|
- a value for the variable was found
|
|
319
|
-
- the directive
|
|
141
|
+
- the directive no_dir_processing is False
|
|
320
142
|
|
|
321
143
|
The specific processing is the following on the Path or on each of the Path in the list of Path:
|
|
322
|
-
-
|
|
144
|
+
- can_be_relative_to: if this directive has a value that can be a path-like directory or the name of another key already defined
|
|
323
145
|
that resolves in a path-like directory and the value found is not an absolute Path:
|
|
324
|
-
- then make a Path with the
|
|
325
|
-
-
|
|
146
|
+
- then make a Path with the can_be_relative_to directory as parent and the value found as its child.
|
|
147
|
+
- make_dirs: if this directive is True , then create the necessary directories of the path if they don't exist yet.
|
|
326
148
|
- Call the 'expanduser()' and 'resolve()' method on the resulting Path.
|
|
327
149
|
|
|
328
150
|
List:
|
|
329
151
|
-----
|
|
330
152
|
|
|
331
|
-
All values found are strings that should be casted to the type specified in
|
|
153
|
+
All values found are strings that should be casted to the type specified in type_info inferred from the type hint of the variable.
|
|
332
154
|
Only list of single type are supported like list[int], list[str], list[MyClass], etc.
|
|
333
|
-
The value is considered as a list when
|
|
155
|
+
The value is considered as a list when split_to_list is not False and a value was found for the variable.
|
|
334
156
|
In this case the temporaray string value found for the variable is split with the string 'split()' method to generate
|
|
335
157
|
a list of string.
|
|
336
|
-
Then all items of the list of strings are casted to the specified
|
|
158
|
+
Then all items of the list of strings are casted to the specified type_info.
|
|
337
159
|
|
|
338
|
-
|
|
160
|
+
scopes:
|
|
339
161
|
--------
|
|
340
|
-
Every configuration variable can specify a list of
|
|
341
|
-
When resolving variables it is also possible to specify for which
|
|
162
|
+
Every configuration variable can specify a list of scope(s) in which it is valid.
|
|
163
|
+
When resolving variables it is also possible to specify for which scope(s) the resolution must be done.
|
|
342
164
|
|
|
343
|
-
When one or several
|
|
344
|
-
as well as the VarDef without
|
|
345
|
-
are specific to their
|
|
165
|
+
When one or several scopes are specify for the resolution then only the variable valid for these scopes will be considered for resolution
|
|
166
|
+
as well as the VarDef without Scope directive. Variable defined without Scope directive are common to all scope, the one with a Scope directive
|
|
167
|
+
are specific to their scopes.
|
|
346
168
|
|
|
347
|
-
This allows to define variables that are specific to some
|
|
348
|
-
When the flage
|
|
349
|
-
of the requested
|
|
169
|
+
This allows to define variables that are specific to some scope and to resolve only these variables when needed.
|
|
170
|
+
When the flage allow_override is False and several resolutions are done, then variables are evaluated only once even if they are valid in several
|
|
171
|
+
of the requested scope(s), only the first valid scope is used.
|
|
350
172
|
|
|
351
173
|
None value:
|
|
352
174
|
----------
|
|
353
|
-
All the VarDef valid for the involved
|
|
354
|
-
flag '
|
|
175
|
+
All the VarDef valid for the involved scopes will be resolved and the one for which no value have been found will be set to None if the
|
|
176
|
+
flag 'mandatory' is False.
|
|
355
177
|
|
|
356
|
-
If the flag '
|
|
178
|
+
If the flag 'mandatory' is true and one varDef for the scope has no value then an exception is raised.
|
|
357
179
|
|
|
358
|
-
Whatever is the value of the flag '
|
|
180
|
+
Whatever is the value of the flag 'mandatory' it is possible to set a value to None either with the 'default' directive or with
|
|
359
181
|
an Eval Form or a None value in one of the search location.
|
|
360
182
|
|
|
183
|
+
AutoProlog variables:
|
|
184
|
+
--------------------
|
|
185
|
+
Variables defined with the auto_prolog directive set to True are considered as AutoProlog variables. These variables are resolved at an early stage
|
|
186
|
+
before all other variables and before the configuration file is processed.
|
|
187
|
+
This allows to define variables that are necessary to locate the configuration file when its path depends on other variables. In this case these variables
|
|
188
|
+
must be defined as AutoProlog variables.
|
|
189
|
+
The default variables defined in the AutoProlog class are all AutoProlog variables and therefore are made available to be used in variable substitution for all other
|
|
190
|
+
variables and for locating the configuration file.
|
|
191
|
+
|
|
361
192
|
Note on implementation:
|
|
362
193
|
-----------------------
|
|
363
194
|
ConfigVarDef is a descriptor class that defines the __get__ and __set__ methods.
|
|
364
195
|
This allows to define configuration variables as class attributes on AppConfig subclasses.
|
|
365
|
-
The __set_name__ method is used to set the
|
|
196
|
+
The __set_name__ method is used to set the name and type_info directives based on the attribute name and type hint.
|
|
366
197
|
"""
|
|
367
198
|
|
|
368
|
-
|
|
369
|
-
_help: str = ""
|
|
370
|
-
_default: Any | Callable[[str, Any, Any], Any] | Undefined = _undef
|
|
371
|
-
_env_name: Optional[str] = None
|
|
372
|
-
_file_key: Optional[str] = None
|
|
373
|
-
_value_key: Optional[str] = None
|
|
374
|
-
_type_info: Any = None
|
|
375
|
-
_transform: Optional[Callable[[str, Any, Any], Any]] = None
|
|
376
|
-
_contexts: Optional[Sequence[str]] = None
|
|
377
|
-
_split_to_list: Optional[bool | str | None] = None
|
|
199
|
+
_auto_prolog: Optional[bool] = None
|
|
378
200
|
_can_be_relative_to: Optional[Path | str] = None
|
|
201
|
+
_scopes: Optional[Sequence[str]] = None
|
|
202
|
+
_default: Any | Callable[[str, Any, Any], Any] | Undefined = _undef
|
|
203
|
+
_env_name: Optional[Sequence[str]] = None
|
|
204
|
+
_file_key: Optional[Sequence[str]] = None
|
|
205
|
+
_help: str = ""
|
|
379
206
|
_make_dirs: Optional[PathType] = None
|
|
207
|
+
_mandatory: Optional[bool] = True
|
|
380
208
|
_no_dir_processing: Optional[bool] = None
|
|
209
|
+
_name: Optional[str] = None
|
|
210
|
+
_split_to_list: Optional[bool | str] = None
|
|
211
|
+
_transform: Optional[Union[Callable[[str, Any, Any], Any], str]] = None
|
|
212
|
+
_type_info: Any = None
|
|
213
|
+
_value_key: Optional[Sequence[str]] = None
|
|
381
214
|
|
|
382
215
|
def __init__(
|
|
383
216
|
self,
|
|
384
217
|
*,
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
218
|
+
allow_override: Optional[bool] = None,
|
|
219
|
+
auto_prolog: Optional[bool] = None,
|
|
220
|
+
can_be_relative_to: Optional[Path | str] = None,
|
|
221
|
+
click_key_conversion: Optional[bool] = None,
|
|
222
|
+
scopes: Optional[Sequence[str]] = None,
|
|
223
|
+
default: Any | Callable[[str, Any, Any], Any] | Undefined = _undef,
|
|
224
|
+
env_name: Optional[str | Sequence[str]] = None,
|
|
225
|
+
file_key: Optional[str | Sequence[str]] = None,
|
|
226
|
+
help: str = "",
|
|
227
|
+
make_dirs: Optional[PathType] = None,
|
|
228
|
+
mandatory: Optional[bool] = None,
|
|
229
|
+
no_conffile_search: Optional[bool] = None,
|
|
230
|
+
no_dir_processing: Optional[bool] = None,
|
|
231
|
+
no_env_search: Optional[bool] = None,
|
|
232
|
+
no_search: Optional[bool] = None,
|
|
233
|
+
no_value_search: Optional[bool] = None,
|
|
234
|
+
split_to_list: Optional[bool | str] = None,
|
|
235
|
+
transform: Optional[Union[Callable[[str, Any, Any], Any], str]] = None,
|
|
236
|
+
type_info: Any = None,
|
|
237
|
+
value_key: Optional[str | Sequence[str]] = None,
|
|
403
238
|
) -> None:
|
|
404
239
|
"""Initialize the configuration variable definition.
|
|
405
240
|
Should not be used directly but be used through the function configvar() to define a configuration variable as a class attribute
|
|
406
241
|
on an AppConfig subclass like this:
|
|
407
242
|
class MyCfg(AppConfig):
|
|
408
|
-
my_var: int = configvar(
|
|
243
|
+
my_var: int = configvar(default=1)
|
|
409
244
|
|
|
410
245
|
"""
|
|
411
|
-
self.
|
|
412
|
-
self.
|
|
413
|
-
self.
|
|
414
|
-
self.
|
|
415
|
-
self.
|
|
416
|
-
self.
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
246
|
+
self.__doc__ = help
|
|
247
|
+
self._auto_prolog = auto_prolog
|
|
248
|
+
self._can_be_relative_to = can_be_relative_to
|
|
249
|
+
self._scopes = scopes
|
|
250
|
+
self._default = default
|
|
251
|
+
self._env_name = (
|
|
252
|
+
None
|
|
253
|
+
if env_name is None
|
|
254
|
+
else (
|
|
255
|
+
env_name
|
|
256
|
+
if is_sequence(env_name)
|
|
257
|
+
else [env_name] if isinstance(env_name, str) else None
|
|
258
|
+
)
|
|
259
|
+
)
|
|
260
|
+
self._file_key = (
|
|
261
|
+
None
|
|
262
|
+
if file_key is None
|
|
263
|
+
else (
|
|
264
|
+
file_key
|
|
265
|
+
if is_sequence(file_key)
|
|
266
|
+
else [file_key] if isinstance(file_key, str) else None
|
|
267
|
+
)
|
|
268
|
+
)
|
|
269
|
+
self._help = help
|
|
270
|
+
self._make_dirs = make_dirs
|
|
271
|
+
self._mandatory = mandatory
|
|
272
|
+
self._no_dir_processing = no_dir_processing
|
|
273
|
+
self._no_search = no_search
|
|
274
|
+
self._split_to_list = split_to_list
|
|
275
|
+
self._transform = transform
|
|
276
|
+
self._type_info = type_info
|
|
277
|
+
self._value_key = (
|
|
278
|
+
None
|
|
279
|
+
if value_key is None
|
|
280
|
+
else (
|
|
281
|
+
value_key
|
|
282
|
+
if is_sequence(value_key)
|
|
283
|
+
else [value_key] if isinstance(value_key, str) else None
|
|
284
|
+
)
|
|
285
|
+
)
|
|
424
286
|
self.flags = Flags(
|
|
425
|
-
no_env_search=
|
|
426
|
-
no_value_search=
|
|
427
|
-
no_conffile_search=
|
|
428
|
-
click_key_conversion=
|
|
429
|
-
allow_override=
|
|
430
|
-
no_exception=NoException,
|
|
287
|
+
no_env_search=no_env_search,
|
|
288
|
+
no_value_search=no_value_search,
|
|
289
|
+
no_conffile_search=no_conffile_search,
|
|
290
|
+
click_key_conversion=click_key_conversion,
|
|
291
|
+
allow_override=allow_override,
|
|
431
292
|
)
|
|
432
293
|
|
|
433
294
|
def __set_name__(self, owner: type, name: str) -> None:
|
|
@@ -435,34 +296,82 @@ class ConfigVarDef(Generic[_T]):
|
|
|
435
296
|
ConfigVarDef is a descriptor class because it defines the __get__ and __set__ methods.
|
|
436
297
|
|
|
437
298
|
The goal of this method is to:
|
|
438
|
-
- set the
|
|
439
|
-
- infer the type of the attribute and set the
|
|
299
|
+
- set the name directive of this ConfigVarDef based on the attribute name.
|
|
300
|
+
- infer the type of the attribute and set the type_info directive with it.
|
|
440
301
|
|
|
441
302
|
Args:
|
|
442
303
|
owner (type): the owning class of the attribute that is being assigned the descriptor
|
|
443
304
|
name (str): the attribute name
|
|
444
305
|
"""
|
|
445
306
|
|
|
446
|
-
# set
|
|
307
|
+
# set name directive
|
|
447
308
|
self._name = name
|
|
448
309
|
|
|
449
|
-
#
|
|
310
|
+
# try to find a type:
|
|
311
|
+
# if we have a type hints and a type_info directive we take the type_info.
|
|
312
|
+
# This allow to define a type for the type checker that allow override with another type if the user wants to.
|
|
313
|
+
# (it is usefull for exec_stage)
|
|
314
|
+
# but still have a correct run time type , this is correct as long as the user use duck typing types
|
|
315
|
+
# that are compatible.
|
|
450
316
|
try:
|
|
451
317
|
hints = get_type_hints(owner, include_extras=True)
|
|
452
318
|
except Exception:
|
|
453
319
|
hints = getattr(owner, "__annotations__", {})
|
|
454
320
|
|
|
455
|
-
# test if there is a type hint for this attribute
|
|
321
|
+
# test if there is a type hint for this attribute
|
|
322
|
+
annotated_type: dict[str, Any] | Any | dict[Any, Any] = None
|
|
456
323
|
if name in hints:
|
|
457
324
|
annotated_type = hints[name]
|
|
325
|
+
if isinstance(annotated_type, str):
|
|
326
|
+
# Why can it be a string? In Python, type hints are strings if:
|
|
327
|
+
# from __future__ import annotations is used (postponed evaluation of annotations).
|
|
328
|
+
# The user explicitly used quotes for a forward reference (e.g., var: "MyClass" where MyClass is defined later).
|
|
329
|
+
for frame_info in inspect.stack():
|
|
330
|
+
# try to resolve the type with an eval to which we provide the globals and locals for its resolution.
|
|
331
|
+
# But it can happen that the type is defined in a local scope, so we need to go through all frames
|
|
332
|
+
# using the stack.
|
|
333
|
+
try:
|
|
334
|
+
resolved_type = eval(
|
|
335
|
+
annotated_type,
|
|
336
|
+
frame_info.frame.f_globals,
|
|
337
|
+
frame_info.frame.f_locals,
|
|
338
|
+
)
|
|
339
|
+
if resolved_type is not None:
|
|
340
|
+
annotated_type = resolved_type
|
|
341
|
+
break
|
|
342
|
+
except Exception:
|
|
343
|
+
continue
|
|
344
|
+
else:
|
|
345
|
+
raise TypeError(
|
|
346
|
+
f"Could not resolve type hint '{annotated_type}' for configuration variable '{name}'. "
|
|
347
|
+
"Please check that the type is imported and available."
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
type_info_directive: type | None = None
|
|
351
|
+
if self._type_info is not None:
|
|
352
|
+
type_info_directive = self._type_info
|
|
353
|
+
|
|
354
|
+
if annotated_type is not None and type_info_directive is not None:
|
|
355
|
+
# both type hint and type_info directive are defined, use type_info directive
|
|
356
|
+
self._type_info = type_info_directive
|
|
357
|
+
elif annotated_type is not None:
|
|
358
|
+
# only type hint is defined, use it
|
|
458
359
|
self._type_info = annotated_type
|
|
360
|
+
elif type_info_directive is not None:
|
|
361
|
+
# only type_info directive is defined, use it
|
|
362
|
+
self._type_info = type_info_directive
|
|
363
|
+
else:
|
|
364
|
+
# no type hint nor type_info directive, default to str
|
|
365
|
+
self._type_info = str
|
|
459
366
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
367
|
+
# We still need to handle split_to_list if not set and the type selected is a list
|
|
368
|
+
if self._split_to_list is None:
|
|
369
|
+
try:
|
|
370
|
+
origin = get_origin(self._type_info)
|
|
371
|
+
args = get_args(self._type_info)
|
|
463
372
|
|
|
464
373
|
# Check for basic list
|
|
465
|
-
if origin is list or
|
|
374
|
+
if origin is list or self._type_info is list:
|
|
466
375
|
self._split_to_list = True
|
|
467
376
|
# Check for Optional[list] / Union[list, ...]
|
|
468
377
|
elif origin is Union:
|
|
@@ -471,9 +380,8 @@ class ConfigVarDef(Generic[_T]):
|
|
|
471
380
|
if arg_origin is list or arg is list:
|
|
472
381
|
self._split_to_list = True
|
|
473
382
|
break
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
self._type_info = str
|
|
383
|
+
except Exception:
|
|
384
|
+
pass
|
|
477
385
|
|
|
478
386
|
def __get__(
|
|
479
387
|
self, instance: Optional[AppConfig], owner: Optional[type] = None
|
|
@@ -481,119 +389,125 @@ class ConfigVarDef(Generic[_T]):
|
|
|
481
389
|
"""
|
|
482
390
|
Descriptor method that gets the value of the configuration variable from the AppConfig instance.
|
|
483
391
|
|
|
484
|
-
The value is retrieved from the instance's __dict__ using the variable's
|
|
392
|
+
The value is retrieved from the instance's __dict__ using the variable's name because we want to
|
|
485
393
|
handle the case where we have dotted names for nested attributes.
|
|
486
394
|
"""
|
|
487
395
|
if instance is None:
|
|
488
396
|
return self
|
|
489
|
-
name = self.
|
|
397
|
+
name = self.name
|
|
490
398
|
if name in instance.__dict__:
|
|
491
|
-
return instance[name]
|
|
399
|
+
return instance[name]
|
|
492
400
|
return None
|
|
493
401
|
|
|
494
402
|
def __set__(self, instance: AppConfig, value: Any) -> None:
|
|
495
403
|
"""
|
|
496
404
|
Descriptor method that gets the value of the configuration variable from the AppConfig instance.
|
|
497
|
-
The value is set in the instance's __dict__ using the variable's
|
|
405
|
+
The value is set in the instance's __dict__ using the variable's name because we want to
|
|
498
406
|
handle the case where we have dotted names for nested attributes.
|
|
499
407
|
"""
|
|
500
|
-
instance._set_value(self.
|
|
408
|
+
instance._set_value(self.name, value)
|
|
501
409
|
|
|
502
410
|
@property
|
|
503
|
-
def
|
|
504
|
-
|
|
505
|
-
raise RuntimeError(
|
|
506
|
-
"ConfigVarDef has no Name. Declare it on an AppConfig subclass "
|
|
507
|
-
)
|
|
508
|
-
return self._name
|
|
411
|
+
def auto_prolog(self) -> Optional[bool]:
|
|
412
|
+
return self._auto_prolog
|
|
509
413
|
|
|
510
414
|
@property
|
|
511
|
-
def
|
|
512
|
-
return self.
|
|
415
|
+
def can_be_relative_to(self) -> Optional[Path | str]:
|
|
416
|
+
return self._can_be_relative_to
|
|
513
417
|
|
|
514
418
|
@property
|
|
515
|
-
def
|
|
516
|
-
return self.
|
|
419
|
+
def scopes(self) -> Sequence[str] | None:
|
|
420
|
+
return self._scopes
|
|
517
421
|
|
|
518
422
|
@property
|
|
519
|
-
def
|
|
520
|
-
|
|
521
|
-
flag that can be set globally or in resolve_vars."""
|
|
522
|
-
if self.flags.no_value_search:
|
|
523
|
-
return None
|
|
524
|
-
else:
|
|
525
|
-
return self.Name if self._value_key is None else self._value_key
|
|
423
|
+
def default(self) -> Any | Callable[[str, Any, Any], Any] | Undefined:
|
|
424
|
+
return self._default
|
|
526
425
|
|
|
527
426
|
@property
|
|
528
|
-
def
|
|
529
|
-
if self.flags.no_env_search:
|
|
427
|
+
def env_name(self) -> Optional[Sequence[str]]:
|
|
428
|
+
if self.flags.no_search or self.flags.no_env_search:
|
|
530
429
|
return None
|
|
531
430
|
else:
|
|
532
|
-
return self._env_name
|
|
431
|
+
return self._env_name or self.name
|
|
533
432
|
|
|
534
433
|
@property
|
|
535
|
-
def
|
|
536
|
-
if self.flags.no_conffile_search:
|
|
434
|
+
def file_key(self) -> Optional[str | Sequence[str]]:
|
|
435
|
+
if self.flags.no_search or self.flags.no_conffile_search:
|
|
537
436
|
return None
|
|
538
437
|
else:
|
|
539
|
-
return self._file_key
|
|
438
|
+
return self._file_key or self.name
|
|
540
439
|
|
|
541
440
|
@property
|
|
542
|
-
def
|
|
543
|
-
return self.
|
|
441
|
+
def help(self) -> str:
|
|
442
|
+
return self._help
|
|
544
443
|
|
|
545
444
|
@property
|
|
546
|
-
def
|
|
547
|
-
return
|
|
445
|
+
def make_dirs(self) -> Optional[PathType]:
|
|
446
|
+
return self._make_dirs
|
|
548
447
|
|
|
549
448
|
@property
|
|
550
|
-
def
|
|
551
|
-
return self.
|
|
449
|
+
def mandatory(self) -> bool:
|
|
450
|
+
return True if self._mandatory is None else self._mandatory
|
|
451
|
+
|
|
452
|
+
@property
|
|
453
|
+
def no_dir_processing(self) -> bool:
|
|
454
|
+
return False if self._no_dir_processing is None else self._no_dir_processing
|
|
552
455
|
|
|
553
456
|
@property
|
|
554
|
-
def
|
|
555
|
-
|
|
457
|
+
def name(self) -> str:
|
|
458
|
+
if self._name is None:
|
|
459
|
+
raise RuntimeError(
|
|
460
|
+
"ConfigVarDef has no name. Declare it on an AppConfig subclass "
|
|
461
|
+
)
|
|
462
|
+
return self._name
|
|
556
463
|
|
|
557
464
|
@property
|
|
558
|
-
def
|
|
559
|
-
return False if self.
|
|
465
|
+
def split_to_list(self) -> bool | str:
|
|
466
|
+
return False if self._split_to_list is None else self._split_to_list
|
|
560
467
|
|
|
561
468
|
@property
|
|
562
|
-
def
|
|
563
|
-
return self.
|
|
469
|
+
def transform(self) -> Optional[Union[Callable[[str, Any, Any], Any], str]]:
|
|
470
|
+
return self._transform
|
|
564
471
|
|
|
565
472
|
@property
|
|
566
|
-
def
|
|
567
|
-
|
|
473
|
+
def value_key(self) -> Optional[str | Sequence[str]]:
|
|
474
|
+
"""Note: we can't compute the final value here because it depends on the click_key_conversion
|
|
475
|
+
flag that can be set globally or in resolve_vars."""
|
|
476
|
+
if self.flags.no_search or self.flags.no_value_search:
|
|
477
|
+
return None
|
|
478
|
+
else:
|
|
479
|
+
return self._value_key or self.name
|
|
568
480
|
|
|
569
481
|
|
|
570
482
|
def configvar(
|
|
571
483
|
*,
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
484
|
+
allow_override: Optional[bool] = None,
|
|
485
|
+
auto_prolog: Optional[bool] = None,
|
|
486
|
+
can_be_relative_to: Optional[Path | str] = None,
|
|
487
|
+
click_key_conversion: Optional[bool] = None,
|
|
488
|
+
scopes: Optional[Sequence[str]] = None,
|
|
489
|
+
default: Any | Callable[[str, Any, Any], Any] | Undefined = _undef,
|
|
490
|
+
env_name: Optional[str | Sequence[str]] = None,
|
|
491
|
+
file_key: Optional[str | Sequence[str]] = None,
|
|
492
|
+
help: str = "",
|
|
493
|
+
make_dirs: Optional[PathType] = None,
|
|
494
|
+
mandatory: Optional[bool] = None,
|
|
495
|
+
no_conffile_search: Optional[bool] = None,
|
|
496
|
+
no_dir_processing: Optional[bool] = None,
|
|
497
|
+
no_env_search: Optional[bool] = None,
|
|
498
|
+
no_search: Optional[bool] = None,
|
|
499
|
+
no_value_search: Optional[bool] = None,
|
|
500
|
+
split_to_list: Optional[bool | str] = None,
|
|
501
|
+
transform: Optional[Union[Callable[[str, Any, Any], Any], str]] = None,
|
|
502
|
+
type_info: Any = None,
|
|
503
|
+
value_key: Optional[str | Sequence[str]] = None,
|
|
590
504
|
) -> Any:
|
|
591
505
|
"""Create a declarative configuration variable definition.
|
|
592
506
|
|
|
593
507
|
Use it as a class attribute on an AppConfig subclass:
|
|
594
508
|
|
|
595
509
|
class MyCfg(AppConfig):
|
|
596
|
-
my_var: int = configvar(
|
|
510
|
+
my_var: int = configvar(default=1)
|
|
597
511
|
|
|
598
512
|
The variable name defaults to the attribute name and its type is inferred from the type hint of the attribute declaration.
|
|
599
513
|
|
|
@@ -605,22 +519,24 @@ def configvar(
|
|
|
605
519
|
"""
|
|
606
520
|
|
|
607
521
|
return ConfigVarDef(
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
522
|
+
allow_override=allow_override,
|
|
523
|
+
auto_prolog=auto_prolog,
|
|
524
|
+
can_be_relative_to=can_be_relative_to,
|
|
525
|
+
click_key_conversion=click_key_conversion,
|
|
526
|
+
scopes=scopes,
|
|
527
|
+
default=default,
|
|
528
|
+
env_name=env_name,
|
|
529
|
+
file_key=file_key,
|
|
530
|
+
help=help,
|
|
531
|
+
make_dirs=make_dirs,
|
|
532
|
+
mandatory=mandatory,
|
|
533
|
+
no_conffile_search=no_conffile_search,
|
|
534
|
+
no_dir_processing=no_dir_processing,
|
|
535
|
+
no_env_search=no_env_search,
|
|
536
|
+
no_search=no_search,
|
|
537
|
+
no_value_search=no_value_search,
|
|
538
|
+
split_to_list=split_to_list,
|
|
539
|
+
transform=transform,
|
|
540
|
+
type_info=type_info,
|
|
541
|
+
value_key=value_key,
|
|
626
542
|
)
|