python-injection 0.19.3__py3-none-any.whl → 0.19.5__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 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
- ) -> Any:
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,74 +136,236 @@ 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(
149
+ self,
150
+ wrapped: None = ...,
151
+ /,
152
+ *,
153
+ threadsafe: bool | None = ...,
154
+ ) -> _Decorator[Callable[..., Any] | type]: ...
155
+ @overload
138
156
  def injectable[**P, T](
139
157
  self,
140
- wrapped: _Recipe[P, T] = ...,
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
- ) -> Any:
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[T](
196
+ self,
197
+ wrapped: None = ...,
198
+ /,
199
+ *,
200
+ cls: _InjectableFactory[T] = ...,
201
+ inject: bool = ...,
202
+ on: _TypeInfo[T],
203
+ mode: Mode | ModeStr = ...,
204
+ ) -> _Decorator[Callable[..., T] | Callable[..., Awaitable[T]] | type[T]]: ...
205
+ @overload
206
+ def injectable(
207
+ self,
208
+ wrapped: None = ...,
209
+ /,
210
+ *,
211
+ cls: _InjectableFactory[Any] = ...,
212
+ inject: bool = ...,
213
+ on: tuple[()] = ...,
214
+ mode: Mode | ModeStr = ...,
215
+ ) -> _Decorator[Callable[..., Any] | type]: ...
216
+ @overload
154
217
  def singleton[**P, T](
155
218
  self,
156
- wrapped: _Recipe[P, T] = ...,
219
+ wrapped: Callable[P, T],
157
220
  /,
158
221
  *,
159
222
  inject: bool = ...,
160
223
  on: _TypeInfo[T] = ...,
161
224
  mode: Mode | ModeStr = ...,
162
- ) -> Any:
225
+ ) -> Callable[P, T]:
163
226
  """
164
227
  Decorator applicable to a class or function. It is used to indicate how the
165
228
  singleton will be constructed. At injection time, the injected instance will
166
229
  always be the same.
167
230
  """
168
231
 
232
+ @overload
233
+ def singleton[**P, T]( # type: ignore[overload-overlap]
234
+ self,
235
+ wrapped: Callable[P, Awaitable[T]],
236
+ /,
237
+ *,
238
+ inject: bool = ...,
239
+ on: _TypeInfo[T] = ...,
240
+ mode: Mode | ModeStr = ...,
241
+ ) -> Callable[P, Awaitable[T]]: ...
242
+ @overload
243
+ def singleton[T](
244
+ self,
245
+ wrapped: type[T],
246
+ /,
247
+ *,
248
+ inject: bool = ...,
249
+ on: _TypeInfo[T] = ...,
250
+ mode: Mode | ModeStr = ...,
251
+ ) -> type[T]: ...
252
+ @overload
253
+ def singleton[T](
254
+ self,
255
+ wrapped: None = ...,
256
+ /,
257
+ *,
258
+ inject: bool = ...,
259
+ on: _TypeInfo[T],
260
+ mode: Mode | ModeStr = ...,
261
+ ) -> _Decorator[Callable[..., T] | Callable[..., Awaitable[T]] | type[T]]: ...
262
+ @overload
263
+ def singleton(
264
+ self,
265
+ wrapped: None = ...,
266
+ /,
267
+ *,
268
+ inject: bool = ...,
269
+ on: tuple[()] = ...,
270
+ mode: Mode | ModeStr = ...,
271
+ ) -> _Decorator[Callable[..., Any] | type]: ...
272
+ @overload
169
273
  def scoped[T](
170
274
  self,
171
275
  scope_name: str,
172
276
  /,
173
277
  *,
174
278
  inject: bool = ...,
175
- on: _TypeInfo[T] = (),
279
+ on: _TypeInfo[T],
176
280
  mode: Mode | ModeStr = ...,
177
- ) -> Any:
281
+ ) -> _Decorator[
282
+ Callable[..., T]
283
+ | Callable[..., Awaitable[T]]
284
+ | Callable[..., AsyncIterator[T]]
285
+ | Callable[..., Iterator[T]]
286
+ | type[T]
287
+ ]:
178
288
  """
179
289
  Decorator applicable to a class or function or generator function. It is used
180
290
  to indicate how the scoped instance will be constructed. At injection time, the
181
291
  injected instance is retrieved from the scope.
182
292
  """
183
293
 
184
- def should_be_injectable[T](self, wrapped: type[T] = ..., /) -> Any:
294
+ @overload
295
+ def scoped(
296
+ self,
297
+ scope_name: str,
298
+ /,
299
+ *,
300
+ inject: bool = ...,
301
+ on: tuple[()] = ...,
302
+ mode: Mode | ModeStr = ...,
303
+ ) -> _Decorator[Callable[..., Any] | type]: ...
304
+ @overload
305
+ def should_be_injectable[T](self, wrapped: type[T], /) -> type[T]:
185
306
  """
186
307
  Decorator applicable to a class. It is used to specify whether an injectable
187
308
  should be registered. Raise an exception at injection time if the class isn't
188
309
  registered.
189
310
  """
190
311
 
312
+ @overload
313
+ def should_be_injectable(
314
+ self,
315
+ wrapped: None = ...,
316
+ /,
317
+ ) -> _Decorator[type]: ...
318
+ @overload
191
319
  def constant[**P, T](
192
320
  self,
193
- wrapped: _Recipe[P, T] = ...,
321
+ wrapped: Callable[P, T],
194
322
  /,
195
323
  *,
196
324
  on: _TypeInfo[T] = ...,
197
325
  mode: Mode | ModeStr = ...,
198
- ) -> Any:
326
+ ) -> Callable[P, T]:
199
327
  """
200
328
  Decorator applicable to a class or function. It is used to indicate how the
201
329
  constant is constructed. At injection time, the injected instance will always
202
330
  be the same. Unlike `@singleton`, dependencies will not be resolved.
203
331
  """
