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.
Files changed (48) hide show
  1. orionis/framework.py +1 -1
  2. orionis/luminate/console/base/command.py +88 -80
  3. orionis/luminate/console/command_filter.py +0 -1
  4. orionis/luminate/console/commands/cache_clear.py +19 -11
  5. orionis/luminate/console/commands/help.py +19 -10
  6. orionis/luminate/console/commands/schedule_work.py +1 -4
  7. orionis/luminate/console/commands/version.py +1 -3
  8. orionis/luminate/console/exceptions/cli-orionis-value-error.py +41 -0
  9. orionis/luminate/console/exceptions/cli_exception.py +1 -127
  10. orionis/luminate/console/exceptions/cli_runtime_error.py +41 -0
  11. orionis/luminate/console/exceptions/cli_schedule_exception.py +41 -0
  12. orionis/luminate/console/output/console.py +160 -68
  13. orionis/luminate/console/output/executor.py +1 -1
  14. orionis/luminate/console/output/styles.py +12 -4
  15. orionis/luminate/console/parser.py +1 -1
  16. orionis/luminate/container/container_integrity.py +56 -1
  17. orionis/luminate/contracts/console/base/command.py +65 -75
  18. orionis/luminate/contracts/console/output/console.py +160 -60
  19. orionis/luminate/contracts/support/{exception_to_dict.py → exception_parse.py} +2 -2
  20. orionis/luminate/facades/tests/tests_facade.py +1 -1
  21. orionis/luminate/services/commands/scheduler_service.py +1 -1
  22. orionis/luminate/support/{exception_to_dict.py → exception_parse.py} +11 -16
  23. orionis/luminate/support/inspection/container_integrity.py +292 -0
  24. orionis/luminate/support/inspection/functions.py +235 -0
  25. orionis/luminate/support/inspection/reflection.py +649 -0
  26. orionis/luminate/support/inspection/reflexion_abstract.py +23 -0
  27. orionis/luminate/support/inspection/reflexion_concrete.py +24 -0
  28. orionis/luminate/support/inspection/reflexion_concrete_with_abstract.py +31 -0
  29. orionis/luminate/support/inspection/reflexion_instance.py +364 -0
  30. orionis/luminate/support/inspection/reflexion_instance_with_abstract.py +309 -0
  31. orionis/luminate/support/inspection/reflexion_module.py +19 -0
  32. orionis/luminate/support/inspection/reflexion_module_with_classname.py +22 -0
  33. orionis/luminate/test/{exception.py → test_exception.py} +1 -2
  34. orionis/luminate/test/test_result.py +30 -0
  35. orionis/luminate/test/test_status.py +22 -0
  36. orionis/luminate/test/tests.py +67 -0
  37. orionis/luminate/test/unit_test.py +276 -56
  38. {orionis-0.199.0.dist-info → orionis-0.202.0.dist-info}/METADATA +1 -1
  39. {orionis-0.199.0.dist-info → orionis-0.202.0.dist-info}/RECORD +45 -31
  40. tests/main.py +0 -0
  41. orionis/luminate/console/commands/tests.py +0 -34
  42. tests/tools/class_example.py +0 -50
  43. tests/tools/test_reflection.py +0 -128
  44. {tests/tools → orionis/luminate/support/inspection}/__init__.py +0 -0
  45. {orionis-0.199.0.dist-info → orionis-0.202.0.dist-info}/LICENCE +0 -0
  46. {orionis-0.199.0.dist-info → orionis-0.202.0.dist-info}/WHEEL +0 -0
  47. {orionis-0.199.0.dist-info → orionis-0.202.0.dist-info}/entry_points.txt +0 -0
  48. {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
+