orionis 0.421.0__py3-none-any.whl → 0.422.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.
@@ -0,0 +1,902 @@
1
+
2
+ from typing import Any
3
+ from orionis.services.environment.contracts.caster import IEnvironmentCaster
4
+ from orionis.services.environment.enums.value_type import EnvironmentValueType
5
+ from orionis.services.environment.exceptions import OrionisEnvironmentValueError, OrionisEnvironmentValueException
6
+
7
+ class EnvironmentCaster(IEnvironmentCaster):
8
+
9
+ # Type class to handle different types of environment variables
10
+ OPTIONS = {e.value for e in EnvironmentValueType}
11
+
12
+ @staticmethod
13
+ def options() -> set:
14
+ """
15
+ Returns the set of valid type hints that can be used with this Type class.
16
+
17
+ Returns
18
+ -------
19
+ set
20
+ A set containing the valid type hints.
21
+ """
22
+ return EnvironmentCaster.OPTIONS
23
+
24
+ def __init__(
25
+ self,
26
+ raw: str | Any
27
+ ) -> None:
28
+ """
29
+ Initializes an EnvTypes instance by parsing a raw input into a type hint and value.
30
+
31
+ Parameters
32
+ ----------
33
+ raw : str or Any
34
+ The input to be parsed. If a string, it may contain a type hint and value separated by a colon
35
+ (e.g., "int: 42"). If a colon is present, the part before the colon is treated as the type hint
36
+ and the part after as the value. If no colon is present, the entire string is treated as the value
37
+ with no type hint. If not a string, the input is treated as the value with no type hint.
38
+
39
+ Attributes
40
+ ----------
41
+ __type_hint : str or None
42
+ The extracted type hint in lowercase, or None if not provided or invalid.
43
+ __value_raw : str or Any
44
+ The extracted value string if input is a string, or the raw value otherwise.
45
+
46
+ Returns
47
+ -------
48
+ None
49
+ This constructor does not return a value. It initializes the instance attributes.
50
+ """
51
+ # Initialize type hint and value to default None
52
+ self.__type_hint: str = None
53
+ self.__value_raw: str | Any = None
54
+
55
+ # If the input is a string, attempt to parse type hint and value
56
+ if isinstance(raw, str):
57
+ # Remove leading whitespace from the input
58
+ self.__value_raw = raw.lstrip()
59
+
60
+ # Check if the string contains a colon, indicating a type hint
61
+ if ':' in self.__value_raw:
62
+ # Split at the first colon to separate type hint and value
63
+ type_hint, value_str = raw.split(':', 1)
64
+
65
+ # Validate the extracted type hint and set attributes if valid
66
+ if type_hint.strip().lower() in self.OPTIONS:
67
+ self.__type_hint = type_hint.strip().lower()
68
+ # Remove leading whitespace from the value part
69
+ self.__value_raw = value_str.lstrip() if value_str else None
70
+ else:
71
+ # If input is not a string, treat it as the value with no type hint
72
+ self.__value_raw = raw
73
+
74
+ def get(self):
75
+ """
76
+ Retrieves the value processed according to the specified type hint.
77
+
78
+ This method checks if a valid type hint is present and dispatches the call to the
79
+ corresponding internal parsing method for that type. Supported type hints include:
80
+ 'path', 'str', 'int', 'float', 'bool', 'list', 'dict', 'tuple', and 'set'.
81
+ If no type hint is set, the raw value is returned as is.
82
+
83
+ Returns
84
+ -------
85
+ Any
86
+ The value converted or processed according to the specified type hint. If no type hint
87
+ is set, returns the raw value.
88
+
89
+ Raises
90
+ ------
91
+ OrionisEnvironmentValueError
92
+ If the type hint is not one of the supported options.
93
+ """
94
+
95
+ try:
96
+
97
+ # If a type hint is set, dispatch to the appropriate parsing method
98
+ if self.__type_hint:
99
+
100
+ # Handle 'path' type hint
101
+ if self.__type_hint == EnvironmentValueType.PATH.value:
102
+ return self.__parsePath()
103
+
104
+ # Handle 'str' type hint
105
+ if self.__type_hint == EnvironmentValueType.STR.value:
106
+ return self.__parseStr()
107
+
108
+ # Handle 'int' type hint
109
+ if self.__type_hint == EnvironmentValueType.INT.value:
110
+ return self.__parseInt()
111
+
112
+ # Handle 'float' type hint
113
+ if self.__type_hint == EnvironmentValueType.FLOAT.value:
114
+ return self.__parseFloat()
115
+
116
+ # Handle 'bool' type hint
117
+ if self.__type_hint == EnvironmentValueType.BOOL.value:
118
+ return self.__parseBool()
119
+
120
+ # Handle 'list' type hint
121
+ if self.__type_hint == EnvironmentValueType.LIST.value:
122
+ return self.__parseList()
123
+
124
+ # Handle 'dict' type hint
125
+ if self.__type_hint == EnvironmentValueType.DICT.value:
126
+ return self.__parseDict()
127
+
128
+ # Handle 'tuple' type hint
129
+ if self.__type_hint == EnvironmentValueType.TUPLE.value:
130
+ return self.__parseTuple()
131
+
132
+ # Handle 'set' type hint
133
+ if self.__type_hint == EnvironmentValueType.SET.value:
134
+ return self.__parseSet()
135
+
136
+ # Handle 'base64' type hint
137
+ if self.__type_hint == EnvironmentValueType.BASE64.value:
138
+ return self.__parseBase64()
139
+
140
+ else:
141
+ # If no type hint is set, return the raw value
142
+ return self.__value_raw
143
+
144
+ except OrionisEnvironmentValueError:
145
+
146
+ # Propagate specific type conversion errors
147
+ raise
148
+
149
+ except Exception as e:
150
+
151
+ # Catch any other unexpected errors and wrap them in an environment value error
152
+ raise OrionisEnvironmentValueError(
153
+ f"Error processing value '{self.__value_raw}' with type hint '{self.__type_hint}': {str(e)}"
154
+ ) from e
155
+
156
+ def to(self, type_hint: str | EnvironmentValueType) -> Any:
157
+ """
158
+ Converts the internal value to the specified type and returns its string representation with the type hint prefix.
159
+
160
+ This method sets the type hint for the instance and attempts to convert the internal value to the specified type.
161
+ The type hint must be one of the valid options defined in `OPTIONS`. If the conversion is successful, a string
162
+ representation of the value prefixed with the type hint is returned. If the type hint is invalid or the conversion
163
+ fails, an exception is raised.
164
+
165
+ Parameters
166
+ ----------
167
+ type_hint : str or EnvironmentValueType
168
+ The type hint to set. Can be a string or an `EnvironmentValueType` enum member. Must be one of the valid options.
169
+
170
+ Returns
171
+ -------
172
+ Any
173
+ The string representation of the value with the type hint prefix, according to the specified type.
174
+ For example, "int:42", "list:[1, 2, 3]", etc.
175
+
176
+ Raises
177
+ ------
178
+ OrionisEnvironmentValueError
179
+ If the provided type hint is not valid or if the value cannot be converted to the specified type.
180
+ """
181
+ try:
182
+ # If type_hint is an enum, convert it to its value string
183
+ if isinstance(type_hint, EnvironmentValueType):
184
+ type_hint = type_hint.value
185
+
186
+ # Validate the type hint against the defined options
187
+ if type_hint not in self.OPTIONS:
188
+ raise OrionisEnvironmentValueError(
189
+ f"Invalid type hint: {type_hint}. Must be one of {self.OPTIONS}."
190
+ )
191
+
192
+ # Set the type hint for the instance
193
+ self.__type_hint = type_hint
194
+
195
+ # Dispatch to the appropriate conversion method based on the type hint
196
+ if self.__type_hint == EnvironmentValueType.PATH.value:
197
+ return self.__toPath()
198
+ if self.__type_hint == EnvironmentValueType.STR.value:
199
+ return self.__toStr()
200
+ if self.__type_hint == EnvironmentValueType.INT.value:
201
+ return self.__toInt()
202
+ if self.__type_hint == EnvironmentValueType.FLOAT.value:
203
+ return self.__toFloat()
204
+ if self.__type_hint == EnvironmentValueType.BOOL.value:
205
+ return self.__toBool()
206
+ if self.__type_hint == EnvironmentValueType.LIST.value:
207
+ return self.__toList()
208
+ if self.__type_hint == EnvironmentValueType.DICT.value:
209
+ return self.__toDict()
210
+ if self.__type_hint == EnvironmentValueType.TUPLE.value:
211
+ return self.__toTuple()
212
+ if self.__type_hint == EnvironmentValueType.SET.value:
213
+ return self.__toSet()
214
+ if self.__type_hint == EnvironmentValueType.BASE64.value:
215
+ return self.__toBase64()
216
+
217
+ except OrionisEnvironmentValueError:
218
+ # Propagate specific type conversion errors
219
+ raise
220
+
221
+ except Exception as e:
222
+ # Catch any other unexpected errors and wrap them in an environment value error
223
+ raise OrionisEnvironmentValueError(
224
+ f"Error converting value '{self.__value_raw}' to type '{type_hint}': {str(e)}"
225
+ ) from e
226
+
227
+ def __toBase64(self) -> str:
228
+ """
229
+ Converts the internal value to a Base64 encoded string with the type hint prefix.
230
+
231
+ This method checks if the internal value is a string or bytes. If so, it encodes the value in Base64
232
+ and returns a string in the format "<type_hint>:<base64_value>". If the internal value is not a string
233
+ or bytes, an exception is raised.
234
+
235
+ Returns
236
+ -------
237
+ str
238
+ A Base64 encoded string combining the type hint and the internal value, separated by a colon.
239
+
240
+ Raises
241
+ ------
242
+ OrionisEnvironmentValueError
243
+ If the internal value is not a string or bytes.
244
+ """
245
+ import base64
246
+
247
+ if not isinstance(self.__value_raw, (str, bytes)):
248
+ raise OrionisEnvironmentValueError(
249
+ f"Value must be a string or bytes to convert to Base64, got {type(self.__value_raw).__name__} instead."
250
+ )
251
+
252
+ # Encode the value in Base64
253
+ encoded_value = base64.b64encode(str(self.__value_raw).encode()).decode()
254
+
255
+ # Return the formatted string with type hint and Base64 encoded value
256
+ return f"{self.__type_hint}:{encoded_value}"
257
+
258
+ def __parseBase64(self) -> str:
259
+ """
260
+ Decodes the Base64 encoded value, assuming the type hint is 'base64:'.
261
+
262
+ This method decodes the internal raw value from Base64 and returns it as a string.
263
+ If the value cannot be decoded, an `OrionisEnvironmentValueException` is raised.
264
+
265
+ Returns
266
+ -------
267
+ str
268
+ The decoded Base64 value as a string.
269
+
270
+ Raises
271
+ ------
272
+ OrionisEnvironmentValueException
273
+ If the value cannot be decoded from Base64.
274
+ """
275
+ import base64
276
+
277
+ try:
278
+ # Decode the Base64 encoded value
279
+ decoded_value = base64.b64decode(self.__value_raw).decode()
280
+ return decoded_value
281
+ except Exception as e:
282
+ raise OrionisEnvironmentValueException(f"Cannot decode Base64 value '{self.__value_raw}': {str(e)}")
283
+
284
+ def __parsePath(self):
285
+ """
286
+ Converts the internal raw value to a `Path` object, assuming the type hint is 'path:'.
287
+
288
+ This method processes the internal value as a file system path. It replaces backslashes
289
+ with forward slashes for normalization and returns a `Path` object representing the path.
290
+
291
+ Parameters
292
+ ----------
293
+ self : EnvironmentCaster
294
+ The instance of the EnvironmentCaster class.
295
+
296
+ Returns
297
+ -------
298
+ pathlib.Path
299
+ A `Path` object representing the normalized file system path.
300
+
301
+ Raises
302
+ ------
303
+ OrionisEnvironmentValueException
304
+ If the value cannot be processed as a valid path.
305
+ """
306
+ from pathlib import Path
307
+
308
+ # Normalize the path by replacing backslashes with forward slashes
309
+ normalized_path = str(self.__value_raw).replace('\\', '/')
310
+
311
+ # Return a Path object constructed from the normalized path string
312
+ return Path(normalized_path)
313
+
314
+ def __toPath(self) -> str:
315
+ """
316
+ Converts the internal value to an absolute path string.
317
+
318
+ Returns
319
+ -------
320
+ str
321
+ A string representing the type hint and the absolute path value.
322
+
323
+ Raises
324
+ ------
325
+ OrionisEnvironmentValueError
326
+ If the internal value is not a string or Path.
327
+ """
328
+ from pathlib import Path
329
+ import os
330
+
331
+ if not isinstance(self.__value_raw, (str, Path)):
332
+ raise OrionisEnvironmentValueError(
333
+ f"Value must be a string or Path to convert to path, got {type(self.__value_raw).__name__} instead."
334
+ )
335
+
336
+ # Normalize slashes and strip whitespace
337
+ raw_path = str(self.__value_raw).replace('\\', '/').strip()
338
+
339
+ # If the path is relative, resolve it from the current working directory
340
+ path_obj = Path(raw_path)
341
+
342
+ # If the path is not absolute, make it absolute by combining with the current working directory
343
+ if not path_obj.is_absolute():
344
+
345
+ # Remove leading slash if present to avoid absolute path when joining
346
+ raw_path_no_leading = raw_path.lstrip('/\\')
347
+ path_obj = Path(Path.cwd()) / raw_path_no_leading
348
+
349
+ # Resolve the path to get the absolute path
350
+ abs_path = path_obj.expanduser().resolve()
351
+
352
+ # Return the absolute path as a string with the type hint
353
+ return f"{self.__type_hint}:{str(abs_path)}"
354
+
355
+ def __parseStr(self):
356
+ """
357
+ Returns the value as a string, assuming the type hint is 'str:'.
358
+
359
+ This method processes the internal raw value and returns it as a string,
360
+ provided the type hint is 'str:'. Leading whitespace is removed from the value
361
+ before returning. No type conversion is performed; the value is returned as-is
362
+ after stripping leading whitespace.
363
+
364
+ Returns
365
+ -------
366
+ str
367
+ The internal value as a string with leading whitespace removed.
368
+
369
+ Raises
370
+ ------
371
+ None
372
+ This method does not raise any exceptions.
373
+ """
374
+
375
+ # Return the internal value as a string, removing leading whitespace
376
+ return self.__value_raw.lstrip()
377
+
378
+ def __toStr(self):
379
+ """
380
+ Converts the internal value to a string representation with the type hint prefix.
381
+
382
+ This method checks if the internal value is a string. If so, it returns a string
383
+ in the format "<type_hint>:<value>", where <type_hint> is the current type hint
384
+ and <value> is the internal string value. If the internal value is not a string,
385
+ an exception is raised.
386
+
387
+ Returns
388
+ -------
389
+ str
390
+ A string combining the type hint and the internal value, separated by a colon.
391
+
392
+ Raises
393
+ ------
394
+ OrionisEnvironmentValueError
395
+ If the internal value is not a string.
396
+ """
397
+
398
+ # Ensure the internal value is a string before conversion
399
+ if not isinstance(self.__value_raw, str):
400
+ raise OrionisEnvironmentValueError(
401
+ f"Value must be a string to convert to str, got {type(self.__value_raw).__name__} instead."
402
+ )
403
+
404
+ # Return the formatted string with type hint and value
405
+ return f"{self.__value_raw}"
406
+
407
+ def __parseInt(self):
408
+ """
409
+ Converts the internal raw value to an integer, assuming the type hint is 'int:'.
410
+
411
+ This method attempts to strip leading and trailing whitespace from the internal
412
+ raw value and convert it to an integer. If the conversion fails due to an invalid
413
+ format or non-integer input, an `OrionisEnvironmentValueException` is raised.
414
+
415
+ Parameters
416
+ ----------
417
+ self : EnvironmentCaster
418
+ The instance of the EnvironmentCaster class.
419
+
420
+ Returns
421
+ -------
422
+ int
423
+ The internal value converted to an integer.
424
+
425
+ Raises
426
+ ------
427
+ OrionisEnvironmentValueException
428
+ If the value cannot be converted to an integer due to invalid format or type.
429
+ """
430
+ # Remove leading and trailing whitespace from the raw value
431
+ value = self.__value_raw.strip()
432
+
433
+ # Attempt to convert the value to an integer
434
+ try:
435
+ return int(value)
436
+
437
+ # Raise a custom exception if conversion fails
438
+ except ValueError as e:
439
+ raise OrionisEnvironmentValueException(f"Cannot convert '{value}' to int: {str(e)}")
440
+
441
+ def __toInt(self):
442
+ """
443
+ Converts the internal value to a string representation with the integer type hint prefix.
444
+
445
+ This method checks if the internal value is an integer. If so, it returns a string
446
+ in the format "<type_hint>:<value>", where <type_hint> is the current type hint
447
+ and <value> is the integer value. If the internal value is not an integer, an exception is raised.
448
+
449
+ Returns
450
+ -------
451
+ str
452
+ A string combining the type hint and the internal integer value, separated by a colon.
453
+
454
+ Raises
455
+ ------
456
+ OrionisEnvironmentValueError
457
+ If the internal value is not an integer.
458
+ """
459
+
460
+ # Ensure the internal value is an integer before conversion
461
+ if not isinstance(self.__value_raw, int):
462
+ raise OrionisEnvironmentValueError(
463
+ f"Value must be an integer to convert to int, got {type(self.__value_raw).__name__} instead."
464
+ )
465
+
466
+ # Return the formatted string with type hint and integer value
467
+ return f"{self.__type_hint}:{str(self.__value_raw)}"
468
+
469
+ def __parseFloat(self):
470
+ """
471
+ Converts the internal raw value to a float, assuming the type hint is 'float:'.
472
+
473
+ This method attempts to strip leading and trailing whitespace from the internal
474
+ raw value and convert it to a float. If the conversion fails due to an invalid
475
+ format or non-numeric input, an `OrionisEnvironmentValueException` is raised.
476
+
477
+ Parameters
478
+ ----------
479
+ self : EnvironmentCaster
480
+ The instance of the EnvironmentCaster class.
481
+
482
+ Returns
483
+ -------
484
+ float
485
+ The internal value converted to a float.
486
+
487
+ Raises
488
+ ------
489
+ OrionisEnvironmentValueException
490
+ If the value cannot be converted to a float due to invalid format or type.
491
+ """
492
+ # Remove leading and trailing whitespace from the raw value
493
+ value = self.__value_raw.strip()
494
+
495
+ # Attempt to convert the value to a float
496
+ try:
497
+ return float(value)
498
+
499
+ # Raise a custom exception if conversion fails
500
+ except ValueError as e:
501
+ raise OrionisEnvironmentValueException(f"Cannot convert '{value}' to float: {str(e)}")
502
+
503
+ def __toFloat(self):
504
+ """
505
+ Converts the internal value to a string representation with the float type hint prefix.
506
+
507
+ This method checks if the internal value is a float. If so, it returns a string
508
+ in the format "<type_hint>:<value>", where <type_hint> is the current type hint
509
+ and <value> is the float value. If the internal value is not a float, an exception is raised.
510
+
511
+ Returns
512
+ -------
513
+ str
514
+ A string combining the type hint and the internal float value, separated by a colon.
515
+ For example, "float:3.14".
516
+
517
+ Raises
518
+ ------
519
+ OrionisEnvironmentValueError
520
+ If the internal value is not a float.
521
+ """
522
+
523
+ # Ensure the internal value is a float before conversion
524
+ if not isinstance(self.__value_raw, float):
525
+ raise OrionisEnvironmentValueError(
526
+ f"Value must be a float to convert to float, got {type(self.__value_raw).__name__} instead."
527
+ )
528
+
529
+ # Return the formatted string with type hint and float value
530
+ return f"{self.__type_hint}:{str(self.__value_raw)}"
531
+
532
+ def __parseBool(self):
533
+ """
534
+ Converts the internal raw value to a boolean, assuming the type hint is 'bool:'.
535
+
536
+ This method processes the internal raw value by stripping leading and trailing whitespace,
537
+ converting it to lowercase, and then checking if it matches the string 'true' or 'false'.
538
+ If the value is 'true', it returns the boolean value True. If the value is 'false', it returns
539
+ the boolean value False. If the value does not match either, an `OrionisEnvironmentValueException`
540
+ is raised.
541
+
542
+ Parameters
543
+ ----------
544
+ self : EnvironmentCaster
545
+ The instance of the EnvironmentCaster class.
546
+
547
+ Returns
548
+ -------
549
+ bool
550
+ Returns True if the value is 'true' (case-insensitive), False if the value is 'false' (case-insensitive).
551
+
552
+ Raises
553
+ ------
554
+ OrionisEnvironmentValueException
555
+ If the value cannot be converted to a boolean because it does not match 'true' or 'false'.
556
+ """
557
+
558
+ # Strip whitespace and convert the value to lowercase for comparison
559
+ value = self.__value_raw.strip().lower()
560
+
561
+ # Check for 'true' and return True
562
+ if value == 'true':
563
+ return True
564
+
565
+ # Check for 'false' and return False
566
+ elif value == 'false':
567
+ return False
568
+
569
+ # Raise an exception if the value cannot be interpreted as a boolean
570
+ else:
571
+ raise OrionisEnvironmentValueException(f"Cannot convert '{value}' to bool.")
572
+
573
+ def __toBool(self):
574
+ """
575
+ Converts the internal value to a string representation with the boolean type hint prefix.
576
+
577
+ This method checks if the internal value is a boolean. If so, it returns a string
578
+ in the format "<type_hint>:<value>", where <type_hint> is the current type hint
579
+ and <value> is the lowercase string representation of the boolean value.
580
+ If the internal value is not a boolean, an exception is raised.
581
+
582
+ Returns
583
+ -------
584
+ str
585
+ A string combining the type hint and the internal boolean value, separated by a colon.
586
+ The boolean value is represented as 'true' or 'false' in lowercase.
587
+
588
+ Raises
589
+ ------
590
+ OrionisEnvironmentValueError
591
+ If the internal value is not a boolean.
592
+ """
593
+
594
+ # Ensure the internal value is a boolean before conversion
595
+ if not isinstance(self.__value_raw, bool):
596
+ raise OrionisEnvironmentValueError(
597
+ f"Value must be a boolean to convert to bool, got {type(self.__value_raw).__name__} instead."
598
+ )
599
+
600
+ # Return the formatted string with type hint and boolean value in lowercase
601
+ return f"{self.__type_hint}:{str(self.__value_raw).lower()}"
602
+
603
+ def __parseList(self):
604
+ """
605
+ Converts the internal raw value to a list, assuming the type hint is 'list:'.
606
+
607
+ This method attempts to strip leading and trailing whitespace from the internal
608
+ raw value and convert it to a Python list using `ast.literal_eval`. If the conversion
609
+ fails due to an invalid format or if the evaluated value is not a list, an
610
+ `OrionisEnvironmentValueException` is raised.
611
+
612
+ Parameters
613
+ ----------
614
+ self : EnvironmentCaster
615
+ The instance of the EnvironmentCaster class.
616
+
617
+ Returns
618
+ -------
619
+ list
620
+ The internal value converted to a list if the type hint is 'list:'.
621
+
622
+ Raises
623
+ ------
624
+ OrionisEnvironmentValueException
625
+ If the value cannot be converted to a list due to invalid format or type.
626
+ """
627
+ import ast
628
+
629
+ # Remove leading and trailing whitespace from the raw value
630
+ value = self.__value_raw.strip()
631
+
632
+ try:
633
+
634
+ # Safely evaluate the string to a Python object
635
+ parsed = ast.literal_eval(value)
636
+
637
+ # Ensure the evaluated object is a list
638
+ if not isinstance(parsed, list):
639
+ raise ValueError("Value is not a list")
640
+
641
+ # Return the parsed list
642
+ return parsed
643
+
644
+ except (ValueError, SyntaxError) as e:
645
+
646
+ # Raise a custom exception if conversion fails
647
+ raise OrionisEnvironmentValueException(f"Cannot convert '{value}' to list: {str(e)}")
648
+
649
+ def __toList(self):
650
+ """
651
+ Converts the internal value to a string representation with the list type hint prefix.
652
+
653
+ This method checks if the internal value is a list. If so, it returns a string
654
+ in the format "<type_hint>:<value>", where <type_hint> is the current type hint
655
+ and <value> is the string representation of the list. If the internal value is not a list,
656
+ an exception is raised.
657
+
658
+ Returns
659
+ -------
660
+ str
661
+ A string combining the type hint and the internal list value, separated by a colon.
662
+ For example, "list:[1, 2, 3]".
663
+
664
+ Raises
665
+ ------
666
+ OrionisEnvironmentValueError
667
+ If the internal value is not a list.
668
+ """
669
+
670
+ # Ensure the internal value is a list before conversion
671
+ if not isinstance(self.__value_raw, list):
672
+ raise OrionisEnvironmentValueError(
673
+ f"Value must be a list to convert to list, got {type(self.__value_raw).__name__} instead."
674
+ )
675
+
676
+ # Return the formatted string with type hint and list value
677
+ return f"{self.__type_hint}:{repr(self.__value_raw)}"
678
+
679
+ def __parseDict(self):
680
+ """
681
+ Converts the internal raw value to a dictionary, assuming the type hint is 'dict:'.
682
+
683
+ This method attempts to strip leading and trailing whitespace from the internal
684
+ raw value and safely evaluate it as a Python dictionary using `ast.literal_eval`.
685
+ If the conversion fails due to an invalid format or if the evaluated value is not
686
+ a dictionary, an `OrionisEnvironmentValueException` is raised.
687
+
688
+ Parameters
689
+ ----------
690
+ self : EnvironmentCaster
691
+ The instance of the EnvironmentCaster class.
692
+
693
+ Returns
694
+ -------
695
+ dict
696
+ The internal value converted to a dictionary if the type hint is 'dict:'.
697
+
698
+ Raises
699
+ ------
700
+ OrionisEnvironmentValueException
701
+ If the value cannot be converted to a dictionary due to invalid format or type.
702
+ """
703
+ import ast
704
+
705
+ # Remove leading and trailing whitespace from the raw value
706
+ value = self.__value_raw.strip()
707
+
708
+ try:
709
+
710
+ # Safely evaluate the string to a Python object
711
+ parsed = ast.literal_eval(value)
712
+
713
+ # Ensure the evaluated object is a dictionary
714
+ if not isinstance(parsed, dict):
715
+ raise ValueError("Value is not a dict")
716
+
717
+ # Return the parsed dictionary
718
+ return parsed
719
+
720
+ except (ValueError, SyntaxError) as e:
721
+
722
+ # Raise a custom exception if conversion fails
723
+ raise OrionisEnvironmentValueException(f"Cannot convert '{value}' to dict: {str(e)}")
724
+
725
+ def __toDict(self):
726
+ """
727
+ Converts the internal value to a string representation with the dictionary type hint prefix.
728
+
729
+ This method checks if the internal value is a dictionary. If so, it returns a string
730
+ in the format "<type_hint>:<value>", where <type_hint> is the current type hint
731
+ and <value> is the string representation of the dictionary. If the internal value is not a dictionary,
732
+ an exception is raised.
733
+
734
+ Returns
735
+ -------
736
+ str
737
+ A string combining the type hint and the internal dictionary value, separated by a colon.
738
+ For example, "dict:{'key': 'value'}".
739
+
740
+ Raises
741
+ ------
742
+ OrionisEnvironmentValueError
743
+ If the internal value is not a dictionary.
744
+ """
745
+
746
+ # Ensure the internal value is a dictionary before conversion
747
+ if not isinstance(self.__value_raw, dict):
748
+ raise OrionisEnvironmentValueError(
749
+ f"Value must be a dict to convert to dict, got {type(self.__value_raw).__name__} instead."
750
+ )
751
+
752
+ # Return the formatted string with type hint and dictionary value
753
+ return f"{self.__type_hint}:{repr(self.__value_raw)}"
754
+
755
+ def __parseTuple(self):
756
+ """
757
+ Converts the internal raw value to a tuple, assuming the type hint is 'tuple:'.
758
+
759
+ This method strips leading and trailing whitespace from the internal raw value,
760
+ then attempts to safely evaluate the string as a Python tuple using `ast.literal_eval`.
761
+ If the conversion is successful and the result is a tuple, it is returned.
762
+ If the conversion fails or the evaluated value is not a tuple, an
763
+ `OrionisEnvironmentValueException` is raised.
764
+
765
+ Parameters
766
+ ----------
767
+ self : EnvironmentCaster
768
+ The instance of the EnvironmentCaster class.
769
+
770
+ Returns
771
+ -------
772
+ tuple
773
+ The internal value converted to a tuple if the type hint is 'tuple:'.
774
+
775
+ Raises
776
+ ------
777
+ OrionisEnvironmentValueException
778
+ If the value cannot be converted to a tuple due to invalid format or type.
779
+ """
780
+ import ast
781
+
782
+ # Remove leading and trailing whitespace from the raw value
783
+ value = self.__value_raw.strip()
784
+
785
+ try:
786
+
787
+ # Safely evaluate the string to a Python object
788
+ parsed = ast.literal_eval(value)
789
+
790
+ # Ensure the evaluated object is a tuple
791
+ if not isinstance(parsed, tuple):
792
+ raise ValueError("Value is not a tuple")
793
+
794
+ # Return the parsed tuple
795
+ return parsed
796
+
797
+ except (ValueError, SyntaxError) as e:
798
+
799
+ # Raise a custom exception if conversion fails
800
+ raise OrionisEnvironmentValueException(f"Cannot convert '{value}' to tuple: {str(e)}")
801
+
802
+ def __toTuple(self):
803
+ """
804
+ Converts the internal value to a string representation with the tuple type hint prefix.
805
+
806
+ This method checks if the internal value is a tuple. If so, it returns a string
807
+ in the format "<type_hint>:<value>", where <type_hint> is the current type hint
808
+ and <value> is the string representation of the tuple. If the internal value is not a tuple,
809
+ an exception is raised.
810
+
811
+ Returns
812
+ -------
813
+ str
814
+ A string combining the type hint and the internal tuple value, separated by a colon.
815
+ For example, "tuple:(1, 2, 3)".
816
+
817
+ Raises
818
+ ------
819
+ OrionisEnvironmentValueError
820
+ If the internal value is not a tuple.
821
+ """
822
+
823
+ # Ensure the internal value is a tuple before conversion
824
+ if not isinstance(self.__value_raw, tuple):
825
+ raise OrionisEnvironmentValueError(
826
+ f"Value must be a tuple to convert to tuple, got {type(self.__value_raw).__name__} instead."
827
+ )
828
+
829
+ # Return the formatted string with type hint and tuple value
830
+ return f"{self.__type_hint}:{repr(self.__value_raw)}"
831
+
832
+ def __parseSet(self):
833
+ """
834
+ Converts the internal raw value to a set, assuming the type hint is 'set:'.
835
+
836
+ This method strips leading and trailing whitespace from the internal raw value,
837
+ then attempts to safely evaluate the string as a Python set using `ast.literal_eval`.
838
+ If the conversion is successful and the result is a set, it is returned.
839
+ If the conversion fails or the evaluated value is not a set, an
840
+ `OrionisEnvironmentValueException` is raised.
841
+
842
+ Returns
843
+ -------
844
+ set
845
+ The internal value converted to a set if the type hint is 'set:'.
846
+
847
+ Raises
848
+ ------
849
+ OrionisEnvironmentValueException
850
+ If the value cannot be converted to a set due to invalid format or type.
851
+ """
852
+ import ast
853
+
854
+ # Remove leading and trailing whitespace from the raw value
855
+ value = self.__value_raw.strip()
856
+
857
+ try:
858
+
859
+ # Safely evaluate the string to a Python object
860
+ parsed = ast.literal_eval(value)
861
+
862
+ # Ensure the evaluated object is a set
863
+ if not isinstance(parsed, set):
864
+ raise ValueError("Value is not a set")
865
+
866
+ # Return the parsed set
867
+ return parsed
868
+
869
+ except (ValueError, SyntaxError) as e:
870
+
871
+ # Raise a custom exception if conversion fails
872
+ raise OrionisEnvironmentValueException(f"Cannot convert '{value}' to set: {str(e)}")
873
+
874
+ def __toSet(self):
875
+ """
876
+ Converts the internal value to a string representation with the set type hint prefix.
877
+
878
+ This method checks if the internal value is a set. If so, it returns a string
879
+ in the format "<type_hint>:<value>", where <type_hint> is the current type hint
880
+ and <value> is the string representation of the set. If the internal value is not a set,
881
+ an exception is raised.
882
+
883
+ Returns
884
+ -------
885
+ str
886
+ A string combining the type hint and the internal set value, separated by a colon.
887
+ For example, "set:{1, 2, 3}".
888
+
889
+ Raises
890
+ ------
891
+ OrionisEnvironmentValueError
892
+ If the internal value is not a set.
893
+ """
894
+
895
+ # Ensure the internal value is a set before conversion
896
+ if not isinstance(self.__value_raw, set):
897
+ raise OrionisEnvironmentValueError(
898
+ f"Value must be a set to convert to set, got {type(self.__value_raw).__name__} instead."
899
+ )
900
+
901
+ # Return the formatted string with type hint and set value
902
+ return f"{self.__type_hint}:{repr(self.__value_raw)}"