orionis 0.199.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.
- orionis/framework.py +1 -1
- orionis/luminate/console/base/command.py +88 -80
- orionis/luminate/console/command_filter.py +0 -1
- orionis/luminate/console/commands/cache_clear.py +19 -11
- orionis/luminate/console/commands/help.py +19 -10
- orionis/luminate/console/commands/schedule_work.py +1 -4
- orionis/luminate/console/commands/version.py +1 -3
- orionis/luminate/console/exceptions/cli-orionis-value-error.py +41 -0
- orionis/luminate/console/exceptions/cli_exception.py +1 -127
- orionis/luminate/console/exceptions/cli_runtime_error.py +41 -0
- orionis/luminate/console/exceptions/cli_schedule_exception.py +41 -0
- orionis/luminate/console/output/console.py +160 -68
- orionis/luminate/console/output/executor.py +1 -1
- orionis/luminate/console/output/styles.py +12 -4
- orionis/luminate/console/parser.py +1 -1
- orionis/luminate/container/container_integrity.py +56 -1
- orionis/luminate/contracts/console/base/command.py +65 -75
- orionis/luminate/contracts/console/output/console.py +160 -60
- orionis/luminate/contracts/support/{exception_to_dict.py → exception_parse.py} +2 -2
- orionis/luminate/facades/tests/tests_facade.py +1 -1
- orionis/luminate/services/commands/scheduler_service.py +1 -1
- orionis/luminate/support/{exception_to_dict.py → exception_parse.py} +11 -16
- orionis/luminate/support/inspection/container_integrity.py +292 -0
- orionis/luminate/support/inspection/functions.py +235 -0
- orionis/luminate/support/inspection/reflection.py +649 -0
- orionis/luminate/support/inspection/reflexion_abstract.py +23 -0
- orionis/luminate/support/inspection/reflexion_concrete.py +24 -0
- orionis/luminate/support/inspection/reflexion_concrete_with_abstract.py +31 -0
- orionis/luminate/support/inspection/reflexion_instance.py +364 -0
- orionis/luminate/support/inspection/reflexion_instance_with_abstract.py +309 -0
- orionis/luminate/support/inspection/reflexion_module.py +19 -0
- orionis/luminate/support/inspection/reflexion_module_with_classname.py +22 -0
- orionis/luminate/test/{exception.py → test_exception.py} +1 -2
- orionis/luminate/test/test_result.py +30 -0
- orionis/luminate/test/test_status.py +22 -0
- orionis/luminate/test/tests.py +67 -0
- orionis/luminate/test/unit_test.py +276 -56
- {orionis-0.199.0.dist-info → orionis-0.202.0.dist-info}/METADATA +1 -1
- {orionis-0.199.0.dist-info → orionis-0.202.0.dist-info}/RECORD +45 -31
- tests/main.py +0 -0
- orionis/luminate/console/commands/tests.py +0 -34
- tests/tools/class_example.py +0 -50
- tests/tools/test_reflection.py +0 -128
- {tests/tools → orionis/luminate/support/inspection}/__init__.py +0 -0
- {orionis-0.199.0.dist-info → orionis-0.202.0.dist-info}/LICENCE +0 -0
- {orionis-0.199.0.dist-info → orionis-0.202.0.dist-info}/WHEEL +0 -0
- {orionis-0.199.0.dist-info → orionis-0.202.0.dist-info}/entry_points.txt +0 -0
- {orionis-0.199.0.dist-info → orionis-0.202.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,649 @@
|
|
1
|
+
import abc
|
2
|
+
from typing import Any, Type, TypeVar
|
3
|
+
from orionis.luminate.support.inspection.functions import (
|
4
|
+
ensure_abstract_class,
|
5
|
+
ensure_instantiable_class,
|
6
|
+
ensure_user_defined_class_instance,
|
7
|
+
ensure_valid_class_name,
|
8
|
+
ensure_valid_module,
|
9
|
+
)
|
10
|
+
from orionis.luminate.support.inspection.reflexion_abstract import ReflexionAbstract
|
11
|
+
from orionis.luminate.support.inspection.reflexion_concrete import ReflexionConcrete
|
12
|
+
from orionis.luminate.support.inspection.reflexion_concrete_with_abstract import ReflexionConcreteWithAbstract
|
13
|
+
from orionis.luminate.support.inspection.reflexion_instance import ReflexionInstance
|
14
|
+
from orionis.luminate.support.inspection.reflexion_instance_with_abstract import ReflexionInstanceWithAbstract
|
15
|
+
from orionis.luminate.support.inspection.reflexion_module import ReflexionModule
|
16
|
+
from orionis.luminate.support.inspection.reflexion_module_with_classname import ReflexionModuleWithClassName
|
17
|
+
|
18
|
+
T = TypeVar('T')
|
19
|
+
ABC = TypeVar('ABC', bound=abc.ABC)
|
20
|
+
|
21
|
+
class Reflection:
|
22
|
+
"""A static class providing factory methods for creating reflection objects.
|
23
|
+
|
24
|
+
This class provides methods to create various types of reflection objects
|
25
|
+
that encapsulate different aspects of Python's reflection capabilities.
|
26
|
+
Each method validates its inputs before creating the appropriate reflection object.
|
27
|
+
|
28
|
+
Methods
|
29
|
+
-------
|
30
|
+
instance(instance: Any) -> ReflexionInstance
|
31
|
+
Creates a reflection object for a class instance
|
32
|
+
instanceWithAbstract(instance: Any, abstract: Type[ABC]) -> ReflexionInstanceWithAbstract
|
33
|
+
Creates a reflection object for a class instance with its abstract parent
|
34
|
+
abstract(abstract: Type[ABC]) -> ReflexionAbstract
|
35
|
+
Creates a reflection object for an abstract class
|
36
|
+
concrete(concrete: Type[T]) -> ReflexionConcrete
|
37
|
+
Creates a reflection object for a concrete class
|
38
|
+
concreteWithAbstract(concrete: Type[T], abstract: Type[ABC]) -> ReflexionConcreteWithAbstract
|
39
|
+
Creates a reflection object for a concrete class with its abstract parent
|
40
|
+
module(module: str) -> ReflexionModule
|
41
|
+
Creates a reflection object for a module
|
42
|
+
moduleWithClassName(module: str, class_name: str) -> ReflexionModuleWithClassName
|
43
|
+
Creates a reflection object for a module with a specific class name
|
44
|
+
"""
|
45
|
+
|
46
|
+
@staticmethod
|
47
|
+
def instance(instance: Any) -> 'ReflexionInstance':
|
48
|
+
"""Create a reflection object for a class instance.
|
49
|
+
|
50
|
+
Parameters
|
51
|
+
----------
|
52
|
+
instance : Any
|
53
|
+
The instance to reflect upon
|
54
|
+
|
55
|
+
Returns
|
56
|
+
-------
|
57
|
+
ReflexionInstance
|
58
|
+
A reflection object encapsulating the instance
|
59
|
+
|
60
|
+
Raises
|
61
|
+
------
|
62
|
+
TypeError
|
63
|
+
If the input is not an object instance
|
64
|
+
ValueError
|
65
|
+
If the instance is from builtins, abc, or __main__
|
66
|
+
"""
|
67
|
+
ensure_user_defined_class_instance(instance)
|
68
|
+
return ReflexionInstance(instance)
|
69
|
+
|
70
|
+
@staticmethod
|
71
|
+
def instanceWithAbstract(instance: Any, abstract: Type[ABC]) -> 'ReflexionInstanceWithAbstract':
|
72
|
+
"""Create a reflection object for a class instance with its abstract parent.
|
73
|
+
|
74
|
+
Parameters
|
75
|
+
----------
|
76
|
+
instance : Any
|
77
|
+
The instance to reflect upon
|
78
|
+
abstract : Type[ABC]
|
79
|
+
The abstract parent class
|
80
|
+
|
81
|
+
Returns
|
82
|
+
-------
|
83
|
+
ReflexionInstanceWithAbstract
|
84
|
+
A reflection object encapsulating the instance and its abstract parent
|
85
|
+
|
86
|
+
Raises
|
87
|
+
------
|
88
|
+
TypeError
|
89
|
+
If the instance is not an object or abstract is not a class
|
90
|
+
ValueError
|
91
|
+
If the instance is invalid or abstract is not actually abstract
|
92
|
+
"""
|
93
|
+
ensure_user_defined_class_instance(instance)
|
94
|
+
ensure_abstract_class(abstract)
|
95
|
+
return ReflexionInstanceWithAbstract(instance, abstract)
|
96
|
+
|
97
|
+
@staticmethod
|
98
|
+
def abstract(abstract: Type[ABC]) -> 'ReflexionAbstract':
|
99
|
+
"""Create a reflection object for an abstract class.
|
100
|
+
|
101
|
+
Parameters
|
102
|
+
----------
|
103
|
+
abstract : Type[ABC]
|
104
|
+
The abstract class to reflect upon
|
105
|
+
|
106
|
+
Returns
|
107
|
+
-------
|
108
|
+
ReflexionAbstract
|
109
|
+
A reflection object encapsulating the abstract class
|
110
|
+
|
111
|
+
Raises
|
112
|
+
------
|
113
|
+
TypeError
|
114
|
+
If the input is not a class
|
115
|
+
ValueError
|
116
|
+
If the class is not abstract
|
117
|
+
"""
|
118
|
+
ensure_abstract_class(abstract)
|
119
|
+
return ReflexionAbstract(abstract)
|
120
|
+
|
121
|
+
@staticmethod
|
122
|
+
def concrete(concrete: Type[T]) -> 'ReflexionConcrete':
|
123
|
+
"""Create a reflection object for a concrete class.
|
124
|
+
|
125
|
+
Parameters
|
126
|
+
----------
|
127
|
+
concrete : Type[T]
|
128
|
+
The concrete class to reflect upon
|
129
|
+
|
130
|
+
Returns
|
131
|
+
-------
|
132
|
+
ReflexionConcrete
|
133
|
+
A reflection object encapsulating the concrete class
|
134
|
+
|
135
|
+
Raises
|
136
|
+
------
|
137
|
+
TypeError
|
138
|
+
If the input is not a class
|
139
|
+
ValueError
|
140
|
+
If the class is abstract or cannot be instantiated
|
141
|
+
"""
|
142
|
+
ensure_instantiable_class(concrete)
|
143
|
+
return ReflexionConcrete(concrete)
|
144
|
+
|
145
|
+
@staticmethod
|
146
|
+
def concreteWithAbstract(concrete: Type[T], abstract: Type[ABC]) -> 'ReflexionConcreteWithAbstract':
|
147
|
+
"""Create a reflection object for a concrete class with its abstract parent.
|
148
|
+
|
149
|
+
Parameters
|
150
|
+
----------
|
151
|
+
concrete : Type[T]
|
152
|
+
The concrete class to reflect upon
|
153
|
+
abstract : Type[ABC]
|
154
|
+
The abstract parent class
|
155
|
+
|
156
|
+
Returns
|
157
|
+
-------
|
158
|
+
ReflexionConcreteWithAbstract
|
159
|
+
A reflection object encapsulating the concrete class and its abstract parent
|
160
|
+
|
161
|
+
Raises
|
162
|
+
------
|
163
|
+
TypeError
|
164
|
+
If either input is not a class
|
165
|
+
ValueError
|
166
|
+
If concrete is not instantiable or abstract is not actually abstract
|
167
|
+
"""
|
168
|
+
ensure_instantiable_class(concrete)
|
169
|
+
ensure_abstract_class(abstract)
|
170
|
+
return ReflexionConcreteWithAbstract(concrete, abstract)
|
171
|
+
|
172
|
+
@staticmethod
|
173
|
+
def module(module: str) -> 'ReflexionModule':
|
174
|
+
"""Create a reflection object for a module.
|
175
|
+
|
176
|
+
Parameters
|
177
|
+
----------
|
178
|
+
module : str
|
179
|
+
The module name to reflect upon
|
180
|
+
|
181
|
+
Returns
|
182
|
+
-------
|
183
|
+
ReflexionModule
|
184
|
+
A reflection object encapsulating the module
|
185
|
+
|
186
|
+
Raises
|
187
|
+
------
|
188
|
+
TypeError
|
189
|
+
If the input is not a string
|
190
|
+
ValueError
|
191
|
+
If the module cannot be imported
|
192
|
+
"""
|
193
|
+
ensure_valid_module(module)
|
194
|
+
return ReflexionModule(module)
|
195
|
+
|
196
|
+
@staticmethod
|
197
|
+
def moduleWithClassName(module: str, class_name: str) -> 'ReflexionModuleWithClassName':
|
198
|
+
"""Create a reflection object for a module with a specific class name.
|
199
|
+
|
200
|
+
Parameters
|
201
|
+
----------
|
202
|
+
module : str
|
203
|
+
The module name to reflect upon
|
204
|
+
class_name : str
|
205
|
+
The class name to look for in the module
|
206
|
+
|
207
|
+
Returns
|
208
|
+
-------
|
209
|
+
ReflexionModuleWithClassName
|
210
|
+
A reflection object encapsulating the module and class name
|
211
|
+
|
212
|
+
Raises
|
213
|
+
------
|
214
|
+
TypeError
|
215
|
+
If either input is not a string
|
216
|
+
ValueError
|
217
|
+
If the module cannot be imported or the class doesn't exist in it
|
218
|
+
"""
|
219
|
+
ensure_valid_module(module)
|
220
|
+
ensure_valid_class_name(module, class_name)
|
221
|
+
return ReflexionModuleWithClassName(module, class_name)
|
222
|
+
|
223
|
+
|
224
|
+
|
225
|
+
|
226
|
+
|
227
|
+
|
228
|
+
|
229
|
+
|
230
|
+
|
231
|
+
|
232
|
+
|
233
|
+
|
234
|
+
|
235
|
+
|
236
|
+
|
237
|
+
|
238
|
+
|
239
|
+
|
240
|
+
|
241
|
+
# def __inidt__(self,
|
242
|
+
# instance: Any = None, # Instancia ya creada de una clase
|
243
|
+
# concrete: Callable[..., Any] = None, # Clase concreta a instanciar
|
244
|
+
# abstract: Callable[..., Any] = None, # Clase abstracta a implementar en clases hijas
|
245
|
+
# module: str = None, # Módulo donde se encuentra la clase
|
246
|
+
# class_name: str = None # Nombre de la clase
|
247
|
+
# ):
|
248
|
+
|
249
|
+
# # Garantizar que al menos un argumento sea proporcionado
|
250
|
+
# if not any([abstract, concrete, module, class_name]):
|
251
|
+
# raise ValueError("At least one argument must be provided.")
|
252
|
+
|
253
|
+
|
254
|
+
# # Validar que 'abstract' y 'concrete' sean callables
|
255
|
+
# if abstract and not callable(abstract):
|
256
|
+
# raise TypeError("The 'abstract' argument must be callable.")
|
257
|
+
# if concrete and not callable(concrete):
|
258
|
+
# raise TypeError("The 'concrete' argument must be callable.")
|
259
|
+
|
260
|
+
# # Validar que si se proporciona una clase, también se proporcione el módulo
|
261
|
+
# if class_name and not module:
|
262
|
+
# raise ValueError("If a class name is provided, a module name must also be provided.")
|
263
|
+
|
264
|
+
# # Validar que el módulo exista e importarlo
|
265
|
+
# if module:
|
266
|
+
# try:
|
267
|
+
# self._module = importlib.import_module(module)
|
268
|
+
# except ModuleNotFoundError:
|
269
|
+
# raise ValueError(f"Module '{module}' not found.")
|
270
|
+
|
271
|
+
# # Validar que la clase exista en el módulo
|
272
|
+
# if module and class_name:
|
273
|
+
# if not hasattr(self._module, class_name):
|
274
|
+
# raise ValueError(f"Class '{class_name}' not found in module '{module}'.")
|
275
|
+
|
276
|
+
# # Validar que la clase no sea abstracta antes de instanciarla
|
277
|
+
# if concrete and inspect.isabstract(concrete):
|
278
|
+
# raise TypeError(f"Cannot instantiate abstract class '{concrete.__name__}'.")
|
279
|
+
|
280
|
+
|
281
|
+
# def safeImport(self):
|
282
|
+
# """
|
283
|
+
# Safely imports the specified module and assigns the class object if a classname is provided.
|
284
|
+
|
285
|
+
# This method raises a ValueError if the module cannot be imported or if the class does not exist
|
286
|
+
# within the module.
|
287
|
+
|
288
|
+
# Raises
|
289
|
+
# ------
|
290
|
+
# ValueError
|
291
|
+
# If the module cannot be imported or the class does not exist in the module.
|
292
|
+
# """
|
293
|
+
# try:
|
294
|
+
# module = importlib.import_module(self.module_name)
|
295
|
+
# if self.classname:
|
296
|
+
# self.cls = getattr(module, self.classname, None)
|
297
|
+
# if self.cls is None:
|
298
|
+
# raise ValueError(f"Class '{self.classname}' not found in module '{self.module_name}'.")
|
299
|
+
# except ImportError as e:
|
300
|
+
# raise ValueError(f"Error importing module '{self.module_name}': {e}")
|
301
|
+
|
302
|
+
|
303
|
+
|
304
|
+
|
305
|
+
|
306
|
+
|
307
|
+
|
308
|
+
|
309
|
+
|
310
|
+
|
311
|
+
|
312
|
+
|
313
|
+
|
314
|
+
|
315
|
+
|
316
|
+
|
317
|
+
|
318
|
+
|
319
|
+
|
320
|
+
|
321
|
+
|
322
|
+
|
323
|
+
|
324
|
+
|
325
|
+
|
326
|
+
|
327
|
+
|
328
|
+
|
329
|
+
|
330
|
+
|
331
|
+
# def getFile(self) -> str:
|
332
|
+
# """
|
333
|
+
# Retrieves the file path where the class is defined.
|
334
|
+
|
335
|
+
# Returns
|
336
|
+
# -------
|
337
|
+
# str
|
338
|
+
# The file path if the class is found, otherwise raises an error.
|
339
|
+
|
340
|
+
# Raises
|
341
|
+
# ------
|
342
|
+
# ValueError
|
343
|
+
# If the class has not been loaded yet.
|
344
|
+
# """
|
345
|
+
# if not self.cls:
|
346
|
+
# raise ValueError("Class not loaded. Use 'safeImport()' first.")
|
347
|
+
# return inspect.getfile(self.cls)
|
348
|
+
|
349
|
+
# def hasClass(self) -> bool:
|
350
|
+
# """
|
351
|
+
# Checks whether the class object is available.
|
352
|
+
|
353
|
+
# Returns
|
354
|
+
# -------
|
355
|
+
# bool
|
356
|
+
# True if the class is loaded, False otherwise.
|
357
|
+
# """
|
358
|
+
# return self.cls is not None
|
359
|
+
|
360
|
+
# def hasMethod(self, method_name: str) -> bool:
|
361
|
+
# """
|
362
|
+
# Checks whether the specified method exists in the class.
|
363
|
+
|
364
|
+
# Parameters
|
365
|
+
# ----------
|
366
|
+
# method_name : str
|
367
|
+
# The name of the method to check.
|
368
|
+
|
369
|
+
# Returns
|
370
|
+
# -------
|
371
|
+
# bool
|
372
|
+
# True if the method exists, False otherwise.
|
373
|
+
# """
|
374
|
+
# return hasattr(self.cls, method_name) if self.cls else False
|
375
|
+
|
376
|
+
# def hasProperty(self, prop: str) -> bool:
|
377
|
+
# """
|
378
|
+
# Checks whether the specified property exists in the class.
|
379
|
+
|
380
|
+
# Parameters
|
381
|
+
# ----------
|
382
|
+
# prop : str
|
383
|
+
# The name of the property to check.
|
384
|
+
|
385
|
+
# Returns
|
386
|
+
# -------
|
387
|
+
# bool
|
388
|
+
# True if the property exists, False otherwise.
|
389
|
+
# """
|
390
|
+
# return hasattr(self.cls, prop) if self.cls else False
|
391
|
+
|
392
|
+
# def hasConstant(self, constant: str) -> bool:
|
393
|
+
# """
|
394
|
+
# Checks whether the specified constant exists in the class.
|
395
|
+
|
396
|
+
# Parameters
|
397
|
+
# ----------
|
398
|
+
# constant : str
|
399
|
+
# The name of the constant to check.
|
400
|
+
|
401
|
+
# Returns
|
402
|
+
# -------
|
403
|
+
# bool
|
404
|
+
# True if the constant exists, False otherwise.
|
405
|
+
# """
|
406
|
+
# return hasattr(self.cls, constant) if self.cls else False
|
407
|
+
|
408
|
+
# def getAttributes(self) -> List[str]:
|
409
|
+
# """
|
410
|
+
# Retrieves a list of all attributes (including methods and properties) of the class.
|
411
|
+
|
412
|
+
# Returns
|
413
|
+
# -------
|
414
|
+
# list
|
415
|
+
# A list of attribute names in the class.
|
416
|
+
# """
|
417
|
+
# return dir(self.cls) if self.cls else []
|
418
|
+
|
419
|
+
# def getConstructor(self):
|
420
|
+
# """
|
421
|
+
# Retrieves the constructor (__init__) of the class.
|
422
|
+
|
423
|
+
# Returns
|
424
|
+
# -------
|
425
|
+
# function or None
|
426
|
+
# The constructor method if available, otherwise None.
|
427
|
+
# """
|
428
|
+
# return self.cls.__init__ if self.cls else None
|
429
|
+
|
430
|
+
# def getDocComment(self) -> Optional[str]:
|
431
|
+
# """
|
432
|
+
# Retrieves the docstring of the class.
|
433
|
+
|
434
|
+
# Returns
|
435
|
+
# -------
|
436
|
+
# str or None
|
437
|
+
# The docstring of the class if available, otherwise None.
|
438
|
+
# """
|
439
|
+
# if not self.cls:
|
440
|
+
# raise ValueError("Class not loaded. Use 'safeImport()' first.")
|
441
|
+
# return self.cls.__doc__
|
442
|
+
|
443
|
+
# def getFileName(self, remove_extension: bool = False) -> str:
|
444
|
+
# """
|
445
|
+
# Retrieves the file name where the class is defined, the same as `get_file()`.
|
446
|
+
|
447
|
+
# Parameters
|
448
|
+
# ----------
|
449
|
+
# remove_extension : bool, optional
|
450
|
+
# If True, the file extension will be removed from the filename. Default is False.
|
451
|
+
|
452
|
+
# Returns
|
453
|
+
# -------
|
454
|
+
# str
|
455
|
+
# The file name of the class definition.
|
456
|
+
# """
|
457
|
+
# file_name = os.path.basename(self.getFile())
|
458
|
+
# if remove_extension:
|
459
|
+
# file_name = os.path.splitext(file_name)[0]
|
460
|
+
# return file_name
|
461
|
+
|
462
|
+
# def getMethod(self, method_name: str):
|
463
|
+
# """
|
464
|
+
# Retrieves the specified method from the class.
|
465
|
+
|
466
|
+
# Parameters
|
467
|
+
# ----------
|
468
|
+
# method_name : str
|
469
|
+
# The name of the method to retrieve.
|
470
|
+
|
471
|
+
# Returns
|
472
|
+
# -------
|
473
|
+
# function or None
|
474
|
+
# The method if it exists, otherwise None.
|
475
|
+
# """
|
476
|
+
# return getattr(self.cls, method_name, None) if self.cls else None
|
477
|
+
|
478
|
+
# def getMethods(self) -> List[str]:
|
479
|
+
# """
|
480
|
+
# Retrieves a list of all methods in the class.
|
481
|
+
|
482
|
+
# Returns
|
483
|
+
# -------
|
484
|
+
# list
|
485
|
+
# A list of method names in the class.
|
486
|
+
# """
|
487
|
+
# return [method for method, _ in inspect.getmembers(self.cls, predicate=inspect.isfunction)] if self.cls else []
|
488
|
+
|
489
|
+
# def getName(self) -> str:
|
490
|
+
# """
|
491
|
+
# Retrieves the name of the class.
|
492
|
+
|
493
|
+
# Returns
|
494
|
+
# -------
|
495
|
+
# str or None
|
496
|
+
# The name of the class if available, otherwise None.
|
497
|
+
# """
|
498
|
+
# return self.cls.__name__ if self.cls else None
|
499
|
+
|
500
|
+
# def getParentClass(self) -> Optional[tuple]:
|
501
|
+
# """
|
502
|
+
# Retrieves the parent classes (base classes) of the class.
|
503
|
+
|
504
|
+
# Returns
|
505
|
+
# -------
|
506
|
+
# tuple or None
|
507
|
+
# A tuple of base classes if available, otherwise None.
|
508
|
+
# """
|
509
|
+
# return self.cls.__bases__ if self.cls else None
|
510
|
+
|
511
|
+
# def getProperties(self) -> List[str]:
|
512
|
+
# """
|
513
|
+
# Retrieves a list of all properties of the class.
|
514
|
+
|
515
|
+
# Returns
|
516
|
+
# -------
|
517
|
+
# list
|
518
|
+
# A list of property names in the class.
|
519
|
+
# """
|
520
|
+
# return [name for name, value in inspect.getmembers(self.cls, lambda x: isinstance(x, property))] if self.cls else []
|
521
|
+
|
522
|
+
# def getProperty(self, prop: str):
|
523
|
+
# """
|
524
|
+
# Retrieves the specified property from the class.
|
525
|
+
|
526
|
+
# Parameters
|
527
|
+
# ----------
|
528
|
+
# prop : str
|
529
|
+
# The name of the property to retrieve.
|
530
|
+
|
531
|
+
# Returns
|
532
|
+
# -------
|
533
|
+
# property or None
|
534
|
+
# The property if it exists, otherwise None.
|
535
|
+
# """
|
536
|
+
# return getattr(self.cls, prop, None) if self.cls else None
|
537
|
+
|
538
|
+
# def isAbstract(self) -> bool:
|
539
|
+
# """
|
540
|
+
# Checks whether the class is abstract.
|
541
|
+
|
542
|
+
# Returns
|
543
|
+
# -------
|
544
|
+
# bool
|
545
|
+
# True if the class is abstract, False otherwise.
|
546
|
+
# """
|
547
|
+
# return hasattr(self.cls, '__abstractmethods__') and bool(self.cls.__abstractmethods__) if self.cls else False
|
548
|
+
|
549
|
+
# def isEnum(self) -> bool:
|
550
|
+
# """
|
551
|
+
# Checks whether the class is an enumeration.
|
552
|
+
|
553
|
+
# Returns
|
554
|
+
# -------
|
555
|
+
# bool
|
556
|
+
# True if the class is a subclass of Enum, False otherwise.
|
557
|
+
# """
|
558
|
+
# return self.cls is not None and isinstance(self.cls, type) and issubclass(self.cls, Enum)
|
559
|
+
|
560
|
+
# def isSubclassOf(self, parent: type) -> bool:
|
561
|
+
# """
|
562
|
+
# Checks whether the class is a subclass of the specified parent class.
|
563
|
+
|
564
|
+
# Parameters
|
565
|
+
# ----------
|
566
|
+
# parent : type
|
567
|
+
# The parent class to check against.
|
568
|
+
|
569
|
+
# Returns
|
570
|
+
# -------
|
571
|
+
# bool
|
572
|
+
# True if the class is a subclass of the parent, False otherwise.
|
573
|
+
# """
|
574
|
+
# return self.cls is not None and issubclass(self.cls, parent)
|
575
|
+
|
576
|
+
# def isInstanceOf(self, instance: Any) -> bool:
|
577
|
+
# """
|
578
|
+
# Checks whether the class is an instance of the specified class.
|
579
|
+
|
580
|
+
# Parameters
|
581
|
+
# ----------
|
582
|
+
# parent : type
|
583
|
+
# The class to check against.
|
584
|
+
|
585
|
+
# Returns
|
586
|
+
# -------
|
587
|
+
# bool
|
588
|
+
# True if the class is a subclass of the parent, False otherwise.
|
589
|
+
# """
|
590
|
+
# return self.cls is not None and isinstance(instance, self.cls)
|
591
|
+
|
592
|
+
# def isIterable(self) -> bool:
|
593
|
+
# """
|
594
|
+
# Checks whether the class is iterable.
|
595
|
+
|
596
|
+
# Returns
|
597
|
+
# -------
|
598
|
+
# bool
|
599
|
+
# True if the class is iterable, False otherwise.
|
600
|
+
# """
|
601
|
+
# return hasattr(self.cls, '__iter__') if self.cls else False
|
602
|
+
|
603
|
+
# def isInstantiable(self) -> bool:
|
604
|
+
# """
|
605
|
+
# Checks whether the class can be instantiated.
|
606
|
+
|
607
|
+
# Returns
|
608
|
+
# -------
|
609
|
+
# bool
|
610
|
+
# True if the class is callable and not abstract, False otherwise.
|
611
|
+
# """
|
612
|
+
# return self.cls is not None and callable(self.cls) and not self.isAbstract()
|
613
|
+
|
614
|
+
# def newInstance(self, *args, **kwargs):
|
615
|
+
# """
|
616
|
+
# Creates a new instance of the class if it is instantiable.
|
617
|
+
|
618
|
+
# Parameters
|
619
|
+
# ----------
|
620
|
+
# args : tuple
|
621
|
+
# Arguments to pass to the class constructor.
|
622
|
+
# kwargs : dict
|
623
|
+
# Keyword arguments to pass to the class constructor.
|
624
|
+
|
625
|
+
# Returns
|
626
|
+
# -------
|
627
|
+
# object
|
628
|
+
# A new instance of the class.
|
629
|
+
|
630
|
+
# Raises
|
631
|
+
# ------
|
632
|
+
# TypeError
|
633
|
+
# If the class is not instantiable.
|
634
|
+
# """
|
635
|
+
# if self.isInstantiable():
|
636
|
+
# return self.cls(*args, **kwargs)
|
637
|
+
# raise TypeError(f"Cannot instantiate class '{self.classname}'. It may be abstract or not callable.")
|
638
|
+
|
639
|
+
# def __str__(self) -> str:
|
640
|
+
# """
|
641
|
+
# Returns a string representation of the Reflection instance.
|
642
|
+
|
643
|
+
# Returns
|
644
|
+
# -------
|
645
|
+
# str
|
646
|
+
# A string describing the class and module.
|
647
|
+
# """
|
648
|
+
# status = "loaded" if self.cls else "not loaded"
|
649
|
+
# return f"<Orionis Reflection class '{self.classname}' in module '{self.module_name}' ({status})>"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
from typing import Type, TypeVar
|
2
|
+
import abc
|
3
|
+
|
4
|
+
T = TypeVar('T')
|
5
|
+
ABC = TypeVar('ABC', bound=abc.ABC)
|
6
|
+
|
7
|
+
class ReflexionAbstract:
|
8
|
+
"""A reflection object encapsulating an abstract class.
|
9
|
+
|
10
|
+
Parameters
|
11
|
+
----------
|
12
|
+
abstract : Type[ABC]
|
13
|
+
The abstract class being reflected upon
|
14
|
+
|
15
|
+
Attributes
|
16
|
+
----------
|
17
|
+
_abstract : Type[ABC]
|
18
|
+
The encapsulated abstract class
|
19
|
+
"""
|
20
|
+
|
21
|
+
def __init__(self, abstract: Type[ABC]) -> None:
|
22
|
+
"""Initialize with the abstract class."""
|
23
|
+
self._abstract = abstract
|
@@ -0,0 +1,24 @@
|
|
1
|
+
from typing import Type, TypeVar
|
2
|
+
import abc
|
3
|
+
|
4
|
+
T = TypeVar('T')
|
5
|
+
ABC = TypeVar('ABC', bound=abc.ABC)
|
6
|
+
|
7
|
+
class ReflexionConcrete:
|
8
|
+
"""A reflection object encapsulating a concrete class.
|
9
|
+
|
10
|
+
Parameters
|
11
|
+
----------
|
12
|
+
concrete : Type[T]
|
13
|
+
The concrete class being reflected upon
|
14
|
+
|
15
|
+
Attributes
|
16
|
+
----------
|
17
|
+
_concrete : Type[T]
|
18
|
+
The encapsulated concrete class
|
19
|
+
"""
|
20
|
+
|
21
|
+
def __init__(self, concrete: Type[T]) -> None:
|
22
|
+
"""Initialize with the concrete class."""
|
23
|
+
self._concrete = concrete
|
24
|
+
|