orionis 0.233.0__py3-none-any.whl → 0.235.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 (73) hide show
  1. orionis/framework.py +1 -1
  2. orionis/luminate/support/introspection/__init__.py +7 -0
  3. orionis/luminate/support/introspection/dependencies/contracts/reflect_dependencies.py +43 -0
  4. orionis/luminate/support/introspection/dependencies/entities/__init__.py +0 -0
  5. orionis/luminate/support/introspection/dependencies/entities/class_dependencies.py +10 -0
  6. orionis/luminate/support/introspection/dependencies/entities/method_dependencies.py +10 -0
  7. orionis/luminate/support/introspection/dependencies/entities/resolved_dependencies.py +12 -0
  8. orionis/luminate/support/introspection/dependencies/reflect_dependencies.py +176 -0
  9. orionis/luminate/support/introspection/helpers/__init__.py +0 -0
  10. orionis/luminate/support/introspection/helpers/functions.py +281 -0
  11. orionis/luminate/support/{inspection/reflexion_abstract.py → introspection/reflect_abstract.py} +1 -1
  12. orionis/luminate/support/introspection/reflect_decorators.py +335 -0
  13. orionis/luminate/support/{inspection → introspection}/reflection.py +21 -27
  14. orionis/luminate/support/introspection/reflection_instance.py +801 -0
  15. orionis/luminate/support/{inspection → introspection}/reflexion_concrete_with_abstract.py +2 -2
  16. orionis/luminate/support/{inspection → introspection}/reflexion_instance_with_abstract.py +4 -4
  17. orionis/luminate/test/__init__.py +13 -0
  18. orionis/luminate/test/cases/__init__.py +0 -0
  19. orionis/luminate/test/cases/test_async.py +32 -0
  20. orionis/luminate/test/cases/test_case.py +23 -0
  21. orionis/luminate/test/cases/test_sync.py +10 -0
  22. orionis/luminate/test/core/__init__.py +0 -0
  23. orionis/luminate/test/core/contracts/__init__.py +0 -0
  24. orionis/luminate/test/{test_suite.py → core/test_suite.py} +2 -2
  25. orionis/luminate/test/{test_unit.py → core/test_unit.py} +4 -4
  26. orionis/luminate/test/entities/__init__.py +0 -0
  27. orionis/luminate/test/{test_result.py → entities/test_result.py} +2 -2
  28. orionis/luminate/test/enums/__init__.py +0 -0
  29. orionis/luminate/test/exceptions/__init__.py +0 -0
  30. orionis/luminate/test/output/__init__.py +0 -0
  31. orionis/luminate/test/{test_std_out.py → output/test_std_out.py} +1 -1
  32. {orionis-0.233.0.dist-info → orionis-0.235.0.dist-info}/METADATA +1 -1
  33. {orionis-0.233.0.dist-info → orionis-0.235.0.dist-info}/RECORD +64 -52
  34. tests/example/test_example.py +1 -1
  35. tests/support/adapters/test_doct_dict.py +1 -1
  36. tests/support/async_io/test_async_coroutine.py +1 -1
  37. tests/support/environment/test_env.py +1 -1
  38. tests/support/inspection/test_reflection_abstract.py +20 -2
  39. tests/support/inspection/test_reflection_concrete.py +3 -3
  40. tests/support/inspection/test_reflection_concrete_with_abstract.py +2 -2
  41. tests/support/inspection/test_reflection_instance.py +41 -17
  42. tests/support/inspection/test_reflection_instance_with_abstract.py +2 -2
  43. tests/support/parsers/test_exception_parser.py +1 -1
  44. tests/support/path/test_resolver.py +6 -6
  45. tests/support/patterns/test_singleton.py +1 -1
  46. tests/support/standard/test_std.py +1 -1
  47. orionis/luminate/support/inspection/functions.py +0 -263
  48. orionis/luminate/support/inspection/reflexion_instance.py +0 -580
  49. orionis/luminate/test/test_case.py +0 -62
  50. orionis/static/favicon/OrionisFrameworkFavicon.png +0 -0
  51. orionis/static/logos/OrionisFramework.jpg +0 -0
  52. orionis/static/logos/OrionisFramework.png +0 -0
  53. orionis/static/logos/OrionisFramework.psd +0 -0
  54. orionis/static/logos/OrionisFramework2.png +0 -0
  55. orionis/static/logos/OrionisFramework3.png +0 -0
  56. /orionis/luminate/support/{inspection → introspection}/container_integrity.py +0 -0
  57. /orionis/luminate/support/{inspection → introspection/contracts}/__init__.py +0 -0
  58. /orionis/luminate/support/{inspection → introspection}/contracts/reflection.py +0 -0
  59. /orionis/luminate/support/{inspection → introspection}/contracts/reflexion_abstract.py +0 -0
  60. /orionis/luminate/support/{inspection/contracts → introspection/dependencies}/__init__.py +0 -0
  61. /orionis/luminate/{test → support/introspection/dependencies}/contracts/__init__.py +0 -0
  62. /orionis/luminate/support/{inspection → introspection}/reflexion_concrete.py +0 -0
  63. /orionis/luminate/support/{inspection → introspection}/reflexion_module.py +0 -0
  64. /orionis/luminate/support/{inspection → introspection}/reflexion_module_with_classname.py +0 -0
  65. /orionis/luminate/test/{contracts → core/contracts}/test_suite.py +0 -0
  66. /orionis/luminate/test/{contracts → core/contracts}/test_unit.py +0 -0
  67. /orionis/luminate/test/{test_status.py → enums/test_status.py} +0 -0
  68. /orionis/luminate/test/{test_exception.py → exceptions/test_exception.py} +0 -0
  69. /orionis/luminate/test/{contracts → output/contracts}/test_std_out.py +0 -0
  70. {orionis-0.233.0.dist-info → orionis-0.235.0.dist-info}/LICENCE +0 -0
  71. {orionis-0.233.0.dist-info → orionis-0.235.0.dist-info}/WHEEL +0 -0
  72. {orionis-0.233.0.dist-info → orionis-0.235.0.dist-info}/entry_points.txt +0 -0
  73. {orionis-0.233.0.dist-info → orionis-0.235.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,335 @@
1
+ import ast
2
+ import inspect
3
+ import re
4
+ from typing import List, Type
5
+ from dataclasses import dataclass
6
+
7
+ @dataclass
8
+ class ClassDecorators:
9
+ """
10
+ ClassDecorators is a dataclass that encapsulates information about class decorators.
11
+
12
+ Attributes
13
+ ----------
14
+ user_defined : tuple[str, ...]
15
+ A tuple containing the names of user-defined decorators applied to a class.
16
+ native : tuple[str, ...]
17
+ A tuple containing the names of native or built-in decorators applied to a class.
18
+ all : tuple[str, ...]
19
+ A tuple containing the names of all decorators (both user-defined and native) applied to a class.
20
+ """
21
+ user_defined: tuple[str, ...]
22
+ native: tuple[str, ...]
23
+ all: tuple[str, ...]
24
+
25
+ @dataclass
26
+ class MethodDecorators:
27
+ """
28
+ MethodDecorators is a dataclass that encapsulates information about method decorators.
29
+
30
+ Attributes
31
+ ----------
32
+ user_defined : tuple[str, ...]
33
+ A tuple containing the names of user-defined decorators applied to a method.
34
+ native : tuple[str, ...]
35
+ A tuple containing the names of native or built-in decorators applied to a method.
36
+ all : tuple[str, ...]
37
+ A tuple containing the names of all decorators (both user-defined and native) applied to a method.
38
+ """
39
+ user_defined: tuple[str, ...]
40
+ native: tuple[str, ...]
41
+ all: tuple[str, ...]
42
+
43
+ class ReflectDecorators(ast.NodeVisitor):
44
+ """
45
+ A class to analyze and extract decorators applied to a specific class or its methods.
46
+
47
+ This class uses the `ast` module to parse the source code of a given class and
48
+ extract the names of decorators applied to the class or its methods.
49
+
50
+ Parameters
51
+ ----------
52
+ cls : Type
53
+ The class to analyze for decorators.
54
+
55
+ Attributes
56
+ ----------
57
+ decorators : List[str]
58
+ A list of unique decorator names applied to the class or its methods.
59
+
60
+ Methods
61
+ -------
62
+ parse()
63
+ Parses the source code of the class and extracts decorator names.
64
+ visit_FunctionDef(node)
65
+ Visits function definitions in the AST and extracts their decorators.
66
+ visit_ClassDef(node)
67
+ Visits the class definition in the AST and extracts its decorators.
68
+ get_class_decorators() -> List[str]
69
+ Retrieves the decorators applied to the class itself.
70
+ get_method_decorators(method_name: str) -> List[str]
71
+ Retrieves the decorators for a specific method in the class.
72
+ """
73
+
74
+ def __init__(self, cls: Type):
75
+ """
76
+ Initializes the ReflectiveDecorators with the class to analyze.
77
+
78
+ Parameters
79
+ ----------
80
+ cls : Type
81
+ The class to analyze for decorators.
82
+ """
83
+ self._decorators: List[str] = []
84
+ self._method_decorators: dict = {}
85
+ self._class_decorators: List[str] = []
86
+ self._cls = cls
87
+ self._parsed = False
88
+
89
+ def visit_ParseSource(self) -> None:
90
+ """
91
+ Parses the source code of the class and extracts decorator names.
92
+
93
+ This method retrieves the source code of the class using `inspect.getsource`,
94
+ parses it into an abstract syntax tree (AST), and visits relevant nodes
95
+ to extract decorator names.
96
+
97
+ Returns
98
+ -------
99
+ dict
100
+ A dictionary containing lists of decorators:
101
+ - 'decorators': All unique decorators found in the class and its methods.
102
+ - 'method_decorators': A dictionary mapping method names to their decorators.
103
+ - 'class_decorators': A list of decorators applied to the class itself.
104
+ """
105
+ if not self._parsed:
106
+
107
+ # Try to get the source code of the class
108
+ try:
109
+ source = inspect.getsource(self._cls)
110
+ except (OSError, TypeError):
111
+ source = ""
112
+
113
+ # Parsed flag to avoid re-parsing
114
+ self._parsed = True
115
+
116
+ # If source code is not available, return empty lists
117
+ if not source:
118
+ return
119
+
120
+ # Parse the source code into an AST
121
+ tree = ast.parse(source)
122
+
123
+ # Visit the AST to extract decorators
124
+ self.visit(tree)
125
+
126
+ # Remove duplicates and non-decorator entries
127
+ self._decorators = list(set(self._decorators))
128
+
129
+ def visit_FunctionDef(self, node: ast.FunctionDef) -> None:
130
+ """
131
+ Visits function definitions in the AST and extracts their decorators.
132
+
133
+ Parameters
134
+ ----------
135
+ node : ast.FunctionDef
136
+ The function definition node in the AST.
137
+
138
+ Returns
139
+ -------
140
+ None
141
+ """
142
+ method_decos = []
143
+ for deco in node.decorator_list:
144
+ if isinstance(deco, ast.Name):
145
+ self._decorators.append(deco.id)
146
+ method_decos.append(deco.id)
147
+ elif isinstance(deco, ast.Call):
148
+ # Handles decorators with arguments like @deco(arg)
149
+ if isinstance(deco.func, ast.Name):
150
+ self._decorators.append(deco.func.id)
151
+ method_decos.append(deco.func.id)
152
+ elif isinstance(deco, ast.Attribute):
153
+ self._decorators.append(deco.attr)
154
+ method_decos.append(deco.attr)
155
+
156
+ # Store method-specific decorators
157
+ self._method_decorators[node.name] = method_decos
158
+
159
+ def visit_ClassDef(self, node: ast.ClassDef) -> None:
160
+ """
161
+ Visits the class definition in the AST and extracts its decorators.
162
+
163
+ Parameters
164
+ ----------
165
+ node : ast.ClassDef
166
+ The class definition node in the AST.
167
+
168
+ Returns
169
+ -------
170
+ None
171
+ """
172
+ if node.name == self._cls.__name__:
173
+ for deco in node.decorator_list:
174
+ if isinstance(deco, ast.Name):
175
+ self._decorators.append(deco.id)
176
+ self._class_decorators.append(deco.id)
177
+ elif isinstance(deco, ast.Call):
178
+ # Handles decorators with arguments like @deco(arg)
179
+ if isinstance(deco.func, ast.Name):
180
+ self._decorators.append(deco.func.id)
181
+ self._class_decorators.append(deco.func.id)
182
+ elif isinstance(deco, ast.Attribute):
183
+ self._decorators.append(deco.attr)
184
+ self._class_decorators.append(deco.attr)
185
+
186
+ # Visit methods within the class
187
+ for child in node.body:
188
+ if isinstance(child, ast.FunctionDef):
189
+ self.visit_FunctionDef(child)
190
+
191
+ # No need to visit deeper
192
+ return
193
+
194
+ def visit_NativeDecorator(self, decorator_name: str) -> bool:
195
+ """
196
+ Checks if a decorator name matches Python's native decorator patterns.
197
+ Parameters
198
+ ----------
199
+ decorator_name : str
200
+ The name of the decorator to check.
201
+ Returns
202
+ -------
203
+ bool
204
+ True if the decorator name matches any of the predefined native patterns,
205
+ False otherwise.
206
+ Notes
207
+ -----
208
+ The method uses a list of regular expressions to identify native Python
209
+ decorators, including built-ins, standard library modules (e.g., `functools`,
210
+ `dataclasses`, `contextlib`), and other commonly used patterns. It also
211
+ accounts for deprecated or obsolete decorators.
212
+ """
213
+
214
+ native_decorator_regular_expr = [
215
+ # Built-ins
216
+ r"^property$",
217
+ r"^\w+\.setter$",
218
+ r"^\w+\.deleter$",
219
+ r"^classmethod$",
220
+ r"^staticmethod$",
221
+
222
+ # abc module
223
+ r"^abstractmethod$",
224
+ r"^abstractclassmethod$",
225
+ r"^abstractstaticmethod$",
226
+
227
+ # functools
228
+ r"^functools\.cache$",
229
+ r"^functools\.lru_cache(\(.*\))?$",
230
+ r"^functools\.cached_property$",
231
+ r"^functools\.singledispatch$",
232
+ r"^functools\.singledispatchmethod$",
233
+ r"^functools\.wraps(\(.*\))?$",
234
+
235
+ # dataclasses
236
+ r"^dataclasses\.dataclass(\(.*\))?$",
237
+
238
+ # contextlib
239
+ r"^contextlib\.contextmanager$",
240
+
241
+ # typing
242
+ r"^typing\.final$",
243
+ r"^typing\.overload$",
244
+
245
+ # enum
246
+ r"^enum\.unique$",
247
+
248
+ # asyncio (obsoleto)
249
+ r"^asyncio\.coroutine$",
250
+
251
+ # unittest.mock
252
+ r"^unittest\.mock\.patch(\(.*\))?$",
253
+
254
+ # Añadidos adicionales
255
+ r"^contextlib\.asynccontextmanager$",
256
+ r"^typing\.runtime_checkable$",
257
+ r"^collections\.abc\.abstractproperty$",
258
+ ]
259
+
260
+ return any(re.fullmatch(pattern, decorator_name) for pattern in native_decorator_regular_expr)
261
+
262
+ def getClassDecorators(self) -> ClassDecorators:
263
+ """
264
+ Retrieves the decorators applied to the class itself.
265
+
266
+ Returns
267
+ -------
268
+ ClassDecorators
269
+ An object containing lists of decorator names for the class.
270
+ """
271
+
272
+ # Parse the source code to extract decorators
273
+ self.visit_ParseSource()
274
+
275
+ # Filter decorators into user-defined and native
276
+ user_defined = []
277
+ native = []
278
+
279
+ # Filter decorators into user-defined and native
280
+ for deco in self._class_decorators:
281
+ if not self.visit_NativeDecorator(deco):
282
+ user_defined.append(deco)
283
+ else:
284
+ native.append(deco)
285
+
286
+ # Return a ClassDecorators object containing the filtered lists
287
+ return ClassDecorators(
288
+ user_defined=tuple(user_defined),
289
+ native=tuple(native),
290
+ all=tuple(self._class_decorators)
291
+ )
292
+
293
+ def getMethodDecorators(self, method_name: str = None) -> MethodDecorators:
294
+ """
295
+ Retrieves the decorators for a specific method in the class.
296
+
297
+ Parameters
298
+ ----------
299
+ method_name : str
300
+ The name of the method to retrieve decorators for.
301
+
302
+ Returns
303
+ -------
304
+ MethodDecorators
305
+ An object containing lists of decorator names for the specified method.
306
+ """
307
+
308
+ # Parse the source code to extract decorators
309
+ self.visit_ParseSource()
310
+
311
+ # Handle mangled names for private methods
312
+ # Check if the method name is mangled (private)
313
+ if method_name.startswith("__") and not method_name.endswith("__"):
314
+ method_name = f"_{self._cls.__name__}{method_name}"
315
+
316
+ # Get the decorators for the specified method
317
+ decorators = self._method_decorators.get(method_name, [])
318
+
319
+ # Filter decorators into user-defined and native
320
+ user_defined = []
321
+ native = []
322
+
323
+ # Filter decorators into user-defined and native
324
+ for deco in decorators:
325
+ if not self.visit_NativeDecorator(deco):
326
+ user_defined.append(deco)
327
+ else:
328
+ native.append(deco)
329
+
330
+ # Return a MethodDecorators object containing the filtered lists
331
+ return MethodDecorators(
332
+ user_defined=tuple(user_defined),
333
+ native=tuple(native),
334
+ all=tuple(decorators)
335
+ )
@@ -1,20 +1,14 @@
1
1
  import abc
2
2
  from typing import Any, Type, TypeVar
3
3
  from orionis.luminate.contracts.support.reflection import IReflection
4
- from orionis.luminate.support.inspection.functions import (
5
- _ensure_abstract_class,
6
- _ensure_instantiable_class,
7
- _ensure_user_defined_class_instance,
8
- _ensure_valid_class_name,
9
- _ensure_valid_module,
10
- )
11
- from orionis.luminate.support.inspection.reflexion_abstract import ReflexionAbstract
12
- from orionis.luminate.support.inspection.reflexion_concrete import ReflexionConcrete
13
- from orionis.luminate.support.inspection.reflexion_concrete_with_abstract import ReflexionConcreteWithAbstract
14
- from orionis.luminate.support.inspection.reflexion_instance import ReflexionInstance
15
- from orionis.luminate.support.inspection.reflexion_instance_with_abstract import ReflexionInstanceWithAbstract
16
- from orionis.luminate.support.inspection.reflexion_module import ReflexionModule
17
- from orionis.luminate.support.inspection.reflexion_module_with_classname import ReflexionModuleWithClassName
4
+ from orionis.luminate.support.introspection.helpers.functions import HelpersReflection
5
+ from orionis.luminate.support.introspection.reflect_abstract import ReflexionAbstract
6
+ from orionis.luminate.support.introspection.reflexion_concrete import ReflexionConcrete
7
+ from orionis.luminate.support.introspection.reflexion_concrete_with_abstract import ReflexionConcreteWithAbstract
8
+ from orionis.luminate.support.introspection.reflection_instance import ReflectionInstance
9
+ from orionis.luminate.support.introspection.reflexion_instance_with_abstract import ReflexionInstanceWithAbstract
10
+ from orionis.luminate.support.introspection.reflexion_module import ReflexionModule
11
+ from orionis.luminate.support.introspection.reflexion_module_with_classname import ReflexionModuleWithClassName
18
12
 
19
13
  T = TypeVar('T')
20
14
  ABC = TypeVar('ABC', bound=abc.ABC)
@@ -45,7 +39,7 @@ class Reflection(IReflection):
45
39
  """
46
40
 
47
41
  @staticmethod
48
- def instance(instance: Any) -> 'ReflexionInstance':
42
+ def instance(instance: Any) -> 'ReflectionInstance':
49
43
  """Create a reflection object for a class instance.
50
44
 
51
45
  Parameters
@@ -55,7 +49,7 @@ class Reflection(IReflection):
55
49
 
56
50
  Returns
57
51
  -------
58
- ReflexionInstance
52
+ ReflectionInstance
59
53
  A reflection object encapsulating the instance
60
54
 
61
55
  Raises
@@ -65,8 +59,8 @@ class Reflection(IReflection):
65
59
  ValueError
66
60
  If the instance is from builtins, abc, or __main__
67
61
  """
68
- _ensure_user_defined_class_instance(instance)
69
- return ReflexionInstance(instance)
62
+ HelpersReflection.ensureUserDefinedClassInstance(instance)
63
+ return ReflectionInstance(instance)
70
64
 
71
65
  @staticmethod
72
66
  def instanceWithAbstract(instance: Any, abstract: Type[ABC]) -> 'ReflexionInstanceWithAbstract':
@@ -91,8 +85,8 @@ class Reflection(IReflection):
91
85
  ValueError
92
86
  If the instance is invalid or abstract is not actually abstract
93
87
  """
94
- _ensure_user_defined_class_instance(instance)
95
- _ensure_abstract_class(abstract)
88
+ HelpersReflection.ensureUserDefinedClassInstance(instance)
89
+ HelpersReflection.ensureAbstractClass(abstract)
96
90
  return ReflexionInstanceWithAbstract(instance, abstract)
97
91
 
98
92
  @staticmethod
@@ -116,7 +110,7 @@ class Reflection(IReflection):
116
110
  ValueError
117
111
  If the class is not abstract
118
112
  """
119
- _ensure_abstract_class(abstract)
113
+ HelpersReflection.ensureAbstractClass(abstract)
120
114
  return ReflexionAbstract(abstract)
121
115
 
122
116
  @staticmethod
@@ -140,7 +134,7 @@ class Reflection(IReflection):
140
134
  ValueError
141
135
  If the class is abstract or cannot be instantiated
142
136
  """
143
- _ensure_instantiable_class(concrete)
137
+ HelpersReflection.ensureInstantiableClass(concrete)
144
138
  return ReflexionConcrete(concrete)
145
139
 
146
140
  @staticmethod
@@ -166,8 +160,8 @@ class Reflection(IReflection):
166
160
  ValueError
167
161
  If concrete is not instantiable or abstract is not actually abstract
168
162
  """
169
- _ensure_instantiable_class(concrete)
170
- _ensure_abstract_class(abstract)
163
+ HelpersReflection.ensureInstantiableClass(concrete)
164
+ HelpersReflection.ensureAbstractClass(abstract)
171
165
  return ReflexionConcreteWithAbstract(concrete, abstract)
172
166
 
173
167
  @staticmethod
@@ -191,7 +185,7 @@ class Reflection(IReflection):
191
185
  ValueError
192
186
  If the module cannot be imported
193
187
  """
194
- _ensure_valid_module(module)
188
+ HelpersReflection.ensureValidModule(module)
195
189
  return ReflexionModule(module)
196
190
 
197
191
  @staticmethod
@@ -217,6 +211,6 @@ class Reflection(IReflection):
217
211
  ValueError
218
212
  If the module cannot be imported or the class doesn't exist in it
219
213
  """
220
- _ensure_valid_module(module)
221
- _ensure_valid_class_name(module, class_name)
214
+ HelpersReflection.ensureValidModule(module)
215
+ HelpersReflection.ensureValidClassName(class_name)
222
216
  return ReflexionModuleWithClassName(module, class_name)