orionis 0.449.0__py3-none-any.whl → 0.451.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/console/base/contracts/command.py +0 -2
- orionis/console/core/__init__.py +0 -0
- orionis/container/container.py +1620 -88
- orionis/container/context/scope.py +1 -1
- orionis/container/contracts/container.py +184 -33
- orionis/foundation/config/database/entities/mysql.py +0 -1
- orionis/metadata/framework.py +1 -1
- orionis/services/inspirational/contracts/__init__.py +0 -0
- orionis/services/introspection/abstract/contracts/reflection.py +5 -6
- orionis/services/introspection/abstract/reflection.py +5 -6
- orionis/services/introspection/callables/contracts/reflection.py +3 -2
- orionis/services/introspection/callables/reflection.py +4 -4
- orionis/services/introspection/concretes/contracts/reflection.py +5 -6
- orionis/services/introspection/concretes/reflection.py +5 -6
- orionis/services/introspection/dependencies/contracts/reflection.py +87 -23
- orionis/services/introspection/dependencies/entities/argument.py +95 -0
- orionis/services/introspection/dependencies/entities/resolve_argument.py +82 -0
- orionis/services/introspection/dependencies/reflection.py +176 -106
- orionis/services/introspection/instances/contracts/reflection.py +5 -6
- orionis/services/introspection/instances/reflection.py +5 -6
- orionis/test/core/unit_test.py +150 -48
- {orionis-0.449.0.dist-info → orionis-0.451.0.dist-info}/METADATA +1 -1
- {orionis-0.449.0.dist-info → orionis-0.451.0.dist-info}/RECORD +35 -38
- tests/container/mocks/mock_auto_resolution.py +192 -0
- tests/services/introspection/dependencies/test_reflect_dependencies.py +135 -58
- tests/services/introspection/reflection/test_reflection_abstract.py +5 -4
- tests/services/introspection/reflection/test_reflection_callable.py +3 -3
- tests/services/introspection/reflection/test_reflection_concrete.py +4 -4
- tests/services/introspection/reflection/test_reflection_instance.py +5 -5
- orionis/console/args/parser.py +0 -40
- orionis/container/contracts/resolver.py +0 -115
- orionis/container/resolver/resolver.py +0 -602
- orionis/services/introspection/dependencies/entities/callable_dependencies.py +0 -54
- orionis/services/introspection/dependencies/entities/class_dependencies.py +0 -61
- orionis/services/introspection/dependencies/entities/known_dependencies.py +0 -67
- orionis/services/introspection/dependencies/entities/method_dependencies.py +0 -61
- tests/container/resolver/test_resolver.py +0 -62
- /orionis/{container/resolver → console/commands}/__init__.py +0 -0
- {tests/container/resolver → orionis/console/contracts}/__init__.py +0 -0
- {orionis-0.449.0.dist-info → orionis-0.451.0.dist-info}/WHEEL +0 -0
- {orionis-0.449.0.dist-info → orionis-0.451.0.dist-info}/licenses/LICENCE +0 -0
- {orionis-0.449.0.dist-info → orionis-0.451.0.dist-info}/top_level.txt +0 -0
- {orionis-0.449.0.dist-info → orionis-0.451.0.dist-info}/zip-safe +0 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Optional, Type, Any
|
|
3
|
+
from orionis.services.introspection.exceptions import ReflectionTypeError
|
|
4
|
+
|
|
5
|
+
@dataclass(frozen=True, kw_only=True)
|
|
6
|
+
class Argument:
|
|
7
|
+
"""
|
|
8
|
+
Represents a function or method argument with type information and resolution status.
|
|
9
|
+
|
|
10
|
+
This class encapsulates metadata about an argument including its type information,
|
|
11
|
+
module location, resolution status, and optional default value. It is primarily
|
|
12
|
+
used in dependency injection and introspection systems to track argument details
|
|
13
|
+
and validate type consistency.
|
|
14
|
+
|
|
15
|
+
Attributes
|
|
16
|
+
----------
|
|
17
|
+
resolved : bool
|
|
18
|
+
Flag indicating whether the argument has been resolved or processed.
|
|
19
|
+
module_name : str
|
|
20
|
+
The name of the module where the argument's type is defined.
|
|
21
|
+
class_name : str
|
|
22
|
+
The name of the class representing the argument's type.
|
|
23
|
+
type : Type[Any]
|
|
24
|
+
The Python type object representing the argument's type.
|
|
25
|
+
full_class_path : str
|
|
26
|
+
The complete dotted path to the argument's type (module.class).
|
|
27
|
+
default : Optional[Any], default=None
|
|
28
|
+
The default value for the argument, if any. When None, indicates
|
|
29
|
+
the argument is required and must be explicitly provided.
|
|
30
|
+
|
|
31
|
+
Notes
|
|
32
|
+
-----
|
|
33
|
+
The class performs automatic validation during initialization through the
|
|
34
|
+
__post_init__ method. Validation ensures type consistency and completeness
|
|
35
|
+
of required fields when no default value is provided.
|
|
36
|
+
"""
|
|
37
|
+
resolved: bool
|
|
38
|
+
module_name: str
|
|
39
|
+
class_name: str
|
|
40
|
+
type: Type[Any]
|
|
41
|
+
full_class_path: str
|
|
42
|
+
default: Optional[Any] = None
|
|
43
|
+
|
|
44
|
+
def __post_init__(self):
|
|
45
|
+
"""
|
|
46
|
+
Validate all fields during initialization to ensure data integrity.
|
|
47
|
+
|
|
48
|
+
This method performs comprehensive validation of the Argument instance fields
|
|
49
|
+
after dataclass initialization. Validation ensures that all required string
|
|
50
|
+
fields are properly typed and that the type field is not None when no default
|
|
51
|
+
value is provided.
|
|
52
|
+
|
|
53
|
+
Returns
|
|
54
|
+
-------
|
|
55
|
+
None
|
|
56
|
+
This method does not return any value. It performs in-place validation
|
|
57
|
+
and raises exceptions if validation fails.
|
|
58
|
+
|
|
59
|
+
Raises
|
|
60
|
+
------
|
|
61
|
+
ReflectionTypeError
|
|
62
|
+
If module_name, class_name, or full_class_path are not string types.
|
|
63
|
+
ValueError
|
|
64
|
+
If the 'type' field is None when default is None, indicating missing
|
|
65
|
+
type information for a required argument.
|
|
66
|
+
|
|
67
|
+
Notes
|
|
68
|
+
-----
|
|
69
|
+
Validation is conditionally performed only when default is None. Arguments
|
|
70
|
+
with default values are assumed to have sufficient type information and
|
|
71
|
+
skip the validation process.
|
|
72
|
+
"""
|
|
73
|
+
# Skip validation when default value is provided
|
|
74
|
+
# Arguments with defaults have implicit type information
|
|
75
|
+
if self.default is None and self.resolved:
|
|
76
|
+
|
|
77
|
+
# Validate module_name is a string type
|
|
78
|
+
# Module names must be valid string identifiers
|
|
79
|
+
if not isinstance(self.module_name, str):
|
|
80
|
+
raise ReflectionTypeError(f"module_name must be str, got {type(self.module_name).__name__}")
|
|
81
|
+
|
|
82
|
+
# Validate class_name is a string type
|
|
83
|
+
# Class names must be valid string identifiers
|
|
84
|
+
if not isinstance(self.class_name, str):
|
|
85
|
+
raise ReflectionTypeError(f"class_name must be str, got {type(self.class_name).__name__}")
|
|
86
|
+
|
|
87
|
+
# Validate type field is not None for required arguments
|
|
88
|
+
# Type information is essential for dependency resolution
|
|
89
|
+
if self.type is None:
|
|
90
|
+
raise ValueError("The 'type' field must not be None. Please provide a valid Python type object for the dependency.")
|
|
91
|
+
|
|
92
|
+
# Validate full_class_path is a string type
|
|
93
|
+
# Full class path must be a valid dotted string notation
|
|
94
|
+
if not isinstance(self.full_class_path, str):
|
|
95
|
+
raise ReflectionTypeError(f"full_class_path must be str, got {type(self.full_class_path).__name__}")
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Dict
|
|
3
|
+
from orionis.services.introspection.dependencies.entities.argument import Argument
|
|
4
|
+
from orionis.services.introspection.exceptions import ReflectionTypeError
|
|
5
|
+
from orionis.support.entities.base import BaseEntity
|
|
6
|
+
|
|
7
|
+
@dataclass(frozen=True, kw_only=True)
|
|
8
|
+
class ResolveArguments(BaseEntity):
|
|
9
|
+
"""
|
|
10
|
+
Represents the dependencies of a class, distinguishing between resolved and unresolved dependencies.
|
|
11
|
+
|
|
12
|
+
This class encapsulates both successfully resolved dependencies (with their corresponding
|
|
13
|
+
Argument instances) and unresolved dependencies that could not be satisfied during
|
|
14
|
+
dependency injection or reflection analysis.
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
resolved : Dict[str, Argument]
|
|
19
|
+
Dictionary mapping dependency names to their corresponding Argument instances
|
|
20
|
+
that have been successfully resolved.
|
|
21
|
+
unresolved : Dict[str, Argument]
|
|
22
|
+
Dictionary mapping dependency names to their corresponding Argument instances
|
|
23
|
+
that could not be resolved during dependency analysis.
|
|
24
|
+
|
|
25
|
+
Attributes
|
|
26
|
+
----------
|
|
27
|
+
resolved : Dict[str, Argument]
|
|
28
|
+
The resolved dependencies for the class, where each key is a dependency name
|
|
29
|
+
and each value is an Argument instance containing the resolved information.
|
|
30
|
+
unresolved : Dict[str, Argument]
|
|
31
|
+
The unresolved dependency names mapped to their Argument instances, representing
|
|
32
|
+
dependencies that could not be satisfied.
|
|
33
|
+
|
|
34
|
+
Raises
|
|
35
|
+
------
|
|
36
|
+
ReflectionTypeError
|
|
37
|
+
If 'resolved' is not a dictionary or 'unresolved' is not a dictionary.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
# Resolved dependencies as a dictionary of names to Argument instances
|
|
41
|
+
resolved: Dict[str, Argument]
|
|
42
|
+
|
|
43
|
+
# Unresolved dependencies as a dictionary of names to Argument instances
|
|
44
|
+
unresolved: Dict[str, Argument]
|
|
45
|
+
|
|
46
|
+
def __post_init__(self):
|
|
47
|
+
"""
|
|
48
|
+
Validates the types and contents of the resolved and unresolved attributes.
|
|
49
|
+
|
|
50
|
+
This method is automatically called by the dataclass after object initialization
|
|
51
|
+
to ensure that both attributes are dictionaries with the correct types. It performs
|
|
52
|
+
runtime type checking to maintain data integrity and provide clear error messages
|
|
53
|
+
when invalid types are provided.
|
|
54
|
+
|
|
55
|
+
Parameters
|
|
56
|
+
----------
|
|
57
|
+
None
|
|
58
|
+
|
|
59
|
+
Returns
|
|
60
|
+
-------
|
|
61
|
+
None
|
|
62
|
+
This method performs validation only and does not return any value.
|
|
63
|
+
|
|
64
|
+
Raises
|
|
65
|
+
------
|
|
66
|
+
ReflectionTypeError
|
|
67
|
+
If 'resolved' is not a dict or 'unresolved' is not a dict.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
# Validate that the 'resolved' attribute is a dictionary type
|
|
71
|
+
# This ensures that resolved dependencies can be properly accessed by name
|
|
72
|
+
if not isinstance(self.resolved, dict):
|
|
73
|
+
raise ReflectionTypeError(
|
|
74
|
+
f"'resolved' must be a dict, got {type(self.resolved).__name__}"
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Validate that the 'unresolved' attribute is a dictionary type
|
|
78
|
+
# This ensures that unresolved dependencies maintain the same structure as resolved ones
|
|
79
|
+
if not isinstance(self.unresolved, dict):
|
|
80
|
+
raise ReflectionTypeError(
|
|
81
|
+
f"'unresolved' must be a dict, got {type(self.unresolved).__name__}"
|
|
82
|
+
)
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import inspect
|
|
2
|
-
from typing import Any, Dict
|
|
2
|
+
from typing import Any, Dict
|
|
3
3
|
from orionis.services.introspection.dependencies.contracts.reflection import IReflectDependencies
|
|
4
|
-
from orionis.services.introspection.dependencies.entities.
|
|
5
|
-
from orionis.services.introspection.dependencies.entities.
|
|
6
|
-
from orionis.services.introspection.dependencies.entities.method_dependencies import MethodDependency
|
|
7
|
-
from orionis.services.introspection.dependencies.entities.known_dependencies import KnownDependency
|
|
4
|
+
from orionis.services.introspection.dependencies.entities.argument import Argument
|
|
5
|
+
from orionis.services.introspection.dependencies.entities.resolve_argument import ResolveArguments
|
|
8
6
|
from orionis.services.introspection.exceptions import ReflectionValueError
|
|
9
7
|
|
|
10
8
|
class ReflectDependencies(IReflectDependencies):
|
|
@@ -77,150 +75,222 @@ class ReflectDependencies(IReflectDependencies):
|
|
|
77
75
|
except (ReflectionValueError, TypeError, Exception) as e:
|
|
78
76
|
raise ReflectionValueError(f"Unable to inspect signature of {target}: {str(e)}")
|
|
79
77
|
|
|
80
|
-
def
|
|
78
|
+
def __getDependencies(self, signature: inspect.Signature) -> ResolveArguments:
|
|
81
79
|
"""
|
|
82
|
-
|
|
80
|
+
Analyze function signature parameters to categorize dependencies as resolved or unresolved.
|
|
81
|
+
|
|
82
|
+
This method examines each parameter in a function signature and determines whether
|
|
83
|
+
it can be automatically resolved for dependency injection based on type annotations
|
|
84
|
+
and default values. Parameters are categorized into two groups: those that can be
|
|
85
|
+
automatically resolved by the dependency injection system and those that require
|
|
86
|
+
manual intervention.
|
|
87
|
+
|
|
88
|
+
Parameters
|
|
89
|
+
----------
|
|
90
|
+
signature : inspect.Signature
|
|
91
|
+
The function signature to analyze for dependencies. Must be a valid signature
|
|
92
|
+
object obtained from inspect.signature().
|
|
83
93
|
|
|
84
94
|
Returns
|
|
85
95
|
-------
|
|
86
|
-
|
|
87
|
-
A
|
|
88
|
-
|
|
89
|
-
-
|
|
96
|
+
ResolveArguments
|
|
97
|
+
A data structure containing two dictionaries:
|
|
98
|
+
|
|
99
|
+
- resolved : Dict[str, Argument]
|
|
100
|
+
Parameters that can be automatically resolved. Includes parameters with:
|
|
101
|
+
- Type annotations from non-builtin modules
|
|
102
|
+
- Default values (regardless of type annotation)
|
|
103
|
+
|
|
104
|
+
- unresolved : Dict[str, Argument]
|
|
105
|
+
Parameters that cannot be automatically resolved. Includes parameters with:
|
|
106
|
+
- No type annotation and no default value
|
|
107
|
+
- Builtin type annotations without default values (int, str, bool, etc.)
|
|
108
|
+
|
|
109
|
+
Notes
|
|
110
|
+
-----
|
|
111
|
+
- Parameters named 'self', 'cls', 'args', 'kwargs' and variadic parameters
|
|
112
|
+
(*args, **kwargs) are automatically excluded from analysis
|
|
113
|
+
- Parameters with default values are always considered resolved, regardless
|
|
114
|
+
of their type annotation
|
|
115
|
+
- Builtin types (int, str, bool, etc.) without default values are considered
|
|
116
|
+
unresolved as they typically require explicit values
|
|
117
|
+
- Custom classes and imported types with annotations are considered resolved
|
|
118
|
+
as they can be instantiated by the dependency injection system
|
|
90
119
|
"""
|
|
91
|
-
signature = self.__inspectSignature(self.__target.__init__)
|
|
92
|
-
resolved_dependencies: Dict[str, Any] = {}
|
|
93
|
-
unresolved_dependencies: List[str] = []
|
|
94
120
|
|
|
121
|
+
# Initialize dictionaries to store categorized dependencies
|
|
122
|
+
resolved_dependencies: Dict[str, Argument] = {}
|
|
123
|
+
unresolved_dependencies: Dict[str, Argument] = {}
|
|
124
|
+
|
|
125
|
+
# Iterate through all parameters in the signature
|
|
95
126
|
for param_name, param in signature.parameters.items():
|
|
96
127
|
|
|
97
128
|
# Skip parameters that are not relevant for dependency resolution
|
|
129
|
+
# (self, cls, *args, **kwargs, etc.)
|
|
98
130
|
if self.__paramSkip(param_name, param):
|
|
99
131
|
continue
|
|
100
132
|
|
|
101
|
-
#
|
|
133
|
+
# Case 1: Parameters with no annotation and no default value
|
|
134
|
+
# These cannot be resolved automatically and require manual provision
|
|
102
135
|
if param.annotation is param.empty and param.default is param.empty:
|
|
103
|
-
unresolved_dependencies
|
|
136
|
+
unresolved_dependencies[param_name] = Argument(
|
|
137
|
+
resolved=False,
|
|
138
|
+
module_name=None,
|
|
139
|
+
class_name=None,
|
|
140
|
+
type=Any,
|
|
141
|
+
full_class_path=None,
|
|
142
|
+
)
|
|
104
143
|
continue
|
|
105
144
|
|
|
106
|
-
# Parameters with default values
|
|
145
|
+
# Case 2: Parameters with default values
|
|
146
|
+
# These are always considered resolved since they have fallback values
|
|
107
147
|
if param.default is not param.empty:
|
|
108
|
-
resolved_dependencies[param_name] =
|
|
148
|
+
resolved_dependencies[param_name] = Argument(
|
|
149
|
+
resolved=True,
|
|
150
|
+
module_name=type(param.default).__module__,
|
|
151
|
+
class_name=type(param.default).__name__,
|
|
152
|
+
type=type(param.default),
|
|
153
|
+
full_class_path=f"{type(param.default).__module__}.{type(param.default).__name__}",
|
|
154
|
+
default=param.default
|
|
155
|
+
)
|
|
109
156
|
continue
|
|
110
157
|
|
|
111
|
-
#
|
|
158
|
+
# Case 3: Parameters with type annotations
|
|
112
159
|
if param.annotation is not param.empty:
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
160
|
+
# Special handling for builtin types without defaults
|
|
161
|
+
# Builtin types (int, str, bool, etc.) are considered unresolved
|
|
162
|
+
# when they lack default values, as they typically need explicit values
|
|
163
|
+
if param.annotation.__module__ == 'builtins' and param.default is param.empty:
|
|
164
|
+
unresolved_dependencies[param_name] = Argument(
|
|
165
|
+
resolved=False,
|
|
166
|
+
module_name=param.annotation.__module__,
|
|
167
|
+
class_name=param.annotation.__name__,
|
|
168
|
+
type=param.annotation,
|
|
169
|
+
full_class_path=f"{param.annotation.__module__}.{param.annotation.__name__}"
|
|
170
|
+
)
|
|
171
|
+
else:
|
|
172
|
+
# Non-builtin types with annotations are considered resolved
|
|
173
|
+
# as they can be instantiated by the dependency injection system
|
|
174
|
+
resolved_dependencies[param_name] = Argument(
|
|
175
|
+
resolved=True,
|
|
176
|
+
module_name=param.annotation.__module__,
|
|
177
|
+
class_name=param.annotation.__name__,
|
|
178
|
+
type=param.annotation,
|
|
179
|
+
full_class_path=f"{param.annotation.__module__}.{param.annotation.__name__}"
|
|
180
|
+
)
|
|
181
|
+
continue
|
|
120
182
|
|
|
121
|
-
|
|
183
|
+
# Return the categorized dependencies
|
|
184
|
+
return ResolveArguments(
|
|
122
185
|
resolved=resolved_dependencies,
|
|
123
186
|
unresolved=unresolved_dependencies
|
|
124
187
|
)
|
|
125
188
|
|
|
126
|
-
def
|
|
189
|
+
def getConstructorDependencies(self) -> ResolveArguments:
|
|
127
190
|
"""
|
|
128
|
-
|
|
191
|
+
Inspects the constructor (__init__) method of the target class to identify and categorize
|
|
192
|
+
its parameter dependencies into resolved and unresolved categories.
|
|
129
193
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
The name of the method to inspect
|
|
194
|
+
This method analyzes the constructor's signature to determine which parameters can be
|
|
195
|
+
automatically resolved (those with type annotations or default values) and which require
|
|
196
|
+
explicit provision during instantiation.
|
|
134
197
|
|
|
135
198
|
Returns
|
|
136
199
|
-------
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
- resolved:
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
resolved_dependencies: Dict[str, Any] = {}
|
|
144
|
-
unresolved_dependencies: List[str] = []
|
|
145
|
-
|
|
146
|
-
for param_name, param in signature.parameters.items():
|
|
200
|
+
ResolveArguments
|
|
201
|
+
An object containing two dictionaries:
|
|
202
|
+
- resolved: Dict[str, Argument] mapping parameter names to Argument objects for
|
|
203
|
+
parameters that have type annotations or default values and can be automatically resolved.
|
|
204
|
+
- unresolved: Dict[str, Argument] mapping parameter names to Argument objects for
|
|
205
|
+
parameters that lack both type annotations and default values, requiring manual resolution.
|
|
147
206
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
continue
|
|
161
|
-
|
|
162
|
-
# If the parameter has an annotation, it is added to the list of resolved dependencies
|
|
163
|
-
if param.annotation is not param.empty:
|
|
164
|
-
module_path = param.annotation.__module__
|
|
165
|
-
resolved_dependencies[param_name] = KnownDependency(
|
|
166
|
-
module_name=module_path,
|
|
167
|
-
class_name=param.annotation.__name__,
|
|
168
|
-
type=param.annotation,
|
|
169
|
-
full_class_path=f"{module_path}.{param.annotation.__name__}"
|
|
170
|
-
)
|
|
207
|
+
Raises
|
|
208
|
+
------
|
|
209
|
+
ReflectionValueError
|
|
210
|
+
If the target object's constructor signature cannot be inspected or if the target
|
|
211
|
+
is not callable.
|
|
212
|
+
|
|
213
|
+
Notes
|
|
214
|
+
-----
|
|
215
|
+
Parameters named 'self', 'cls', 'args', 'kwargs', and variadic parameters (*args, **kwargs)
|
|
216
|
+
are automatically excluded from dependency analysis as they are not relevant for
|
|
217
|
+
dependency injection purposes.
|
|
218
|
+
"""
|
|
171
219
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
unresolved=unresolved_dependencies
|
|
175
|
-
)
|
|
220
|
+
# Extract the constructor signature from the target class
|
|
221
|
+
return self.__getDependencies(self.__inspectSignature(self.__target.__init__))
|
|
176
222
|
|
|
177
|
-
def
|
|
223
|
+
def getMethodDependencies(self, method_name: str) -> ResolveArguments:
|
|
178
224
|
"""
|
|
179
|
-
|
|
225
|
+
Inspects a specific method of the target class to identify and categorize
|
|
226
|
+
its parameter dependencies into resolved and unresolved categories.
|
|
227
|
+
|
|
228
|
+
This method analyzes the specified method's signature to determine which parameters
|
|
229
|
+
can be automatically resolved (those with type annotations or default values) and
|
|
230
|
+
which require explicit provision during method invocation.
|
|
180
231
|
|
|
181
232
|
Parameters
|
|
182
233
|
----------
|
|
183
|
-
|
|
184
|
-
The
|
|
234
|
+
method_name : str
|
|
235
|
+
The name of the method within the target class to inspect for dependencies.
|
|
236
|
+
The method must exist as an attribute of the target object.
|
|
185
237
|
|
|
186
238
|
Returns
|
|
187
239
|
-------
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
- resolved:
|
|
191
|
-
|
|
240
|
+
ResolveArguments
|
|
241
|
+
An object containing two dictionaries:
|
|
242
|
+
- resolved: Dict[str, Argument] mapping parameter names to Argument objects for
|
|
243
|
+
parameters that have type annotations or default values and can be automatically resolved.
|
|
244
|
+
- unresolved: Dict[str, Argument] mapping parameter names to Argument objects for
|
|
245
|
+
parameters that lack both type annotations and default values, requiring manual resolution.
|
|
246
|
+
|
|
247
|
+
Raises
|
|
248
|
+
------
|
|
249
|
+
ReflectionValueError
|
|
250
|
+
If the specified method does not exist on the target object, if the method's
|
|
251
|
+
signature cannot be inspected, or if the target is not callable.
|
|
252
|
+
AttributeError
|
|
253
|
+
If the method_name does not correspond to an existing attribute on the target object.
|
|
254
|
+
|
|
255
|
+
Notes
|
|
256
|
+
-----
|
|
257
|
+
Parameters named 'self', 'cls', 'args', 'kwargs', and variadic parameters (*args, **kwargs)
|
|
258
|
+
are automatically excluded from dependency analysis as they are not relevant for
|
|
259
|
+
dependency injection purposes.
|
|
192
260
|
"""
|
|
193
|
-
signature = inspect.signature(fn)
|
|
194
|
-
resolved_dependencies: Dict[str, Any] = {}
|
|
195
|
-
unresolved_dependencies: List[str] = []
|
|
196
261
|
|
|
197
|
-
|
|
262
|
+
# Extract the method signature from the target class
|
|
263
|
+
return self.__getDependencies(self.__inspectSignature(getattr(self.__target, method_name)))
|
|
198
264
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
265
|
+
def getCallableDependencies(self) -> ResolveArguments:
|
|
266
|
+
"""
|
|
267
|
+
Inspects a callable target (function, lambda, or other callable object) to identify
|
|
268
|
+
and categorize its parameter dependencies into resolved and unresolved categories.
|
|
202
269
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
continue
|
|
270
|
+
This method analyzes the callable's signature to determine which parameters can be
|
|
271
|
+
automatically resolved (those with type annotations or default values) and which
|
|
272
|
+
require explicit provision during function invocation.
|
|
207
273
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
274
|
+
Returns
|
|
275
|
+
-------
|
|
276
|
+
ResolveArguments
|
|
277
|
+
An object containing two dictionaries:
|
|
278
|
+
- resolved: Dict[str, Argument] mapping parameter names to Argument objects for
|
|
279
|
+
parameters that have type annotations or default values and can be automatically resolved.
|
|
280
|
+
- unresolved: Dict[str, Argument] mapping parameter names to Argument objects for
|
|
281
|
+
parameters that lack both type annotations and default values, requiring manual resolution.
|
|
212
282
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
module_name=module_path,
|
|
218
|
-
class_name=param.annotation.__name__,
|
|
219
|
-
type=param.annotation,
|
|
220
|
-
full_class_path=f"{module_path}.{param.annotation.__name__}"
|
|
221
|
-
)
|
|
283
|
+
Raises
|
|
284
|
+
------
|
|
285
|
+
ReflectionValueError
|
|
286
|
+
If the target object is not callable or if the callable's signature cannot be inspected.
|
|
222
287
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
288
|
+
Notes
|
|
289
|
+
-----
|
|
290
|
+
Parameters named 'self', 'cls', 'args', 'kwargs', and variadic parameters (*args, **kwargs)
|
|
291
|
+
are automatically excluded from dependency analysis as they are not relevant for
|
|
292
|
+
dependency injection purposes.
|
|
293
|
+
"""
|
|
294
|
+
|
|
295
|
+
# Extract the callable signature from the target object
|
|
296
|
+
return self.__getDependencies(inspect.signature(self.__target))
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
2
|
import inspect
|
|
3
3
|
from typing import Any, Callable, Dict, List, Optional, Tuple, Type
|
|
4
|
-
from orionis.services.introspection.dependencies.entities.
|
|
5
|
-
from orionis.services.introspection.dependencies.entities.method_dependencies import MethodDependency
|
|
4
|
+
from orionis.services.introspection.dependencies.entities.resolve_argument import ResolveArguments
|
|
6
5
|
|
|
7
6
|
class IReflectionInstance(ABC):
|
|
8
7
|
|
|
@@ -836,13 +835,13 @@ class IReflectionInstance(ABC):
|
|
|
836
835
|
pass
|
|
837
836
|
|
|
838
837
|
@abstractmethod
|
|
839
|
-
def getConstructorDependencies(self) ->
|
|
838
|
+
def getConstructorDependencies(self) -> ResolveArguments:
|
|
840
839
|
"""
|
|
841
840
|
Get the resolved and unresolved dependencies from the constructor of the instance's class.
|
|
842
841
|
|
|
843
842
|
Returns
|
|
844
843
|
-------
|
|
845
|
-
|
|
844
|
+
ResolveArguments
|
|
846
845
|
A structured representation of the constructor dependencies, containing:
|
|
847
846
|
- resolved: Dictionary of resolved dependencies with their names and values.
|
|
848
847
|
- unresolved: List of unresolved dependencies (parameter names without default values or annotations).
|
|
@@ -850,7 +849,7 @@ class IReflectionInstance(ABC):
|
|
|
850
849
|
pass
|
|
851
850
|
|
|
852
851
|
@abstractmethod
|
|
853
|
-
def getMethodDependencies(self, method_name: str) ->
|
|
852
|
+
def getMethodDependencies(self, method_name: str) -> ResolveArguments:
|
|
854
853
|
"""
|
|
855
854
|
Get the resolved and unresolved dependencies from a method of the instance's class.
|
|
856
855
|
|
|
@@ -861,7 +860,7 @@ class IReflectionInstance(ABC):
|
|
|
861
860
|
|
|
862
861
|
Returns
|
|
863
862
|
-------
|
|
864
|
-
|
|
863
|
+
ResolveArguments
|
|
865
864
|
A structured representation of the method dependencies, containing:
|
|
866
865
|
- resolved: Dictionary of resolved dependencies with their names and values.
|
|
867
866
|
- unresolved: List of unresolved dependencies (parameter names without default values or annotations).
|
|
@@ -2,8 +2,7 @@ import inspect
|
|
|
2
2
|
import keyword
|
|
3
3
|
from typing import Any, Callable, Dict, List, Optional, Tuple, Type
|
|
4
4
|
from orionis.services.asynchrony.coroutines import Coroutine
|
|
5
|
-
from orionis.services.introspection.dependencies.entities.
|
|
6
|
-
from orionis.services.introspection.dependencies.entities.method_dependencies import MethodDependency
|
|
5
|
+
from orionis.services.introspection.dependencies.entities.resolve_argument import ResolveArguments
|
|
7
6
|
from orionis.services.introspection.dependencies.reflection import ReflectDependencies
|
|
8
7
|
from orionis.services.introspection.exceptions import (
|
|
9
8
|
ReflectionAttributeError,
|
|
@@ -1561,13 +1560,13 @@ class ReflectionInstance(IReflectionInstance):
|
|
|
1561
1560
|
# If the property does not exist, raise an error
|
|
1562
1561
|
raise ReflectionAttributeError(f"Property '{original_name}' does not exist on '{self.getClassName()}'.")
|
|
1563
1562
|
|
|
1564
|
-
def getConstructorDependencies(self) ->
|
|
1563
|
+
def getConstructorDependencies(self) -> ResolveArguments:
|
|
1565
1564
|
"""
|
|
1566
1565
|
Retrieves the resolved and unresolved dependencies from the constructor (__init__) of the instance's class.
|
|
1567
1566
|
|
|
1568
1567
|
Returns
|
|
1569
1568
|
-------
|
|
1570
|
-
|
|
1569
|
+
ResolveArguments
|
|
1571
1570
|
An object representing the constructor dependencies, including:
|
|
1572
1571
|
- resolved : dict
|
|
1573
1572
|
Dictionary of resolved dependencies with their names and values.
|
|
@@ -1581,7 +1580,7 @@ class ReflectionInstance(IReflectionInstance):
|
|
|
1581
1580
|
"""
|
|
1582
1581
|
return ReflectDependencies(self._instance.__class__).getConstructorDependencies()
|
|
1583
1582
|
|
|
1584
|
-
def getMethodDependencies(self, method_name: str) ->
|
|
1583
|
+
def getMethodDependencies(self, method_name: str) -> ResolveArguments:
|
|
1585
1584
|
"""
|
|
1586
1585
|
Get the resolved and unresolved dependencies from a method of the instance's class.
|
|
1587
1586
|
|
|
@@ -1592,7 +1591,7 @@ class ReflectionInstance(IReflectionInstance):
|
|
|
1592
1591
|
|
|
1593
1592
|
Returns
|
|
1594
1593
|
-------
|
|
1595
|
-
|
|
1594
|
+
ResolveArguments
|
|
1596
1595
|
A structured representation of the method dependencies, containing:
|
|
1597
1596
|
- resolved: Dictionary of resolved dependencies with their names and values.
|
|
1598
1597
|
- unresolved: List of unresolved dependencies (parameter names without default values or annotations).
|