orionis 0.203.0__py3-none-any.whl → 0.205.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/framework.py +1 -1
- orionis/luminate/support/inspection/reflexion_abstract.py +250 -2
- orionis/luminate/support/inspection/reflexion_instance.py +26 -0
- orionis/luminate/test/test_output.py +65 -0
- {orionis-0.203.0.dist-info → orionis-0.205.0.dist-info}/METADATA +1 -1
- {orionis-0.203.0.dist-info → orionis-0.205.0.dist-info}/RECORD +14 -12
- tests/example/test_example.py +0 -1
- tests/support/inspection/fakes/fake_reflection.py +60 -0
- tests/support/inspection/test_reflection_instance.py +147 -0
- tests/support/inspection/test_reflection.py +0 -9
- {orionis-0.203.0.dist-info → orionis-0.205.0.dist-info}/LICENCE +0 -0
- {orionis-0.203.0.dist-info → orionis-0.205.0.dist-info}/WHEEL +0 -0
- {orionis-0.203.0.dist-info → orionis-0.205.0.dist-info}/entry_points.txt +0 -0
- {orionis-0.203.0.dist-info → orionis-0.205.0.dist-info}/top_level.txt +0 -0
- /tests/{main.py → support/inspection/fakes/__init__.py} +0 -0
orionis/framework.py
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
from typing import Type, TypeVar
|
1
|
+
from typing import Any, Type, Dict, List, Tuple, Callable, Optional, TypeVar, Set
|
2
|
+
import inspect
|
2
3
|
import abc
|
4
|
+
from functools import wraps
|
3
5
|
|
4
|
-
T = TypeVar('T')
|
5
6
|
ABC = TypeVar('ABC', bound=abc.ABC)
|
6
7
|
|
7
8
|
class ReflexionAbstract:
|
@@ -21,3 +22,250 @@ class ReflexionAbstract:
|
|
21
22
|
def __init__(self, abstract: Type[ABC]) -> None:
|
22
23
|
"""Initialize with the abstract class."""
|
23
24
|
self._abstract = abstract
|
25
|
+
|
26
|
+
def getClassName(self) -> str:
|
27
|
+
"""Get the name of the abstract class.
|
28
|
+
|
29
|
+
Returns
|
30
|
+
-------
|
31
|
+
str
|
32
|
+
The name of the abstract class
|
33
|
+
"""
|
34
|
+
return self._abstract.__name__
|
35
|
+
|
36
|
+
def getModuleName(self) -> str:
|
37
|
+
"""Get the name of the module where the abstract class is defined.
|
38
|
+
|
39
|
+
Returns
|
40
|
+
-------
|
41
|
+
str
|
42
|
+
The module name
|
43
|
+
"""
|
44
|
+
return self._abstract.__module__
|
45
|
+
|
46
|
+
def getAbstractMethods(self) -> Set[str]:
|
47
|
+
"""Get all abstract method names required by the class.
|
48
|
+
|
49
|
+
Returns
|
50
|
+
-------
|
51
|
+
Set[str]
|
52
|
+
Set of abstract method names
|
53
|
+
"""
|
54
|
+
return {name for name, _ in self._abstract.__abstractmethods__}
|
55
|
+
|
56
|
+
def getConcreteMethods(self) -> Dict[str, Callable]:
|
57
|
+
"""Get all concrete methods implemented in the abstract class.
|
58
|
+
|
59
|
+
Returns
|
60
|
+
-------
|
61
|
+
Dict[str, Callable]
|
62
|
+
Dictionary of method names and their implementations
|
63
|
+
"""
|
64
|
+
return {
|
65
|
+
name: member for name, member in inspect.getmembers(
|
66
|
+
self._abstract,
|
67
|
+
predicate=inspect.isfunction
|
68
|
+
) if not name.startswith('_') and name not in self.getAbstractMethods()
|
69
|
+
}
|
70
|
+
|
71
|
+
def getStaticMethods(self) -> List[str]:
|
72
|
+
"""Get all static method names of the abstract class.
|
73
|
+
|
74
|
+
Returns
|
75
|
+
-------
|
76
|
+
List[str]
|
77
|
+
List of static method names
|
78
|
+
"""
|
79
|
+
return [
|
80
|
+
name for name in dir( self._abstract)
|
81
|
+
if not name.startswith('_') and
|
82
|
+
isinstance(inspect.getattr_static( self._abstract, name), staticmethod)
|
83
|
+
]
|
84
|
+
|
85
|
+
def getClassMethods(self) -> List[str]:
|
86
|
+
"""Get all class method names of the abstract class.
|
87
|
+
|
88
|
+
Returns
|
89
|
+
-------
|
90
|
+
List[str]
|
91
|
+
List of class method names
|
92
|
+
"""
|
93
|
+
return [
|
94
|
+
name for name, member in inspect.getmembers(
|
95
|
+
self._abstract,
|
96
|
+
predicate=lambda x: isinstance(x, classmethod))
|
97
|
+
if not name.startswith('_')
|
98
|
+
]
|
99
|
+
|
100
|
+
def getProperties(self) -> List[str]:
|
101
|
+
"""Get all property names of the abstract class.
|
102
|
+
|
103
|
+
Returns
|
104
|
+
-------
|
105
|
+
List[str]
|
106
|
+
List of property names
|
107
|
+
"""
|
108
|
+
return [
|
109
|
+
name for name, member in inspect.getmembers(
|
110
|
+
self._abstract,
|
111
|
+
predicate=lambda x: isinstance(x, property))
|
112
|
+
if not name.startswith('_')
|
113
|
+
]
|
114
|
+
|
115
|
+
def getMethodSignature(self, methodName: str) -> inspect.Signature:
|
116
|
+
"""Get the signature of a method.
|
117
|
+
|
118
|
+
Parameters
|
119
|
+
----------
|
120
|
+
methodName : str
|
121
|
+
Name of the method
|
122
|
+
|
123
|
+
Returns
|
124
|
+
-------
|
125
|
+
inspect.Signature
|
126
|
+
The method signature
|
127
|
+
|
128
|
+
Raises
|
129
|
+
------
|
130
|
+
AttributeError
|
131
|
+
If the method doesn't exist
|
132
|
+
"""
|
133
|
+
method = getattr(self._abstract, methodName)
|
134
|
+
return inspect.signature(method)
|
135
|
+
|
136
|
+
def getDocstring(self) -> Optional[str]:
|
137
|
+
"""Get the docstring of the abstract class.
|
138
|
+
|
139
|
+
Returns
|
140
|
+
-------
|
141
|
+
Optional[str]
|
142
|
+
The class docstring
|
143
|
+
"""
|
144
|
+
return self._abstract.__doc__
|
145
|
+
|
146
|
+
def getBaseAbstractClasses(self) -> Tuple[Type[ABC], ...]:
|
147
|
+
"""Get the abstract base classes.
|
148
|
+
|
149
|
+
Returns
|
150
|
+
-------
|
151
|
+
Tuple[Type[ABC], ...]
|
152
|
+
Tuple of abstract base classes
|
153
|
+
"""
|
154
|
+
return tuple(
|
155
|
+
base for base in self._abstract.__bases__
|
156
|
+
if inspect.isabstract(base)
|
157
|
+
)
|
158
|
+
|
159
|
+
def getInterfaceMethods(self) -> Dict[str, inspect.Signature]:
|
160
|
+
"""Get all abstract methods with their signatures.
|
161
|
+
|
162
|
+
Returns
|
163
|
+
-------
|
164
|
+
Dict[str, inspect.Signature]
|
165
|
+
Dictionary of method names and their signatures
|
166
|
+
"""
|
167
|
+
return {
|
168
|
+
name: inspect.signature(getattr(self._abstract, name))
|
169
|
+
for name in self.getAbstractMethods()
|
170
|
+
}
|
171
|
+
|
172
|
+
def isSubclassOf(self, abstract_class: Type[ABC]) -> bool:
|
173
|
+
"""Check if the abstract class inherits from another abstract class.
|
174
|
+
|
175
|
+
Parameters
|
176
|
+
----------
|
177
|
+
abstract_class : Type[ABC]
|
178
|
+
The abstract class to check against
|
179
|
+
|
180
|
+
Returns
|
181
|
+
-------
|
182
|
+
bool
|
183
|
+
True if this is a subclass
|
184
|
+
"""
|
185
|
+
return issubclass(self._abstract, abstract_class)
|
186
|
+
|
187
|
+
def getSourceCode(self) -> Optional[str]:
|
188
|
+
"""Get the source code of the abstract class.
|
189
|
+
|
190
|
+
Returns
|
191
|
+
-------
|
192
|
+
Optional[str]
|
193
|
+
The source code if available
|
194
|
+
"""
|
195
|
+
try:
|
196
|
+
return inspect.getsource(self._abstract)
|
197
|
+
except (TypeError, OSError):
|
198
|
+
return None
|
199
|
+
|
200
|
+
def getFileLocation(self) -> Optional[str]:
|
201
|
+
"""Get the file location where the abstract class is defined.
|
202
|
+
|
203
|
+
Returns
|
204
|
+
-------
|
205
|
+
Optional[str]
|
206
|
+
The file path if available
|
207
|
+
"""
|
208
|
+
try:
|
209
|
+
return inspect.getfile(self._abstract)
|
210
|
+
except (TypeError, OSError):
|
211
|
+
return None
|
212
|
+
|
213
|
+
def getAnnotations(self) -> Dict[str, Any]:
|
214
|
+
"""Get type annotations of the abstract class.
|
215
|
+
|
216
|
+
Returns
|
217
|
+
-------
|
218
|
+
Dict[str, Any]
|
219
|
+
Dictionary of attribute names and their type annotations
|
220
|
+
"""
|
221
|
+
return self._abstract.__annotations__
|
222
|
+
|
223
|
+
def getDecorators(self, method_name: str) -> List[Callable]:
|
224
|
+
"""Get decorators applied to a method.
|
225
|
+
|
226
|
+
Parameters
|
227
|
+
----------
|
228
|
+
method_name : str
|
229
|
+
Name of the method
|
230
|
+
|
231
|
+
Returns
|
232
|
+
-------
|
233
|
+
List[Callable]
|
234
|
+
List of decorator functions
|
235
|
+
"""
|
236
|
+
method = getattr(self._abstract, method_name)
|
237
|
+
decorators = []
|
238
|
+
|
239
|
+
if hasattr(method, '__wrapped__'):
|
240
|
+
# Unwrap decorated functions
|
241
|
+
while hasattr(method, '__wrapped__'):
|
242
|
+
decorators.append(method)
|
243
|
+
method = method.__wrapped__
|
244
|
+
|
245
|
+
return decorators
|
246
|
+
|
247
|
+
def isProtocol(self) -> bool:
|
248
|
+
"""Check if the abstract class is a Protocol.
|
249
|
+
|
250
|
+
Returns
|
251
|
+
-------
|
252
|
+
bool
|
253
|
+
True if this is a Protocol class
|
254
|
+
"""
|
255
|
+
return hasattr(self._abstract, '_is_protocol') and self._abstract._is_protocol
|
256
|
+
|
257
|
+
def getRequiredAttributes(self) -> Set[str]:
|
258
|
+
"""For Protocol classes, get required attributes.
|
259
|
+
|
260
|
+
Returns
|
261
|
+
-------
|
262
|
+
Set[str]
|
263
|
+
Set of required attribute names
|
264
|
+
"""
|
265
|
+
if not self.isProtocol():
|
266
|
+
return set()
|
267
|
+
|
268
|
+
return {
|
269
|
+
name for name in dir(self._abstract)
|
270
|
+
if not name.startswith('_') and not inspect.isfunction(getattr(self._abstract, name))
|
271
|
+
}
|
@@ -99,6 +99,32 @@ class ReflexionInstance:
|
|
99
99
|
predicate=inspect.ismethod
|
100
100
|
)]
|
101
101
|
|
102
|
+
def getStaticMethods(self) -> List[str]:
|
103
|
+
"""Get all static method names of the instance.
|
104
|
+
|
105
|
+
Returns
|
106
|
+
-------
|
107
|
+
List[str]
|
108
|
+
List of static method names, excluding private methods (starting with '_')
|
109
|
+
|
110
|
+
Examples
|
111
|
+
--------
|
112
|
+
>>> class MyClass:
|
113
|
+
... @staticmethod
|
114
|
+
... def static_method(): pass
|
115
|
+
... @staticmethod
|
116
|
+
... def _private_static(): pass
|
117
|
+
...
|
118
|
+
>>> reflex = ReflexionInstance(MyClass())
|
119
|
+
>>> reflex.getStaticMethods()
|
120
|
+
['static_method']
|
121
|
+
"""
|
122
|
+
return [
|
123
|
+
name for name in dir(self._instance.__class__)
|
124
|
+
if not name.startswith('_') and
|
125
|
+
isinstance(inspect.getattr_static(self._instance.__class__, name), staticmethod)
|
126
|
+
]
|
127
|
+
|
102
128
|
def getPropertyNames(self) -> List[str]:
|
103
129
|
"""Get all property names of the instance.
|
104
130
|
|
@@ -0,0 +1,65 @@
|
|
1
|
+
import sys
|
2
|
+
from orionis.luminate.console.output.console import Console
|
3
|
+
import os
|
4
|
+
|
5
|
+
class PrinterInTest:
|
6
|
+
"""
|
7
|
+
A utility class for printing debug information during testing. This class temporarily
|
8
|
+
redirects the standard output and error streams to their original states to ensure
|
9
|
+
proper console output, and provides contextual information about the file and line
|
10
|
+
number where the print call was made.
|
11
|
+
Methods
|
12
|
+
-------
|
13
|
+
print(*args)
|
14
|
+
Prints the provided arguments to the console with contextual information
|
15
|
+
about the file and line number of the caller. If no arguments are provided,
|
16
|
+
the method does nothing.
|
17
|
+
"""
|
18
|
+
|
19
|
+
def print(*args):
|
20
|
+
"""
|
21
|
+
Prints the provided arguments to the console with contextual information
|
22
|
+
about the file and line number of the caller. The output is formatted with
|
23
|
+
muted text decorations for better readability.
|
24
|
+
Parameters
|
25
|
+
----------
|
26
|
+
*args : tuple
|
27
|
+
The arguments to be printed. The first argument is ignored, and the
|
28
|
+
remaining arguments are printed. If no arguments are provided, the
|
29
|
+
method does nothing.
|
30
|
+
Notes
|
31
|
+
-----
|
32
|
+
- The method temporarily redirects `sys.stdout` and `sys.stderr` to their
|
33
|
+
original states (`sys.__stdout__` and `sys.__stderr__`) to ensure proper
|
34
|
+
console output.
|
35
|
+
- The contextual information includes the file path and line number of the
|
36
|
+
caller, which is displayed in a muted text format.
|
37
|
+
- After printing, the method restores the original `sys.stdout` and
|
38
|
+
`sys.stderr` streams.
|
39
|
+
"""
|
40
|
+
|
41
|
+
# Check if the first argument is a string and remove it from the args tuple
|
42
|
+
if len(args) == 0:
|
43
|
+
return
|
44
|
+
|
45
|
+
# Change the output stream to the original stdout and stderr
|
46
|
+
# to avoid any issues with the console output
|
47
|
+
original_stdout = sys.stdout
|
48
|
+
original_stderr = sys.stderr
|
49
|
+
sys.stdout = sys.__stdout__
|
50
|
+
sys.stderr = sys.__stderr__
|
51
|
+
|
52
|
+
# Get the file name and line number of the caller
|
53
|
+
# using sys._getframe(1) to access the caller's frame
|
54
|
+
_file = os.path.relpath(sys._getframe(1).f_code.co_filename, start=os.getcwd())
|
55
|
+
_method = sys._getframe(1).f_code.co_name
|
56
|
+
_line = sys._getframe(1).f_lineno
|
57
|
+
|
58
|
+
# Print the contextual information and the provided arguments
|
59
|
+
Console.textMuted(f"[DEBUG] File: {_file}, Line: {_line}, Method: {_method}")
|
60
|
+
print(*args[1:], end='\n')
|
61
|
+
Console.newLine()
|
62
|
+
|
63
|
+
# Restore the original stdout and stderr streams
|
64
|
+
sys.stdout = original_stdout
|
65
|
+
sys.stderr = original_stderr
|
@@ -1,6 +1,6 @@
|
|
1
1
|
orionis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
2
|
orionis/console.py,sha256=4gYWxf0fWYgJ4RKwARvnTPh06FL3GJ6SAZ7R2NzOICw,1342
|
3
|
-
orionis/framework.py,sha256=
|
3
|
+
orionis/framework.py,sha256=fUxv8sJtO5v-ERZPJzgKhGDePNz3AbKp-n-HE7IIhZo,1469
|
4
4
|
orionis/installer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
5
|
orionis/installer/manager.py,sha256=Li4TVziRXWfum02xNG4JHwbnLk-u8xzHjdqKz-D894k,2755
|
6
6
|
orionis/installer/output.py,sha256=7O9qa2xtXMB_4ZvVi-Klneom9YazwygAd_4uYAoxhbU,8548
|
@@ -171,15 +171,16 @@ orionis/luminate/support/inspection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQ
|
|
171
171
|
orionis/luminate/support/inspection/container_integrity.py,sha256=6d9FsGk-Rm1AXgqBS3Nww49dR7n1ptXTTNyGUuBHgNY,10111
|
172
172
|
orionis/luminate/support/inspection/functions.py,sha256=XVDLdygONcfDNlH7CZ6muNdtYHLgNp5RybqC3smL4Y4,6400
|
173
173
|
orionis/luminate/support/inspection/reflection.py,sha256=x_UHBY9pBSKgct13-u1WbhoONqLoGG60OpgoCsKE0AI,20368
|
174
|
-
orionis/luminate/support/inspection/reflexion_abstract.py,sha256=
|
174
|
+
orionis/luminate/support/inspection/reflexion_abstract.py,sha256=yZTl_oZACjlXKKPmQimGsfre3qQUO2hbNDf7PJ4gKZE,7661
|
175
175
|
orionis/luminate/support/inspection/reflexion_concrete.py,sha256=0WOlLeTWLwMeAUReoaJetqlnT1_TxW_jMnbk_yXRR0g,549
|
176
176
|
orionis/luminate/support/inspection/reflexion_concrete_with_abstract.py,sha256=ZuAFoSPkgbOFMIbVR0hvlkKsm1dIpY1_bsXxZxvXcmU,801
|
177
|
-
orionis/luminate/support/inspection/reflexion_instance.py,sha256=
|
177
|
+
orionis/luminate/support/inspection/reflexion_instance.py,sha256=k6bpRYjLeTUDqquluYrDZUtBLpLuGe4wm7PMUM8Sz-E,9914
|
178
178
|
orionis/luminate/support/inspection/reflexion_instance_with_abstract.py,sha256=dag6QdVp1CydREWdpQvzAyOPX3q-lSb0_XzB0u3odQE,9629
|
179
179
|
orionis/luminate/support/inspection/reflexion_module.py,sha256=OgBXpqNJHkmq-gX4rqFStv-WVNe9R38RsgUgfHpak8k,405
|
180
180
|
orionis/luminate/support/inspection/reflexion_module_with_classname.py,sha256=YZHZI0XUZkSWnq9wrGxrIXtI64nY9yVSZoMe7PZXq8Y,620
|
181
181
|
orionis/luminate/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
182
182
|
orionis/luminate/test/test_exception.py,sha256=21PILTXnMuL5-wT3HGKjIklt8VeIYDcQDN346i-BbJw,1336
|
183
|
+
orionis/luminate/test/test_output.py,sha256=7QvkxbKOp56GcznjaJSX9I072gkut1NvuaexqO3v8BM,2768
|
183
184
|
orionis/luminate/test/test_result.py,sha256=Px2_M70r_y7BntRITk_h0IPTbSTW5XhDyklMKHm3JJI,999
|
184
185
|
orionis/luminate/test/test_status.py,sha256=vNKRmp1lud_ZGTayf3A8wO_0vEYdFABy_oMw-RcEc1c,673
|
185
186
|
orionis/luminate/test/tests.py,sha256=KZRFHB6C8S2DN6JHqJ2sIuSNAUMh9JW1Yn-XGjXjjTw,2218
|
@@ -194,15 +195,16 @@ orionis/static/logos/OrionisFramework.psd,sha256=QFMRe_HENaIgQi9VWMvNV3OHKOFofFG
|
|
194
195
|
orionis/static/logos/OrionisFramework2.png,sha256=Z_-yBHNSo33QeSTyi-8GfiFozdRqUomIZ28bGx6Py5c,256425
|
195
196
|
orionis/static/logos/OrionisFramework3.png,sha256=BPG9ZB58vDALavI9OMmr8Ym0DQa44s5NL_3M4M6dIYs,193734
|
196
197
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
197
|
-
tests/main.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
198
198
|
tests/example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
199
|
-
tests/example/test_example.py,sha256=
|
199
|
+
tests/example/test_example.py,sha256=MNYissCEa0mzx1YA2gTiqXRX8r2v_vfB_Ew0jBFmBag,556
|
200
200
|
tests/support/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
201
201
|
tests/support/inspection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
202
|
-
tests/support/inspection/
|
203
|
-
|
204
|
-
|
205
|
-
orionis-0.
|
206
|
-
orionis-0.
|
207
|
-
orionis-0.
|
208
|
-
orionis-0.
|
202
|
+
tests/support/inspection/test_reflection_instance.py,sha256=aYi4qmuAzQ4-gAUrtc9Lx6gNR4Mw4GcOF_T8iWsWZoQ,7266
|
203
|
+
tests/support/inspection/fakes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
204
|
+
tests/support/inspection/fakes/fake_reflection.py,sha256=G16rZdJWC3L8SGEQkmwktvw4n7IAusIIx9Tm-ZFLcg4,1419
|
205
|
+
orionis-0.205.0.dist-info/LICENCE,sha256=-_4cF2EBKuYVS_SQpy1uapq0oJPUU1vl_RUWSy2jJTo,1111
|
206
|
+
orionis-0.205.0.dist-info/METADATA,sha256=aFCgP3-K5OmZ5KziS4bEwafD_YPA4RxPvIZHjYCIHb0,3003
|
207
|
+
orionis-0.205.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
208
|
+
orionis-0.205.0.dist-info/entry_points.txt,sha256=a_e0faeSqyUCVZd0MqljQ2oaHHdlsz6g9sU_bMqi5zQ,49
|
209
|
+
orionis-0.205.0.dist-info/top_level.txt,sha256=2bdoHgyGZhOtLAXS6Om8OCTmL24dUMC_L1quMe_ETbk,14
|
210
|
+
orionis-0.205.0.dist-info/RECORD,,
|
tests/example/test_example.py
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
class BaseFakeClass:
|
2
|
+
pass
|
3
|
+
|
4
|
+
class FakeClass(BaseFakeClass):
|
5
|
+
"""This is a test class for ReflexionInstance.
|
6
|
+
|
7
|
+
Attributes
|
8
|
+
----------
|
9
|
+
public_attr : int
|
10
|
+
An example public attribute
|
11
|
+
_private_attr : str
|
12
|
+
An example "private" attribute
|
13
|
+
"""
|
14
|
+
|
15
|
+
class_attr: str = "class_value"
|
16
|
+
|
17
|
+
def __init__(self) -> None:
|
18
|
+
self.public_attr = 42
|
19
|
+
self._private_attr = "secret"
|
20
|
+
self.dynamic_attr = None
|
21
|
+
|
22
|
+
def instance_method(self, x: int, y: int) -> int:
|
23
|
+
"""Adds two numbers.
|
24
|
+
|
25
|
+
Parameters
|
26
|
+
----------
|
27
|
+
x : int
|
28
|
+
First number
|
29
|
+
y : int
|
30
|
+
Second number
|
31
|
+
|
32
|
+
Returns
|
33
|
+
-------
|
34
|
+
int
|
35
|
+
The sum of x and y
|
36
|
+
"""
|
37
|
+
return x + y
|
38
|
+
|
39
|
+
@property
|
40
|
+
def computed_property(self) -> str:
|
41
|
+
"""A computed property."""
|
42
|
+
return f"Value: {self.public_attr}"
|
43
|
+
|
44
|
+
@classmethod
|
45
|
+
def class_method(cls) -> str:
|
46
|
+
"""A class method."""
|
47
|
+
return f"Class attr: {cls.class_attr}"
|
48
|
+
|
49
|
+
@staticmethod
|
50
|
+
def static_method(text: str) -> str:
|
51
|
+
"""A static method."""
|
52
|
+
return text.upper()
|
53
|
+
|
54
|
+
def __private_method(self) -> str:
|
55
|
+
"""A 'private' method."""
|
56
|
+
return "This is private"
|
57
|
+
|
58
|
+
def _protected_method(self) -> str:
|
59
|
+
"""A 'protected' method."""
|
60
|
+
return "This is protected"
|
@@ -0,0 +1,147 @@
|
|
1
|
+
import unittest
|
2
|
+
from orionis.luminate.support.inspection.reflection import Reflection
|
3
|
+
from orionis.luminate.support.inspection.reflexion_instance import ReflexionInstance
|
4
|
+
from orionis.luminate.test.test_output import PrinterInTest
|
5
|
+
from tests.support.inspection.fakes.fake_reflection import BaseFakeClass, FakeClass
|
6
|
+
|
7
|
+
class TestReflection(unittest.TestCase, PrinterInTest):
|
8
|
+
"""
|
9
|
+
Unit tests for the Reflection class.
|
10
|
+
This class tests the functionality of the Reflection class, ensuring that it correctly handles
|
11
|
+
"""
|
12
|
+
|
13
|
+
def testReflectionInstanceExceptionValueError(self):
|
14
|
+
"""Test that Reflection.instance raises ValueError for invalid types."""
|
15
|
+
with self.assertRaises(ValueError):
|
16
|
+
Reflection.instance(str)
|
17
|
+
|
18
|
+
def testReflectionInstance(self):
|
19
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
20
|
+
self.assertIsInstance(Reflection.instance(FakeClass()), ReflexionInstance)
|
21
|
+
|
22
|
+
def testReflectionInstanceGetClassName(self):
|
23
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
24
|
+
reflex = Reflection.instance(FakeClass())
|
25
|
+
self.assertEqual(reflex.getClassName(), "FakeClass")
|
26
|
+
|
27
|
+
def testReflectionInstanceGetClass(self):
|
28
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
29
|
+
reflex = Reflection.instance(FakeClass())
|
30
|
+
self.assertEqual(reflex.getClass(), FakeClass)
|
31
|
+
|
32
|
+
def testReflectionInstanceGetModuleName(self):
|
33
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
34
|
+
reflex = Reflection.instance(FakeClass())
|
35
|
+
self.assertEqual(reflex.getModuleName(), "tests.support.inspection.fakes.fake_reflection")
|
36
|
+
|
37
|
+
def testReflectionInstanceGetAttributes(self):
|
38
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
39
|
+
reflex = Reflection.instance(FakeClass())
|
40
|
+
attributes = reflex.getAttributes()
|
41
|
+
self.assertTrue("public_attr" in attributes)
|
42
|
+
self.assertTrue("_private_attr" in attributes)
|
43
|
+
self.assertTrue("dynamic_attr" in attributes)
|
44
|
+
|
45
|
+
def testReflectionInstanceGetMethods(self):
|
46
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
47
|
+
reflex = Reflection.instance(FakeClass())
|
48
|
+
methods = reflex.getMethods()
|
49
|
+
self.assertTrue("instance_method" in methods)
|
50
|
+
self.assertTrue("class_method" in methods)
|
51
|
+
|
52
|
+
def testReflectionInstanceGetStaticMethods(self):
|
53
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
54
|
+
reflex = Reflection.instance(FakeClass())
|
55
|
+
methods = reflex.getStaticMethods()
|
56
|
+
self.assertTrue("static_method" in methods)
|
57
|
+
|
58
|
+
def testReflectionInstanceGetPropertyNames(self):
|
59
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
60
|
+
reflex = Reflection.instance(FakeClass())
|
61
|
+
properties = reflex.getPropertyNames()
|
62
|
+
self.assertTrue("computed_property" in properties)
|
63
|
+
|
64
|
+
def testReflectionInstanceCallMethod(self):
|
65
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
66
|
+
reflex = Reflection.instance(FakeClass())
|
67
|
+
result = reflex.callMethod("instance_method", 1, 2)
|
68
|
+
self.assertEqual(result, 3)
|
69
|
+
|
70
|
+
def testReflectionInstanceGetMethodSignature(self):
|
71
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
72
|
+
reflex = Reflection.instance(FakeClass())
|
73
|
+
signature = reflex.getMethodSignature("instance_method")
|
74
|
+
self.assertEqual(str(signature), "(x: int, y: int) -> int")
|
75
|
+
|
76
|
+
def testReflectionInstanceGetDocstring(self):
|
77
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
78
|
+
reflex = Reflection.instance(FakeClass())
|
79
|
+
docstring = reflex.getDocstring()
|
80
|
+
self.assertIn("This is a test class for ReflexionInstance", docstring)
|
81
|
+
|
82
|
+
def testReflectionInstanceGetBaseClasses(self):
|
83
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
84
|
+
reflex = Reflection.instance(FakeClass())
|
85
|
+
base_classes = reflex.getBaseClasses()
|
86
|
+
self.assertIn(BaseFakeClass, base_classes)
|
87
|
+
|
88
|
+
def testReflectionInstanceIsInstanceOf(self):
|
89
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
90
|
+
reflex = Reflection.instance(FakeClass())
|
91
|
+
self.assertTrue(reflex.isInstanceOf(BaseFakeClass))
|
92
|
+
|
93
|
+
def testReflectionInstanceGetSourceCode(self):
|
94
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
95
|
+
reflex = Reflection.instance(FakeClass())
|
96
|
+
source_code = reflex.getSourceCode()
|
97
|
+
self.assertIn("class FakeClass(BaseFakeClass):", source_code)
|
98
|
+
|
99
|
+
def testReflectionInstanceGetFileLocation(self):
|
100
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
101
|
+
reflex = Reflection.instance(FakeClass())
|
102
|
+
file_location = reflex.getFileLocation()
|
103
|
+
self.assertIn("fake_reflection.py", file_location)
|
104
|
+
|
105
|
+
def testReflectionInstanceGetAnnotations(self):
|
106
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
107
|
+
reflex = Reflection.instance(FakeClass())
|
108
|
+
annotations = reflex.getAnnotations()
|
109
|
+
self.assertEqual("{'class_attr': <class 'str'>}", str(annotations))
|
110
|
+
|
111
|
+
def testReflectionInstanceHasAttribute(self):
|
112
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
113
|
+
reflex = Reflection.instance(FakeClass())
|
114
|
+
self.assertTrue(reflex.hasAttribute("public_attr"))
|
115
|
+
self.assertFalse(reflex.hasAttribute("non_existent_attr"))
|
116
|
+
|
117
|
+
def testReflectionInstanceGetAttribute(self):
|
118
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
119
|
+
reflex = Reflection.instance(FakeClass())
|
120
|
+
attr_value = reflex.getAttribute("public_attr")
|
121
|
+
self.assertEqual(attr_value, 42)
|
122
|
+
|
123
|
+
def testReflectionInstanceGetCallableMembers(self):
|
124
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
125
|
+
reflex = Reflection.instance(FakeClass())
|
126
|
+
callable_members = reflex.getCallableMembers()
|
127
|
+
self.assertIn("instance_method", callable_members)
|
128
|
+
self.assertIn("class_method", callable_members)
|
129
|
+
self.assertIn("static_method", callable_members)
|
130
|
+
|
131
|
+
def testReflectionInstanceSetAttribute(self):
|
132
|
+
"""Test that Reflection.instance returns an instance of ReflexionInstance."""
|
133
|
+
|
134
|
+
# Create a new macro function
|
135
|
+
def myMacro(cls:FakeClass, num):
|
136
|
+
return cls.instance_method(10, 12) + num
|
137
|
+
|
138
|
+
# Create an instance of FakeClass and set the macro as an attribute
|
139
|
+
reflex = Reflection.instance(FakeClass())
|
140
|
+
reflex.setAttribute("myMacro", myMacro)
|
141
|
+
|
142
|
+
# Check if the macro was set correctly
|
143
|
+
self.assertTrue(reflex.hasAttribute("myMacro"))
|
144
|
+
|
145
|
+
# Call the macro method and check the result
|
146
|
+
result = reflex.callMethod("myMacro", reflex._instance, 3)
|
147
|
+
self.assertEqual(result, 25)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|