IDS peak ICV v1.1.0
Loading...
Searching...
No Matches
archive.py
Go to the documentation of this file.
1from __future__ import annotations
2
3from typing import Any, Dict, List, Type, TypeAlias
4
6from ids_peak_icv.exceptions import NotSupportedException, CorruptedException
7
8
9T: TypeAlias = IArchive.T
10
12 """!
13 @brief
14 A simple key-value store with type checking, similar to a dict.
15
16 Supports only:
17 - bool, int, float, str
18 - IArchive
19 - Lists of the above
20
21 @since ids_peak_icv 1.0
22 @ingroup ids_peak_icv_python_serialization
23 """
24 AllowedValue = IArchive.AllowedValue | IArchive
25
26 def __init__(self, data: Dict[str, Archive.AllowedValue] | None = None) -> None:
27 if data is None:
28 data = {}
29 else:
30 for key, value in data.items():
31 self._validate_value(key, value)
32 self._storage: Dict = data
33
34 def set(self, key: str, value: AllowedValue) -> None:
35 """!
36 @brief
37 Stores a value under the given key.
38
39 @param key: Key to store the value under.
40 @param value: The value to store (restricted types only).
41
42 @since ids_peak_icv 1.0
43 """
44 self._validate_value(key, value)
45 self._storage[key] = value
46
47 def get(self, key: str, datatype: Type[T] | None) -> T:
48 """!
49 @brief
50 Retrieves the value stored under the given key.
51
52 @param key: Key of the value to retrieve.
53 @param datatype: The expected datatype of the value.
54 If None is given, the type check is not executed.
55
56 @exception CorruptedException: If the key is not found or the specified datatype is not the type of the stored value.
57
58 @return The stored value.
59
60 @since ids_peak_icv 1.0
61 """
62
63 if key not in self._storage:
64 raise CorruptedException(f"The specified key '{key}' is not in the archive.")
65
66 value = self._storage[key]
67 if datatype is not type(value) and datatype is not None:
68 raise CorruptedException(f"The value of the specified key '{key}' is not of the expected datatype.")
69
70 return value
71
72 def get_archive(self, key: str) -> IArchive:
73 """!
74 @brief
75 Retrieves the archive stored under the given key.
76
77 @param key: Key of the archive to retrieve.
78
79 @exception CorruptedException: If the key is not found or the specified datatype is not of type archive.
80
81 @return The stored archive.
82
83 @since ids_peak_icv 1.0
84 """
85
86 if key not in self._storage:
87 raise CorruptedException(f"The specified key '{key}' is not in the archive.")
88 value = self._storage[key]
89 if not isinstance(value, IArchive):
90 raise CorruptedException(f"The value of the specified key '{key}' is not of the expected datatype.")
91
92 return value
93
94 def has(self, key: str) -> bool:
95 """!
96 @brief
97 Checks whether a given key exists in the archive.
98
99 @param key: The key to check.
100 @return True if the key exists, False otherwise.
101
102 @since ids_peak_icv 1.0
103 """
104 return key in self._storage
105
106 def keys(self) -> List[str]:
107 """!
108 @brief
109 Returns all keys currently stored in the archive.
110
111 @return List of keys.
112
113 @since ids_peak_icv 1.0
114 """
115 return list(self._storage.keys())
116
117 def create_archive(self) -> IArchive:
118 """!
119 @brief
120 Creates a new, empty archive instance.
121 @since ids_peak_icv 1.0
122 """
123 return Archive()
124
125 def __str__(self) -> str:
126 """!
127 @brief
128 Human-readable string representation of the archive.
129
130 @since ids_peak_icv 1.0
131 """
132 return str(self._storage)
133
134 def __repr__(self) -> str:
135 return f"Archive({str(self)})"
136
137 def __eq__(self, other: Any) -> bool:
138 if not isinstance(other, Archive):
139 return False
140
141 if set(self._storage.keys()) != set(other._storage.keys()):
142 return False
143
144 for key in self._storage:
145 if not self._compare_values(self._storage[key], other._storage[key]):
146 return False
147
148 return True
149
150 def _compare_values(self, lhs: Any, rhs: Any) -> bool:
151 if isinstance(lhs, Archive) and isinstance(rhs, Archive):
152 return bool(lhs == rhs)
153
154 if isinstance(lhs, list) and isinstance(rhs, list):
155 if len(lhs) != len(rhs):
156 return False
157 return all(self._compare_values(val1, val2) for val1, val2 in zip(lhs, rhs))
158
159 return bool(lhs == rhs)
160
161 _ALLOWED_SCALARS = (bool, int, float, str, IArchive)
162
163 def _validate_value(self, key: str, value: Any) -> None:
164 """!
165 @brief
166 Ensures the provided value matches the allowed types.
167
168 @param key: The key for which the value is being validated.
169 @param value: The value to check.
170 @exception NotSupportedException: If the type is not supported.
171 """
172 if isinstance(value, self._ALLOWED_SCALARS):
173 return
174 if isinstance(value, list):
175 if len(value) == 0:
176 return
177
178 first_type = type(value[0])
179 if all(isinstance(v, first_type) for v in value):
180 if issubclass(first_type, self._ALLOWED_SCALARS):
181 return
183 f"Unsupported value type for key '{key}': {type(value).__name__}"
184 )
Simplified interface for a hierarchical key-value archive system.
Definition iarchive.py:7
Thrown when input data or a file is malformed, unreadable, or otherwise corrupted.
Thrown when a requested operation is not implemented or supported.
Definition exceptions.py:71
A simple key-value store with type checking, similar to a dict.
Definition archive.py:11
T get(self, str key, Type[T]|None datatype)
Retrieves the value stored under the given key.
Definition archive.py:47
IArchive create_archive(self)
Creates a new, empty archive instance.
Definition archive.py:117
None __init__(self, Dict[str, Archive.AllowedValue]|None data=None)
Definition archive.py:26
IArchive get_archive(self, str key)
Retrieves the archive stored under the given key.
Definition archive.py:72
List[str] keys(self)
Returns all keys currently stored in the archive.
Definition archive.py:106
None set(self, str key, AllowedValue value)
Stores a value under the given key.
Definition archive.py:34
bool _compare_values(self, Any lhs, Any rhs)
Definition archive.py:150
bool has(self, str key)
Checks whether a given key exists in the archive.
Definition archive.py:94
str __str__(self)
Human-readable string representation of the archive.
Definition archive.py:125
None _validate_value(self, str key, Any value)
Ensures the provided value matches the allowed types.
Definition archive.py:163