python-injection 0.18.12__py3-none-any.whl → 0.18.14__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.
- injection/__init__.pyi +6 -6
- injection/_core/module.py +4 -4
- injection/loaders.py +23 -2
- {python_injection-0.18.12.dist-info → python_injection-0.18.14.dist-info}/METADATA +19 -7
- {python_injection-0.18.12.dist-info → python_injection-0.18.14.dist-info}/RECORD +7 -7
- {python_injection-0.18.12.dist-info → python_injection-0.18.14.dist-info}/WHEEL +0 -0
- {python_injection-0.18.12.dist-info → python_injection-0.18.14.dist-info}/licenses/LICENSE +0 -0
injection/__init__.pyi
CHANGED
@@ -115,7 +115,7 @@ class Module:
|
|
115
115
|
parameter type annotations. If applied to a class, the dependencies resolved
|
116
116
|
will be those of the `__init__` method.
|
117
117
|
|
118
|
-
With `threadsafe=True`, the injection logic is wrapped in a `threading.
|
118
|
+
With `threadsafe=True`, the injection logic is wrapped in a `threading.RLock`.
|
119
119
|
"""
|
120
120
|
|
121
121
|
def injectable[**P, T](
|
@@ -171,18 +171,18 @@ class Module:
|
|
171
171
|
registered.
|
172
172
|
"""
|
173
173
|
|
174
|
-
def constant[T](
|
174
|
+
def constant[**P, T](
|
175
175
|
self,
|
176
|
-
wrapped:
|
176
|
+
wrapped: _Recipe[P, T] = ...,
|
177
177
|
/,
|
178
178
|
*,
|
179
179
|
on: _TypeInfo[T] = ...,
|
180
180
|
mode: Mode | ModeStr = ...,
|
181
181
|
) -> Any:
|
182
182
|
"""
|
183
|
-
Decorator applicable to a class. It is used to indicate how the
|
184
|
-
constructed. At injection time, the injected instance will always
|
185
|
-
Unlike `@singleton`, dependencies will not be resolved.
|
183
|
+
Decorator applicable to a class or function. It is used to indicate how the
|
184
|
+
constant is constructed. At injection time, the injected instance will always
|
185
|
+
be the same. Unlike `@singleton`, dependencies will not be resolved.
|
186
186
|
"""
|
187
187
|
|
188
188
|
def set_constant[T](
|
injection/_core/module.py
CHANGED
@@ -503,15 +503,15 @@ class Module(Broker, EventListener):
|
|
503
503
|
|
504
504
|
return decorator(wrapped) if wrapped else decorator
|
505
505
|
|
506
|
-
def constant[T](
|
506
|
+
def constant[**P, T](
|
507
507
|
self,
|
508
|
-
wrapped:
|
508
|
+
wrapped: Recipe[P, T] | None = None,
|
509
509
|
/,
|
510
510
|
*,
|
511
511
|
on: TypeInfo[T] = (),
|
512
512
|
mode: Mode | ModeStr = Mode.get_default(),
|
513
513
|
) -> Any:
|
514
|
-
def decorator(wp:
|
514
|
+
def decorator(wp: Recipe[P, T]) -> Recipe[P, T]:
|
515
515
|
lazy_instance = lazy(wp)
|
516
516
|
self.injectable(
|
517
517
|
lambda: ~lazy_instance,
|
@@ -1087,7 +1087,7 @@ class InjectMetadata[**P, T](Caller[P, T], EventListener):
|
|
1087
1087
|
return decorator(wrapped) if wrapped else decorator
|
1088
1088
|
|
1089
1089
|
@singledispatchmethod
|
1090
|
-
def on_event(self, event: Event, /) -> ContextManager[None] | None:
|
1090
|
+
def on_event(self, event: Event, /) -> ContextManager[None] | None:
|
1091
1091
|
return None
|
1092
1092
|
|
1093
1093
|
@on_event.register
|
injection/loaders.py
CHANGED
@@ -149,14 +149,26 @@ class ProfileLoader:
|
|
149
149
|
def __is_empty(self) -> bool:
|
150
150
|
return not self.module_subsets
|
151
151
|
|
152
|
+
def required_module_names(self, name: str | None = None, /) -> frozenset[str]:
|
153
|
+
names = {self.module.name}
|
154
|
+
|
155
|
+
if name is not None:
|
156
|
+
names.add(name)
|
157
|
+
|
158
|
+
subsets = (self.__walk_subsets_for(name) for name in names)
|
159
|
+
return frozenset(itertools.chain.from_iterable(subsets))
|
160
|
+
|
152
161
|
def init(self) -> Self:
|
153
162
|
self.__init_subsets_for(self.module)
|
154
163
|
return self
|
155
164
|
|
156
165
|
def load(self, name: str, /) -> LoadedProfile:
|
157
166
|
self.init()
|
158
|
-
|
159
|
-
self.
|
167
|
+
|
168
|
+
if not self.__is_default_module(name):
|
169
|
+
target_module = self.__init_subsets_for(mod(name))
|
170
|
+
self.module.use(target_module, priority=Priority.HIGH)
|
171
|
+
|
160
172
|
return _UserLoadedProfile(self, name)
|
161
173
|
|
162
174
|
def _unload(self, name: str, /) -> None:
|
@@ -173,12 +185,21 @@ class ProfileLoader:
|
|
173
185
|
|
174
186
|
return module
|
175
187
|
|
188
|
+
def __is_default_module(self, module_name: str) -> bool:
|
189
|
+
return module_name == self.module.name
|
190
|
+
|
176
191
|
def __is_initialized(self, module: Module) -> bool:
|
177
192
|
return module.name in self.__initialized_modules
|
178
193
|
|
179
194
|
def __mark_initialized(self, module: Module) -> None:
|
180
195
|
self.__initialized_modules.add(module.name)
|
181
196
|
|
197
|
+
def __walk_subsets_for(self, module_name: str) -> Iterator[str]:
|
198
|
+
yield module_name
|
199
|
+
|
200
|
+
for name in self.module_subsets.get(module_name, ()):
|
201
|
+
yield from self.__walk_subsets_for(name)
|
202
|
+
|
182
203
|
|
183
204
|
@runtime_checkable
|
184
205
|
class LoadedProfile(Protocol):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: python-injection
|
3
|
-
Version: 0.18.
|
3
|
+
Version: 0.18.14
|
4
4
|
Summary: Fast and easy dependency injection framework.
|
5
5
|
Project-URL: Repository, https://github.com/100nm/python-injection
|
6
6
|
Author: remimd
|
@@ -14,6 +14,8 @@ Classifier: Operating System :: OS Independent
|
|
14
14
|
Classifier: Programming Language :: Python
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
16
16
|
Classifier: Programming Language :: Python :: 3 :: Only
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
17
19
|
Classifier: Topic :: Software Development :: Libraries
|
18
20
|
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
19
21
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
@@ -27,11 +29,10 @@ Description-Content-Type: text/markdown
|
|
27
29
|
# python-injection
|
28
30
|
|
29
31
|
[](https://github.com/100nm/python-injection)
|
30
|
-
[](https://pypi.org/project/python-injection)
|
32
|
+
[](https://pypi.org/project/python-injection)
|
33
|
+
[](https://pypistats.org/packages/python-injection)
|
31
34
|
[](https://github.com/astral-sh/ruff)
|
32
35
|
|
33
|
-
Fast and easy dependency injection framework.
|
34
|
-
|
35
36
|
## Installation
|
36
37
|
|
37
38
|
⚠️ _Requires Python 3.12 or higher_
|
@@ -40,12 +41,22 @@ Fast and easy dependency injection framework.
|
|
40
41
|
pip install python-injection
|
41
42
|
```
|
42
43
|
|
44
|
+
## Features
|
45
|
+
|
46
|
+
* Automatic dependency resolution based on type hints.
|
47
|
+
* Support for multiple dependency lifetimes: `transient`, `singleton`, `constant`, and `scoped`.
|
48
|
+
* Works seamlessly in both `async` and `sync` environments.
|
49
|
+
* Separation of dependency sets using modules.
|
50
|
+
* Runtime switching between different sets of dependencies.
|
51
|
+
* Centralized setup logic using entrypoints.
|
52
|
+
* Built-in type annotation for easy integration with [`FastAPI`](https://github.com/fastapi/fastapi).
|
53
|
+
* Lazy dependency resolution for optimized performance.
|
54
|
+
|
43
55
|
## Motivations
|
44
56
|
|
45
57
|
1. Easy to use
|
46
58
|
2. No impact on class and function definitions
|
47
|
-
3.
|
48
|
-
4. No prerequisites
|
59
|
+
3. No tedious configuration
|
49
60
|
|
50
61
|
## Quick start
|
51
62
|
|
@@ -90,5 +101,6 @@ if __name__ == "__main__":
|
|
90
101
|
* [**Advanced usage**](https://github.com/100nm/python-injection/tree/prod/documentation/advanced-usage.md)
|
91
102
|
* [**Loaders**](https://github.com/100nm/python-injection/tree/prod/documentation/loaders.md)
|
92
103
|
* [**Entrypoint**](https://github.com/100nm/python-injection/tree/prod/documentation/entrypoint.md)
|
93
|
-
* [**Integrations**](https://github.com/100nm/python-injection/tree/prod/documentation/integrations
|
104
|
+
* [**Integrations**](https://github.com/100nm/python-injection/tree/prod/documentation/integrations)
|
105
|
+
* [**FastAPI**](https://github.com/100nm/python-injection/tree/prod/documentation/integrations/fastapi.md)
|
94
106
|
* [**Concrete example**](https://github.com/100nm/python-injection-example)
|
@@ -1,13 +1,13 @@
|
|
1
1
|
injection/__init__.py,sha256=7ZRUlO5EEPWO7IlbYHD-8DOX-cg4Np4nYq5fpw-U56o,1259
|
2
|
-
injection/__init__.pyi,sha256=
|
2
|
+
injection/__init__.pyi,sha256=94F3A7lPmEyaJtsetVQpmS33LiY-BpymOLcFA6xvFBk,10964
|
3
3
|
injection/entrypoint.py,sha256=12b0_zHAFxHCerAoJTIHkhqi3mLkgheECYAaCUZv_DU,4751
|
4
4
|
injection/exceptions.py,sha256=v57yMujiq6H_zwwn30A8UYEZX9R9k-bY8FnsdaimPM4,1025
|
5
|
-
injection/loaders.py,sha256=
|
5
|
+
injection/loaders.py,sha256=gKlJfe9nXCuB8r6j0RF9_2FHC6YplM8GQYsgRqyxYw8,7257
|
6
6
|
injection/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
7
|
injection/_core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
8
|
injection/_core/descriptors.py,sha256=RRng9lx-ET6An1d_244rAv4iLUTQUGvDh1ugLfImuW8,794
|
9
9
|
injection/_core/injectables.py,sha256=Rg1nxDkbcpeX4ELohrNVMguPhN36SNQuD0JKfyfL6bI,6192
|
10
|
-
injection/_core/module.py,sha256=
|
10
|
+
injection/_core/module.py,sha256=lQFhfc9vDCiENkMvgkCzc-wW50uEl2bjKKBfRlR6nv8,32408
|
11
11
|
injection/_core/scope.py,sha256=NY6YWcIIXqBKTjXVsqsahxbw-bPJiL0CwHp6CyjBGJo,8753
|
12
12
|
injection/_core/slots.py,sha256=g9TG6CbqRzCsjg01iPyfRtTTUCJnnJOwcj9mJabH0dc,37
|
13
13
|
injection/_core/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -23,7 +23,7 @@ injection/ext/fastapi.py,sha256=YdCVO1WgZRhv0CFrDnIdsbeRprtcHb-snIL4B4mpLnk,1388
|
|
23
23
|
injection/ext/fastapi.pyi,sha256=HLs7mfruIEFRrN_Xf8oCvSa4qwHWfwm6HHU_KMedXkE,185
|
24
24
|
injection/testing/__init__.py,sha256=bJ7WXBXrw4rHc91AFVFnOwFLWOlpvX9Oh2SnRQ_NESo,919
|
25
25
|
injection/testing/__init__.pyi,sha256=raGsGlxwbz3jkzJwA_5oCIE1emWINjT2UuwzbnqRb-0,577
|
26
|
-
python_injection-0.18.
|
27
|
-
python_injection-0.18.
|
28
|
-
python_injection-0.18.
|
29
|
-
python_injection-0.18.
|
26
|
+
python_injection-0.18.14.dist-info/METADATA,sha256=jtUZE1HuKfARdckxvXvKbw-xSnBuLEq0KTi5gmZZx2c,4155
|
27
|
+
python_injection-0.18.14.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
28
|
+
python_injection-0.18.14.dist-info/licenses/LICENSE,sha256=oC77BOa9kaaQni5rW-Z-ytz3E5h4EVg248BHg9UFgyg,1063
|
29
|
+
python_injection-0.18.14.dist-info/RECORD,,
|
File without changes
|
File without changes
|