204
332
 
333
+ @overload
334
+ def constant[**P, T]( # type: ignore[overload-overlap]
335
+ self,
336
+ wrapped: Callable[P, Awaitable[T]],
337
+ /,
338
+ *,
339
+ on: _TypeInfo[T] = ...,
340
+ mode: Mode | ModeStr = ...,
341
+ ) -> Callable[P, Awaitable[T]]: ...
342
+ @overload
343
+ def constant[T](
344
+ self,
345
+ wrapped: type[T],
346
+ /,
347
+ *,
348
+ on: _TypeInfo[T] = ...,
349
+ mode: Mode | ModeStr = ...,
350
+ ) -> type[T]: ...
351
+ @overload
352
+ def constant[T](
353
+ self,
354
+ wrapped: None = ...,
355
+ /,
356
+ *,
357
+ on: _TypeInfo[T],
358
+ mode: Mode | ModeStr = ...,
359
+ ) -> _Decorator[Callable[..., T] | Callable[..., Awaitable[T]] | type[T]]: ...
360
+ @overload
361
+ def constant(
362
+ self,
363
+ wrapped: None = ...,
364
+ /,
365
+ *,
366
+ on: tuple[()] = ...,
367
+ mode: Mode | ModeStr = ...,
368
+ ) -> _Decorator[Callable[..., Any] | type]: ...
205
369
  def set_constant[T](
206
370
  self,
207
371
  instance: T,
@@ -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, SimpleInvertible
4
+ from injection._core.common.invertible import Invertible
5
5
 
6
6
 
7
- def lazy[T](factory: Callable[..., T]) -> Invertible[T]:
7
+ def lazy[T](factory: Callable[..., T]) -> Callable[[], T]:
8
8
  def cache() -> Iterator[T]:
9
- nonlocal factory
10
9
  value = factory()
11
- del factory
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
- getter = partial(next, cache())
17
- return SimpleInvertible(getter)
22
+ return partial(_anext, cache())
18
23
 
19
24
 
20
25
  class Lazy[T](Invertible[T]):
21
- __slots__ = ("__invertible", "__is_set")
26
+ __slots__ = ("__get", "__is_set")
22
27
 
23
- __invertible: Invertible[T]
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 invertible() -> T:
33
+ def get() -> T:
29
34
  value = factory()
30
35
  self.__is_set = True
31
36
  return value
32
37
 
33
- self.__invertible = invertible
38
+ self.__get = get
34
39
  self.__is_set = False
35
40
 
36
41
  def __invert__(self) -> T:
37
- return ~self.__invertible
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)
@@ -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
- | Iterable[TypeInfo[T]]
30
+ | Sequence[TypeInfo[T]]
30
31
  )
31
32
 
32
33
 
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,
@@ -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
- lazy_instance = lazy(wp)
515
+ recipe: Recipe[[], T] = alazy(wp) if iscoroutinefunction(wp) else lazy(wp) # type: ignore[arg-type]
516
516
  self.injectable(
517
- lambda: ~lazy_instance,
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
- def autocall[**P, T](wrapped: Callable[P, T] | None = None, /) -> Any:
26
- def decorator(wp: Callable[P, T]) -> Callable[P, T]:
27
- wp() # type: ignore[call-arg]
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
  Metadata-Version: 2.4
2
2
  Name: python-injection
3
- Version: 0.19.3
3
+ Version: 0.19.5
4
4
  Summary: Fast and easy dependency injection framework.
5
5
  Project-URL: Repository, https://github.com/100nm/python-injection
6
6
  Author: remimd
@@ -1,6 +1,6 @@
1
1
  injection/__init__.py,sha256=iJm0BbyGZw-Qr5e8d2C3n8-7FiVD-sy4LU_i_n3AgHY,1318
2
- injection/__init__.pyi,sha256=2ndBULZyjN0SnyRml2gba9OOsTY0BhR3STEyvv1aZOA,11566
3
- injection/entrypoint.py,sha256=NIILL_w3z2JKyn7S9XXwE0JtH2icuDWnAVpUY1fAMf8,4805
2
+ injection/__init__.pyi,sha256=mWwRp9nS0zW4QOmQUUmyuH2-27acG4iG8vwq-ARzhMs,15671
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=yK3-WKi5vJoTSw6ESDQkJzp4uQeP8GdVRoO5BV6hXcM,32617
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=L7C2dB5UBI--W5Kkvntp_jypYhudY3SHqs8rM6jxxsk,965
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=hlhzpWHgvdMKMVaGBSwFhgEur0Sruzj67Md-yV-1cNw,2550
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.3.dist-info/METADATA,sha256=Ybbbf_GEZF9uEOexRMieKVXKh2by7czCpD7MTJQkECk,4301
28
- python_injection-0.19.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
29
- python_injection-0.19.3.dist-info/licenses/LICENSE,sha256=oC77BOa9kaaQni5rW-Z-ytz3E5h4EVg248BHg9UFgyg,1063
30
- python_injection-0.19.3.dist-info/RECORD,,
27
+ python_injection-0.19.5.dist-info/METADATA,sha256=S648vq2CXn8QOZ4g4sZxODXh9OTAvR8JI6T3PlKPj4U,4301
28
+ python_injection-0.19.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
29
+ python_injection-0.19.5.dist-info/licenses/LICENSE,sha256=oC77BOa9kaaQni5rW-Z-ytz3E5h4EVg248BHg9UFgyg,1063
30
+ python_injection-0.19.5.dist-info/RECORD,,