orionis 0.285.0__py3-none-any.whl → 0.287.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.
- orionis/metadata/framework.py +1 -1
- orionis/services/asynchrony/contracts/__init__.py +0 -0
- orionis/services/asynchrony/contracts/coroutines.py +24 -0
- orionis/services/asynchrony/coroutines.py +58 -19
- orionis/services/asynchrony/exceptions/coroutine_exception.py +8 -15
- orionis/services/environment/contracts/env.py +45 -50
- orionis/services/environment/dot_env.py +205 -181
- orionis/services/environment/env.py +68 -85
- orionis/services/environment/exceptions/environment_value_error.py +18 -0
- orionis/services/environment/exceptions/environment_value_exception.py +23 -0
- orionis/services/environment/type_hint.py +559 -0
- orionis/test/exceptions/test_config_exception.py +8 -17
- orionis/test/exceptions/test_failure_exception.py +27 -27
- orionis/test/exceptions/test_persistence_error.py +10 -20
- orionis/test/exceptions/test_runtime_error.py +8 -15
- orionis/test/exceptions/test_value_error.py +8 -15
- orionis/test/logs/history.py +3 -5
- {orionis-0.285.0.dist-info → orionis-0.287.0.dist-info}/METADATA +1 -1
- {orionis-0.285.0.dist-info → orionis-0.287.0.dist-info}/RECORD +66 -62
- tests/example/test_example.py +5 -2
- tests/foundation/config/app/test_app.py +13 -3
- tests/foundation/config/auth/test_auth.py +9 -4
- tests/foundation/config/cache/test_cache.py +60 -15
- tests/foundation/config/cache/test_cache_file.py +62 -14
- tests/foundation/config/cache/test_cache_stores.py +74 -14
- tests/foundation/config/cors/test_cors.py +102 -33
- tests/foundation/config/database/test_database.py +38 -14
- tests/foundation/config/database/test_database_connections.py +79 -5
- tests/foundation/config/database/test_database_mysql.py +138 -15
- tests/foundation/config/database/test_database_oracle.py +110 -26
- tests/foundation/config/database/test_database_pgsql.py +96 -26
- tests/foundation/config/database/test_database_sqlite.py +56 -2
- tests/foundation/config/exceptions/test_exceptions_integrity.py +44 -10
- tests/foundation/config/filesystems/test_filesystems.py +64 -14
- tests/foundation/config/filesystems/test_filesystems_aws.py +45 -7
- tests/foundation/config/filesystems/test_filesystems_disks.py +78 -8
- tests/foundation/config/filesystems/test_filesystems_local.py +66 -18
- tests/foundation/config/filesystems/test_filesystems_public.py +37 -0
- tests/foundation/config/logging/test_logging.py +75 -11
- tests/foundation/config/logging/test_logging_channels.py +79 -2
- tests/foundation/config/logging/test_logging_chunked.py +85 -12
- tests/foundation/config/logging/test_logging_daily.py +79 -12
- tests/foundation/config/logging/test_logging_hourly.py +68 -2
- tests/foundation/config/logging/test_logging_monthly.py +48 -2
- tests/foundation/config/logging/test_logging_stack.py +49 -14
- tests/foundation/config/logging/test_logging_weekly.py +92 -2
- tests/foundation/config/mail/test_mail.py +87 -15
- tests/foundation/config/mail/test_mail_file.py +40 -4
- tests/foundation/config/mail/test_mail_mailers.py +56 -8
- tests/foundation/config/mail/test_mail_smtp.py +58 -14
- tests/foundation/config/queue/test_queue.py +62 -9
- tests/foundation/config/queue/test_queue_brokers.py +27 -10
- tests/foundation/config/queue/test_queue_database.py +53 -15
- tests/foundation/config/root/test_root_paths.py +69 -2
- tests/foundation/config/session/test_session.py +30 -1
- tests/foundation/config/startup/test_config_startup.py +77 -7
- tests/foundation/config/testing/test_testing.py +68 -0
- tests/patterns/singleton/test_singleton.py +10 -1
- tests/services/asynchrony/test_async_io.py +4 -4
- tests/services/environment/test_env.py +3 -4
- tests/testing/test_testing_result.py +56 -19
- tests/testing/test_testing_unit.py +93 -24
- orionis/services/environment/exceptions/value_exception.py +0 -27
- {orionis-0.285.0.dist-info → orionis-0.287.0.dist-info}/WHEEL +0 -0
- {orionis-0.285.0.dist-info → orionis-0.287.0.dist-info}/licenses/LICENCE +0 -0
- {orionis-0.285.0.dist-info → orionis-0.287.0.dist-info}/top_level.txt +0 -0
- {orionis-0.285.0.dist-info → orionis-0.287.0.dist-info}/zip-safe +0 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
class OrionisEnvironmentValueException(Exception):
|
2
|
+
|
3
|
+
def __init__(self, msg: str):
|
4
|
+
"""
|
5
|
+
Exception raised for errors related to environment values.
|
6
|
+
|
7
|
+
Parameters
|
8
|
+
----------
|
9
|
+
msg : str
|
10
|
+
The error message describing the exception.
|
11
|
+
"""
|
12
|
+
super().__init__(msg)
|
13
|
+
|
14
|
+
def __str__(self) -> str:
|
15
|
+
"""
|
16
|
+
Returns a string representation of the exception.
|
17
|
+
|
18
|
+
Returns
|
19
|
+
-------
|
20
|
+
str
|
21
|
+
A formatted string with the exception class name and its first argument.
|
22
|
+
"""
|
23
|
+
return f"{self.__class__.__name__}: {self.args[0]}"
|
@@ -0,0 +1,559 @@
|
|
1
|
+
from orionis.services.environment.exceptions.environment_value_error import OrionisEnvironmentValueError
|
2
|
+
from orionis.services.environment.exceptions.environment_value_exception import OrionisEnvironmentValueException
|
3
|
+
|
4
|
+
class EnvTypes:
|
5
|
+
|
6
|
+
# Type class to handle different types of environment variables
|
7
|
+
OPTIONS = {
|
8
|
+
'path',
|
9
|
+
'str',
|
10
|
+
'int',
|
11
|
+
'float',
|
12
|
+
'bool',
|
13
|
+
'list',
|
14
|
+
'dict',
|
15
|
+
'tuple',
|
16
|
+
'set'
|
17
|
+
}
|
18
|
+
|
19
|
+
@staticmethod
|
20
|
+
def options() -> set:
|
21
|
+
"""
|
22
|
+
Returns the set of valid type hints that can be used with this Type class.
|
23
|
+
|
24
|
+
Returns
|
25
|
+
-------
|
26
|
+
set
|
27
|
+
A set containing the valid type hints.
|
28
|
+
"""
|
29
|
+
return EnvTypes.OPTIONS
|
30
|
+
|
31
|
+
def __init__(self, raw: str = None):
|
32
|
+
"""
|
33
|
+
Parse a raw string input into a type hint and value string.
|
34
|
+
|
35
|
+
Parameters
|
36
|
+
----------
|
37
|
+
raw : str, optional
|
38
|
+
String that may contain a type hint and value separated by a colon (e.g., "int: 42").
|
39
|
+
If a colon is present, the part before the colon is treated as the type hint and the part after as the value.
|
40
|
+
If no colon is present, the entire string is treated as the value with no type hint.
|
41
|
+
|
42
|
+
Attributes
|
43
|
+
----------
|
44
|
+
__type_hint : str or None
|
45
|
+
The extracted type hint in lowercase, or None if not provided.
|
46
|
+
__value_str : str or None
|
47
|
+
The extracted value string, or None if not provided.
|
48
|
+
"""
|
49
|
+
type_hint, value_str = raw.split(':', 1)
|
50
|
+
if type_hint.strip().lower() in self.OPTIONS:
|
51
|
+
self.__type_hint = type_hint.strip().lower()
|
52
|
+
self.__value_str = value_str.strip() if value_str else None
|
53
|
+
else:
|
54
|
+
self.__type_hint = None
|
55
|
+
self.__value_str = raw.strip() if raw else None
|
56
|
+
|
57
|
+
def to(self, type_hint: str):
|
58
|
+
"""
|
59
|
+
Set the type hint for the Type instance.
|
60
|
+
|
61
|
+
Parameters
|
62
|
+
----------
|
63
|
+
type_hint : str
|
64
|
+
The type hint to set, which must be one of the valid options defined in OPTIONS.
|
65
|
+
|
66
|
+
Raises
|
67
|
+
------
|
68
|
+
OrionisEnvironmentValueError
|
69
|
+
If the provided type hint is not one of the valid options.
|
70
|
+
"""
|
71
|
+
|
72
|
+
# Validate and set the type hint
|
73
|
+
type_hint = type_hint.strip().lower()
|
74
|
+
if type_hint not in self.OPTIONS:
|
75
|
+
raise OrionisEnvironmentValueError(f"Invalid type hint: {type_hint}. Must be one of {self.OPTIONS}.")
|
76
|
+
self.__type_hint = type_hint
|
77
|
+
|
78
|
+
# Parse the value to the specified type hint
|
79
|
+
if self.__type_hint == 'path':
|
80
|
+
return self.__toPath()
|
81
|
+
|
82
|
+
if self.__type_hint == 'str':
|
83
|
+
return self.__toStr()
|
84
|
+
|
85
|
+
if self.__type_hint == 'int':
|
86
|
+
return self.__toInt()
|
87
|
+
|
88
|
+
if self.__type_hint == 'float':
|
89
|
+
return self.__toFloat()
|
90
|
+
|
91
|
+
if self.__type_hint == 'bool':
|
92
|
+
return self.__toBool()
|
93
|
+
|
94
|
+
if self.__type_hint == 'list':
|
95
|
+
return self.__toList()
|
96
|
+
|
97
|
+
if self.__type_hint == 'dict':
|
98
|
+
return self.__toDict()
|
99
|
+
|
100
|
+
if self.__type_hint == 'tuple':
|
101
|
+
return self.__toTuple()
|
102
|
+
|
103
|
+
if self.__type_hint == 'set':
|
104
|
+
return self.__toSet()
|
105
|
+
|
106
|
+
def hasValidTypeHint(self) -> bool:
|
107
|
+
"""
|
108
|
+
Check if the type hint is valid.
|
109
|
+
|
110
|
+
Returns
|
111
|
+
-------
|
112
|
+
bool
|
113
|
+
True if the type hint is valid (exists in the OPTIONS set), False otherwise.
|
114
|
+
"""
|
115
|
+
return self.__type_hint in self.OPTIONS
|
116
|
+
|
117
|
+
def explode(self) -> tuple:
|
118
|
+
"""
|
119
|
+
Returns a tuple containing the type hint and value string.
|
120
|
+
|
121
|
+
Returns
|
122
|
+
-------
|
123
|
+
tuple
|
124
|
+
A tuple (type_hint, value_str) where:
|
125
|
+
type_hint : str or None
|
126
|
+
The extracted type hint in lowercase, or None if not provided.
|
127
|
+
value_str : str or None
|
128
|
+
The extracted value string, or None if not provided.
|
129
|
+
"""
|
130
|
+
return self.__type_hint, self.__value_str
|
131
|
+
|
132
|
+
def __parsePath(self):
|
133
|
+
"""
|
134
|
+
Returns the value as a string, assuming the type hint is 'path:'.
|
135
|
+
|
136
|
+
Parameters
|
137
|
+
----------
|
138
|
+
None
|
139
|
+
|
140
|
+
Returns
|
141
|
+
-------
|
142
|
+
str
|
143
|
+
The value string with backslashes replaced by forward slashes, if the type hint is 'path:'.
|
144
|
+
|
145
|
+
Raises
|
146
|
+
------
|
147
|
+
OrionisEnvironmentValueException
|
148
|
+
If the value cannot be processed as a path.
|
149
|
+
"""
|
150
|
+
return self.__value_str.replace('\\', '/').strip()
|
151
|
+
|
152
|
+
def __toPath(self):
|
153
|
+
"""
|
154
|
+
Converts the internal string value to a formatted path string.
|
155
|
+
|
156
|
+
Returns
|
157
|
+
-------
|
158
|
+
str
|
159
|
+
A string representing the type hint and the value, with backslashes replaced by forward slashes.
|
160
|
+
|
161
|
+
Raises
|
162
|
+
------
|
163
|
+
OrionisEnvironmentValueError
|
164
|
+
If the internal value is not a string.
|
165
|
+
"""
|
166
|
+
if not isinstance(self.__value_str, str):
|
167
|
+
raise OrionisEnvironmentValueError(f"Value must be a string to convert to path, got {type(self.__value_str).__name__} instead.")
|
168
|
+
value = self.__value_str.replace('\\', '/').strip()
|
169
|
+
return f"{self.__type_hint}:{value}"
|
170
|
+
|
171
|
+
def __parseStr(self):
|
172
|
+
"""
|
173
|
+
Returns the value as a string, assuming the type hint is 'str:'.
|
174
|
+
|
175
|
+
Returns
|
176
|
+
-------
|
177
|
+
str
|
178
|
+
The value string if the type hint is 'str:', otherwise raises an error.
|
179
|
+
"""
|
180
|
+
return self.__value_str.strip()
|
181
|
+
|
182
|
+
def __toStr(self):
|
183
|
+
"""
|
184
|
+
Converts the internal value to a string representation.
|
185
|
+
|
186
|
+
Returns
|
187
|
+
-------
|
188
|
+
str
|
189
|
+
A string representing the type hint and the value.
|
190
|
+
|
191
|
+
Raises
|
192
|
+
------
|
193
|
+
OrionisEnvironmentValueError
|
194
|
+
If the internal value is not a string.
|
195
|
+
"""
|
196
|
+
if not isinstance(self.__value_str, str):
|
197
|
+
raise OrionisEnvironmentValueError(f"Value must be a string to convert to str, got {type(self.__value_str).__name__} instead.")
|
198
|
+
return f"{self.__type_hint}:{self.__value_str}"
|
199
|
+
|
200
|
+
def __parseInt(self):
|
201
|
+
"""
|
202
|
+
Returns the value as an integer, assuming the type hint is 'int:'.
|
203
|
+
|
204
|
+
Parameters
|
205
|
+
----------
|
206
|
+
None
|
207
|
+
|
208
|
+
Returns
|
209
|
+
-------
|
210
|
+
int
|
211
|
+
The value converted to an integer if the type hint is 'int:'.
|
212
|
+
|
213
|
+
Raises
|
214
|
+
------
|
215
|
+
OrionisEnvironmentValueException
|
216
|
+
If the value cannot be converted to an integer.
|
217
|
+
"""
|
218
|
+
value = self.__value_str.strip()
|
219
|
+
try:
|
220
|
+
return int(value)
|
221
|
+
except ValueError as e:
|
222
|
+
raise OrionisEnvironmentValueException(f"Cannot convert '{value}' to int: {str(e)}")
|
223
|
+
|
224
|
+
def __toInt(self):
|
225
|
+
"""
|
226
|
+
Converts the internal value to an integer representation.
|
227
|
+
|
228
|
+
Returns
|
229
|
+
-------
|
230
|
+
str
|
231
|
+
A string representing the type hint and the value as an integer.
|
232
|
+
|
233
|
+
Raises
|
234
|
+
------
|
235
|
+
OrionisEnvironmentValueError
|
236
|
+
If the internal value is not a string or cannot be converted to an integer.
|
237
|
+
"""
|
238
|
+
if not isinstance(self.__value_str, int):
|
239
|
+
raise OrionisEnvironmentValueError(f"Value must be an integer to convert to int, got {type(self.__value_str).__name__} instead.")
|
240
|
+
return f"{self.__type_hint}:{str(self.__value_str)}"
|
241
|
+
|
242
|
+
def __parseFloat(self):
|
243
|
+
"""
|
244
|
+
Returns the value as a float, assuming the type hint is 'float:'.
|
245
|
+
|
246
|
+
Parameters
|
247
|
+
----------
|
248
|
+
None
|
249
|
+
|
250
|
+
Returns
|
251
|
+
-------
|
252
|
+
float
|
253
|
+
The value converted to a float if the type hint is 'float:'.
|
254
|
+
|
255
|
+
Raises
|
256
|
+
------
|
257
|
+
OrionisEnvironmentValueException
|
258
|
+
If the value cannot be converted to a float.
|
259
|
+
"""
|
260
|
+
value = self.__value_str.strip()
|
261
|
+
try:
|
262
|
+
return float(value)
|
263
|
+
except ValueError as e:
|
264
|
+
raise OrionisEnvironmentValueException(f"Cannot convert '{value}' to float: {str(e)}")
|
265
|
+
|
266
|
+
def __toFloat(self):
|
267
|
+
"""
|
268
|
+
Converts the internal value to a float representation.
|
269
|
+
|
270
|
+
Returns
|
271
|
+
-------
|
272
|
+
str
|
273
|
+
A string representing the type hint and the value as a float.
|
274
|
+
|
275
|
+
Raises
|
276
|
+
------
|
277
|
+
OrionisEnvironmentValueError
|
278
|
+
If the internal value is not a string or cannot be converted to a float.
|
279
|
+
"""
|
280
|
+
if not isinstance(self.__value_str, float):
|
281
|
+
raise OrionisEnvironmentValueError(f"Value must be a float to convert to float, got {type(self.__value_str).__name__} instead.")
|
282
|
+
return f"{self.__type_hint}:{str(self.__value_str)}"
|
283
|
+
|
284
|
+
def __parseBool(self):
|
285
|
+
"""
|
286
|
+
Returns the value as a boolean, assuming the type hint is 'bool:'.
|
287
|
+
|
288
|
+
Parameters
|
289
|
+
----------
|
290
|
+
None
|
291
|
+
|
292
|
+
Returns
|
293
|
+
-------
|
294
|
+
bool
|
295
|
+
The value converted to a boolean if the type hint is 'bool:'.
|
296
|
+
|
297
|
+
Raises
|
298
|
+
------
|
299
|
+
OrionisEnvironmentValueException
|
300
|
+
If the value cannot be converted to a boolean.
|
301
|
+
"""
|
302
|
+
value = self.__value_str.strip().lower()
|
303
|
+
if value in {'true', '1', 'yes', 'on'}:
|
304
|
+
return True
|
305
|
+
elif value in {'false', '0', 'no', 'off'}:
|
306
|
+
return False
|
307
|
+
else:
|
308
|
+
raise OrionisEnvironmentValueException(f"Cannot convert '{value}' to bool.")
|
309
|
+
|
310
|
+
def __toBool(self):
|
311
|
+
"""
|
312
|
+
Converts the internal value to a boolean representation.
|
313
|
+
|
314
|
+
Returns
|
315
|
+
-------
|
316
|
+
str
|
317
|
+
A string representing the type hint and the value as a boolean.
|
318
|
+
|
319
|
+
Raises
|
320
|
+
------
|
321
|
+
OrionisEnvironmentValueError
|
322
|
+
If the internal value is not a boolean.
|
323
|
+
"""
|
324
|
+
if not isinstance(self.__value_str, bool):
|
325
|
+
raise OrionisEnvironmentValueError(f"Value must be a boolean to convert to bool, got {type(self.__value_str).__name__} instead.")
|
326
|
+
return f"{self.__type_hint}:{str(self.__value_str).lower()}"
|
327
|
+
|
328
|
+
def __parseList(self):
|
329
|
+
"""
|
330
|
+
Returns the value as a list, assuming the type hint is 'list:'.
|
331
|
+
|
332
|
+
Returns
|
333
|
+
-------
|
334
|
+
list
|
335
|
+
The value converted to a list if the type hint is 'list:'.
|
336
|
+
|
337
|
+
Raises
|
338
|
+
------
|
339
|
+
OrionisEnvironmentValueException
|
340
|
+
If the value cannot be converted to a list.
|
341
|
+
"""
|
342
|
+
import ast
|
343
|
+
|
344
|
+
value = self.__value_str.strip()
|
345
|
+
try:
|
346
|
+
parsed = ast.literal_eval(value)
|
347
|
+
if not isinstance(parsed, list):
|
348
|
+
raise ValueError("Value is not a list")
|
349
|
+
return parsed
|
350
|
+
except (ValueError, SyntaxError) as e:
|
351
|
+
raise OrionisEnvironmentValueException(f"Cannot convert '{value}' to list: {str(e)}")
|
352
|
+
|
353
|
+
def __toList(self):
|
354
|
+
"""
|
355
|
+
Converts the internal value to a list representation.
|
356
|
+
|
357
|
+
Returns
|
358
|
+
-------
|
359
|
+
str
|
360
|
+
A string representing the type hint and the value as a list.
|
361
|
+
|
362
|
+
Raises
|
363
|
+
------
|
364
|
+
OrionisEnvironmentValueError
|
365
|
+
If the internal value is not a list.
|
366
|
+
"""
|
367
|
+
if not isinstance(self.__value_str, list):
|
368
|
+
raise OrionisEnvironmentValueError(f"Value must be a list to convert to list, got {type(self.__value_str).__name__} instead.")
|
369
|
+
return f"{self.__type_hint}:{repr(self.__value_str)}"
|
370
|
+
|
371
|
+
def __parseDict(self):
|
372
|
+
"""
|
373
|
+
Returns the value as a dict, assuming the type hint is 'dict:'.
|
374
|
+
|
375
|
+
Parameters
|
376
|
+
----------
|
377
|
+
None
|
378
|
+
|
379
|
+
Returns
|
380
|
+
-------
|
381
|
+
dict
|
382
|
+
The value converted to a dict if the type hint is 'dict:'.
|
383
|
+
|
384
|
+
Raises
|
385
|
+
------
|
386
|
+
OrionisEnvironmentValueException
|
387
|
+
If the value cannot be converted to a dict.
|
388
|
+
"""
|
389
|
+
import ast
|
390
|
+
|
391
|
+
value = self.__value_str.strip()
|
392
|
+
try:
|
393
|
+
parsed = ast.literal_eval(value)
|
394
|
+
if not isinstance(parsed, dict):
|
395
|
+
raise ValueError("Value is not a dict")
|
396
|
+
return parsed
|
397
|
+
except (ValueError, SyntaxError) as e:
|
398
|
+
raise OrionisEnvironmentValueException(f"Cannot convert '{value}' to dict: {str(e)}")
|
399
|
+
|
400
|
+
def __toDict(self):
|
401
|
+
"""
|
402
|
+
Converts the internal value to a dict representation.
|
403
|
+
|
404
|
+
Returns
|
405
|
+
-------
|
406
|
+
str
|
407
|
+
A string representing the type hint and the value as a dict.
|
408
|
+
|
409
|
+
Raises
|
410
|
+
------
|
411
|
+
OrionisEnvironmentValueError
|
412
|
+
If the internal value is not a dict.
|
413
|
+
"""
|
414
|
+
if not isinstance(self.__value_str, dict):
|
415
|
+
raise OrionisEnvironmentValueError(f"Value must be a dict to convert to dict, got {type(self.__value_str).__name__} instead.")
|
416
|
+
return f"{self.__type_hint}:{repr(self.__value_str)}"
|
417
|
+
|
418
|
+
def __parseTuple(self):
|
419
|
+
"""
|
420
|
+
Returns the value as a tuple, assuming the type hint is 'tuple:'.
|
421
|
+
|
422
|
+
Parameters
|
423
|
+
----------
|
424
|
+
None
|
425
|
+
|
426
|
+
Returns
|
427
|
+
-------
|
428
|
+
tuple
|
429
|
+
The value converted to a tuple if the type hint is 'tuple:'.
|
430
|
+
|
431
|
+
Raises
|
432
|
+
------
|
433
|
+
OrionisEnvironmentValueException
|
434
|
+
If the value cannot be converted to a tuple.
|
435
|
+
"""
|
436
|
+
import ast
|
437
|
+
|
438
|
+
value = self.__value_str.strip()
|
439
|
+
try:
|
440
|
+
parsed = ast.literal_eval(value)
|
441
|
+
if not isinstance(parsed, tuple):
|
442
|
+
raise ValueError("Value is not a tuple")
|
443
|
+
return parsed
|
444
|
+
except (ValueError, SyntaxError) as e:
|
445
|
+
raise OrionisEnvironmentValueException(f"Cannot convert '{value}' to tuple: {str(e)}")
|
446
|
+
|
447
|
+
def __toTuple(self):
|
448
|
+
"""
|
449
|
+
Converts the internal value to a tuple representation.
|
450
|
+
|
451
|
+
Returns
|
452
|
+
-------
|
453
|
+
str
|
454
|
+
A string representing the type hint and the value as a tuple.
|
455
|
+
|
456
|
+
Raises
|
457
|
+
------
|
458
|
+
OrionisEnvironmentValueError
|
459
|
+
If the internal value is not a tuple.
|
460
|
+
"""
|
461
|
+
if not isinstance(self.__value_str, tuple):
|
462
|
+
raise OrionisEnvironmentValueError(f"Value must be a tuple to convert to tuple, got {type(self.__value_str).__name__} instead.")
|
463
|
+
return f"{self.__type_hint}:{repr(self.__value_str)}"
|
464
|
+
|
465
|
+
def __parseSet(self):
|
466
|
+
"""
|
467
|
+
Returns the value as a set, assuming the type hint is 'set:'.
|
468
|
+
|
469
|
+
Parameters
|
470
|
+
----------
|
471
|
+
None
|
472
|
+
|
473
|
+
Returns
|
474
|
+
-------
|
475
|
+
set
|
476
|
+
The value converted to a set if the type hint is 'set:'.
|
477
|
+
|
478
|
+
Raises
|
479
|
+
------
|
480
|
+
OrionisEnvironmentValueException
|
481
|
+
If the value cannot be converted to a set.
|
482
|
+
"""
|
483
|
+
import ast
|
484
|
+
|
485
|
+
value = self.__value_str.strip()
|
486
|
+
try:
|
487
|
+
parsed = ast.literal_eval(value)
|
488
|
+
if not isinstance(parsed, set):
|
489
|
+
raise ValueError("Value is not a set")
|
490
|
+
return parsed
|
491
|
+
except (ValueError, SyntaxError) as e:
|
492
|
+
raise OrionisEnvironmentValueException(f"Cannot convert '{value}' to set: {str(e)}")
|
493
|
+
|
494
|
+
def __toSet(self):
|
495
|
+
"""
|
496
|
+
Converts the internal value to a set representation.
|
497
|
+
|
498
|
+
Returns
|
499
|
+
-------
|
500
|
+
str
|
501
|
+
A string representing the type hint and the value as a set.
|
502
|
+
|
503
|
+
Raises
|
504
|
+
------
|
505
|
+
OrionisEnvironmentValueError
|
506
|
+
If the internal value is not a set.
|
507
|
+
"""
|
508
|
+
if not isinstance(self.__value_str, set):
|
509
|
+
raise OrionisEnvironmentValueError(f"Value must be a set to convert to set, got {type(self.__value_str).__name__} instead.")
|
510
|
+
return f"{self.__type_hint}:{repr(self.__value_str)}"
|
511
|
+
|
512
|
+
def get(self):
|
513
|
+
"""
|
514
|
+
Returns the value corresponding to the specified type hint.
|
515
|
+
|
516
|
+
Checks if the provided type hint is valid and then dispatches the call to the appropriate
|
517
|
+
method for handling the type.
|
518
|
+
|
519
|
+
Supported type hints include: 'path:', 'str:', 'int:', 'float:', 'bool:', 'list:', 'dict:', 'tuple:', and 'set:'.
|
520
|
+
|
521
|
+
Returns
|
522
|
+
-------
|
523
|
+
Any
|
524
|
+
The value converted or processed according to the specified type hint.
|
525
|
+
|
526
|
+
Raises
|
527
|
+
------
|
528
|
+
OrionisEnvironmentValueError
|
529
|
+
If the type hint is not one of the supported options.
|
530
|
+
"""
|
531
|
+
if not self.__type_hint in self.OPTIONS:
|
532
|
+
raise OrionisEnvironmentValueError(f"Invalid type hint: {self.__type_hint}. Must be one of {self.OPTIONS}.")
|
533
|
+
|
534
|
+
if self.__type_hint == 'path':
|
535
|
+
return self.__parsePath()
|
536
|
+
|
537
|
+
if self.__type_hint == 'str':
|
538
|
+
return self.__parseStr()
|
539
|
+
|
540
|
+
if self.__type_hint == 'int':
|
541
|
+
return self.__parseInt()
|
542
|
+
|
543
|
+
if self.__type_hint == 'float':
|
544
|
+
return self.__parseFloat()
|
545
|
+
|
546
|
+
if self.__type_hint == 'bool':
|
547
|
+
return self.__parseBool()
|
548
|
+
|
549
|
+
if self.__type_hint == 'list':
|
550
|
+
return self.__parseList()
|
551
|
+
|
552
|
+
if self.__type_hint == 'dict':
|
553
|
+
return self.__parseDict()
|
554
|
+
|
555
|
+
if self.__type_hint == 'tuple':
|
556
|
+
return self.__parseTuple()
|
557
|
+
|
558
|
+
if self.__type_hint == 'set':
|
559
|
+
return self.__parseSet()
|
@@ -1,28 +1,19 @@
|
|
1
1
|
class OrionisTestConfigException(Exception):
|
2
|
-
"""
|
3
|
-
Custom exception for test configuration errors in the Orionis framework.
|
4
|
-
|
5
|
-
This exception is raised when there is an issue with the test configuration,
|
6
|
-
providing a clear and descriptive error message to aid in debugging.
|
7
|
-
"""
|
8
2
|
|
9
3
|
def __init__(self, msg: str):
|
10
4
|
"""
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
5
|
+
Parameters
|
6
|
+
----------
|
7
|
+
msg : str
|
8
|
+
Descriptive error message explaining the cause of the exception.
|
15
9
|
"""
|
16
10
|
super().__init__(msg)
|
17
11
|
|
18
12
|
def __str__(self) -> str:
|
19
13
|
"""
|
20
|
-
Returns
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
Returns:
|
26
|
-
str: A formatted string describing the exception.
|
14
|
+
Returns
|
15
|
+
-------
|
16
|
+
str
|
17
|
+
Formatted string describing the exception, including the exception name and error message.
|
27
18
|
"""
|
28
19
|
return f"{self.__class__.__name__}: {self.args[0]}"
|
@@ -1,29 +1,31 @@
|
|
1
1
|
import unittest
|
2
2
|
|
3
3
|
class OrionisTestFailureException(Exception):
|
4
|
-
"""
|
5
|
-
OrionisTestFailureException is a custom exception class used to handle test failures and errors
|
6
|
-
in a structured manner. It provides detailed information about the failed and errored tests,
|
7
|
-
including their IDs and formatted error messages.
|
8
|
-
Methods:
|
9
|
-
__init__(result: unittest.TestResult):
|
10
|
-
__str__() -> str:
|
11
|
-
"""
|
12
4
|
|
13
5
|
def __init__(self, result: unittest.TestResult):
|
14
6
|
"""
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
7
|
+
Initialize the exception with details about failed and errored tests.
|
8
|
+
|
9
|
+
Parameters
|
10
|
+
----------
|
11
|
+
result : unittest.TestResult
|
12
|
+
The test result object containing information about test failures and errors.
|
13
|
+
|
14
|
+
Attributes
|
15
|
+
----------
|
16
|
+
failed_tests : list
|
17
|
+
List of IDs for tests that failed.
|
18
|
+
errored_tests : list
|
19
|
+
List of IDs for tests that encountered errors.
|
20
|
+
error_messages : list
|
21
|
+
List of formatted error messages for failed and errored tests.
|
22
|
+
text : str
|
23
|
+
Formatted string summarizing the test failures and errors.
|
24
|
+
|
25
|
+
Raises
|
26
|
+
------
|
27
|
+
Exception
|
28
|
+
If there are failed or errored tests, raises an exception with a summary message.
|
27
29
|
"""
|
28
30
|
failed_tests = [test.id() for test, _ in result.failures]
|
29
31
|
errored_tests = [test.id() for test, _ in result.errors]
|
@@ -40,13 +42,11 @@ class OrionisTestFailureException(Exception):
|
|
40
42
|
|
41
43
|
def __str__(self) -> str:
|
42
44
|
"""
|
43
|
-
|
45
|
+
Return a string representation of the exception.
|
44
46
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
Returns:
|
50
|
-
str: A formatted string describing the exception.
|
47
|
+
Returns
|
48
|
+
-------
|
49
|
+
str
|
50
|
+
A formatted string describing the exception, including the exception name and the message.
|
51
51
|
"""
|
52
52
|
return f"{self.__class__.__name__}: {self.args[0]}"
|