orionis 0.409.0__py3-none-any.whl → 0.411.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/support/patterns/singleton/meta.py +68 -18
- orionis/support/wrapper/dot_dict.py +118 -39
- {orionis-0.409.0.dist-info → orionis-0.411.0.dist-info}/METADATA +1 -1
- {orionis-0.409.0.dist-info → orionis-0.411.0.dist-info}/RECORD +27 -27
- tests/services/{inspection → introspection}/dependencies/mocks/mock_user_controller.py +2 -2
- tests/services/{inspection → introspection}/dependencies/test_reflect_dependencies.py +7 -7
- tests/services/{inspection → introspection}/reflection/test_reflection_abstract.py +3 -3
- tests/services/{inspection → introspection}/reflection/test_reflection_concrete.py +5 -5
- tests/services/{inspection → introspection}/reflection/test_reflection_instance.py +4 -4
- tests/services/{inspection → introspection}/reflection/test_reflection_module.py +1 -1
- tests/support/patterns/singleton/test_patterns_singleton.py +22 -9
- tests/support/wrapper/test_services_wrapper_docdict.py +106 -30
- {orionis-0.409.0.dist-info → orionis-0.411.0.dist-info}/WHEEL +0 -0
- {orionis-0.409.0.dist-info → orionis-0.411.0.dist-info}/licenses/LICENCE +0 -0
- {orionis-0.409.0.dist-info → orionis-0.411.0.dist-info}/top_level.txt +0 -0
- {orionis-0.409.0.dist-info → orionis-0.411.0.dist-info}/zip-safe +0 -0
- /tests/services/{inspection → introspection}/__init__.py +0 -0
- /tests/services/{inspection → introspection}/dependencies/__init__.py +0 -0
- /tests/services/{inspection → introspection}/dependencies/mocks/__init__.py +0 -0
- /tests/services/{inspection → introspection}/dependencies/mocks/mock_user.py +0 -0
- /tests/services/{inspection → introspection}/dependencies/mocks/mock_users_permissions.py +0 -0
- /tests/services/{inspection → introspection}/reflection/__init__.py +0 -0
- /tests/services/{inspection → introspection}/reflection/mock/__init__.py +0 -0
- /tests/services/{inspection → introspection}/reflection/mock/fake_reflect_instance.py +0 -0
- /tests/services/{inspection → introspection}/reflection/test_reflection_callable.py +0 -0
- /tests/services/{inspection → introspection}/test_reflection.py +0 -0
orionis/metadata/framework.py
CHANGED
|
@@ -6,8 +6,25 @@ T = TypeVar('T')
|
|
|
6
6
|
|
|
7
7
|
class Singleton(type):
|
|
8
8
|
"""
|
|
9
|
-
Thread-safe
|
|
10
|
-
|
|
9
|
+
Thread-safe and async-safe singleton metaclass.
|
|
10
|
+
|
|
11
|
+
Ensures that only one instance of a class exists, regardless of whether the code is running in a synchronous or asynchronous context. This metaclass provides both a synchronous (`__call__`) and asynchronous (`__acall__`) method for instance creation, using appropriate locking mechanisms to prevent race conditions in multi-threaded or async environments.
|
|
12
|
+
|
|
13
|
+
Attributes
|
|
14
|
+
----------
|
|
15
|
+
_instances : Dict[Type[T], T]
|
|
16
|
+
Stores singleton instances for each class using this metaclass.
|
|
17
|
+
_lock : threading.Lock
|
|
18
|
+
Thread lock for synchronizing instance creation in synchronous contexts.
|
|
19
|
+
_async_lock : asyncio.Lock
|
|
20
|
+
Async lock for synchronizing instance creation in asynchronous contexts.
|
|
21
|
+
|
|
22
|
+
Methods
|
|
23
|
+
-------
|
|
24
|
+
__call__(cls, *args, **kwargs)
|
|
25
|
+
Synchronously creates or retrieves the singleton instance.
|
|
26
|
+
__acall__(cls, *args, **kwargs)
|
|
27
|
+
Asynchronously creates or retrieves the singleton instance.
|
|
11
28
|
"""
|
|
12
29
|
|
|
13
30
|
_instances: Dict[Type[T], T] = {}
|
|
@@ -16,41 +33,74 @@ class Singleton(type):
|
|
|
16
33
|
|
|
17
34
|
def __call__(cls: Type[T], *args: Any, **kwargs: Any) -> T:
|
|
18
35
|
"""
|
|
19
|
-
|
|
36
|
+
Synchronously creates or retrieves a singleton instance of the class.
|
|
20
37
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
38
|
+
This method ensures that only one instance of the class is created, even in multi-threaded environments.
|
|
39
|
+
If the instance does not exist, it acquires a thread lock to prevent race conditions, creates the instance,
|
|
40
|
+
and stores it in the class-level `_instances` dictionary. If the instance already exists, it simply returns
|
|
41
|
+
the existing instance.
|
|
24
42
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
*args : Any
|
|
46
|
+
Positional arguments to pass to the class constructor.
|
|
47
|
+
**kwargs : Any
|
|
48
|
+
Keyword arguments to pass to the class constructor.
|
|
28
49
|
|
|
29
|
-
Returns
|
|
30
|
-
|
|
50
|
+
Returns
|
|
51
|
+
-------
|
|
52
|
+
T
|
|
53
|
+
The singleton instance of the class.
|
|
31
54
|
"""
|
|
55
|
+
|
|
56
|
+
# Check if the instance already exists
|
|
32
57
|
if cls not in cls._instances:
|
|
58
|
+
|
|
59
|
+
# Acquire the thread lock to ensure thread safety
|
|
33
60
|
with cls._lock:
|
|
61
|
+
|
|
62
|
+
# Double-check if the instance was created while waiting for the lock
|
|
34
63
|
if cls not in cls._instances:
|
|
64
|
+
|
|
65
|
+
# Create and store the singleton instance
|
|
35
66
|
cls._instances[cls] = super().__call__(*args, **kwargs)
|
|
67
|
+
|
|
68
|
+
# Return the singleton instance
|
|
36
69
|
return cls._instances[cls]
|
|
37
70
|
|
|
38
71
|
async def __acall__(cls: Type[T], *args: Any, **kwargs: Any) -> T:
|
|
39
72
|
"""
|
|
40
73
|
Asynchronously creates or retrieves a singleton instance of the class.
|
|
41
74
|
|
|
42
|
-
|
|
43
|
-
|
|
75
|
+
This method ensures that only one instance of the class is created, even in asynchronous contexts.
|
|
76
|
+
If the instance does not exist, it acquires an asynchronous lock to prevent race conditions,
|
|
77
|
+
creates the instance, and stores it in the class-level `_instances` dictionary. If the instance
|
|
78
|
+
already exists, it simply returns the existing instance.
|
|
44
79
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
80
|
+
Parameters
|
|
81
|
+
----------
|
|
82
|
+
*args : Any
|
|
83
|
+
Positional arguments to pass to the class constructor.
|
|
84
|
+
**kwargs : Any
|
|
85
|
+
Keyword arguments to pass to the class constructor.
|
|
48
86
|
|
|
49
|
-
Returns
|
|
50
|
-
|
|
87
|
+
Returns
|
|
88
|
+
-------
|
|
89
|
+
T
|
|
90
|
+
The singleton instance of the class.
|
|
51
91
|
"""
|
|
92
|
+
|
|
93
|
+
# Check if the instance already exists
|
|
52
94
|
if cls not in cls._instances:
|
|
95
|
+
|
|
96
|
+
# Acquire the asynchronous lock to ensure async safety
|
|
53
97
|
async with cls._async_lock:
|
|
98
|
+
|
|
99
|
+
# Double-check if the instance was created while waiting for the lock
|
|
54
100
|
if cls not in cls._instances:
|
|
101
|
+
|
|
102
|
+
# Create and store the singleton instance
|
|
55
103
|
cls._instances[cls] = super().__call__(*args, **kwargs)
|
|
104
|
+
|
|
105
|
+
# Return the singleton instance
|
|
56
106
|
return cls._instances[cls]
|
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
from typing import Any, Optional, Dict
|
|
2
2
|
|
|
3
3
|
class DotDict(dict):
|
|
4
|
-
"""
|
|
5
|
-
Dictionary subclass with attribute-style access and recursive dot notation.
|
|
6
|
-
|
|
7
|
-
This class allows accessing dictionary keys as attributes, with automatic
|
|
8
|
-
conversion of nested dictionaries to DotDict instances. Missing keys return
|
|
9
|
-
None instead of raising AttributeError or KeyError.
|
|
10
|
-
"""
|
|
11
4
|
|
|
12
5
|
__slots__ = ()
|
|
13
6
|
|
|
@@ -16,7 +9,7 @@ class DotDict(dict):
|
|
|
16
9
|
Retrieve the value associated with the given key as an attribute.
|
|
17
10
|
|
|
18
11
|
If the value is a dictionary (but not already a DotDict), it is converted
|
|
19
|
-
to a DotDict and updated in-place.
|
|
12
|
+
to a DotDict and updated in-place. If the key does not exist, returns None.
|
|
20
13
|
|
|
21
14
|
Parameters
|
|
22
15
|
----------
|
|
@@ -25,56 +18,92 @@ class DotDict(dict):
|
|
|
25
18
|
|
|
26
19
|
Returns
|
|
27
20
|
-------
|
|
28
|
-
|
|
29
|
-
The value associated with the key
|
|
30
|
-
|
|
21
|
+
Any or None
|
|
22
|
+
The value associated with the key. If the value is a dict, it is converted
|
|
23
|
+
to a DotDict before returning. Returns None if the key is not present.
|
|
24
|
+
|
|
25
|
+
Notes
|
|
26
|
+
-----
|
|
27
|
+
This method allows attribute-style access to dictionary keys. If the value
|
|
28
|
+
is a plain dictionary, it is automatically wrapped as a DotDict for consistency.
|
|
31
29
|
"""
|
|
32
30
|
try:
|
|
33
|
-
value = self[key]
|
|
31
|
+
value = self[key] # Attempt to retrieve the value by key
|
|
32
|
+
# Convert plain dicts to DotDict for attribute access
|
|
34
33
|
if isinstance(value, dict) and not isinstance(value, DotDict):
|
|
35
34
|
value = DotDict(value)
|
|
36
|
-
self[key] = value
|
|
35
|
+
self[key] = value # Update the value in-place
|
|
37
36
|
return value
|
|
38
37
|
except KeyError:
|
|
38
|
+
# Return None if the key does not exist
|
|
39
39
|
return None
|
|
40
40
|
|
|
41
41
|
def __setattr__(self, key: str, value: Any) -> None:
|
|
42
42
|
"""
|
|
43
|
-
|
|
43
|
+
Assign a value to an attribute of the DotDict instance.
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
This method enables attribute-style assignment for dictionary keys. If the
|
|
46
|
+
assigned value is a plain dictionary (not a DotDict), it is automatically
|
|
47
|
+
converted to a DotDict for consistency and recursive attribute access.
|
|
48
48
|
|
|
49
49
|
Parameters
|
|
50
50
|
----------
|
|
51
51
|
key : str
|
|
52
|
-
The attribute name to
|
|
52
|
+
The attribute name to assign.
|
|
53
53
|
value : Any
|
|
54
|
-
The value to assign to the attribute. If it
|
|
55
|
-
converted to a DotDict.
|
|
54
|
+
The value to assign to the attribute. If it is a dict (but not a DotDict),
|
|
55
|
+
it will be converted to a DotDict before assignment.
|
|
56
|
+
|
|
57
|
+
Returns
|
|
58
|
+
-------
|
|
59
|
+
None
|
|
60
|
+
This method does not return a value.
|
|
61
|
+
|
|
62
|
+
Notes
|
|
63
|
+
-----
|
|
64
|
+
The attribute is stored as a key-value pair in the underlying dictionary.
|
|
65
|
+
This allows seamless attribute-style access and assignment for dictionary keys.
|
|
56
66
|
"""
|
|
67
|
+
|
|
68
|
+
# Convert plain dicts to DotDict for recursive attribute access
|
|
57
69
|
if isinstance(value, dict) and not isinstance(value, DotDict):
|
|
58
70
|
value = DotDict(value)
|
|
71
|
+
|
|
72
|
+
# Store the value in the underlying dictionary using the key
|
|
59
73
|
self[key] = value
|
|
60
74
|
|
|
61
75
|
def __delattr__(self, key: str) -> None:
|
|
62
76
|
"""
|
|
63
|
-
|
|
77
|
+
Remove an attribute from the DotDict instance.
|
|
78
|
+
|
|
79
|
+
This method deletes the key-value pair corresponding to the given attribute name
|
|
80
|
+
from the underlying dictionary. If the key does not exist, an AttributeError is raised.
|
|
64
81
|
|
|
65
82
|
Parameters
|
|
66
83
|
----------
|
|
67
84
|
key : str
|
|
68
|
-
The name of the attribute to
|
|
85
|
+
The name of the attribute to remove.
|
|
86
|
+
|
|
87
|
+
Returns
|
|
88
|
+
-------
|
|
89
|
+
None
|
|
90
|
+
This method does not return a value.
|
|
69
91
|
|
|
70
92
|
Raises
|
|
71
93
|
------
|
|
72
94
|
AttributeError
|
|
73
|
-
If the attribute does not exist.
|
|
95
|
+
If the specified attribute does not exist in the DotDict.
|
|
96
|
+
|
|
97
|
+
Notes
|
|
98
|
+
-----
|
|
99
|
+
This method enables attribute-style deletion for dictionary keys, allowing
|
|
100
|
+
seamless removal of items using dot notation.
|
|
74
101
|
"""
|
|
75
102
|
try:
|
|
103
|
+
# Attempt to delete the key from the dictionary
|
|
76
104
|
del self[key]
|
|
77
105
|
except KeyError as e:
|
|
106
|
+
# Raise AttributeError if the key is not present
|
|
78
107
|
raise AttributeError(f"'{self.__class__.__name__}' has no attribute '{key}'") from e
|
|
79
108
|
|
|
80
109
|
def get(self, key: str, default: Optional[Any] = None) -> Optional[Any]:
|
|
@@ -82,7 +111,8 @@ class DotDict(dict):
|
|
|
82
111
|
Retrieve the value associated with the given key, returning a default value if the key is not found.
|
|
83
112
|
|
|
84
113
|
If the retrieved value is a plain dictionary (not a DotDict), it is converted to a DotDict,
|
|
85
|
-
stored back in the dictionary, and then returned.
|
|
114
|
+
stored back in the dictionary, and then returned. This ensures consistent attribute-style access
|
|
115
|
+
for nested dictionaries.
|
|
86
116
|
|
|
87
117
|
Parameters
|
|
88
118
|
----------
|
|
@@ -93,64 +123,113 @@ class DotDict(dict):
|
|
|
93
123
|
|
|
94
124
|
Returns
|
|
95
125
|
-------
|
|
96
|
-
|
|
97
|
-
The value associated with the key, converted to a DotDict if it is a dict
|
|
98
|
-
|
|
126
|
+
Any or None
|
|
127
|
+
The value associated with the key, converted to a DotDict if it is a dict.
|
|
128
|
+
If the key is not present, returns the specified default value.
|
|
129
|
+
|
|
130
|
+
Notes
|
|
131
|
+
-----
|
|
132
|
+
This method overrides the standard dict.get() to provide automatic conversion of nested
|
|
133
|
+
dictionaries to DotDict instances, enabling recursive attribute-style access.
|
|
99
134
|
"""
|
|
135
|
+
# Retrieve the value using the base dict's get method
|
|
100
136
|
value = super().get(key, default)
|
|
137
|
+
# If the value is a plain dict, convert it to DotDict for consistency
|
|
101
138
|
if isinstance(value, dict) and not isinstance(value, DotDict):
|
|
102
139
|
value = DotDict(value)
|
|
103
|
-
self[key] = value
|
|
140
|
+
self[key] = value # Store the converted value back in the dictionary
|
|
104
141
|
return value
|
|
105
142
|
|
|
106
143
|
def export(self) -> Dict[str, Any]:
|
|
107
144
|
"""
|
|
108
|
-
Recursively export the contents of the DotDict as a standard dictionary.
|
|
145
|
+
Recursively export the contents of the DotDict as a standard Python dictionary.
|
|
146
|
+
|
|
147
|
+
This method traverses the DotDict and converts all nested DotDict instances
|
|
148
|
+
into regular dictionaries by recursively calling their `export` method.
|
|
149
|
+
Non-DotDict values are included as-is. This ensures that the returned object
|
|
150
|
+
is composed entirely of built-in Python types, making it suitable for serialization
|
|
151
|
+
or interoperability with code expecting standard dictionaries.
|
|
152
|
+
|
|
153
|
+
Parameters
|
|
154
|
+
----------
|
|
155
|
+
None
|
|
109
156
|
|
|
110
157
|
Returns
|
|
111
158
|
-------
|
|
112
159
|
result : dict
|
|
113
|
-
A dictionary representation of the DotDict, where
|
|
114
|
-
are
|
|
160
|
+
A dictionary representation of the DotDict, where all nested DotDict instances
|
|
161
|
+
are recursively converted to dictionaries. Non-DotDict values are returned unchanged.
|
|
162
|
+
|
|
163
|
+
Notes
|
|
164
|
+
-----
|
|
165
|
+
This method is useful for converting a DotDict (which supports attribute-style access)
|
|
166
|
+
into a plain dictionary for use with APIs, serialization, or other libraries that
|
|
167
|
+
require standard dict objects.
|
|
115
168
|
"""
|
|
116
169
|
result = {}
|
|
170
|
+
# Iterate through all key-value pairs in the DotDict
|
|
117
171
|
for k, v in self.items():
|
|
118
172
|
if isinstance(v, DotDict):
|
|
173
|
+
# Recursively export nested DotDicts
|
|
119
174
|
result[k] = v.export()
|
|
120
175
|
else:
|
|
176
|
+
# Include non-DotDict values as-is
|
|
121
177
|
result[k] = v
|
|
122
178
|
return result
|
|
123
179
|
|
|
124
180
|
def copy(self) -> 'DotDict':
|
|
125
181
|
"""
|
|
126
|
-
Create a deep copy of the DotDict instance.
|
|
182
|
+
Create a deep copy of the DotDict instance, recursively copying all nested DotDict and dict objects.
|
|
183
|
+
|
|
184
|
+
This method traverses the DotDict and ensures that all nested DotDict and dict instances are
|
|
185
|
+
copied recursively, so that the returned DotDict is fully independent of the original. Non-dict
|
|
186
|
+
values are copied by reference.
|
|
127
187
|
|
|
128
188
|
Returns
|
|
129
189
|
-------
|
|
130
|
-
|
|
131
|
-
A new DotDict
|
|
132
|
-
|
|
190
|
+
DotDict
|
|
191
|
+
A new DotDict instance containing a deep copy of the original contents. All nested DotDict
|
|
192
|
+
and dict objects are recursively copied, ensuring no shared references with the original.
|
|
193
|
+
|
|
194
|
+
Notes
|
|
195
|
+
-----
|
|
196
|
+
This method is useful when you need a completely independent copy of a DotDict, including all
|
|
197
|
+
nested structures, to avoid unintended side effects from shared references.
|
|
133
198
|
"""
|
|
134
199
|
copied = {}
|
|
200
|
+
# Iterate through all key-value pairs in the DotDict
|
|
135
201
|
for k, v in self.items():
|
|
136
202
|
if isinstance(v, DotDict):
|
|
203
|
+
# Recursively copy nested DotDict instances
|
|
137
204
|
copied[k] = v.copy()
|
|
138
205
|
elif isinstance(v, dict):
|
|
206
|
+
# Convert plain dicts to DotDict and recursively copy
|
|
139
207
|
copied[k] = DotDict(v).copy()
|
|
140
208
|
else:
|
|
209
|
+
# Copy non-dict values by reference
|
|
141
210
|
copied[k] = v
|
|
211
|
+
# Return a new DotDict containing the copied data
|
|
142
212
|
return DotDict(copied)
|
|
143
213
|
|
|
144
214
|
def __repr__(self) -> str:
|
|
145
215
|
"""
|
|
146
216
|
Return a string representation of the DotDict instance.
|
|
147
217
|
|
|
148
|
-
This method overrides the default __repr__ implementation to provide a
|
|
149
|
-
string that
|
|
218
|
+
This method overrides the default `__repr__` implementation to provide a concise
|
|
219
|
+
and informative string that displays the class name (`DotDict`) and the contents
|
|
220
|
+
of the underlying dictionary. This is useful for debugging and logging, as it
|
|
221
|
+
clearly distinguishes DotDict objects from regular dictionaries.
|
|
150
222
|
|
|
151
223
|
Returns
|
|
152
224
|
-------
|
|
153
|
-
|
|
154
|
-
A string representation of the DotDict object
|
|
225
|
+
str
|
|
226
|
+
A string representation of the DotDict object, formatted as
|
|
227
|
+
'DotDict({...})', where {...} is the dictionary content.
|
|
228
|
+
|
|
229
|
+
Notes
|
|
230
|
+
-----
|
|
231
|
+
The returned string uses the base dictionary's representation, but is prefixed
|
|
232
|
+
with the DotDict class name for clarity.
|
|
155
233
|
"""
|
|
234
|
+
# Use the base dict's __repr__ for the contents, but keep DotDict class name
|
|
156
235
|
return super().__repr__()
|
|
@@ -258,7 +258,7 @@ orionis/foundation/providers/progress_bar_provider.py,sha256=WW3grNgH-yV2meSSTeO
|
|
|
258
258
|
orionis/foundation/providers/testing_provider.py,sha256=iJSN2RIChbYIL-1ue6vmPmDMCSrvERDkti4Er9MPiLA,1102
|
|
259
259
|
orionis/foundation/providers/workers_provider.py,sha256=kiQjQRyUEyiBX2zcbF_KmqRgvc7Bvxsvg5oMtIvYniM,1075
|
|
260
260
|
orionis/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
261
|
-
orionis/metadata/framework.py,sha256=
|
|
261
|
+
orionis/metadata/framework.py,sha256=wQLkWeq7vpfowJoSfUdTQO9y5ZNFQ0NyuElKBvZM5y4,4960
|
|
262
262
|
orionis/metadata/package.py,sha256=tqLfBRo-w1j_GN4xvzUNFyweWYFS-qhSgAEc-AmCH1M,5452
|
|
263
263
|
orionis/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
264
264
|
orionis/services/asynchrony/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -371,7 +371,7 @@ orionis/support/formatter/exceptions/contracts/__init__.py,sha256=47DEQpj8HBSa-_
|
|
|
371
371
|
orionis/support/formatter/exceptions/contracts/parser.py,sha256=HcWN7nJrvD7xLREPKEnBhyG30IkkAB7Bx_hGpcfb0ZE,912
|
|
372
372
|
orionis/support/patterns/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
373
373
|
orionis/support/patterns/singleton/__init__.py,sha256=BIyMYL5yXpzv_F-jsSEtoKYseGlM8jdJT8hwGuXZZl8,62
|
|
374
|
-
orionis/support/patterns/singleton/meta.py,sha256=
|
|
374
|
+
orionis/support/patterns/singleton/meta.py,sha256=Flq6UNaBPJqx8gZv7m6lEAbgorPjkbEWH4LVRKt-Vs8,4114
|
|
375
375
|
orionis/support/standard/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
376
376
|
orionis/support/standard/std.py,sha256=afe3m7XzzzbFa89RhPVN11LKcgkL3afQHNXHhH3GwjQ,3679
|
|
377
377
|
orionis/support/standard/contracts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -379,7 +379,7 @@ orionis/support/standard/contracts/std.py,sha256=w4F0fIHIOhCPPiBgTLIIWR9EFdjeTjL
|
|
|
379
379
|
orionis/support/standard/exceptions/__init__.py,sha256=MPwL4i8GSUtLJ82wQ_SlcdgtnIBRk3_CR7JbDhxHf20,93
|
|
380
380
|
orionis/support/standard/exceptions/value.py,sha256=7xry_TZz3k-BLAZTR_uDiQ0RfXOkSBOnBzp9kKUl5xE,471
|
|
381
381
|
orionis/support/wrapper/__init__.py,sha256=jGoWoIGYuRYqMYQKlrX7Dpcbg-AGkHoB_aM2xhu73yc,62
|
|
382
|
-
orionis/support/wrapper/dot_dict.py,sha256=
|
|
382
|
+
orionis/support/wrapper/dot_dict.py,sha256=L4J_3id0EHXyjv5FCofXK0ONC2WOoAXZSwX1csitf5E,9299
|
|
383
383
|
orionis/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
384
384
|
orionis/test/kernel.py,sha256=i1VlWl4ZqfGxpc1-JiV3RS0rTrfOMqZJAde1GADK00c,5500
|
|
385
385
|
orionis/test/cases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -428,7 +428,7 @@ orionis/test/validators/web_report.py,sha256=-h3Fe9jY93_kzUhd2NBIqEfCcBpu-8Ei9x3
|
|
|
428
428
|
orionis/test/validators/workers.py,sha256=LGffDKtK6SKixFKzIYPQpI5aFeQPAGXpv_LUtmEu6g4,1102
|
|
429
429
|
orionis/test/view/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
430
430
|
orionis/test/view/render.py,sha256=3ICz68l-WF3BtnYqH5m-ktN9UD00MELMbmMnyJDV74A,4768
|
|
431
|
-
orionis-0.
|
|
431
|
+
orionis-0.411.0.dist-info/licenses/LICENCE,sha256=-_4cF2EBKuYVS_SQpy1uapq0oJPUU1vl_RUWSy2jJTo,1111
|
|
432
432
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
433
433
|
tests/container/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
434
434
|
tests/container/test_container.py,sha256=asv8TkkupVoex6SWod74NBl4dSs7wb9mLmu_glNdNy8,14815
|
|
@@ -523,22 +523,22 @@ tests/services/asynchrony/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
|
523
523
|
tests/services/asynchrony/test_services_asynchrony_coroutine.py,sha256=34Y0D6w2bVo_dm3oj0wzedMIJuSYieUG9Y2J1EQmZeo,3439
|
|
524
524
|
tests/services/environment/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
525
525
|
tests/services/environment/test_services_environment.py,sha256=6UH3g2Z2DQYtGnyySCRnT35VCENlL-PQWHIdH6zA9rw,3767
|
|
526
|
-
tests/services/
|
|
527
|
-
tests/services/
|
|
528
|
-
tests/services/
|
|
529
|
-
tests/services/
|
|
530
|
-
tests/services/
|
|
531
|
-
tests/services/
|
|
532
|
-
tests/services/
|
|
533
|
-
tests/services/
|
|
534
|
-
tests/services/
|
|
535
|
-
tests/services/
|
|
536
|
-
tests/services/
|
|
537
|
-
tests/services/
|
|
538
|
-
tests/services/
|
|
539
|
-
tests/services/
|
|
540
|
-
tests/services/
|
|
541
|
-
tests/services/
|
|
526
|
+
tests/services/introspection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
527
|
+
tests/services/introspection/test_reflection.py,sha256=AaBi0zi7GphOqnagV8N48GZHUuoT7743Pw3oc6_As6I,13700
|
|
528
|
+
tests/services/introspection/dependencies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
529
|
+
tests/services/introspection/dependencies/test_reflect_dependencies.py,sha256=8Tuz76-RUPQuUPzx0aUALiXwbmEr2q7RrMp_wV2SQw0,7361
|
|
530
|
+
tests/services/introspection/dependencies/mocks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
531
|
+
tests/services/introspection/dependencies/mocks/mock_user.py,sha256=RxATxe0-Vm4HfX5jKz9Tny42E2fmrdtEN6ZEntbqRL8,912
|
|
532
|
+
tests/services/introspection/dependencies/mocks/mock_user_controller.py,sha256=Hu4Xys5HENpKaLqsEAjtp_C-M9y6ozmJ_-qmj3ZvK6c,1214
|
|
533
|
+
tests/services/introspection/dependencies/mocks/mock_users_permissions.py,sha256=oENXbS2qmQUudYSmnhB8fgHBqXZdbplplB-Y2nbx4hw,1388
|
|
534
|
+
tests/services/introspection/reflection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
535
|
+
tests/services/introspection/reflection/test_reflection_abstract.py,sha256=V2d_N-dyXrFL1h1FvOpyVMse5Mw_qvnd_yUWYVkIG10,27417
|
|
536
|
+
tests/services/introspection/reflection/test_reflection_callable.py,sha256=lc0tnFMkBqyF5BtaGEtsMzSB3K0rfX4jDSc-rzmtN7o,6846
|
|
537
|
+
tests/services/introspection/reflection/test_reflection_concrete.py,sha256=nG9FBwvd7_E6skZBPRT19lifjKfBSCRx-Sc16ZtZnOI,44650
|
|
538
|
+
tests/services/introspection/reflection/test_reflection_instance.py,sha256=k4V190KLob-rBILK7S6zU5VktqW1IOTNSYZNXNxF4p4,46306
|
|
539
|
+
tests/services/introspection/reflection/test_reflection_module.py,sha256=BmKWDu7JOgq-Jwb1eVbqZjt6GHN3nW0a4NKJDvJvLSM,19768
|
|
540
|
+
tests/services/introspection/reflection/mock/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
541
|
+
tests/services/introspection/reflection/mock/fake_reflect_instance.py,sha256=iqWoT6tNym3OijK0wcF0iKMp3HTlq5kAoztzC4fdTlM,18595
|
|
542
542
|
tests/services/log/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
543
543
|
tests/services/log/test_log.py,sha256=fCI2gX9-YN1z-xPMwIlggUFHeBlqfUajQoyQu4dmao0,2868
|
|
544
544
|
tests/services/path/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -553,16 +553,16 @@ tests/support/parsers/mocks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMp
|
|
|
553
553
|
tests/support/parsers/mocks/mock_custom_error.py,sha256=LWgjeog2rpmfw6j7Bgzvfvmeby8uSBuB1B3d_DgRcFQ,752
|
|
554
554
|
tests/support/patterns/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
555
555
|
tests/support/patterns/singleton/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
556
|
-
tests/support/patterns/singleton/test_patterns_singleton.py,sha256=
|
|
556
|
+
tests/support/patterns/singleton/test_patterns_singleton.py,sha256=L7Q2QEBwSdG_JGfSB4s4AKqxsV4cXeKR1d8V7MbyzFY,1461
|
|
557
557
|
tests/support/standard/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
558
558
|
tests/support/standard/test_services_std.py,sha256=U0hNF50YE4aLE3Z9yWB2awl9owFQRIV8ptSN7G3xZSk,5517
|
|
559
559
|
tests/support/wrapper/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
560
|
-
tests/support/wrapper/test_services_wrapper_docdict.py,sha256=
|
|
560
|
+
tests/support/wrapper/test_services_wrapper_docdict.py,sha256=Q_qyqZodLiTQ6Pv9zILfIoZj6l-WPzNWuIoRf1GTGY0,7535
|
|
561
561
|
tests/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
562
562
|
tests/testing/test_testing_result.py,sha256=aWOOJiHji_U7gcJHbDukgMmfBEEQCLQdyqpXJD5q4BE,4643
|
|
563
563
|
tests/testing/test_testing_unit.py,sha256=Krz0Bw1toI9qvLtKtYe_slNvi7fYmZbHK1i4DRPMfUM,7952
|
|
564
|
-
orionis-0.
|
|
565
|
-
orionis-0.
|
|
566
|
-
orionis-0.
|
|
567
|
-
orionis-0.
|
|
568
|
-
orionis-0.
|
|
564
|
+
orionis-0.411.0.dist-info/METADATA,sha256=81oCjYi2PnQnkDud4fwUp7UPJu8X5Q2VlFNuBTKMYLA,4772
|
|
565
|
+
orionis-0.411.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
566
|
+
orionis-0.411.0.dist-info/top_level.txt,sha256=2bdoHgyGZhOtLAXS6Om8OCTmL24dUMC_L1quMe_ETbk,14
|
|
567
|
+
orionis-0.411.0.dist-info/zip-safe,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
568
|
+
orionis-0.411.0.dist-info/RECORD,,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
from tests.services.
|
|
2
|
-
from tests.services.
|
|
1
|
+
from tests.services.introspection.dependencies.mocks.mock_user import FakeUser
|
|
2
|
+
from tests.services.introspection.dependencies.mocks.mock_users_permissions import FakeUserWithPermissions
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class UserController:
|
|
@@ -7,9 +7,9 @@ from orionis.services.introspection.dependencies.reflection import (
|
|
|
7
7
|
KnownDependency
|
|
8
8
|
)
|
|
9
9
|
from orionis.test.cases.asynchronous import AsyncTestCase
|
|
10
|
-
from tests.services.
|
|
11
|
-
from tests.services.
|
|
12
|
-
from tests.services.
|
|
10
|
+
from tests.services.introspection.dependencies.mocks.mock_user import FakeUser
|
|
11
|
+
from tests.services.introspection.dependencies.mocks.mock_user_controller import UserController
|
|
12
|
+
from tests.services.introspection.dependencies.mocks.mock_users_permissions import FakeUserWithPermissions
|
|
13
13
|
|
|
14
14
|
class TestReflectDependencies(AsyncTestCase):
|
|
15
15
|
"""
|
|
@@ -48,9 +48,9 @@ class TestReflectDependencies(AsyncTestCase):
|
|
|
48
48
|
|
|
49
49
|
# Check resolved dependencies for 'user_repository'
|
|
50
50
|
dependencies:KnownDependency = dep_user_repository
|
|
51
|
-
self.assertEqual(dependencies.module_name, 'tests.services.
|
|
51
|
+
self.assertEqual(dependencies.module_name, 'tests.services.introspection.dependencies.mocks.mock_user')
|
|
52
52
|
self.assertEqual(dependencies.class_name, 'FakeUser')
|
|
53
|
-
self.assertEqual(dependencies.full_class_path, 'tests.services.
|
|
53
|
+
self.assertEqual(dependencies.full_class_path, 'tests.services.introspection.dependencies.mocks.mock_user.FakeUser')
|
|
54
54
|
self.assertEqual(dependencies.type, FakeUser)
|
|
55
55
|
|
|
56
56
|
async def testReflectionDependenciesGetMethodDependencies(self):
|
|
@@ -80,9 +80,9 @@ class TestReflectDependencies(AsyncTestCase):
|
|
|
80
80
|
self.assertIsInstance(dep_user_permissions, KnownDependency)
|
|
81
81
|
|
|
82
82
|
# Check resolved dependencies for 'user_permissions'
|
|
83
|
-
self.assertEqual(dep_user_permissions.module_name, 'tests.services.
|
|
83
|
+
self.assertEqual(dep_user_permissions.module_name, 'tests.services.introspection.dependencies.mocks.mock_users_permissions')
|
|
84
84
|
self.assertEqual(dep_user_permissions.class_name, 'FakeUserWithPermissions')
|
|
85
|
-
self.assertEqual(dep_user_permissions.full_class_path, 'tests.services.
|
|
85
|
+
self.assertEqual(dep_user_permissions.full_class_path, 'tests.services.introspection.dependencies.mocks.mock_users_permissions.FakeUserWithPermissions')
|
|
86
86
|
self.assertEqual(dep_user_permissions.type, FakeUserWithPermissions)
|
|
87
87
|
|
|
88
88
|
# Check Instance of KnownDependency for 'permissions'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from orionis.services.introspection.abstract.reflection import ReflectionAbstract
|
|
2
2
|
from orionis.services.introspection.dependencies.entities.class_dependencies import ClassDependency
|
|
3
|
-
from tests.services.
|
|
3
|
+
from tests.services.introspection.reflection.mock.fake_reflect_instance import AbstractFakeClass
|
|
4
4
|
from orionis.test.cases.asynchronous import AsyncTestCase
|
|
5
5
|
|
|
6
6
|
class TestServiceReflectionAbstract(AsyncTestCase):
|
|
@@ -27,7 +27,7 @@ class TestServiceReflectionAbstract(AsyncTestCase):
|
|
|
27
27
|
"""
|
|
28
28
|
reflect = ReflectionAbstract(AbstractFakeClass)
|
|
29
29
|
module_name = reflect.getModuleName()
|
|
30
|
-
self.assertEqual(module_name, 'tests.services.
|
|
30
|
+
self.assertEqual(module_name, 'tests.services.introspection.reflection.mock.fake_reflect_instance')
|
|
31
31
|
|
|
32
32
|
async def testGetModuleWithClassName(self):
|
|
33
33
|
"""
|
|
@@ -35,7 +35,7 @@ class TestServiceReflectionAbstract(AsyncTestCase):
|
|
|
35
35
|
"""
|
|
36
36
|
reflect = ReflectionAbstract(AbstractFakeClass)
|
|
37
37
|
module_with_class_name = reflect.getModuleWithClassName()
|
|
38
|
-
self.assertEqual(module_with_class_name, 'tests.services.
|
|
38
|
+
self.assertEqual(module_with_class_name, 'tests.services.introspection.reflection.mock.fake_reflect_instance.AbstractFakeClass')
|
|
39
39
|
|
|
40
40
|
async def testGetDocstring(self):
|
|
41
41
|
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from orionis.services.introspection.concretes.reflection import ReflectionConcrete
|
|
2
2
|
from orionis.services.introspection.dependencies.entities.class_dependencies import ClassDependency
|
|
3
|
-
from tests.services.
|
|
3
|
+
from tests.services.introspection.reflection.mock.fake_reflect_instance import FakeClass
|
|
4
4
|
from orionis.test.cases.asynchronous import AsyncTestCase
|
|
5
5
|
|
|
6
6
|
class TestServiceReflectionConcrete(AsyncTestCase):
|
|
@@ -44,11 +44,11 @@ class TestServiceReflectionConcrete(AsyncTestCase):
|
|
|
44
44
|
"""
|
|
45
45
|
Tests that the getModuleName method of the ReflectionConcrete class returns the correct module name
|
|
46
46
|
for the provided FakeClass. Asserts that the returned module name matches the expected string
|
|
47
|
-
'tests.services.
|
|
47
|
+
'tests.services.introspection.reflection.mock.fake_reflect_instance'.
|
|
48
48
|
"""
|
|
49
49
|
reflect = ReflectionConcrete(FakeClass)
|
|
50
50
|
module_name = reflect.getModuleName()
|
|
51
|
-
self.assertEqual(module_name, 'tests.services.
|
|
51
|
+
self.assertEqual(module_name, 'tests.services.introspection.reflection.mock.fake_reflect_instance')
|
|
52
52
|
|
|
53
53
|
async def testGetModuleWithClassName(self):
|
|
54
54
|
"""
|
|
@@ -57,11 +57,11 @@ class TestServiceReflectionConcrete(AsyncTestCase):
|
|
|
57
57
|
|
|
58
58
|
Asserts:
|
|
59
59
|
The returned string matches the expected module path and class name:
|
|
60
|
-
'tests.services.
|
|
60
|
+
'tests.services.introspection.reflection.mock.fake_reflect_instance.FakeClass'
|
|
61
61
|
"""
|
|
62
62
|
reflect = ReflectionConcrete(FakeClass)
|
|
63
63
|
module_with_class_name = reflect.getModuleWithClassName()
|
|
64
|
-
self.assertEqual(module_with_class_name, 'tests.services.
|
|
64
|
+
self.assertEqual(module_with_class_name, 'tests.services.introspection.reflection.mock.fake_reflect_instance.FakeClass')
|
|
65
65
|
|
|
66
66
|
async def testGetDocstring(self):
|
|
67
67
|
"""
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from orionis.services.introspection.dependencies.entities.class_dependencies import ClassDependency
|
|
2
|
-
from tests.services.
|
|
2
|
+
from tests.services.introspection.reflection.mock.fake_reflect_instance import FakeClass
|
|
3
3
|
from orionis.services.introspection.instances.reflection import ReflectionInstance
|
|
4
4
|
from orionis.test.cases.asynchronous import AsyncTestCase
|
|
5
5
|
|
|
@@ -43,11 +43,11 @@ class TestServiceReflectionInstance(AsyncTestCase):
|
|
|
43
43
|
|
|
44
44
|
Asserts:
|
|
45
45
|
The returned module name matches the expected string
|
|
46
|
-
'tests.services.
|
|
46
|
+
'tests.services.introspection.reflection.mock.fake_reflect_instance'.
|
|
47
47
|
"""
|
|
48
48
|
reflect = ReflectionInstance(FakeClass())
|
|
49
49
|
module_name = reflect.getModuleName()
|
|
50
|
-
self.assertEqual(module_name, 'tests.services.
|
|
50
|
+
self.assertEqual(module_name, 'tests.services.introspection.reflection.mock.fake_reflect_instance')
|
|
51
51
|
|
|
52
52
|
async def testGetModuleWithClassName(self):
|
|
53
53
|
"""
|
|
@@ -59,7 +59,7 @@ class TestServiceReflectionInstance(AsyncTestCase):
|
|
|
59
59
|
"""
|
|
60
60
|
reflect = ReflectionInstance(FakeClass())
|
|
61
61
|
module_with_class_name = reflect.getModuleWithClassName()
|
|
62
|
-
self.assertEqual(module_with_class_name, 'tests.services.
|
|
62
|
+
self.assertEqual(module_with_class_name, 'tests.services.introspection.reflection.mock.fake_reflect_instance.FakeClass')
|
|
63
63
|
|
|
64
64
|
async def testGetDocstring(self):
|
|
65
65
|
"""
|
|
@@ -4,7 +4,7 @@ from orionis.services.introspection.exceptions import ReflectionTypeError, Refle
|
|
|
4
4
|
|
|
5
5
|
class TestServiceReflectionModule(AsyncTestCase):
|
|
6
6
|
|
|
7
|
-
module_name = 'tests.services.
|
|
7
|
+
module_name = 'tests.services.introspection.reflection.mock.fake_reflect_instance'
|
|
8
8
|
|
|
9
9
|
async def testGetModule(self):
|
|
10
10
|
"""
|
|
@@ -2,26 +2,39 @@ from orionis.support.patterns.singleton import Singleton
|
|
|
2
2
|
from orionis.test.cases.asynchronous import AsyncTestCase
|
|
3
3
|
|
|
4
4
|
class TestPatternsSingleton(AsyncTestCase):
|
|
5
|
-
"""
|
|
6
|
-
Test cases for the Singleton metaclass.
|
|
7
|
-
|
|
8
|
-
This class contains asynchronous test methods to verify the correct behavior
|
|
9
|
-
of the Singleton metaclass, ensuring that only one instance of a class is created.
|
|
10
|
-
"""
|
|
11
5
|
|
|
12
6
|
async def testSingleton(self):
|
|
13
7
|
"""
|
|
14
|
-
|
|
8
|
+
Tests the behavior of the Singleton metaclass.
|
|
9
|
+
|
|
10
|
+
Validates that a class using the Singleton metaclass only ever creates a single instance,
|
|
11
|
+
regardless of how many times it is instantiated. Also checks that the initial state of the
|
|
12
|
+
singleton instance remains unchanged after subsequent instantiations.
|
|
13
|
+
|
|
14
|
+
Parameters
|
|
15
|
+
----------
|
|
16
|
+
self : TestPatternsSingleton
|
|
17
|
+
The test case instance.
|
|
18
|
+
|
|
19
|
+
Returns
|
|
20
|
+
-------
|
|
21
|
+
None
|
|
22
|
+
This method does not return any value. Assertions are used to verify singleton behavior.
|
|
15
23
|
|
|
16
|
-
Ensures that only one instance of a class using the Singleton metaclass is created,
|
|
17
|
-
regardless of how many times the class is instantiated.
|
|
18
24
|
"""
|
|
25
|
+
# Define a class using the Singleton metaclass
|
|
19
26
|
class SingletonClass(metaclass=Singleton):
|
|
20
27
|
def __init__(self, value):
|
|
21
28
|
self.value = value
|
|
22
29
|
|
|
30
|
+
# Create the first instance of SingletonClass
|
|
23
31
|
instance1 = SingletonClass(1)
|
|
32
|
+
|
|
33
|
+
# Attempt to create a second instance with a different value
|
|
24
34
|
instance2 = SingletonClass(2)
|
|
25
35
|
|
|
36
|
+
# Assert that both instances are actually the same object
|
|
26
37
|
self.assertIs(instance1, instance2)
|
|
38
|
+
|
|
39
|
+
# Assert that the value remains as set by the first instantiation
|
|
27
40
|
self.assertEqual(instance1.value, 1)
|
|
@@ -2,77 +2,123 @@ from orionis.support.wrapper import DotDict
|
|
|
2
2
|
from orionis.test.cases.asynchronous import AsyncTestCase
|
|
3
3
|
|
|
4
4
|
class TestSupportWrapperDocDict(AsyncTestCase):
|
|
5
|
-
"""
|
|
6
|
-
Test cases for the DotDict class which provides dictionary with dot notation access.
|
|
7
|
-
|
|
8
|
-
Notes
|
|
9
|
-
-----
|
|
10
|
-
These tests cover dot notation access, assignment, deletion, and utility methods
|
|
11
|
-
for the DotDict class, ensuring correct behavior and compatibility with nested
|
|
12
|
-
dictionaries.
|
|
13
|
-
"""
|
|
14
5
|
|
|
15
6
|
async def testDotNotationAccess(self):
|
|
16
7
|
"""
|
|
17
|
-
|
|
8
|
+
Tests dot notation access for dictionary values.
|
|
9
|
+
|
|
10
|
+
This method verifies that values in a DotDict instance can be accessed using dot notation.
|
|
11
|
+
It checks that existing keys return their corresponding values, nested dictionaries are
|
|
12
|
+
accessible via chained dot notation, and accessing a non-existent key returns None.
|
|
18
13
|
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
Returns
|
|
15
|
+
-------
|
|
16
|
+
None
|
|
17
|
+
This is a test method and does not return a value.
|
|
21
18
|
"""
|
|
19
|
+
|
|
20
|
+
# Create a DotDict instance with initial values
|
|
22
21
|
dd = DotDict({'key1': 'value1', 'nested': {'inner': 42}})
|
|
22
|
+
|
|
23
|
+
# Access existing key using dot notation
|
|
23
24
|
self.assertEqual(dd.key1, 'value1')
|
|
25
|
+
|
|
26
|
+
# Access nested dictionary value using chained dot notation
|
|
24
27
|
self.assertEqual(dd.nested.inner, 42)
|
|
28
|
+
|
|
29
|
+
# Access non-existent key, should return None
|
|
25
30
|
self.assertIsNone(dd.non_existent)
|
|
26
31
|
|
|
27
32
|
async def testDotNotationAssignment(self):
|
|
28
33
|
"""
|
|
29
|
-
|
|
34
|
+
Tests assignment of dictionary values using dot notation.
|
|
35
|
+
|
|
36
|
+
This method verifies that new keys can be added and existing keys can be updated
|
|
37
|
+
using dot notation. It also checks that nested dictionaries assigned via dot notation
|
|
38
|
+
are automatically converted to DotDict instances.
|
|
30
39
|
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
None
|
|
43
|
+
This is a test method and does not return a value.
|
|
33
44
|
"""
|
|
45
|
+
|
|
46
|
+
# Create a DotDict instance and assign values using dot notation
|
|
34
47
|
dd = DotDict()
|
|
48
|
+
|
|
49
|
+
# Assign new key using dot notation
|
|
35
50
|
dd.key1 = 'value1'
|
|
51
|
+
|
|
52
|
+
# Assign nested dictionary, should convert to DotDict
|
|
36
53
|
dd.nested = {'inner': 42}
|
|
37
54
|
|
|
55
|
+
# Verify the assignments
|
|
38
56
|
self.assertEqual(dd['key1'], 'value1')
|
|
39
57
|
self.assertIsInstance(dd.nested, DotDict)
|
|
40
58
|
self.assertEqual(dd.nested.inner, 42)
|
|
41
59
|
|
|
42
60
|
async def testDotNotationDeletion(self):
|
|
43
61
|
"""
|
|
44
|
-
|
|
62
|
+
Tests deletion of dictionary keys using dot notation.
|
|
45
63
|
|
|
46
|
-
|
|
47
|
-
|
|
64
|
+
This method verifies that existing keys can be deleted using dot notation.
|
|
65
|
+
It also checks that attempting to delete a non-existent key raises an AttributeError.
|
|
66
|
+
|
|
67
|
+
Returns
|
|
68
|
+
-------
|
|
69
|
+
None
|
|
70
|
+
This is a test method and does not return a value.
|
|
48
71
|
"""
|
|
72
|
+
|
|
73
|
+
# Create a DotDict instance and delete an existing key
|
|
49
74
|
dd = DotDict({'key1': 'value1', 'key2': 'value2'})
|
|
75
|
+
|
|
76
|
+
# Delete existing key using dot notation
|
|
50
77
|
del dd.key1
|
|
51
78
|
self.assertNotIn('key1', dd)
|
|
52
79
|
|
|
80
|
+
# Attempt to delete non-existent key, should raise AttributeError
|
|
53
81
|
with self.assertRaises(AttributeError):
|
|
54
82
|
del dd.non_existent
|
|
55
83
|
|
|
56
84
|
async def testGetMethod(self):
|
|
57
85
|
"""
|
|
58
|
-
|
|
86
|
+
Tests the `get` method with automatic DotDict conversion.
|
|
59
87
|
|
|
60
|
-
|
|
61
|
-
and converts nested dictionaries to
|
|
88
|
+
This method verifies that the `get` method returns the correct value for a given key,
|
|
89
|
+
returns the provided default for missing keys, and converts nested dictionaries to
|
|
90
|
+
DotDict instances when accessed.
|
|
91
|
+
|
|
92
|
+
Returns
|
|
93
|
+
-------
|
|
94
|
+
None
|
|
95
|
+
This is a test method and does not return a value.
|
|
62
96
|
"""
|
|
97
|
+
|
|
98
|
+
# Create a DotDict instance and test the `get` method
|
|
63
99
|
dd = DotDict({'key1': 'value1', 'nested': {'inner': 42}})
|
|
64
100
|
|
|
65
101
|
self.assertEqual(dd.get('key1'), 'value1')
|
|
66
102
|
self.assertEqual(dd.get('non_existent', 'default'), 'default')
|
|
103
|
+
|
|
104
|
+
# Nested dictionary should be returned as DotDict
|
|
67
105
|
self.assertIsInstance(dd.get('nested'), DotDict)
|
|
68
106
|
self.assertEqual(dd.get('nested').inner, 42)
|
|
69
107
|
|
|
70
108
|
async def testExportMethod(self):
|
|
71
109
|
"""
|
|
72
|
-
|
|
110
|
+
Tests the `export` method for recursive conversion to regular dict.
|
|
73
111
|
|
|
74
|
-
|
|
112
|
+
This method verifies that calling `export` on a DotDict instance recursively converts
|
|
113
|
+
all nested DotDict objects back to regular Python dictionaries.
|
|
114
|
+
|
|
115
|
+
Returns
|
|
116
|
+
-------
|
|
117
|
+
None
|
|
118
|
+
This is a test method and does not return a value.
|
|
75
119
|
"""
|
|
120
|
+
|
|
121
|
+
# Create a DotDict instance and export it
|
|
76
122
|
dd = DotDict({
|
|
77
123
|
'key1': 'value1',
|
|
78
124
|
'nested': DotDict({
|
|
@@ -82,6 +128,8 @@ class TestSupportWrapperDocDict(AsyncTestCase):
|
|
|
82
128
|
})
|
|
83
129
|
|
|
84
130
|
exported = dd.export()
|
|
131
|
+
|
|
132
|
+
# Top-level and nested DotDicts should be converted to dicts
|
|
85
133
|
self.assertIsInstance(exported, dict)
|
|
86
134
|
self.assertIsInstance(exported['nested'], dict)
|
|
87
135
|
self.assertIsInstance(exported['nested']['deep'], dict)
|
|
@@ -89,19 +137,32 @@ class TestSupportWrapperDocDict(AsyncTestCase):
|
|
|
89
137
|
|
|
90
138
|
async def testCopyMethod(self):
|
|
91
139
|
"""
|
|
92
|
-
|
|
140
|
+
Tests the `copy` method for deep copy with DotDict conversion.
|
|
93
141
|
|
|
94
|
-
|
|
142
|
+
This method verifies that copying a DotDict instance produces an independent copy,
|
|
143
|
+
with all nested dictionaries converted to DotDict instances. It checks that changes
|
|
144
|
+
to the copy do not affect the original.
|
|
145
|
+
|
|
146
|
+
Returns
|
|
147
|
+
-------
|
|
148
|
+
None
|
|
149
|
+
This is a test method and does not return a value.
|
|
95
150
|
"""
|
|
151
|
+
|
|
152
|
+
# Create a DotDict instance and copy it
|
|
96
153
|
original = DotDict({
|
|
97
154
|
'key1': 'value1',
|
|
98
155
|
'nested': {'inner': 42}
|
|
99
156
|
})
|
|
100
157
|
|
|
158
|
+
# Copy the original DotDict
|
|
101
159
|
copied = original.copy()
|
|
160
|
+
|
|
161
|
+
# Modify the copy and verify original is unchanged
|
|
102
162
|
copied.key1 = 'modified'
|
|
103
163
|
copied.nested.inner = 100
|
|
104
164
|
|
|
165
|
+
# Check that original remains unchanged
|
|
105
166
|
self.assertEqual(original.key1, 'value1')
|
|
106
167
|
self.assertEqual(original.nested.inner, 42)
|
|
107
168
|
self.assertEqual(copied.key1, 'modified')
|
|
@@ -110,9 +171,15 @@ class TestSupportWrapperDocDict(AsyncTestCase):
|
|
|
110
171
|
|
|
111
172
|
async def testNestedDictConversion(self):
|
|
112
173
|
"""
|
|
113
|
-
|
|
174
|
+
Tests automatic conversion of nested dictionaries to DotDict.
|
|
114
175
|
|
|
115
|
-
|
|
176
|
+
This method verifies that nested dictionaries are converted to DotDict instances
|
|
177
|
+
both during initialization and dynamic assignment.
|
|
178
|
+
|
|
179
|
+
Returns
|
|
180
|
+
-------
|
|
181
|
+
None
|
|
182
|
+
This is a test method and does not return a value.
|
|
116
183
|
"""
|
|
117
184
|
dd = DotDict({
|
|
118
185
|
'level1': {
|
|
@@ -122,20 +189,29 @@ class TestSupportWrapperDocDict(AsyncTestCase):
|
|
|
122
189
|
}
|
|
123
190
|
})
|
|
124
191
|
|
|
192
|
+
# Nested dicts should be DotDict instances
|
|
125
193
|
self.assertIsInstance(dd.level1, DotDict)
|
|
126
194
|
self.assertIsInstance(dd.level1.level2, DotDict)
|
|
127
195
|
self.assertEqual(dd.level1.level2.value, 42)
|
|
128
196
|
|
|
129
|
-
# Test dynamic assignment
|
|
197
|
+
# Test dynamic assignment of nested dict
|
|
130
198
|
dd.new_nested = {'a': {'b': 1}}
|
|
131
199
|
self.assertIsInstance(dd.new_nested, DotDict)
|
|
132
200
|
self.assertIsInstance(dd.new_nested.a, DotDict)
|
|
133
201
|
|
|
134
202
|
async def testReprMethod(self):
|
|
135
203
|
"""
|
|
136
|
-
|
|
204
|
+
Tests the string representation of DotDict.
|
|
205
|
+
|
|
206
|
+
This method verifies that the `__repr__` method of DotDict returns a string
|
|
207
|
+
representation that includes the DotDict prefix.
|
|
137
208
|
|
|
138
|
-
|
|
209
|
+
Returns
|
|
210
|
+
-------
|
|
211
|
+
None
|
|
212
|
+
This is a test method and does not return a value.
|
|
139
213
|
"""
|
|
214
|
+
|
|
215
|
+
# Create a DotDict instance and test its string representation
|
|
140
216
|
dd = DotDict({'key': 'value'})
|
|
141
217
|
self.assertEqual(repr(dd), "{'key': 'value'}")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|