python-injection 0.19.2__py3-none-any.whl → 0.19.4__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 +148 -13
- injection/_core/common/lazy.py +21 -12
- injection/_core/common/type.py +12 -3
- injection/_core/module.py +5 -5
- injection/entrypoint.py +14 -3
- {python_injection-0.19.2.dist-info → python_injection-0.19.4.dist-info}/METADATA +1 -1
- {python_injection-0.19.2.dist-info → python_injection-0.19.4.dist-info}/RECORD +9 -9
- {python_injection-0.19.2.dist-info → python_injection-0.19.4.dist-info}/WHEEL +0 -0
- {python_injection-0.19.2.dist-info → python_injection-0.19.4.dist-info}/licenses/LICENSE +0 -0
injection/__init__.pyi
CHANGED
@@ -11,9 +11,10 @@ from ._core.common.type import InputType as _InputType
|
|
11
11
|
from ._core.common.type import TypeInfo as _TypeInfo
|
12
12
|
from ._core.module import InjectableFactory as _InjectableFactory
|
13
13
|
from ._core.module import ModeStr, PriorityStr
|
14
|
-
from ._core.module import Recipe as _Recipe
|
15
14
|
from ._core.scope import ScopeKindStr
|
16
15
|
|
16
|
+
type _Decorator[T] = Callable[[T], T]
|
17
|
+
|
17
18
|
__MODULE: Final[Module] = ...
|
18
19
|
|
19
20
|
afind_instance = __MODULE.afind_instance
|
@@ -120,13 +121,14 @@ class Module:
|
|
120
121
|
def __contains__(self, cls: _InputType[Any], /) -> bool: ...
|
121
122
|
@property
|
122
123
|
def is_locked(self) -> bool: ...
|
124
|
+
@overload
|
123
125
|
def inject[**P, T](
|
124
126
|
self,
|
125
|
-
wrapped: Callable[P, T]
|
127
|
+
wrapped: Callable[P, T],
|
126
128
|
/,
|
127
129
|
*,
|
128
130
|
threadsafe: bool | None = ...,
|
129
|
-
) ->
|
131
|
+
) -> Callable[P, T]:
|
130
132
|
"""
|
131
133
|
Decorator applicable to a class or function. Inject function dependencies using
|
132
134
|
parameter type annotations. If applied to a class, the dependencies resolved
|
@@ -134,39 +136,127 @@ class Module:
|
|
134
136
|
|
135
137
|
With `threadsafe=True`, the injection logic is wrapped in a `threading.RLock`.
|
136
138
|
"""
|
137
|
-
|
139
|
+
@overload
|
140
|
+
def inject[T](
|
141
|
+
self,
|
142
|
+
wrapped: type[T],
|
143
|
+
/,
|
144
|
+
*,
|
145
|
+
threadsafe: bool | None = ...,
|
146
|
+
) -> type[T]: ...
|
147
|
+
@overload
|
148
|
+
def inject[**P, T](
|
149
|
+
self,
|
150
|
+
wrapped: None = ...,
|
151
|
+
/,
|
152
|
+
*,
|
153
|
+
threadsafe: bool | None = ...,
|
154
|
+
) -> _Decorator[Callable[P, T]] | _Decorator[type[T]]: ...
|
155
|
+
@overload
|
138
156
|
def injectable[**P, T](
|
139
157
|
self,
|
140
|
-
wrapped:
|
158
|
+
wrapped: Callable[P, T],
|
141
159
|
/,
|
142
160
|
*,
|
143
161
|
cls: _InjectableFactory[T] = ...,
|
144
162
|
inject: bool = ...,
|
145
163
|
on: _TypeInfo[T] = ...,
|
146
164
|
mode: Mode | ModeStr = ...,
|
147
|
-
) ->
|
165
|
+
) -> Callable[P, T]:
|
148
166
|
"""
|
149
167
|
Decorator applicable to a class or function. It is used to indicate how the
|
150
168
|
injectable will be constructed. At injection time, a new instance will be
|
151
169
|
injected each time.
|
152
170
|
"""
|
153
171
|
|
172
|
+
@overload
|
173
|
+
def injectable[**P, T]( # type: ignore[overload-overlap]
|
174
|
+
self,
|
175
|
+
wrapped: Callable[P, Awaitable[T]],
|
176
|
+
/,
|
177
|
+
*,
|
178
|
+
cls: _InjectableFactory[T] = ...,
|
179
|
+
inject: bool = ...,
|
180
|
+
on: _TypeInfo[T] = ...,
|
181
|
+
mode: Mode | ModeStr = ...,
|
182
|
+
) -> Callable[P, Awaitable[T]]: ...
|
183
|
+
@overload
|
184
|
+
def injectable[T](
|
185
|
+
self,
|
186
|
+
wrapped: type[T],
|
187
|
+
/,
|
188
|
+
*,
|
189
|
+
cls: _InjectableFactory[T] = ...,
|
190
|
+
inject: bool = ...,
|
191
|
+
on: _TypeInfo[T] = ...,
|
192
|
+
mode: Mode | ModeStr = ...,
|
193
|
+
) -> type[T]: ...
|
194
|
+
@overload
|
195
|
+
def injectable[**P, T](
|
196
|
+
self,
|
197
|
+
wrapped: None = ...,
|
198
|
+
/,
|
199
|
+
*,
|
200
|
+
cls: _InjectableFactory[T] = ...,
|
201
|
+
inject: bool = ...,
|
202
|
+
on: _TypeInfo[T] = ...,
|
203
|
+
mode: Mode | ModeStr = ...,
|
204
|
+
) -> (
|
205
|
+
_Decorator[Callable[P, T]]
|
206
|
+
| _Decorator[Callable[P, Awaitable[T]]]
|
207
|
+
| _Decorator[type[T]]
|
208
|
+
): ...
|
209
|
+
@overload
|
154
210
|
def singleton[**P, T](
|
155
211
|
self,
|
156
|
-
wrapped:
|
212
|
+
wrapped: Callable[P, T],
|
157
213
|
/,
|
158
214
|
*,
|
159
215
|
inject: bool = ...,
|
160
216
|
on: _TypeInfo[T] = ...,
|
161
217
|
mode: Mode | ModeStr = ...,
|
162
|
-
) ->
|
218
|
+
) -> Callable[P, T]:
|
163
219
|
"""
|
164
220
|
Decorator applicable to a class or function. It is used to indicate how the
|
165
221
|
singleton will be constructed. At injection time, the injected instance will
|
166
222
|
always be the same.
|
167
223
|
"""
|
168
224
|
|
169
|
-
|
225
|
+
@overload
|
226
|
+
def singleton[**P, T]( # type: ignore[overload-overlap]
|
227
|
+
self,
|
228
|
+
wrapped: Callable[P, Awaitable[T]],
|
229
|
+
/,
|
230
|
+
*,
|
231
|
+
inject: bool = ...,
|
232
|
+
on: _TypeInfo[T] = ...,
|
233
|
+
mode: Mode | ModeStr = ...,
|
234
|
+
) -> Callable[P, Awaitable[T]]: ...
|
235
|
+
@overload
|
236
|
+
def singleton[T](
|
237
|
+
self,
|
238
|
+
wrapped: type[T],
|
239
|
+
/,
|
240
|
+
*,
|
241
|
+
inject: bool = ...,
|
242
|
+
on: _TypeInfo[T] = ...,
|
243
|
+
mode: Mode | ModeStr = ...,
|
244
|
+
) -> type[T]: ...
|
245
|
+
@overload
|
246
|
+
def singleton[**P, T](
|
247
|
+
self,
|
248
|
+
wrapped: None = ...,
|
249
|
+
/,
|
250
|
+
*,
|
251
|
+
inject: bool = ...,
|
252
|
+
on: _TypeInfo[T] = ...,
|
253
|
+
mode: Mode | ModeStr = ...,
|
254
|
+
) -> (
|
255
|
+
_Decorator[Callable[P, T]]
|
256
|
+
| _Decorator[Callable[P, Awaitable[T]]]
|
257
|
+
| _Decorator[type[T]]
|
258
|
+
): ...
|
259
|
+
def scoped[**P, T](
|
170
260
|
self,
|
171
261
|
scope_name: str,
|
172
262
|
/,
|
@@ -174,34 +264,79 @@ class Module:
|
|
174
264
|
inject: bool = ...,
|
175
265
|
on: _TypeInfo[T] = (),
|
176
266
|
mode: Mode | ModeStr = ...,
|
177
|
-
) ->
|
267
|
+
) -> (
|
268
|
+
_Decorator[Callable[P, T]]
|
269
|
+
| _Decorator[Callable[P, Awaitable[T]]]
|
270
|
+
| _Decorator[Callable[P, AsyncIterator[T]]]
|
271
|
+
| _Decorator[Callable[P, Iterator[T]]]
|
272
|
+
| _Decorator[type[T]]
|
273
|
+
):
|
178
274
|
"""
|
179
275
|
Decorator applicable to a class or function or generator function. It is used
|
180
276
|
to indicate how the scoped instance will be constructed. At injection time, the
|
181
277
|
injected instance is retrieved from the scope.
|
182
278
|
"""
|
183
279
|
|
184
|
-
|
280
|
+
@overload
|
281
|
+
def should_be_injectable[T](self, wrapped: type[T], /) -> type[T]:
|
185
282
|
"""
|
186
283
|
Decorator applicable to a class. It is used to specify whether an injectable
|
187
284
|
should be registered. Raise an exception at injection time if the class isn't
|
188
285
|
registered.
|
189
286
|
"""
|
190
287
|
|
288
|
+
@overload
|
289
|
+
def should_be_injectable[T](
|
290
|
+
self,
|
291
|
+
wrapped: None = ...,
|
292
|
+
/,
|
293
|
+
) -> _Decorator[type[T]]: ...
|
294
|
+
@overload
|
191
295
|
def constant[**P, T](
|
192
296
|
self,
|
193
|
-
wrapped:
|
297
|
+
wrapped: Callable[P, T],
|
194
298
|
/,
|
195
299
|
*,
|
196
300
|
on: _TypeInfo[T] = ...,
|
197
301
|
mode: Mode | ModeStr = ...,
|
198
|
-
) ->
|
302
|
+
) -> Callable[P, T]:
|
199
303
|
"""
|
200
304
|
Decorator applicable to a class or function. It is used to indicate how the
|
201
305
|
constant is constructed. At injection time, the injected instance will always
|
202
306
|
be the same. Unlike `@singleton`, dependencies will not be resolved.
|
203
307
|
"""
|
204
308
|
|
309
|
+
@overload
|
310
|
+
def constant[**P, T]( # type: ignore[overload-overlap]
|
311
|
+
self,
|
312
|
+
wrapped: Callable[P, Awaitable[T]],
|
313
|
+
/,
|
314
|
+
*,
|
315
|
+
on: _TypeInfo[T] = ...,
|
316
|
+
mode: Mode | ModeStr = ...,
|
317
|
+
) -> Callable[P, Awaitable[T]]: ...
|
318
|
+
@overload
|
319
|
+
def constant[T](
|
320
|
+
self,
|
321
|
+
wrapped: type[T],
|
322
|
+
/,
|
323
|
+
*,
|
324
|
+
on: _TypeInfo[T] = ...,
|
325
|
+
mode: Mode | ModeStr = ...,
|
326
|
+
) -> type[T]: ...
|
327
|
+
@overload
|
328
|
+
def constant[**P, T](
|
329
|
+
self,
|
330
|
+
wrapped: None = ...,
|
331
|
+
/,
|
332
|
+
*,
|
333
|
+
on: _TypeInfo[T] = ...,
|
334
|
+
mode: Mode | ModeStr = ...,
|
335
|
+
) -> (
|
336
|
+
_Decorator[Callable[P, T]]
|
337
|
+
| _Decorator[Callable[P, Awaitable[T]]]
|
338
|
+
| _Decorator[type[T]]
|
339
|
+
): ...
|
205
340
|
def set_constant[T](
|
206
341
|
self,
|
207
342
|
instance: T,
|
injection/_core/common/lazy.py
CHANGED
@@ -1,41 +1,50 @@
|
|
1
|
-
from collections.abc import Callable, Iterator
|
1
|
+
from collections.abc import AsyncIterator, Awaitable, Callable, Iterator
|
2
2
|
from functools import partial
|
3
3
|
|
4
|
-
from injection._core.common.invertible import Invertible
|
4
|
+
from injection._core.common.invertible import Invertible
|
5
5
|
|
6
6
|
|
7
|
-
def lazy[T](factory: Callable[..., T]) ->
|
7
|
+
def lazy[T](factory: Callable[..., T]) -> Callable[[], T]:
|
8
8
|
def cache() -> Iterator[T]:
|
9
|
-
nonlocal factory
|
10
9
|
value = factory()
|
11
|
-
|
10
|
+
while True:
|
11
|
+
yield value
|
12
|
+
|
13
|
+
return partial(next, cache())
|
12
14
|
|
15
|
+
|
16
|
+
def alazy[T](factory: Callable[..., Awaitable[T]]) -> Callable[[], Awaitable[T]]:
|
17
|
+
async def cache() -> AsyncIterator[T]:
|
18
|
+
value = await factory()
|
13
19
|
while True:
|
14
20
|
yield value
|
15
21
|
|
16
|
-
|
17
|
-
return SimpleInvertible(getter)
|
22
|
+
return partial(_anext, cache())
|
18
23
|
|
19
24
|
|
20
25
|
class Lazy[T](Invertible[T]):
|
21
|
-
__slots__ = ("
|
26
|
+
__slots__ = ("__get", "__is_set")
|
22
27
|
|
23
|
-
|
28
|
+
__get: Callable[[], T]
|
24
29
|
__is_set: bool
|
25
30
|
|
26
31
|
def __init__(self, factory: Callable[..., T]) -> None:
|
27
32
|
@lazy
|
28
|
-
def
|
33
|
+
def get() -> T:
|
29
34
|
value = factory()
|
30
35
|
self.__is_set = True
|
31
36
|
return value
|
32
37
|
|
33
|
-
self.
|
38
|
+
self.__get = get
|
34
39
|
self.__is_set = False
|
35
40
|
|
36
41
|
def __invert__(self) -> T:
|
37
|
-
return
|
42
|
+
return self.__get()
|
38
43
|
|
39
44
|
@property
|
40
45
|
def is_set(self) -> bool:
|
41
46
|
return self.__is_set
|
47
|
+
|
48
|
+
|
49
|
+
async def _anext[T](async_iterator: AsyncIterator[T]) -> T:
|
50
|
+
return await anext(async_iterator)
|
injection/_core/common/type.py
CHANGED
@@ -7,6 +7,7 @@ from collections.abc import (
|
|
7
7
|
Generator,
|
8
8
|
Iterable,
|
9
9
|
Iterator,
|
10
|
+
Sequence,
|
10
11
|
)
|
11
12
|
from inspect import isfunction
|
12
13
|
from types import GenericAlias, UnionType
|
@@ -26,7 +27,7 @@ type TypeInfo[T] = (
|
|
26
27
|
InputType[T]
|
27
28
|
| Callable[..., T]
|
28
29
|
| Callable[..., Awaitable[T]]
|
29
|
-
|
|
30
|
+
| Sequence[TypeInfo[T]]
|
30
31
|
)
|
31
32
|
|
32
33
|
|
@@ -89,8 +90,16 @@ def standardize_types(
|
|
89
90
|
else:
|
90
91
|
yield tp
|
91
92
|
|
92
|
-
if with_origin
|
93
|
-
|
93
|
+
if with_origin:
|
94
|
+
if origin is not None:
|
95
|
+
yield origin
|
96
|
+
|
97
|
+
for alias in (tp, origin):
|
98
|
+
if isinstance(alias, TypeAliasType):
|
99
|
+
yield from standardize_types(
|
100
|
+
alias.__value__,
|
101
|
+
with_origin=with_origin,
|
102
|
+
)
|
94
103
|
|
95
104
|
continue
|
96
105
|
|
injection/_core/module.py
CHANGED
@@ -50,7 +50,7 @@ from injection._core.common.asynchronous import (
|
|
50
50
|
from injection._core.common.event import Event, EventChannel, EventListener
|
51
51
|
from injection._core.common.invertible import Invertible, SimpleInvertible
|
52
52
|
from injection._core.common.key import new_short_key
|
53
|
-
from injection._core.common.lazy import Lazy, lazy
|
53
|
+
from injection._core.common.lazy import Lazy, alazy, lazy
|
54
54
|
from injection._core.common.threading import get_lock
|
55
55
|
from injection._core.common.type import (
|
56
56
|
InputType,
|
@@ -347,8 +347,8 @@ class Locator(Broker):
|
|
347
347
|
@staticmethod
|
348
348
|
def __standardize_inputs[T](
|
349
349
|
classes: Iterable[InputType[T]],
|
350
|
-
) ->
|
351
|
-
return
|
350
|
+
) -> Iterator[InputType[T]]:
|
351
|
+
return standardize_types(*classes, with_origin=True)
|
352
352
|
|
353
353
|
@staticmethod
|
354
354
|
def __update_preprocessing[T](updater: Updater[T]) -> Updater[T]:
|
@@ -512,9 +512,9 @@ class Module(Broker, EventListener):
|
|
512
512
|
mode: Mode | ModeStr = Mode.get_default(),
|
513
513
|
) -> Any:
|
514
514
|
def decorator(wp: Recipe[P, T]) -> Recipe[P, T]:
|
515
|
-
|
515
|
+
recipe: Recipe[[], T] = alazy(wp) if iscoroutinefunction(wp) else lazy(wp) # type: ignore[arg-type]
|
516
516
|
self.injectable(
|
517
|
-
|
517
|
+
recipe,
|
518
518
|
ignore_type_hint=True,
|
519
519
|
inject=False,
|
520
520
|
on=(wp, on),
|
injection/entrypoint.py
CHANGED
@@ -22,9 +22,20 @@ type EntrypointSetupMethod[**P, **EPP, T1, T2] = Callable[
|
|
22
22
|
]
|
23
23
|
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
@overload
|
26
|
+
def autocall[T: Callable[..., Any]](wrapped: T, /) -> T: ...
|
27
|
+
|
28
|
+
|
29
|
+
@overload
|
30
|
+
def autocall[T: Callable[..., Any]](wrapped: None = ..., /) -> Callable[[T], T]: ...
|
31
|
+
|
32
|
+
|
33
|
+
def autocall[T: Callable[..., Any]](
|
34
|
+
wrapped: T | None = None,
|
35
|
+
/,
|
36
|
+
) -> T | Callable[[T], T]:
|
37
|
+
def decorator(wp: T) -> T:
|
38
|
+
wp()
|
28
39
|
return wp
|
29
40
|
|
30
41
|
return decorator(wrapped) if wrapped else decorator
|
@@ -1,6 +1,6 @@
|
|
1
1
|
injection/__init__.py,sha256=iJm0BbyGZw-Qr5e8d2C3n8-7FiVD-sy4LU_i_n3AgHY,1318
|
2
|
-
injection/__init__.pyi,sha256=
|
3
|
-
injection/entrypoint.py,sha256=
|
2
|
+
injection/__init__.pyi,sha256=VCuJkbE1S2XppeTkwiDAbOsVBmlmCpFFXe5ztTUb_-Q,14942
|
3
|
+
injection/entrypoint.py,sha256=1JtooUCE9nIvHGAps5ypRb9ZEbgLdLwydkGF-kXMXDY,4953
|
4
4
|
injection/exceptions.py,sha256=v57yMujiq6H_zwwn30A8UYEZX9R9k-bY8FnsdaimPM4,1025
|
5
5
|
injection/loaders.py,sha256=gKlJfe9nXCuB8r6j0RF9_2FHC6YplM8GQYsgRqyxYw8,7257
|
6
6
|
injection/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -8,7 +8,7 @@ injection/_core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
8
|
injection/_core/asfunction.py,sha256=fTgAAWsDWUz89kYsoSVDXdqYKIuh6HtUW5MohGp3ov4,1767
|
9
9
|
injection/_core/descriptors.py,sha256=1OX6JnM8Ux14vW1JSW3FzPgKc2VMTKqJUYBGT3Ypafg,800
|
10
10
|
injection/_core/injectables.py,sha256=fxhiGv7qTCbUunhhd6a3ahosFmgznUFsEvqlwxi4gS4,6098
|
11
|
-
injection/_core/module.py,sha256=
|
11
|
+
injection/_core/module.py,sha256=IrNpWIO75kO3REQX6RdQdtZDjc-S17B8Y2KdM_NGacA,32684
|
12
12
|
injection/_core/scope.py,sha256=r094k1Vjvwm0hTf7AQGYrxxvqQgb7_CDVUKaHQ8wyeM,8772
|
13
13
|
injection/_core/slots.py,sha256=g9TG6CbqRzCsjg01iPyfRtTTUCJnnJOwcj9mJabH0dc,37
|
14
14
|
injection/_core/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -16,15 +16,15 @@ injection/_core/common/asynchronous.py,sha256=nKY2_PAMFF2haC75Fwp8O9Zd-SDuenE6n3
|
|
16
16
|
injection/_core/common/event.py,sha256=XjzV8gxtGlGvzZs_ykvoC60qmdpd3RN08Eiqz5QUwes,1236
|
17
17
|
injection/_core/common/invertible.py,sha256=gA_vw5nBjgp_w9MrDK5jMO8lhuOQWON8BbPpKzEuIY0,502
|
18
18
|
injection/_core/common/key.py,sha256=ghkZD-Y8Moz6SEPNgMh3xgsZUjDVq-XYAmXaCu5VuCA,80
|
19
|
-
injection/_core/common/lazy.py,sha256=
|
19
|
+
injection/_core/common/lazy.py,sha256=hZvz9LhlYxVkD_D8VBAvQmy7YuVaaw075jq0XM0w9_Y,1193
|
20
20
|
injection/_core/common/threading.py,sha256=kwRXNa9ocndIqeZA9kMHjEa8SBpHFcJARj1bgrWCpxE,225
|
21
|
-
injection/_core/common/type.py,sha256=
|
21
|
+
injection/_core/common/type.py,sha256=mmDMaR68pQpwGnOLLkOmy9slCvgjLVYuEhoYVyANRlk,2564
|
22
22
|
injection/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
23
23
|
injection/ext/fastapi.py,sha256=fiy3-mZIIwGcql3Y5ekFX8_7hALzqXP5u40qbtNE73o,1441
|
24
24
|
injection/ext/fastapi.pyi,sha256=HLs7mfruIEFRrN_Xf8oCvSa4qwHWfwm6HHU_KMedXkE,185
|
25
25
|
injection/testing/__init__.py,sha256=bJ7WXBXrw4rHc91AFVFnOwFLWOlpvX9Oh2SnRQ_NESo,919
|
26
26
|
injection/testing/__init__.pyi,sha256=raGsGlxwbz3jkzJwA_5oCIE1emWINjT2UuwzbnqRb-0,577
|
27
|
-
python_injection-0.19.
|
28
|
-
python_injection-0.19.
|
29
|
-
python_injection-0.19.
|
30
|
-
python_injection-0.19.
|
27
|
+
python_injection-0.19.4.dist-info/METADATA,sha256=xtDdgHy2s2fYA8jwKObxTd--xD2gC6yPVkDNKSwgr8c,4301
|
28
|
+
python_injection-0.19.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
29
|
+
python_injection-0.19.4.dist-info/licenses/LICENSE,sha256=oC77BOa9kaaQni5rW-Z-ytz3E5h4EVg248BHg9UFgyg,1063
|
30
|
+
python_injection-0.19.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|