python-injection 0.14.0.post0__tar.gz → 0.14.1__tar.gz

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.
Files changed (26) hide show
  1. {python_injection-0.14.0.post0 → python_injection-0.14.1}/PKG-INFO +1 -1
  2. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/__init__.pyi +9 -2
  3. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/_core/hook.py +3 -5
  4. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/_core/module.py +27 -20
  5. {python_injection-0.14.0.post0 → python_injection-0.14.1}/pyproject.toml +1 -1
  6. {python_injection-0.14.0.post0 → python_injection-0.14.1}/.gitignore +0 -0
  7. {python_injection-0.14.0.post0 → python_injection-0.14.1}/README.md +0 -0
  8. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/__init__.py +0 -0
  9. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/_core/__init__.py +0 -0
  10. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/_core/common/__init__.py +0 -0
  11. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/_core/common/asynchronous.py +0 -0
  12. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/_core/common/event.py +0 -0
  13. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/_core/common/invertible.py +0 -0
  14. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/_core/common/key.py +0 -0
  15. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/_core/common/lazy.py +0 -0
  16. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/_core/common/type.py +0 -0
  17. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/_core/descriptors.py +0 -0
  18. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/_core/injectables.py +0 -0
  19. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/_core/scope.py +0 -0
  20. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/exceptions.py +0 -0
  21. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/integrations/__init__.py +0 -0
  22. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/integrations/fastapi.py +0 -0
  23. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/py.typed +0 -0
  24. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/testing/__init__.py +0 -0
  25. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/testing/__init__.pyi +0 -0
  26. {python_injection-0.14.0.post0 → python_injection-0.14.1}/injection/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-injection
3
- Version: 0.14.0.post0
3
+ Version: 0.14.1
4
4
  Summary: Fast and easy dependency injection framework.
5
5
  Project-URL: Repository, https://github.com/100nm/python-injection
6
6
  Author: remimd
@@ -10,6 +10,7 @@ from ._core.common.type import InputType as _InputType
10
10
  from ._core.common.type import TypeInfo as _TypeInfo
11
11
  from ._core.module import InjectableFactory as _InjectableFactory
12
12
  from ._core.module import ModeStr, PriorityStr
13
+ from ._core.module import Recipe as _Recipe
13
14
 
14
15
  __MODULE: Final[Module] = ...
15
16
 
@@ -91,7 +92,7 @@ class Module:
91
92
 
