orionis 0.200.0__py3-none-any.whl → 0.202.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.
Files changed (28) hide show
  1. orionis/framework.py +1 -1
  2. orionis/luminate/container/container_integrity.py +56 -1
  3. orionis/luminate/facades/tests/tests_facade.py +1 -1
  4. orionis/luminate/support/inspection/container_integrity.py +292 -0
  5. orionis/luminate/support/inspection/functions.py +235 -0
  6. orionis/luminate/support/inspection/reflection.py +649 -0
  7. orionis/luminate/support/inspection/reflexion_abstract.py +23 -0
  8. orionis/luminate/support/inspection/reflexion_concrete.py +24 -0
  9. orionis/luminate/support/inspection/reflexion_concrete_with_abstract.py +31 -0
  10. orionis/luminate/support/inspection/reflexion_instance.py +364 -0
  11. orionis/luminate/support/inspection/reflexion_instance_with_abstract.py +309 -0
  12. orionis/luminate/support/inspection/reflexion_module.py +19 -0
  13. orionis/luminate/support/inspection/reflexion_module_with_classname.py +22 -0
  14. orionis/luminate/test/{exception.py → test_exception.py} +1 -2
  15. orionis/luminate/test/test_result.py +30 -0
  16. orionis/luminate/test/test_status.py +22 -0
  17. orionis/luminate/test/tests.py +67 -0
  18. orionis/luminate/test/unit_test.py +276 -56
  19. {orionis-0.200.0.dist-info → orionis-0.202.0.dist-info}/METADATA +1 -1
  20. {orionis-0.200.0.dist-info → orionis-0.202.0.dist-info}/RECORD +26 -14
  21. tests/main.py +0 -0
  22. tests/tools/class_example.py +0 -50
  23. tests/tools/test_reflection.py +0 -128
  24. {tests/tools → orionis/luminate/support/inspection}/__init__.py +0 -0
  25. {orionis-0.200.0.dist-info → orionis-0.202.0.dist-info}/LICENCE +0 -0
  26. {orionis-0.200.0.dist-info → orionis-0.202.0.dist-info}/WHEEL +0 -0
  27. {orionis-0.200.0.dist-info → orionis-0.202.0.dist-info}/entry_points.txt +0 -0
  28. {orionis-0.200.0.dist-info → orionis-0.202.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,31 @@
1
+ from typing import Type, TypeVar
2
+ import abc
3
+
4
+ T = TypeVar('T')
5
+ ABC = TypeVar('ABC', bound=abc.ABC)
6
+
7
+
8
+ class ReflexionConcreteWithAbstract:
9
+ """A reflection object encapsulating a concrete class and its abstract parent.
10
+
11
+ Parameters
12
+ ----------
13
+ concrete : Type[T]
14
+ The concrete class being reflected upon
15
+ abstract : Type[ABC]
16
+ The abstract parent class
17
+
18
+ Attributes
19
+ ----------
20
+ _concrete : Type[T]
21
+ The encapsulated concrete class
22
+ _abstract : Type[ABC]
23
+ The encapsulated abstract parent class
24
+ """
25
+
26
+ def __init__(self, concrete: Type[T], abstract: Type[ABC]) -> None:
27
+ """Initialize with the concrete class and abstract parent."""
28
+ self._concrete = concrete
29
+ self._abstract = abstract
30
+
31
+
@@ -0,0 +1,364 @@
1
+ from typing import Any, Type, Dict, List, Tuple, Callable, Optional
2
+ import inspect
3
+
4
+ class ReflexionInstance:
5
+ """A reflection object encapsulating a class instance.
6
+
7
+ Parameters
8
+ ----------
9
+ instance : Any
10
+ The instance being reflected upon
11
+
12
+ Attributes
13
+ ----------
14
+ _instance : Any
15
+ The encapsulated instance
16
+ """
17
+
18
+ def __init__(self, instance: Any) -> None:
19
+ """Initialize with the instance to reflect upon."""
20
+ self._instance = instance
21
+
22
+ def getClassName(self) -> str:
23
+ """Get the name of the instance's class.
24
+
25
+ Returns
26
+ -------
27
+ str
28
+ The name of the class
29
+
30
+ Examples
31
+ --------
32
+ >>> obj = SomeClass()
33
+ >>> reflex = ReflexionInstance(obj)
34
+ >>> reflex.getClassName()
35
+ 'SomeClass'
36
+ """
37
+ return self._instance.__class__.__name__
38
+
39
+ def getClass(self) -> Type:
40
+ """Get the class of the instance.
41
+
42
+ Returns
43
+ -------
44
+ Type
45
+ The class object of the instance
46
+
47
+ Examples
48
+ --------
49
+ >>> reflex.getClass() is SomeClass
50
+ True
51
+ """
52
+ return self._instance.__class__
53
+
54
+ def getModuleName(self) -> str:
55
+ """Get the name of the module where the class is defined.
56
+
57
+ Returns
58
+ -------
59
+ str
60
+ The module name
61
+
62
+ Examples
63
+ --------
64
+ >>> reflex.getModuleName()
65
+ 'some_module'
66
+ """
67
+ return self._instance.__class__.__module__
68
+
69
+ def getAttributes(self) -> Dict[str, Any]:
70
+ """Get all attributes of the instance.
71
+
72
+ Returns
73
+ -------
74
+ Dict[str, Any]
75
+ Dictionary of attribute names and their values
76
+
77
+ Examples
78
+ --------
79
+ >>> reflex.getAttributes()
80
+ {'attr1': value1, 'attr2': value2}
81
+ """
82
+ return vars(self._instance)
83
+
84
+ def getMethods(self) -> List[str]:
85
+ """Get all method names of the instance.
86
+
87
+ Returns
88
+ -------
89
+ List[str]
90
+ List of method names
91
+
92
+ Examples
93
+ --------
94
+ >>> reflex.getMethods()
95
+ ['method1', 'method2']
96
+ """
97
+ return [name for name, _ in inspect.getmembers(
98
+ self._instance,
99
+ predicate=inspect.ismethod
100
+ )]
101
+
102
+ def getPropertyNames(self) -> List[str]:
103
+ """Get all property names of the instance.
104
+
105
+ Returns
106
+ -------
107
+ List[str]
108
+ List of property names
109
+
110
+ Examples
111
+ --------
112
+ >>> reflex.getPropertyNames()
113
+ ['prop1', 'prop2']
114
+ """
115
+ return [name for name, _ in inspect.getmembers(
116
+ self._instance.__class__,
117
+ lambda x: isinstance(x, property)
118
+ )]
119
+
120
+ def callMethod(self, methodName: str, *args: Any, **kwargs: Any) -> Any:
121
+ """Call a method on the instance.
122
+
123
+ Parameters
124
+ ----------
125
+ methodName : str
126
+ Name of the method to call
127
+ *args : Any
128
+ Positional arguments for the method
129
+ **kwargs : Any
130
+ Keyword arguments for the method
131
+
132
+ Returns
133
+ -------
134
+ Any
135
+ The return value of the method
136
+
137
+ Raises
138
+ ------
139
+ AttributeError
140
+ If the method doesn't exist
141
+
142
+ Examples
143
+ --------
144
+ >>> reflex.callMethod('calculate', 2, 3)
145
+ 5
146
+ """
147
+ method = getattr(self._instance, methodName)
148
+ return method(*args, **kwargs)
149
+
150
+ def getMethodSignature(self, methodName: str) -> inspect.Signature:
151
+ """Get the signature of a method.
152
+
153
+ Parameters
154
+ ----------
155
+ methodName : str
156
+ Name of the method
157
+
158
+ Returns
159
+ -------
160
+ inspect.Signature
161
+ The method signature
162
+
163
+ Raises
164
+ ------
165
+ AttributeError
166
+ If the method doesn't exist
167
+
168
+ Examples
169
+ --------
170
+ >>> sig = reflex.getMethodSignature('calculate')
171
+ >>> str(sig)
172
+ '(x, y)'
173
+ """
174
+ method = getattr(self._instance, methodName)
175
+ return inspect.signature(method)
176
+
177
+ def getDocstring(self) -> Optional[str]:
178
+ """Get the docstring of the instance's class.
179
+
180
+ Returns
181
+ -------
182
+ Optional[str]
183
+ The class docstring, or None if not available
184
+
185
+ Examples
186
+ --------
187
+ >>> reflex.getDocstring()
188
+ 'This class does something important.'
189
+ """
190
+ return self._instance.__class__.__doc__
191
+
192
+ def getBaseClasses(self) -> Tuple[Type, ...]:
193
+ """Get the base classes of the instance's class.
194
+
195
+ Returns
196
+ -------
197
+ Tuple[Type, ...]
198
+ Tuple of base classes
199
+
200
+ Examples
201
+ --------
202
+ >>> reflex.getBaseClasses()
203
+ (<class 'object'>,)
204
+ """
205
+ return self._instance.__class__.__bases__
206
+
207
+ def isInstanceOf(self, cls: Type) -> bool:
208
+ """Check if the instance is of a specific class.
209
+
210
+ Parameters
211
+ ----------
212
+ cls : Type
213
+ The class to check against
214
+
215
+ Returns
216
+ -------
217
+ bool
218
+ True if the instance is of the specified class
219
+
220
+ Examples
221
+ --------
222
+ >>> reflex.isInstanceOf(SomeClass)
223
+ True
224
+ """
225
+ return isinstance(self._instance, cls)
226
+
227
+ def getSourceCode(self) -> Optional[str]:
228
+ """Get the source code of the instance's class.
229
+
230
+ Returns
231
+ -------
232
+ Optional[str]
233
+ The source code if available, None otherwise
234
+
235
+ Examples
236
+ --------
237
+ >>> print(reflex.getSourceCode())
238
+ class SomeClass:
239
+ def __init__(self):
240
+ ...
241
+ """
242
+ try:
243
+ return inspect.getsource(self._instance.__class__)
244
+ except (TypeError, OSError):
245
+ return None
246
+
247
+ def getFileLocation(self) -> Optional[str]:
248
+ """Get the file location where the class is defined.
249
+
250
+ Returns
251
+ -------
252
+ Optional[str]
253
+ The file path if available, None otherwise
254
+
255
+ Examples
256
+ --------
257
+ >>> reflex.getFileLocation()
258
+ '/path/to/module.py'
259
+ """
260
+ try:
261
+ return inspect.getfile(self._instance.__class__)
262
+ except (TypeError, OSError):
263
+ return None
264
+
265
+ def getAnnotations(self) -> Dict[str, Any]:
266
+ """Get type annotations of the class.
267
+
268
+ Returns
269
+ -------
270
+ Dict[str, Any]
271
+ Dictionary of attribute names and their type annotations
272
+
273
+ Examples
274
+ --------
275
+ >>> reflex.getAnnotations()
276
+ {'name': str, 'value': int}
277
+ """
278
+ return self._instance.__class__.__annotations__
279
+
280
+ def hasAttribute(self, name: str) -> bool:
281
+ """Check if the instance has a specific attribute.
282
+
283
+ Parameters
284
+ ----------
285
+ name : str
286
+ The attribute name to check
287
+
288
+ Returns
289
+ -------
290
+ bool
291
+ True if the attribute exists
292
+
293
+ Examples
294
+ --------
295
+ >>> reflex.hasAttribute('important_attr')
296
+ True
297
+ """
298
+ return hasattr(self._instance, name)
299
+
300
+ def getAttribute(self, name: str) -> Any:
301
+ """Get an attribute value by name.
302
+
303
+ Parameters
304
+ ----------
305
+ name : str
306
+ The attribute name
307
+
308
+ Returns
309
+ -------
310
+ Any
311
+ The attribute value
312
+
313
+ Raises
314
+ ------
315
+ AttributeError
316
+ If the attribute doesn't exist
317
+
318
+ Examples
319
+ --------
320
+ >>> reflex.getAttribute('count')
321
+ 42
322
+ """
323
+ return getattr(self._instance, name)
324
+
325
+ def setAttribute(self, name: str, value: Any) -> None:
326
+ """Set an attribute value.
327
+
328
+ Parameters
329
+ ----------
330
+ name : str
331
+ The attribute name
332
+ value : Any
333
+ The value to set
334
+
335
+ Raises
336
+ ------
337
+ AttributeError
338
+ If the attribute is read-only
339
+
340
+ Examples
341
+ --------
342
+ >>> reflex.setAttribute('count', 100)
343
+ """
344
+ setattr(self._instance, name, value)
345
+
346
+ def getCallableMembers(self) -> Dict[str, Callable]:
347
+ """Get all callable members (methods) of the instance.
348
+
349
+ Returns
350
+ -------
351
+ Dict[str, Callable]
352
+ Dictionary of method names and their callable objects
353
+
354
+ Examples
355
+ --------
356
+ >>> reflex.getCallableMembers()
357
+ {'calculate': <bound method SomeClass.calculate>, ...}
358
+ """
359
+ return {
360
+ name: member for name, member in inspect.getmembers(
361
+ self._instance,
362
+ callable
363
+ ) if not name.startswith('__')
364
+ }
@@ -0,0 +1,309 @@
1
+ from typing import Any, Type, Dict, List, Tuple, Callable, Optional, Set, TypeVar
2
+ import inspect
3
+ import abc
4
+
5
+ T = TypeVar('T')
6
+ ABC = TypeVar('ABC', bound=abc.ABC)
7
+
8
+ class ReflexionInstanceWithAbstract:
9
+ """A reflection object encapsulating a class instance and its abstract parent.
10
+
11
+ This class provides methods to inspect both the concrete instance and its
12
+ abstract parent class, including their relationships and implementations.
13
+
14
+ Parameters
15
+ ----------
16
+ instance : Any
17
+ The instance being reflected upon
18
+ abstract : Type[ABC]
19
+ The abstract parent class
20
+
21
+ Attributes
22
+ ----------
23
+ _instance : Any
24
+ The encapsulated instance
25
+ _abstract : Type[ABC]
26
+ The encapsulated abstract parent class
27
+ """
28
+
29
+ def __init__(self, instance: Any, abstract: Type[ABC]) -> None:
30
+ """Initialize with the instance and abstract parent."""
31
+ self._instance = instance
32
+ self._abstract = abstract
33
+
34
+ def getClassName(self) -> str:
35
+ """Get the name of the instance's class.
36
+
37
+ Returns
38
+ -------
39
+ str
40
+ The name of the concrete class
41
+ """
42
+ return self._instance.__class__.__name__
43
+
44
+ def getAbstractClassName(self) -> str:
45
+ """Get the name of the abstract parent class.
46
+
47
+ Returns
48
+ -------
49
+ str
50
+ The name of the abstract class
51
+ """
52
+ return self._abstract.__name__
53
+
54
+ def getImplementationStatus(self) -> Dict[str, bool]:
55
+ """Check which abstract methods are implemented.
56
+
57
+ Returns
58
+ -------
59
+ Dict[str, bool]
60
+ Dictionary mapping abstract method names to implementation status
61
+ """
62
+ abstract_methods = getattr(self._abstract, '__abstractmethods__', set())
63
+ return {
64
+ method: method in dir(self._instance)
65
+ for method in abstract_methods
66
+ }
67
+
68
+ def getMissingImplementations(self) -> Set[str]:
69
+ """Get abstract methods not implemented by the concrete class.
70
+
71
+ Returns
72
+ -------
73
+ Set[str]
74
+ Set of abstract method names not implemented
75
+ """
76
+ abstract_methods = getattr(self._abstract, '__abstractmethods__', set())
77
+ return abstract_methods - set(dir(self._instance))
78
+
79
+ def isProperImplementation(self) -> bool:
80
+ """Check if the instance properly implements all abstract methods.
81
+
82
+ Returns
83
+ -------
84
+ bool
85
+ True if all abstract methods are implemented, False otherwise
86
+ """
87
+ return len(self.getMissingImplementations()) == 0
88
+
89
+ def getAbstractMethods(self) -> Set[str]:
90
+ """Get all abstract methods from the parent class.
91
+
92
+ Returns
93
+ -------
94
+ Set[str]
95
+ Set of abstract method names
96
+ """
97
+ return getattr(self._abstract, '__abstractmethods__', set())
98
+
99
+ def getConcreteMethods(self) -> List[str]:
100
+ """Get all concrete methods of the instance.
101
+
102
+ Returns
103
+ -------
104
+ List[str]
105
+ List of method names implemented by the instance
106
+ """
107
+ return [name for name, _ in inspect.getmembers(
108
+ self._instance,
109
+ predicate=inspect.ismethod
110
+ )]
111
+
112
+ def getOverriddenMethods(self) -> Dict[str, Tuple[Type, Type]]:
113
+ """Get methods that override abstract ones with their signatures.
114
+
115
+ Returns
116
+ -------
117
+ Dict[str, Tuple[Type, Type]]
118
+ Dictionary mapping method names to tuples of
119
+ (abstract_signature, concrete_signature)
120
+ """
121
+ overridden = {}
122
+ abstract_methods = self.getAbstractMethods()
123
+
124
+ for method in abstract_methods:
125
+ if hasattr(self._instance, method):
126
+ abstract_sig = inspect.signature(getattr(self._abstract, method))
127
+ concrete_sig = inspect.signature(getattr(self._instance, method))
128
+ overridden[method] = (abstract_sig, concrete_sig)
129
+
130
+ return overridden
131
+
132
+ def checkSignatureCompatibility(self) -> Dict[str, bool]:
133
+ """Check if implemented methods match abstract signatures.
134
+
135
+ Returns
136
+ -------
137
+ Dict[str, bool]
138
+ Dictionary mapping method names to compatibility status
139
+ """
140
+ compatibility = {}
141
+ overridden = self.getOverriddenMethods()
142
+
143
+ for method, (abstract_sig, concrete_sig) in overridden.items():
144
+ compatibility[method] = (
145
+ abstract_sig.parameters == concrete_sig.parameters and
146
+ abstract_sig.return_annotation == concrete_sig.return_annotation
147
+ )
148
+
149
+ return compatibility
150
+
151
+ def getAbstractProperties(self) -> Set[str]:
152
+ """Get all abstract properties from the parent class.
153
+
154
+ Returns
155
+ -------
156
+ Set[str]
157
+ Set of abstract property names
158
+ """
159
+ return {
160
+ name for name, member in inspect.getmembers(
161
+ self._abstract,
162
+ lambda x: isinstance(x, property) and
163
+ name in getattr(self._abstract, '__abstractmethods__', set())
164
+ )
165
+ }
166
+
167
+ def getInstanceAttributes(self) -> Dict[str, Any]:
168
+ """Get all attributes of the concrete instance.
169
+
170
+ Returns
171
+ -------
172
+ Dict[str, Any]
173
+ Dictionary of attribute names and their values
174
+ """
175
+ return vars(self._instance)
176
+
177
+ def getAbstractClassDocstring(self) -> Optional[str]:
178
+ """Get the docstring of the abstract parent class.
179
+
180
+ Returns
181
+ -------
182
+ Optional[str]
183
+ The abstract class docstring, or None if not available
184
+ """
185
+ return self._abstract.__doc__
186
+
187
+ def getConcreteClassDocstring(self) -> Optional[str]:
188
+ """Get the docstring of the concrete instance's class.
189
+
190
+ Returns
191
+ -------
192
+ Optional[str]
193
+ The concrete class docstring, or None if not available
194
+ """
195
+ return self._instance.__class__.__doc__
196
+
197
+ def getAbstractClassModule(self) -> str:
198
+ """Get the module name where the abstract class is defined.
199
+
200
+ Returns
201
+ -------
202
+ str
203
+ The module name of the abstract class
204
+ """
205
+ return self._abstract.__module__
206
+
207
+ def getConcreteClassModule(self) -> str:
208
+ """Get the module name where the concrete class is defined.
209
+
210
+ Returns
211
+ -------
212
+ str
213
+ The module name of the concrete class
214
+ """
215
+ return self._instance.__class__.__module__
216
+
217
+ def isDirectSubclass(self) -> bool:
218
+ """Check if the concrete class directly inherits from the abstract class.
219
+
220
+ Returns
221
+ -------
222
+ bool
223
+ True if direct subclass, False otherwise
224
+ """
225
+ return self._abstract in self._instance.__class__.__bases__
226
+
227
+ def getAbstractClassHierarchy(self) -> List[Type]:
228
+ """Get the inheritance hierarchy of the abstract class.
229
+
230
+ Returns
231
+ -------
232
+ List[Type]
233
+ List of classes in the inheritance hierarchy
234
+ """
235
+ return inspect.getmro(self._abstract)
236
+
237
+ def getConcreteClassHierarchy(self) -> List[Type]:
238
+ """Get the inheritance hierarchy of the concrete class.
239
+
240
+ Returns
241
+ -------
242
+ List[Type]
243
+ List of classes in the inheritance hierarchy
244
+ """
245
+ return inspect.getmro(self._instance.__class__)
246
+
247
+ def getCommonBaseClasses(self) -> List[Type]:
248
+ """Get base classes common to both abstract and concrete classes.
249
+
250
+ Returns
251
+ -------
252
+ List[Type]
253
+ List of common base classes
254
+ """
255
+ abstract_bases = set(inspect.getmro(self._abstract))
256
+ concrete_bases = set(inspect.getmro(self._instance.__class__))
257
+ return list(abstract_bases & concrete_bases - {self._abstract, object})
258
+
259
+ def getAbstractClassSource(self) -> Optional[str]:
260
+ """Get the source code of the abstract class.
261
+
262
+ Returns
263
+ -------
264
+ Optional[str]
265
+ The source code if available, None otherwise
266
+ """
267
+ try:
268
+ return inspect.getsource(self._abstract)
269
+ except (TypeError, OSError):
270
+ return None
271
+
272
+ def getConcreteClassSource(self) -> Optional[str]:
273
+ """Get the source code of the concrete class.
274
+
275
+ Returns
276
+ -------
277
+ Optional[str]
278
+ The source code if available, None otherwise
279
+ """
280
+ try:
281
+ return inspect.getsource(self._instance.__class__)
282
+ except (TypeError, OSError):
283
+ return None
284
+
285
+ def getAbstractClassFile(self) -> Optional[str]:
286
+ """Get the file location of the abstract class definition.
287
+
288
+ Returns
289
+ -------
290
+ Optional[str]
291
+ The file path if available, None otherwise
292
+ """
293
+ try:
294
+ return inspect.getfile(self._abstract)
295
+ except (TypeError, OSError):
296
+ return None
297
+
298
+ def getConcreteClassFile(self) -> Optional[str]:
299
+ """Get the file location of the concrete class definition.
300
+
301
+ Returns
302
+ -------
303
+ Optional[str]
304
+ The file path if available, None otherwise
305
+ """
306
+ try:
307
+ return inspect.getfile(self._instance.__class__)
308
+ except (TypeError, OSError):
309
+ return None