orionis 0.317.0__py3-none-any.whl → 0.319.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/container/container.py +397 -15
- orionis/container/contracts/container.py +202 -0
- orionis/metadata/framework.py +1 -1
- orionis/services/introspection/callables/reflection_callable.py +15 -2
- orionis/services/introspection/concretes/reflection_concrete.py +11 -0
- orionis/services/introspection/dependencies/entities/callable_dependencies.py +55 -0
- orionis/services/introspection/dependencies/reflect_dependencies.py +3 -2
- {orionis-0.317.0.dist-info → orionis-0.319.0.dist-info}/METADATA +1 -1
- {orionis-0.317.0.dist-info → orionis-0.319.0.dist-info}/RECORD +15 -13
- tests/services/inspection/dependencies/test_reflect_dependencies.py +2 -1
- tests/services/inspection/reflection/test_reflection_callable.py +2 -3
- {orionis-0.317.0.dist-info → orionis-0.319.0.dist-info}/WHEEL +0 -0
- {orionis-0.317.0.dist-info → orionis-0.319.0.dist-info}/licenses/LICENCE +0 -0
- {orionis-0.317.0.dist-info → orionis-0.319.0.dist-info}/top_level.txt +0 -0
- {orionis-0.317.0.dist-info → orionis-0.319.0.dist-info}/zip-safe +0 -0
orionis/container/container.py
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
+
import threading
|
1
2
|
from typing import Any, Callable
|
3
|
+
from orionis.container.contracts.container import IContainer
|
2
4
|
from orionis.container.entities.binding import Binding
|
3
5
|
from orionis.container.enums.lifetimes import Lifetime
|
4
6
|
from orionis.container.exceptions.container_exception import OrionisContainerException
|
@@ -6,12 +8,11 @@ from orionis.container.exceptions.type_error_exception import OrionisContainerTy
|
|
6
8
|
from orionis.services.introspection.abstract.reflection_abstract import ReflectionAbstract
|
7
9
|
from orionis.services.introspection.callables.reflection_callable import ReflectionCallable
|
8
10
|
from orionis.services.introspection.concretes.reflection_concrete import ReflectionConcrete
|
11
|
+
from orionis.services.introspection.dependencies.entities.resolved_dependencies import ResolvedDependency
|
9
12
|
from orionis.services.introspection.instances.reflection_instance import ReflectionInstance
|
10
13
|
from orionis.services.introspection.reflection import Reflection
|
11
|
-
import inspect
|
12
|
-
import threading
|
13
14
|
|
14
|
-
class Container:
|
15
|
+
class Container(IContainer):
|
15
16
|
|
16
17
|
# Singleton instance of the container.
|
17
18
|
# This is a class variable that holds the single instance of the Container class.
|
@@ -27,7 +28,11 @@ class Container:
|
|
27
28
|
# regardless of how many times the class is instantiated.
|
28
29
|
_initialized = False
|
29
30
|
|
30
|
-
def __new__(
|
31
|
+
def __new__(
|
32
|
+
cls,
|
33
|
+
*args,
|
34
|
+
**kwargs
|
35
|
+
) -> 'Container':
|
31
36
|
"""
|
32
37
|
Creates and returns a singleton instance of the class.
|
33
38
|
|
@@ -52,24 +57,29 @@ class Container:
|
|
52
57
|
cls._instance = super(Container, cls).__new__(cls)
|
53
58
|
return cls._instance
|
54
59
|
|
55
|
-
def __init__(
|
60
|
+
def __init__(
|
61
|
+
self
|
62
|
+
) -> None:
|
56
63
|
"""
|
57
64
|
Initializes a new instance of the container.
|
58
65
|
|
59
66
|
This constructor sets up the internal dictionaries for bindings and aliases,
|
60
67
|
ensuring that these are only initialized once per class. The initialization
|
61
68
|
is guarded by the `_initialized` class attribute to prevent redundant setup.
|
69
|
+
The container also registers itself as a service to allow for injection.
|
62
70
|
|
63
71
|
Notes
|
64
72
|
-----
|
65
73
|
- The `__bindings` dictionary is used to store service bindings.
|
66
74
|
- The `__aliasses` dictionary is used to store service aliases.
|
67
75
|
- Initialization occurs only once per class, regardless of the number of instances.
|
76
|
+
- The container registers itself under the IContainer interface to allow for dependency injection.
|
68
77
|
"""
|
69
78
|
if not self.__class__._initialized:
|
70
79
|
self.__bindings = {}
|
71
80
|
self.__aliasses = {}
|
72
81
|
self.__class__._initialized = True
|
82
|
+
self.instance(IContainer, self)
|
73
83
|
|
74
84
|
def __dropService(
|
75
85
|
self,
|
@@ -380,6 +390,48 @@ class Container:
|
|
380
390
|
"Please ensure that all abstract methods are implemented."
|
381
391
|
)
|
382
392
|
|
393
|
+
def __getService(
|
394
|
+
self,
|
395
|
+
abstract_or_alias: Any
|
396
|
+
) -> Binding:
|
397
|
+
"""
|
398
|
+
Retrieves the binding for the requested abstract type or alias.
|
399
|
+
|
400
|
+
Parameters
|
401
|
+
----------
|
402
|
+
abstract_or_alias : Any
|
403
|
+
The abstract class, interface, or alias (str) to retrieve.
|
404
|
+
|
405
|
+
Returns
|
406
|
+
-------
|
407
|
+
Binding
|
408
|
+
The binding associated with the requested abstract type or alias.
|
409
|
+
"""
|
410
|
+
return self.__bindings.get(abstract_or_alias) or self.__aliasses.get(abstract_or_alias)
|
411
|
+
|
412
|
+
def __getFirstService(
|
413
|
+
self,
|
414
|
+
abstract_or_aliasses: list
|
415
|
+
) -> Binding:
|
416
|
+
"""
|
417
|
+
Retrieves the first binding from a list of abstract types or aliases.
|
418
|
+
|
419
|
+
Parameters
|
420
|
+
----------
|
421
|
+
abstract_or_aliasses : list
|
422
|
+
A list of abstract classes, interfaces, or aliases (str) to retrieve.
|
423
|
+
|
424
|
+
Returns
|
425
|
+
-------
|
426
|
+
Binding
|
427
|
+
The first binding found in the container for the provided abstract types or aliases.
|
428
|
+
"""
|
429
|
+
for item in abstract_or_aliasses:
|
430
|
+
binding = self.__getService(item)
|
431
|
+
if binding:
|
432
|
+
return binding
|
433
|
+
return None
|
434
|
+
|
383
435
|
def transient(
|
384
436
|
self,
|
385
437
|
abstract: Callable[..., Any],
|
@@ -716,7 +768,7 @@ class Container:
|
|
716
768
|
def function(
|
717
769
|
self,
|
718
770
|
alias: str,
|
719
|
-
|
771
|
+
fn: Callable[..., Any],
|
720
772
|
*,
|
721
773
|
lifetime: Lifetime = Lifetime.TRANSIENT
|
722
774
|
) -> bool:
|
@@ -727,7 +779,7 @@ class Container:
|
|
727
779
|
----------
|
728
780
|
alias : str
|
729
781
|
The alias to register the function under.
|
730
|
-
|
782
|
+
fn : Callable[..., Any]
|
731
783
|
The function or factory to register.
|
732
784
|
lifetime : Lifetime, optional
|
733
785
|
The lifetime of the function registration (default is TRANSIENT).
|
@@ -764,10 +816,10 @@ class Container:
|
|
764
816
|
self.__ensureAliasType(alias)
|
765
817
|
|
766
818
|
# Validate that the function is callable
|
767
|
-
self.__ensureIsCallable(
|
819
|
+
self.__ensureIsCallable(fn)
|
768
820
|
|
769
821
|
# Inspect the function signature
|
770
|
-
params = ReflectionCallable(
|
822
|
+
params = ReflectionCallable(fn).getDependencies()
|
771
823
|
|
772
824
|
# If the function requires arguments, only allow TRANSIENT
|
773
825
|
if (len(params.resolved) + len(params.unresolved)) > 0 and lifetime != Lifetime.TRANSIENT:
|
@@ -780,7 +832,7 @@ class Container:
|
|
780
832
|
|
781
833
|
# Register the function with the specified alias and lifetime
|
782
834
|
self.__bindings[alias] = Binding(
|
783
|
-
function=
|
835
|
+
function=fn,
|
784
836
|
lifetime=lifetime,
|
785
837
|
alias=alias
|
786
838
|
)
|
@@ -820,8 +872,8 @@ class Container:
|
|
820
872
|
def make(
|
821
873
|
self,
|
822
874
|
abstract_or_alias: Any,
|
823
|
-
*args,
|
824
|
-
**kwargs
|
875
|
+
*args: tuple,
|
876
|
+
**kwargs: dict
|
825
877
|
) -> Any:
|
826
878
|
"""
|
827
879
|
Resolves and returns an instance of the requested service.
|
@@ -845,11 +897,341 @@ class Container:
|
|
845
897
|
OrionisContainerException
|
846
898
|
If the requested service is not registered in the container.
|
847
899
|
"""
|
848
|
-
|
900
|
+
# Retrieve the binding for the requested abstract or alias
|
901
|
+
binding = self.__getService(abstract_or_alias)
|
902
|
+
|
903
|
+
# Check if the requested service is registered in the container
|
904
|
+
if not binding:
|
849
905
|
raise OrionisContainerException(
|
850
906
|
f"The requested service '{abstract_or_alias}' is not registered in the container."
|
851
907
|
)
|
852
908
|
|
853
|
-
binding
|
909
|
+
# Handle based on binding type and lifetime
|
910
|
+
if binding.lifetime == Lifetime.TRANSIENT:
|
911
|
+
return self.__resolveTransient(binding, *args, **kwargs)
|
912
|
+
elif binding.lifetime == Lifetime.SINGLETON:
|
913
|
+
return self.__resolveSingleton(binding, *args, **kwargs)
|
914
|
+
elif binding.lifetime == Lifetime.SCOPED:
|
915
|
+
# TODO: Implement scoped lifetime resolution
|
916
|
+
raise OrionisContainerException(
|
917
|
+
"Scoped lifetime resolution is not yet implemented."
|
918
|
+
)
|
919
|
+
|
920
|
+
def __resolveTransient(self, binding: Binding, *args, **kwargs) -> Any:
|
921
|
+
"""
|
922
|
+
Resolves a service with transient lifetime.
|
923
|
+
|
924
|
+
Parameters
|
925
|
+
----------
|
926
|
+
binding : Binding
|
927
|
+
The binding to resolve.
|
928
|
+
*args : tuple
|
929
|
+
Positional arguments to pass to the constructor.
|
930
|
+
**kwargs : dict
|
931
|
+
Keyword arguments to pass to the constructor.
|
932
|
+
|
933
|
+
Returns
|
934
|
+
-------
|
935
|
+
Any
|
936
|
+
A new instance of the requested service.
|
937
|
+
"""
|
938
|
+
|
939
|
+
# Check if the binding has a concrete class or function defined
|
940
|
+
if binding.concrete:
|
941
|
+
if args or kwargs:
|
942
|
+
return self.__instantiateConcreteWithArgs(binding.concrete, *args, **kwargs)
|
943
|
+
else:
|
944
|
+
return self.__instantiateConcreteReflective(binding.concrete)
|
945
|
+
|
946
|
+
# If the binding has a function defined
|
947
|
+
elif binding.function:
|
948
|
+
if args or kwargs:
|
949
|
+
return self.__instantiateCallableWithArgs(binding.function, *args, **kwargs)
|
950
|
+
else:
|
951
|
+
return self.__instantiateCallableReflective(binding.function)
|
952
|
+
|
953
|
+
# If neither concrete class nor function is defined
|
954
|
+
else:
|
955
|
+
raise OrionisContainerException(
|
956
|
+
"Cannot resolve transient binding: neither a concrete class nor a function is defined."
|
957
|
+
)
|
958
|
+
|
959
|
+
def __resolveSingleton(self, binding: Binding, *args, **kwargs) -> Any:
|
960
|
+
"""
|
961
|
+
Resolves a service with singleton lifetime.
|
962
|
+
|
963
|
+
Parameters
|
964
|
+
----------
|
965
|
+
binding : Binding
|
966
|
+
The binding to resolve.
|
967
|
+
*args : tuple
|
968
|
+
Positional arguments to pass to the constructor (only used if instance doesn't exist yet).
|
969
|
+
**kwargs : dict
|
970
|
+
Keyword arguments to pass to the constructor (only used if instance doesn't exist yet).
|
971
|
+
|
972
|
+
Returns
|
973
|
+
-------
|
974
|
+
Any
|
975
|
+
The singleton instance of the requested service.
|
976
|
+
"""
|
977
|
+
# Return existing instance if available
|
978
|
+
if binding.instance:
|
979
|
+
return binding.instance
|
980
|
+
|
981
|
+
# Create instance if needed
|
982
|
+
if binding.concrete:
|
983
|
+
if args or kwargs:
|
984
|
+
binding.instance = self.__instantiateConcreteWithArgs(binding.concrete, *args, **kwargs)
|
985
|
+
else:
|
986
|
+
binding.instance = self.__instantiateConcreteReflective(binding.concrete)
|
987
|
+
return binding.instance
|
988
|
+
|
989
|
+
# If the binding has a function defined
|
990
|
+
elif binding.function:
|
991
|
+
if args or kwargs:
|
992
|
+
result = self.__instantiateCallableWithArgs(binding.function, *args, **kwargs)
|
993
|
+
else:
|
994
|
+
result = self.__instantiateCallableReflective(binding.function)
|
995
|
+
|
996
|
+
# Store the result directly as the singleton instance
|
997
|
+
# We don't automatically invoke factory function results anymore
|
998
|
+
binding.instance = result
|
999
|
+
return binding.instance
|
1000
|
+
|
1001
|
+
# If neither concrete class nor function is defined
|
1002
|
+
else:
|
1003
|
+
raise OrionisContainerException(
|
1004
|
+
"Cannot resolve singleton binding: neither a concrete class, instance, nor function is defined."
|
1005
|
+
)
|
1006
|
+
|
1007
|
+
def __instantiateConcreteWithArgs(self, concrete: Callable[..., Any], *args, **kwargs) -> Any:
|
1008
|
+
"""
|
1009
|
+
Instantiates a concrete class with the provided arguments.
|
1010
|
+
|
1011
|
+
Parameters
|
1012
|
+
----------
|
1013
|
+
concrete : Callable[..., Any]
|
1014
|
+
Class to instantiate.
|
1015
|
+
*args : tuple
|
1016
|
+
Positional arguments to pass to the constructor.
|
1017
|
+
**kwargs : dict
|
1018
|
+
Keyword arguments to pass to the constructor.
|
854
1019
|
|
855
|
-
|
1020
|
+
Returns
|
1021
|
+
-------
|
1022
|
+
object
|
1023
|
+
A new instance of the specified concrete class.
|
1024
|
+
"""
|
1025
|
+
|
1026
|
+
# try to instantiate the concrete class with the provided arguments
|
1027
|
+
try:
|
1028
|
+
|
1029
|
+
# If the concrete is a class, instantiate it directly
|
1030
|
+
return concrete(*args, **kwargs)
|
1031
|
+
|
1032
|
+
except TypeError as e:
|
1033
|
+
|
1034
|
+
# If instantiation fails, use ReflectionConcrete to get class name and constructor signature
|
1035
|
+
rf_concrete = ReflectionConcrete(concrete)
|
1036
|
+
class_name = rf_concrete.getClassName()
|
1037
|
+
signature = rf_concrete.getConstructorSignature()
|
1038
|
+
|
1039
|
+
# Raise an exception with detailed information about the failure
|
1040
|
+
raise OrionisContainerException(
|
1041
|
+
f"Failed to instantiate [{class_name}] with the provided arguments: {e}\n"
|
1042
|
+
f"Expected constructor signature: [{signature}]"
|
1043
|
+
) from e
|
1044
|
+
|
1045
|
+
def __instantiateCallableWithArgs(self, fn: Callable[..., Any], *args, **kwargs) -> Any:
|
1046
|
+
"""
|
1047
|
+
Invokes a callable with the provided arguments.
|
1048
|
+
|
1049
|
+
Parameters
|
1050
|
+
----------
|
1051
|
+
fn : Callable[..., Any]
|
1052
|
+
The callable to invoke.
|
1053
|
+
*args : tuple
|
1054
|
+
Positional arguments to pass to the callable.
|
1055
|
+
**kwargs : dict
|
1056
|
+
Keyword arguments to pass to the callable.
|
1057
|
+
|
1058
|
+
Returns
|
1059
|
+
-------
|
1060
|
+
Any
|
1061
|
+
The result of the callable.
|
1062
|
+
"""
|
1063
|
+
|
1064
|
+
# Try to invoke the callable with the provided arguments
|
1065
|
+
try:
|
1066
|
+
|
1067
|
+
# If the callable is a function, invoke it directly
|
1068
|
+
return fn(*args, **kwargs)
|
1069
|
+
|
1070
|
+
except TypeError as e:
|
1071
|
+
|
1072
|
+
# If invocation fails, use ReflectionCallable to get function name and signature
|
1073
|
+
rf_callable = ReflectionCallable(fn)
|
1074
|
+
function_name = rf_callable.getName()
|
1075
|
+
signature = rf_callable.getSignature()
|
1076
|
+
|
1077
|
+
# Raise an exception with detailed information about the failure
|
1078
|
+
raise OrionisContainerException(
|
1079
|
+
f"Failed to invoke function [{function_name}] with the provided arguments: {e}\n"
|
1080
|
+
f"Expected function signature: [{signature}]"
|
1081
|
+
) from e
|
1082
|
+
|
1083
|
+
def __instantiateConcreteReflective(self, concrete: Callable[..., Any]) -> Any:
|
1084
|
+
"""
|
1085
|
+
Instantiates a concrete class reflectively, resolving its dependencies from the container.
|
1086
|
+
|
1087
|
+
Parameters
|
1088
|
+
----------
|
1089
|
+
concrete : Callable[..., Any]
|
1090
|
+
The concrete class to instantiate.
|
1091
|
+
|
1092
|
+
Returns
|
1093
|
+
-------
|
1094
|
+
Any
|
1095
|
+
A new instance of the concrete class.
|
1096
|
+
"""
|
1097
|
+
# Resolve dependencies for the concrete class
|
1098
|
+
params = self.__resolveDependencies(concrete, is_class=True)
|
1099
|
+
|
1100
|
+
# Instantiate the concrete class with resolved dependencies
|
1101
|
+
return concrete(**params)
|
1102
|
+
|
1103
|
+
def __instantiateCallableReflective(self, fn: Callable[..., Any]) -> Any:
|
1104
|
+
"""
|
1105
|
+
Invokes a callable reflectively, resolving its dependencies from the container.
|
1106
|
+
|
1107
|
+
Parameters
|
1108
|
+
----------
|
1109
|
+
fn : Callable[..., Any]
|
1110
|
+
The callable to invoke.
|
1111
|
+
|
1112
|
+
Returns
|
1113
|
+
-------
|
1114
|
+
Any
|
1115
|
+
The result of the callable.
|
1116
|
+
"""
|
1117
|
+
|
1118
|
+
# Resolve dependencies for the callable
|
1119
|
+
params = self.__resolveDependencies(fn, is_class=False)
|
1120
|
+
|
1121
|
+
# Invoke the callable with resolved dependencies
|
1122
|
+
return fn(**params)
|
1123
|
+
|
1124
|
+
def __resolveDependencies(
|
1125
|
+
self,
|
1126
|
+
target: Callable[..., Any],
|
1127
|
+
*,
|
1128
|
+
is_class: bool = False
|
1129
|
+
) -> dict:
|
1130
|
+
"""
|
1131
|
+
Resolves dependencies for a target callable or class.
|
1132
|
+
|
1133
|
+
Parameters
|
1134
|
+
----------
|
1135
|
+
target : Callable[..., Any]
|
1136
|
+
The target callable or class whose dependencies to resolve.
|
1137
|
+
is_class : bool, optional
|
1138
|
+
Whether the target is a class (True) or a callable (False).
|
1139
|
+
|
1140
|
+
Returns
|
1141
|
+
-------
|
1142
|
+
dict
|
1143
|
+
A dictionary of resolved dependencies.
|
1144
|
+
"""
|
1145
|
+
try:
|
1146
|
+
|
1147
|
+
# Use ReflectionConcrete for classes and ReflectionCallable for callables
|
1148
|
+
if is_class:
|
1149
|
+
reflection = ReflectionConcrete(target)
|
1150
|
+
dependencies = reflection.getConstructorDependencies()
|
1151
|
+
name = reflection.getClassName()
|
1152
|
+
|
1153
|
+
# If the target is a callable, use ReflectionCallable
|
1154
|
+
else:
|
1155
|
+
reflection = ReflectionCallable(target)
|
1156
|
+
dependencies = reflection.getDependencies()
|
1157
|
+
name = reflection.getName()
|
1158
|
+
|
1159
|
+
# Check for unresolved dependencies
|
1160
|
+
if dependencies.unresolved:
|
1161
|
+
unresolved_args = ', '.join(dependencies.unresolved)
|
1162
|
+
raise OrionisContainerException(
|
1163
|
+
f"Cannot resolve '{name}' because the following required arguments are missing: [{unresolved_args}]."
|
1164
|
+
)
|
1165
|
+
|
1166
|
+
# Resolve dependencies
|
1167
|
+
params = {}
|
1168
|
+
for param_name, dep in dependencies.resolved.items():
|
1169
|
+
|
1170
|
+
# If the dependency is a ResolvedDependency, resolve it
|
1171
|
+
if isinstance(dep, ResolvedDependency):
|
1172
|
+
|
1173
|
+
# If the dependency is a built-in type, raise an exception
|
1174
|
+
if dep.module_name == 'builtins':
|
1175
|
+
raise OrionisContainerException(
|
1176
|
+
f"Cannot resolve '{name}' because parameter '{param_name}' depends on built-in type '{dep.type.__name__}'."
|
1177
|
+
)
|
1178
|
+
|
1179
|
+
# Try to resolve from container
|
1180
|
+
service = self.__getFirstService([dep.type, dep.full_class_path])
|
1181
|
+
if service:
|
1182
|
+
params[param_name] = self.make(service.alias)
|
1183
|
+
|
1184
|
+
# Try to instantiate directly if it's a concrete class
|
1185
|
+
elif ReflectionConcrete.isConcreteClass(dep.type):
|
1186
|
+
params[param_name] = dep.type(**self.__resolveDependencies(dep.type, is_class=True))
|
1187
|
+
|
1188
|
+
# Try to call directly if it's a callable
|
1189
|
+
elif callable(dep.type) and not isinstance(dep.type, type):
|
1190
|
+
params[param_name] = dep.type(**self.__resolveDependencies(dep.type, is_class=False))
|
1191
|
+
|
1192
|
+
# If the dependency cannot be resolved, raise an exception
|
1193
|
+
else:
|
1194
|
+
raise OrionisContainerException(
|
1195
|
+
f"Cannot resolve dependency '{param_name}' of type '{dep.type.__name__}' for '{name}'."
|
1196
|
+
)
|
1197
|
+
else:
|
1198
|
+
# Use default value
|
1199
|
+
params[param_name] = dep
|
1200
|
+
|
1201
|
+
# Return the resolved parameters
|
1202
|
+
return params
|
1203
|
+
|
1204
|
+
except ImportError as e:
|
1205
|
+
|
1206
|
+
# Extract module name from the error message if possible
|
1207
|
+
import_msg = str(e)
|
1208
|
+
module_name = target.__module__ if hasattr(target, '__module__') else "unknown module"
|
1209
|
+
|
1210
|
+
# Check for potential circular import patterns
|
1211
|
+
if "circular import" in import_msg.lower() or "cannot import name" in import_msg.lower():
|
1212
|
+
raise OrionisContainerException(
|
1213
|
+
f"Circular import detected while resolving dependencies for '{target.__name__}' in module '{module_name}'.\n"
|
1214
|
+
f"This typically happens when two modules import each other. Consider:\n"
|
1215
|
+
f"1. Restructuring your code to avoid circular dependencies\n"
|
1216
|
+
f"2. Using delayed imports inside methods rather than at module level\n"
|
1217
|
+
f"3. Using dependency injection to break the cycle\n"
|
1218
|
+
f"Original error: {import_msg}"
|
1219
|
+
) from e
|
1220
|
+
else:
|
1221
|
+
raise OrionisContainerException(
|
1222
|
+
f"Import error while resolving dependencies for '{target.__name__}' in module '{module_name}':\n"
|
1223
|
+
f"{import_msg}"
|
1224
|
+
) from e
|
1225
|
+
|
1226
|
+
except Exception as e:
|
1227
|
+
|
1228
|
+
# Get more context about where the error occurred
|
1229
|
+
target_type = "class" if isinstance(target, type) else "function"
|
1230
|
+
target_name = target.__name__ if hasattr(target, '__name__') else str(target)
|
1231
|
+
module_name = target.__module__ if hasattr(target, '__module__') else "unknown module"
|
1232
|
+
|
1233
|
+
raise OrionisContainerException(
|
1234
|
+
f"Error resolving dependencies for {target_type} '{target_name}' in '{module_name}':\n"
|
1235
|
+
f"{str(e)}\n"
|
1236
|
+
f"Check that all dependencies are properly registered in the container."
|
1237
|
+
) from e
|
@@ -0,0 +1,202 @@
|
|
1
|
+
from abc import ABC, abstractmethod
|
2
|
+
from typing import Any, Callable
|
3
|
+
from orionis.container.enums.lifetimes import Lifetime
|
4
|
+
|
5
|
+
class IContainer(ABC):
|
6
|
+
"""
|
7
|
+
IContainer is an interface that defines the structure for a dependency injection container.
|
8
|
+
It provides methods for registering and resolving services with different lifetimes.
|
9
|
+
"""
|
10
|
+
|
11
|
+
@abstractmethod
|
12
|
+
def singleton(
|
13
|
+
self,
|
14
|
+
abstract: Callable[..., Any],
|
15
|
+
concrete: Callable[..., Any],
|
16
|
+
*,
|
17
|
+
alias: str = None,
|
18
|
+
enforce_decoupling: bool = False
|
19
|
+
) -> bool:
|
20
|
+
"""
|
21
|
+
Register a service as a singleton.
|
22
|
+
|
23
|
+
Parameters
|
24
|
+
----------
|
25
|
+
abstract : Callable[..., Any]
|
26
|
+
The abstract base type or interface to be bound.
|
27
|
+
concrete : Callable[..., Any]
|
28
|
+
The concrete implementation to associate with the abstract type.
|
29
|
+
alias : str, optional
|
30
|
+
An alternative name to register the service under.
|
31
|
+
enforce_decoupling : bool, optional
|
32
|
+
Whether to enforce that concrete is not a subclass of abstract.
|
33
|
+
|
34
|
+
Returns
|
35
|
+
-------
|
36
|
+
bool
|
37
|
+
True if the service was registered successfully.
|
38
|
+
"""
|
39
|
+
pass
|
40
|
+
|
41
|
+
@abstractmethod
|
42
|
+
def transient(
|
43
|
+
self,
|
44
|
+
abstract: Callable[..., Any],
|
45
|
+
concrete: Callable[..., Any],
|
46
|
+
*,
|
47
|
+
alias: str = None,
|
48
|
+
enforce_decoupling: bool = False
|
49
|
+
) -> bool:
|
50
|
+
"""
|
51
|
+
Register a service as transient.
|
52
|
+
|
53
|
+
Parameters
|
54
|
+
----------
|
55
|
+
abstract : Callable[..., Any]
|
56
|
+
The abstract base type or interface to be bound.
|
57
|
+
concrete : Callable[..., Any]
|
58
|
+
The concrete implementation to associate with the abstract type.
|
59
|
+
alias : str, optional
|
60
|
+
An alternative name to register the service under.
|
61
|
+
enforce_decoupling : bool, optional
|
62
|
+
Whether to enforce that concrete is not a subclass of abstract.
|
63
|
+
|
64
|
+
Returns
|
65
|
+
-------
|
66
|
+
bool
|
67
|
+
True if the service was registered successfully.
|
68
|
+
"""
|
69
|
+
pass
|
70
|
+
|
71
|
+
@abstractmethod
|
72
|
+
def scoped(
|
73
|
+
self,
|
74
|
+
abstract: Callable[..., Any],
|
75
|
+
concrete: Callable[..., Any],
|
76
|
+
*,
|
77
|
+
alias: str = None,
|
78
|
+
enforce_decoupling: bool = False
|
79
|
+
) -> bool:
|
80
|
+
"""
|
81
|
+
Register a service as scoped.
|
82
|
+
|
83
|
+
Parameters
|
84
|
+
----------
|
85
|
+
abstract : Callable[..., Any]
|
86
|
+
The abstract base type or interface to be bound.
|
87
|
+
concrete : Callable[..., Any]
|
88
|
+
The concrete implementation to associate with the abstract type.
|
89
|
+
alias : str, optional
|
90
|
+
An alternative name to register the service under.
|
91
|
+
enforce_decoupling : bool, optional
|
92
|
+
Whether to enforce that concrete is not a subclass of abstract.
|
93
|
+
|
94
|
+
Returns
|
95
|
+
-------
|
96
|
+
bool
|
97
|
+
True if the service was registered successfully.
|
98
|
+
"""
|
99
|
+
pass
|
100
|
+
|
101
|
+
@abstractmethod
|
102
|
+
def instance(
|
103
|
+
self,
|
104
|
+
abstract: Callable[..., Any],
|
105
|
+
instance: Any,
|
106
|
+
*,
|
107
|
+
alias: str = None,
|
108
|
+
enforce_decoupling: bool = False
|
109
|
+
) -> bool:
|
110
|
+
"""
|
111
|
+
Register an instance of a service.
|
112
|
+
|
113
|
+
Parameters
|
114
|
+
----------
|
115
|
+
abstract : Callable[..., Any]
|
116
|
+
The abstract class or interface to associate with the instance.
|
117
|
+
instance : Any
|
118
|
+
The concrete instance to register.
|
119
|
+
alias : str, optional
|
120
|
+
An optional alias to register the instance under.
|
121
|
+
enforce_decoupling : bool, optional
|
122
|
+
Whether to enforce that instance's class is not a subclass of abstract.
|
123
|
+
|
124
|
+
Returns
|
125
|
+
-------
|
126
|
+
bool
|
127
|
+
True if the instance was successfully registered.
|
128
|
+
"""
|
129
|
+
pass
|
130
|
+
|
131
|
+
@abstractmethod
|
132
|
+
def function(
|
133
|
+
self,
|
134
|
+
alias: str,
|
135
|
+
fn: Callable[..., Any],
|
136
|
+
*,
|
137
|
+
lifetime: Lifetime = Lifetime.TRANSIENT
|
138
|
+
) -> bool:
|
139
|
+
"""
|
140
|
+
Register a function as a service.
|
141
|
+
|
142
|
+
Parameters
|
143
|
+
----------
|
144
|
+
alias : str
|
145
|
+
The alias to register the function under.
|
146
|
+
fn : Callable[..., Any]
|
147
|
+
The function or factory to register.
|
148
|
+
lifetime : Lifetime, optional
|
149
|
+
The lifetime of the function registration (default is TRANSIENT).
|
150
|
+
|
151
|
+
Returns
|
152
|
+
-------
|
153
|
+
bool
|
154
|
+
True if the function was registered successfully.
|
155
|
+
"""
|
156
|
+
pass
|
157
|
+
|
158
|
+
@abstractmethod
|
159
|
+
def make(
|
160
|
+
self,
|
161
|
+
abstract_or_alias: Any,
|
162
|
+
*args: tuple,
|
163
|
+
**kwargs: dict
|
164
|
+
) -> Any:
|
165
|
+
"""
|
166
|
+
Resolve a service from the container.
|
167
|
+
|
168
|
+
Parameters
|
169
|
+
----------
|
170
|
+
abstract_or_alias : Any
|
171
|
+
The abstract class, interface, or alias (str) to resolve.
|
172
|
+
*args : tuple
|
173
|
+
Positional arguments to pass to the constructor.
|
174
|
+
**kwargs : dict
|
175
|
+
Keyword arguments to pass to the constructor.
|
176
|
+
|
177
|
+
Returns
|
178
|
+
-------
|
179
|
+
Any
|
180
|
+
An instance of the requested service.
|
181
|
+
"""
|
182
|
+
pass
|
183
|
+
|
184
|
+
@abstractmethod
|
185
|
+
def bound(
|
186
|
+
self,
|
187
|
+
abstract_or_alias: Any
|
188
|
+
) -> bool:
|
189
|
+
"""
|
190
|
+
Check if a service is registered in the container.
|
191
|
+
|
192
|
+
Parameters
|
193
|
+
----------
|
194
|
+
abstract_or_alias : Any
|
195
|
+
The abstract class, interface, or alias (str) to check.
|
196
|
+
|
197
|
+
Returns
|
198
|
+
-------
|
199
|
+
bool
|
200
|
+
True if the service is registered, False otherwise.
|
201
|
+
"""
|
202
|
+
pass
|
orionis/metadata/framework.py
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
import inspect
|
2
2
|
from orionis.services.asynchrony.coroutines import Coroutine
|
3
|
-
from orionis.services.introspection.dependencies.entities.
|
3
|
+
from orionis.services.introspection.dependencies.entities.callable_dependencies import CallableDependency
|
4
4
|
from orionis.services.introspection.dependencies.reflect_dependencies import ReflectDependencies
|
5
5
|
from orionis.services.introspection.exceptions.reflection_attribute_error import ReflectionAttributeError
|
6
6
|
from orionis.services.introspection.exceptions.reflection_type_error import ReflectionTypeError
|
7
|
-
import asyncio
|
8
7
|
|
9
8
|
class ReflectionCallable:
|
10
9
|
|
@@ -131,6 +130,20 @@ class ReflectionCallable:
|
|
131
130
|
return Coroutine(self.__function(*args, **kwargs)).run()
|
132
131
|
return self.__function(*args, **kwargs)
|
133
132
|
|
133
|
+
def getSignature(self) -> inspect.Signature:
|
134
|
+
"""
|
135
|
+
Retrieve the signature of the callable function.
|
136
|
+
Returns
|
137
|
+
-------
|
138
|
+
inspect.Signature
|
139
|
+
An `inspect.Signature` object representing the callable's signature.
|
140
|
+
Notes
|
141
|
+
-----
|
142
|
+
This method provides detailed information about the parameters of the callable,
|
143
|
+
including their names, default values, and annotations.
|
144
|
+
"""
|
145
|
+
return inspect.signature(self.__function)
|
146
|
+
|
134
147
|
def getDependencies(self) -> CallableDependency:
|
135
148
|
"""
|
136
149
|
Analyzes the callable associated with this instance and retrieves its dependencies.
|
@@ -1442,6 +1442,17 @@ class ReflectionConcrete(IReflectionConcrete):
|
|
1442
1442
|
|
1443
1443
|
return prop.fget.__doc__ if prop.fget else None
|
1444
1444
|
|
1445
|
+
def getConstructorSignature(self) -> inspect.Signature:
|
1446
|
+
"""
|
1447
|
+
Get the signature of the constructor of the instance's class.
|
1448
|
+
|
1449
|
+
Returns
|
1450
|
+
-------
|
1451
|
+
inspect.Signature
|
1452
|
+
The signature of the constructor
|
1453
|
+
"""
|
1454
|
+
return inspect.signature(self._concrete.__init__)
|
1455
|
+
|
1445
1456
|
def getConstructorDependencies(self) -> ClassDependency:
|
1446
1457
|
"""
|
1447
1458
|
Get the resolved and unresolved dependencies from the constructor of the instance's class.
|
@@ -0,0 +1,55 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from typing import Any, Dict, List
|
3
|
+
from orionis.services.introspection.dependencies.entities.resolved_dependencies import ResolvedDependency
|
4
|
+
from orionis.services.introspection.exceptions.reflection_type_error import ReflectionTypeError
|
5
|
+
|
6
|
+
@dataclass(frozen=True, kw_only=True)
|
7
|
+
class CallableDependency:
|
8
|
+
"""
|
9
|
+
Represents the dependencies of a callable, separating resolved and unresolved dependencies.
|
10
|
+
|
11
|
+
Parameters
|
12
|
+
----------
|
13
|
+
resolved : Dict[ResolvedDependency, Any]
|
14
|
+
A dictionary mapping resolved dependency descriptors to their corresponding
|
15
|
+
resolved instances or values for the method. All keys must be ResolvedDependency instances.
|
16
|
+
unresolved : List[str]
|
17
|
+
A list of method parameter names or dependency identifiers that could not be resolved.
|
18
|
+
Must contain only non-empty strings.
|
19
|
+
|
20
|
+
Raises
|
21
|
+
------
|
22
|
+
ReflectionTypeError
|
23
|
+
If types don't match the expected:
|
24
|
+
- resolved: Dict[ResolvedDependency, Any]
|
25
|
+
- unresolved: List[str]
|
26
|
+
ValueError
|
27
|
+
If resolved contains None keys or unresolved contains empty strings
|
28
|
+
"""
|
29
|
+
resolved: Dict[ResolvedDependency, Any]
|
30
|
+
unresolved: List[str]
|
31
|
+
|
32
|
+
def __post_init__(self):
|
33
|
+
"""
|
34
|
+
Validates types and values of attributes during initialization.
|
35
|
+
|
36
|
+
Raises
|
37
|
+
------
|
38
|
+
ReflectionTypeError
|
39
|
+
If types don't match the expected:
|
40
|
+
- resolved: Dict[ResolvedDependency, Any]
|
41
|
+
- unresolved: List[str]
|
42
|
+
ValueError
|
43
|
+
If resolved contains None keys or unresolved contains empty strings
|
44
|
+
"""
|
45
|
+
# Validate 'resolved' is a dict with proper key types
|
46
|
+
if not isinstance(self.resolved, dict):
|
47
|
+
raise ReflectionTypeError(
|
48
|
+
f"'resolved' must be a dict, got {type(self.resolved).__name__}"
|
49
|
+
)
|
50
|
+
|
51
|
+
# Validate 'unresolved' is a list of valid parameter names
|
52
|
+
if not isinstance(self.unresolved, list):
|
53
|
+
raise ReflectionTypeError(
|
54
|
+
f"'unresolved' must be a list, got {type(self.unresolved).__name__}"
|
55
|
+
)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import inspect
|
2
2
|
from typing import Any, Dict, List
|
3
3
|
from orionis.services.introspection.contracts.reflect_dependencies import IReflectDependencies
|
4
|
+
from orionis.services.introspection.dependencies.entities.callable_dependencies import CallableDependency
|
4
5
|
from orionis.services.introspection.dependencies.entities.class_dependencies import ClassDependency
|
5
6
|
from orionis.services.introspection.dependencies.entities.method_dependencies import MethodDependency
|
6
7
|
from orionis.services.introspection.dependencies.entities.resolved_dependencies import ResolvedDependency
|
@@ -176,7 +177,7 @@ class ReflectDependencies(IReflectDependencies):
|
|
176
177
|
unresolved=unresolved_dependencies
|
177
178
|
)
|
178
179
|
|
179
|
-
def getCallableDependencies(self, fn: callable) ->
|
180
|
+
def getCallableDependencies(self, fn: callable) -> CallableDependency:
|
180
181
|
"""
|
181
182
|
Get the resolved and unresolved dependencies from a callable function.
|
182
183
|
|
@@ -222,7 +223,7 @@ class ReflectDependencies(IReflectDependencies):
|
|
222
223
|
full_class_path=f"{module_path}.{param.annotation.__name__}"
|
223
224
|
)
|
224
225
|
|
225
|
-
return
|
226
|
+
return CallableDependency(
|
226
227
|
resolved=resolved_dependencies,
|
227
228
|
unresolved=unresolved_dependencies
|
228
229
|
)
|
@@ -135,7 +135,8 @@ orionis/console/output/console.py,sha256=TE_Hl720ADd82dbERFSWhkoQRukDQZmETSw4nkw
|
|
135
135
|
orionis/console/output/executor.py,sha256=bdvkzW2-buy0BPpy2r5qUGrRFW2Ay6k-5rSeHb0gQ3o,3352
|
136
136
|
orionis/console/output/progress_bar.py,sha256=vFy582z6VJS46LV6tuyrmr9qvdVeTEtw3hyNcEHezeg,3088
|
137
137
|
orionis/console/output/styles.py,sha256=6a4oQCOBOKMh2ARdeq5GlIskJ3wjiylYmh66tUKKmpQ,4053
|
138
|
-
orionis/container/container.py,sha256=
|
138
|
+
orionis/container/container.py,sha256=ZL3S0HyAt8Hm58dPjltNMCSMNNP30VR61ByslzmCGgs,45066
|
139
|
+
orionis/container/contracts/container.py,sha256=LkZ5til_3Um8ctCVTwuO36HkysL59saKwUzXR5cWUBs,5750
|
139
140
|
orionis/container/entities/binding.py,sha256=Qp6Lf4XUDp2NjqXDAC2lzvhOFQWiBDKiGFcKfwb4axw,4342
|
140
141
|
orionis/container/enums/lifetimes.py,sha256=RqQmugMIB1Ev_j_vFLcWorndm-to7xg4stQ7yKFDdDw,190
|
141
142
|
orionis/container/exceptions/container_exception.py,sha256=goTDEwC70xTMD2qppN8KV-xyR0Nps218OD4D1LZ2-3s,470
|
@@ -232,7 +233,7 @@ orionis/foundation/contracts/config.py,sha256=Rpz6U6t8OXHO9JJKSTnCimytXE-tfCB-1i
|
|
232
233
|
orionis/foundation/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
233
234
|
orionis/foundation/exceptions/integrity.py,sha256=mc4pL1UMoYRHEmphnpW2oGk5URhu7DJRREyzHaV-cs8,472
|
234
235
|
orionis/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
235
|
-
orionis/metadata/framework.py,sha256=
|
236
|
+
orionis/metadata/framework.py,sha256=MyXQ31_zvD5irlN_XvuSicVccDNBPb64XCKc8qujCEc,4960
|
236
237
|
orionis/metadata/package.py,sha256=tqLfBRo-w1j_GN4xvzUNFyweWYFS-qhSgAEc-AmCH1M,5452
|
237
238
|
orionis/patterns/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
238
239
|
orionis/patterns/singleton/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -259,9 +260,9 @@ orionis/services/introspection/reflection.py,sha256=6z4VkDICohMIkm9jEd7nmFABwVuU
|
|
259
260
|
orionis/services/introspection/abstract/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
260
261
|
orionis/services/introspection/abstract/reflection_abstract.py,sha256=SPK2X11VvGORxxPOYloaD6hPAvky--obRU4CO1DE4zM,43865
|
261
262
|
orionis/services/introspection/callables/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
262
|
-
orionis/services/introspection/callables/reflection_callable.py,sha256=
|
263
|
+
orionis/services/introspection/callables/reflection_callable.py,sha256=0B2B6ZV-ql_aZk97W4Q12MVvi0gwErjekgWaMBxjfV0,6147
|
263
264
|
orionis/services/introspection/concretes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
264
|
-
orionis/services/introspection/concretes/reflection_concrete.py,sha256=
|
265
|
+
orionis/services/introspection/concretes/reflection_concrete.py,sha256=SdE2IWEgt30eO9-f_VRNdIZ_OWWidauQzQZQVrXjcXY,51310
|
265
266
|
orionis/services/introspection/contracts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
266
267
|
orionis/services/introspection/contracts/reflect_dependencies.py,sha256=5fdImZarC1ixoFM-1JSBx28RvYbY3GGZhDGjar7cvHc,1771
|
267
268
|
orionis/services/introspection/contracts/reflection_abstract.py,sha256=-ugpFcAkGTlk0Md5ft8NrvupnlfVji8QZjGYqWBxqeY,22370
|
@@ -269,8 +270,9 @@ orionis/services/introspection/contracts/reflection_concrete.py,sha256=9ZQjJpZwv
|
|
269
270
|
orionis/services/introspection/contracts/reflection_instance.py,sha256=D9sH-uOSZ_E7luAfbjI_ML6kfxuO5MtvLk6037iQJ7o,20936
|
270
271
|
orionis/services/introspection/contracts/reflection_module.py,sha256=YLqKg5EhaddUBrytMHX1-uz9mNsRISK1iVyG_iUiVYA,9666
|
271
272
|
orionis/services/introspection/dependencies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
272
|
-
orionis/services/introspection/dependencies/reflect_dependencies.py,sha256=
|
273
|
+
orionis/services/introspection/dependencies/reflect_dependencies.py,sha256=OXMfWqacFM7Mo5y0zmPprP4ECHqImChDFsfzTyhqS9A,9414
|
273
274
|
orionis/services/introspection/dependencies/entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
275
|
+
orionis/services/introspection/dependencies/entities/callable_dependencies.py,sha256=GJPS1pO8aIhYjtYw7bEoV8WfUCn-ZPGt5mD1WvfoAxg,2198
|
274
276
|
orionis/services/introspection/dependencies/entities/class_dependencies.py,sha256=pALvV_duAvDYmNp7PJYWkpIIQYmqWxuc_RGruEckfPA,2063
|
275
277
|
orionis/services/introspection/dependencies/entities/method_dependencies.py,sha256=FDwroILMPhqPxaxisPVEeKeLUg57GNQ4tQfWjGMh40E,2194
|
276
278
|
orionis/services/introspection/dependencies/entities/resolved_dependencies.py,sha256=0qnEj-3H8iclCc79AduQrqAAdAihv7k39gipo3RT2zc,2216
|
@@ -343,7 +345,7 @@ orionis/test/suite/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
|
|
343
345
|
orionis/test/suite/test_unit.py,sha256=MWgW8dRCRyT1XZ5LsbXQ7-KVPReasoXwzEEL1EWWfE4,52190
|
344
346
|
orionis/test/view/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
345
347
|
orionis/test/view/render.py,sha256=jXZkbITBknbUwm_mD8bcTiwLDvsFkrO9qrf0ZgPwqxc,4903
|
346
|
-
orionis-0.
|
348
|
+
orionis-0.319.0.dist-info/licenses/LICENCE,sha256=-_4cF2EBKuYVS_SQpy1uapq0oJPUU1vl_RUWSy2jJTo,1111
|
347
349
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
348
350
|
tests/example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
349
351
|
tests/example/test_example.py,sha256=kvWgiW3ADEZf718dGsMPtDh_rmOSx1ypEInKm7_6ZPQ,601
|
@@ -414,14 +416,14 @@ tests/services/environment/test_services_environment.py,sha256=fdkjwbY-aDEA1FT-9
|
|
414
416
|
tests/services/inspection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
415
417
|
tests/services/inspection/test_reflection.py,sha256=ZApQeaDxYLsrfGN6UqEDPbyNzocMV9CURflQ35YMfqk,13678
|
416
418
|
tests/services/inspection/dependencies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
417
|
-
tests/services/inspection/dependencies/test_reflect_dependencies.py,sha256=
|
419
|
+
tests/services/inspection/dependencies/test_reflect_dependencies.py,sha256=s_P4ST_dmjzRKmUL4bPFs-oR-Mf5PENGmYk56WiGO9g,7388
|
418
420
|
tests/services/inspection/dependencies/mocks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
419
421
|
tests/services/inspection/dependencies/mocks/mock_user.py,sha256=RxATxe0-Vm4HfX5jKz9Tny42E2fmrdtEN6ZEntbqRL8,912
|
420
422
|
tests/services/inspection/dependencies/mocks/mock_user_controller.py,sha256=P3sOUXVZ55auudwiNtvNCEQuTz0cgAZjvhicLZ4xaz4,1208
|
421
423
|
tests/services/inspection/dependencies/mocks/mock_users_permissions.py,sha256=oENXbS2qmQUudYSmnhB8fgHBqXZdbplplB-Y2nbx4hw,1388
|
422
424
|
tests/services/inspection/reflection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
423
425
|
tests/services/inspection/reflection/test_reflection_abstract.py,sha256=MbGDfCDkfj8wVJcyAlwV6na98JLzbGaYa3QjXR1alL8,27395
|
424
|
-
tests/services/inspection/reflection/test_reflection_callable.py,sha256=
|
426
|
+
tests/services/inspection/reflection/test_reflection_callable.py,sha256=ZcZ1_v4Nv22gIleflCRzE0Kfwy5Kjj8XjZ9Z1cKdXt8,6855
|
425
427
|
tests/services/inspection/reflection/test_reflection_concrete.py,sha256=5-iQh1whfpBa47jBWwtg-MIk6ysg92my5J9JdrTBm5E,44622
|
426
428
|
tests/services/inspection/reflection/test_reflection_instance.py,sha256=ZCFTLY_KtLAIq58PuDWak-T1c2PcCKiwTOdI9EDubww,46281
|
427
429
|
tests/services/inspection/reflection/test_reflection_module.py,sha256=Cl-3kWoJMQ2ufOO4VP6M28Tk6kmY4OhVEoW_b0wqw7Y,19849
|
@@ -444,8 +446,8 @@ tests/support/wrapper/test_services_wrapper_docdict.py,sha256=yeVwl-VcwkWSQYyxZu
|
|
444
446
|
tests/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
445
447
|
tests/testing/test_testing_result.py,sha256=MrGK3ZimedL0b5Ydu69Dg8Iul017AzLTm7VPxpXlpfU,4315
|
446
448
|
tests/testing/test_testing_unit.py,sha256=DjLBtvVn8B1KlVJNNkstBT8_csA1yeaMqnGrbanN_J4,7438
|
447
|
-
orionis-0.
|
448
|
-
orionis-0.
|
449
|
-
orionis-0.
|
450
|
-
orionis-0.
|
451
|
-
orionis-0.
|
449
|
+
orionis-0.319.0.dist-info/METADATA,sha256=426gql1AFezl4n3-_ORGM8wdkUYcEsZr8n3ykl6ruOI,4772
|
450
|
+
orionis-0.319.0.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
|
451
|
+
orionis-0.319.0.dist-info/top_level.txt,sha256=2bdoHgyGZhOtLAXS6Om8OCTmL24dUMC_L1quMe_ETbk,14
|
452
|
+
orionis-0.319.0.dist-info/zip-safe,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
453
|
+
orionis-0.319.0.dist-info/RECORD,,
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import asyncio
|
2
|
+
from orionis.services.introspection.dependencies.entities.callable_dependencies import CallableDependency
|
2
3
|
from orionis.services.introspection.dependencies.reflect_dependencies import (
|
3
4
|
ReflectDependencies,
|
4
5
|
ClassDependency,
|
@@ -113,7 +114,7 @@ class TestReflectDependencies(TestCase):
|
|
113
114
|
callable_dependencies = depend.getCallableDependencies(fake_function)
|
114
115
|
|
115
116
|
# Check Instance of MethodDependency
|
116
|
-
self.assertIsInstance(callable_dependencies,
|
117
|
+
self.assertIsInstance(callable_dependencies, CallableDependency)
|
117
118
|
|
118
119
|
# Check unresolved dependencies
|
119
120
|
self.assertEqual(callable_dependencies.unresolved, [])
|
@@ -1,9 +1,7 @@
|
|
1
1
|
from orionis.services.introspection.callables.reflection_callable import ReflectionCallable
|
2
|
+
from orionis.services.introspection.dependencies.entities.callable_dependencies import CallableDependency
|
2
3
|
from orionis.unittesting import TestCase
|
3
4
|
from orionis.services.introspection.exceptions.reflection_type_error import ReflectionTypeError
|
4
|
-
from orionis.services.introspection.exceptions.reflection_attribute_error import ReflectionAttributeError
|
5
|
-
from orionis.services.introspection.dependencies.entities.method_dependencies import MethodDependency as CallableDependency
|
6
|
-
from orionis.services.introspection.dependencies.reflect_dependencies import ReflectDependencies
|
7
5
|
|
8
6
|
class TestReflectionCallable(TestCase):
|
9
7
|
|
@@ -153,5 +151,6 @@ class TestReflectionCallable(TestCase):
|
|
153
151
|
return a + b
|
154
152
|
rc = ReflectionCallable(sample_function)
|
155
153
|
deps = rc.getDependencies()
|
154
|
+
self.assertIsInstance(deps, CallableDependency)
|
156
155
|
self.assertTrue(hasattr(deps, "resolved"))
|
157
156
|
self.assertTrue(hasattr(deps, "unresolved"))
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|