92
93
  def injectable[**P, T](
93
94
  self,
94
- wrapped: Callable[P, T] | Callable[P, Awaitable[T]] = ...,
95
+ wrapped: _Recipe[P, T] = ...,
95
96
  /,
96
97
  *,
97
98
  cls: _InjectableFactory[T] = ...,
@@ -107,7 +108,7 @@ class Module:
107
108
 
108
109
  def singleton[**P, T](
109
110
  self,
110
- wrapped: Callable[P, T] | Callable[P, Awaitable[T]] = ...,
111
+ wrapped: _Recipe[P, T] = ...,
111
112
  /,
112
113
  *,
113
114
  inject: bool = ...,
@@ -176,6 +177,12 @@ class Module:
176
177
  /,
177
178
  threadsafe: bool = ...,
178
179
  ) -> Callable[P, T]: ...
180
+ def make_async_factory[T](
181
+ self,
182
+ wrapped: type[T],
183
+ /,
184
+ threadsafe: bool = ...,
185
+ ) -> Callable[..., Awaitable[T]]: ...
179
186
  async def afind_instance[T](self, cls: _InputType[T]) -> T: ...
180
187
  def find_instance[T](self, cls: _InputType[T]) -> T:
181
188
  """
@@ -1,5 +1,4 @@
1
1
  import itertools
2
- from collections import deque
3
2
  from collections.abc import Callable, Generator, Iterator
4
3
  from dataclasses import dataclass, field
5
4
  from inspect import isclass, isgeneratorfunction
@@ -14,8 +13,8 @@ type HookFunction[**P, T] = Callable[P, T] | HookGeneratorFunction[P, T]
14
13
 
15
14
  @dataclass(eq=False, frozen=True, slots=True)
16
15
  class Hook[**P, T]:
17
- __functions: deque[HookFunction[P, T]] = field(
18
- default_factory=deque,
16
+ __functions: list[HookFunction[P, T]] = field(
17
+ default_factory=list,
19
18
  init=False,
20
19
  repr=False,
21
20
  )
@@ -36,7 +35,7 @@ class Hook[**P, T]:
36
35
  return iter(self.__functions)
37
36
 
38
37
  def add(self, *functions: HookFunction[P, T]) -> Self:
39
- self.__functions.extendleft(functions)
38
+ self.__functions.extend(reversed(functions))
40
39
  return self
41
40
 
42
41
  @classmethod
@@ -65,7 +64,6 @@ class Hook[**P, T]:
65
64
  hook.throw(exc)
66
65
  else:
67
66
  hook.send(value)
68
- return value
69
67
 
70
68
  except StopIteration as stop:
71
69
  return stop.value
@@ -3,10 +3,12 @@ from __future__ import annotations
3
3
  from abc import ABC, abstractmethod
4
4
  from collections import OrderedDict, deque
5
5
  from collections.abc import (
6
+ AsyncGenerator,
6
7
  AsyncIterator,
7
8
  Awaitable,
8
9
  Callable,
9
10
  Collection,
11
+ Generator,
10
12
  Iterable,
11
13
  Iterator,
12
14
  Mapping,
@@ -360,6 +362,14 @@ class Priority(StrEnum):
360
362
 
361
363
  type PriorityStr = Literal["low", "high"]
362
364
 
365
+ type ContextManagerLikeRecipe[**P, T] = (
366
+ Callable[P, ContextManager[T]] | Callable[P, AsyncContextManager[T]]
367
+ )
368
+ type GeneratorRecipe[**P, T] = (
369
+ Callable[P, Generator[T, Any, Any]] | Callable[P, AsyncGenerator[T, Any]]
370
+ )
371
+ type Recipe[**P, T] = Callable[P, T] | Callable[P, Awaitable[T]]
372
+
363
373
 
364
374
  @dataclass(eq=False, frozen=True, slots=True)
365
375
  class Module(Broker, EventListener):
@@ -411,7 +421,7 @@ class Module(Broker, EventListener):
411
421
 
412
422
  def injectable[**P, T](
413
423
  self,
414
- wrapped: Callable[P, T] | Callable[P, Awaitable[T]] | None = None,
424
+ wrapped: Recipe[P, T] | None = None,
415
425
  /,
416
426
  *,
417
427
  cls: InjectableFactory[T] = SimpleInjectable,
@@ -420,9 +430,7 @@ class Module(Broker, EventListener):
420
430
  on: TypeInfo[T] = (),
421
431
  mode: Mode | ModeStr = Mode.get_default(),
422
432
  ) -> Any:
423
- def decorator(
424
- wp: Callable[P, T] | Callable[P, Awaitable[T]],
425
- ) -> Callable[P, T] | Callable[P, Awaitable[T]]:
433
+ def decorator(wp: Recipe[P, T]) -> Recipe[P, T]:
426
434
  factory = extract_caller(self.make_injected_function(wp) if inject else wp)
427
435
  hints = on if ignore_type_hint else (wp, on)
428
436
  updater = Updater(
@@ -447,23 +455,10 @@ class Module(Broker, EventListener):
447
455
  mode: Mode | ModeStr = Mode.get_default(),
448
456
  ) -> Any:
449
457
  def decorator(
450
- wrapped: Callable[P, T]
451
- | Callable[P, Awaitable[T]]
452
- | Callable[P, Iterator[T]]
453
- | Callable[P, AsyncIterator[T]],
454
- ) -> (
455
- Callable[P, T]
456
- | Callable[P, Awaitable[T]]
457
- | Callable[P, Iterator[T]]
458
- | Callable[P, AsyncIterator[T]]
459
- ):
458
+ wrapped: Recipe[P, T] | GeneratorRecipe[P, T],
459
+ ) -> Recipe[P, T] | GeneratorRecipe[P, T]:
460
460
  injectable_class: Callable[[Caller[P, Any], str], Injectable[T]]
461
- wrapper: (
462
- Callable[P, T]
463
- | Callable[P, Awaitable[T]]
464
- | Callable[P, ContextManager[T]]
465
- | Callable[P, AsyncContextManager[T]]
466
- )
461
+ wrapper: Recipe[P, T] | ContextManagerLikeRecipe[P, T]
467
462
 
468
463
  if isasyncgenfunction(wrapped):
469
464
  hint = get_yield_hint(wrapped)
@@ -588,6 +583,18 @@ class Module(Broker, EventListener):
588
583
 
589
584
  return SyncInjectedFunction(metadata)
590
585
 
586
+ def make_async_factory[T](
587
+ self,
588
+ wrapped: type[T],
589
+ /,
590
+ threadsafe: bool = False,
591
+ ) -> Callable[..., Awaitable[T]]:
592
+ factory: InjectedFunction[..., T] = self.make_injected_function(
593
+ wrapped,
594
+ threadsafe,
595
+ )
596
+ return factory.__inject_metadata__.acall
597
+
591
598
  async def afind_instance[T](self, cls: InputType[T]) -> T:
592
599
  injectable = self[cls]
593
600
  return await injectable.aget_instance()
@@ -24,7 +24,7 @@ test = [
24
24
 
25
25
  [project]
26
26
  name = "python-injection"
27
- version = "0.14.0.post0"
27
+ version = "0.14.1"
28
28
  description = "Fast and easy dependency injection framework."
29
29
  license = { text = "MIT" }
30
30
  readme = "README.md"