python-injection 0.13.0__tar.gz → 0.13.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 (27) hide show
  1. {python_injection-0.13.0 → python_injection-0.13.1}/PKG-INFO +1 -1
  2. {python_injection-0.13.0 → python_injection-0.13.1}/injection/__init__.pyi +7 -1
  3. {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/descriptors.py +8 -2
  4. {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/module.py +9 -9
  5. {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/scope.py +5 -11
  6. python_injection-0.13.1/injection/integrations/fastapi.py +27 -0
  7. {python_injection-0.13.0 → python_injection-0.13.1}/pyproject.toml +10 -10
  8. python_injection-0.13.0/injection/integrations/fastapi.py +0 -38
  9. {python_injection-0.13.0 → python_injection-0.13.1}/.gitignore +0 -0
  10. {python_injection-0.13.0 → python_injection-0.13.1}/README.md +0 -0
  11. {python_injection-0.13.0 → python_injection-0.13.1}/injection/__init__.py +0 -0
  12. {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/__init__.py +0 -0
  13. {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/common/__init__.py +0 -0
  14. {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/common/asynchronous.py +0 -0
  15. {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/common/event.py +0 -0
  16. {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/common/invertible.py +0 -0
  17. {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/common/key.py +0 -0
  18. {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/common/lazy.py +0 -0
  19. {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/common/type.py +0 -0
  20. {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/hook.py +0 -0
  21. {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/injectables.py +0 -0
  22. {python_injection-0.13.0 → python_injection-0.13.1}/injection/exceptions.py +0 -0
  23. {python_injection-0.13.0 → python_injection-0.13.1}/injection/integrations/__init__.py +0 -0
  24. {python_injection-0.13.0 → python_injection-0.13.1}/injection/py.typed +0 -0
  25. {python_injection-0.13.0 → python_injection-0.13.1}/injection/testing/__init__.py +0 -0
  26. {python_injection-0.13.0 → python_injection-0.13.1}/injection/testing/__init__.pyi +0 -0
  27. {python_injection-0.13.0 → python_injection-0.13.1}/injection/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-injection
3
- Version: 0.13.0
3
+ Version: 0.13.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
@@ -46,7 +46,13 @@ class Injectable[T](Protocol):
46
46
  def get_instance(self) -> T: ...
47
47
 
48
48
  class LazyInstance[T]:
49
- def __init__(self, cls: _InputType[T], module: Module = ...) -> None: ...
49
+ def __init__(
50
+ self,
51
+ cls: _InputType[T],
52
+ /,
53
+ default: T = ...,
54
+ module: Module = ...,
55
+ ) -> None: ...
50
56
  @overload
51
57
  def __get__(self, instance: object, owner: type | None = ...) -> T: ...
52
58
  @overload
@@ -10,9 +10,15 @@ class LazyInstance[T]:
10
10
 
11
11
  __value: Invertible[T]
12
12
 
13
- def __init__(self, cls: InputType[T], module: Module | None = None) -> None:
13
+ def __init__(
14
+ self,
15
+ cls: InputType[T],
16
+ /,
17
+ default: T = NotImplemented,
18
+ module: Module | None = None,
19
+ ) -> None:
14
20
  module = module or mod()
15
- self.__value = module.get_lazy_instance(cls, default=NotImplemented)
21
+ self.__value = module.get_lazy_instance(cls, default)
16
22
 
17
23
  def __get__(
18
24
  self,
@@ -445,7 +445,7 @@ class Module(Broker, EventListener):
445
445
  mode: Mode | ModeStr = Mode.get_default(),
446
446
  ) -> Any:
447
447
  def decorator(
448
- wp: Callable[P, T]
448
+ wrapped: Callable[P, T]
449
449
  | Callable[P, Awaitable[T]]
450
450
  | Callable[P, Iterator[T]]
451
451
  | Callable[P, AsyncIterator[T]],
@@ -463,19 +463,19 @@ class Module(Broker, EventListener):
463
463
  | Callable[P, AsyncContextManager[T]]
464
464
  )
465
465
 
466
- if isasyncgenfunction(wp):
467
- hint = get_yield_hint(wp)
466
+ if isasyncgenfunction(wrapped):
467
+ hint = get_yield_hint(wrapped)
468
468
  injectable_class = AsyncCMScopedInjectable
469
- wrapper = asynccontextmanager(wp)
469
+ wrapper = asynccontextmanager(wrapped)
470
470
 
471
- elif isgeneratorfunction(wp):
472
- hint = get_yield_hint(wp)
471
+ elif isgeneratorfunction(wrapped):
472
+ hint = get_yield_hint(wrapped)
473
473
  injectable_class = CMScopedInjectable
474
- wrapper = contextmanager(wp)
474
+ wrapper = contextmanager(wrapped)
475
475
 
476
476
  else:
477
477
  injectable_class = SimpleScopedInjectable
478
- hint = wrapper = wp # type: ignore[assignment]
478
+ hint = wrapper = wrapped # type: ignore[assignment]
479
479
 
480
480
  hints = on if hint is None else (hint, on)
481
481
  self.injectable(
@@ -486,7 +486,7 @@ class Module(Broker, EventListener):
486
486
  on=hints,
487
487
  mode=mode,
488
488
  )
489
- return wp
489
+ return wrapped
490
490
 
491
491
  return decorator
492
492
 
@@ -3,14 +3,7 @@ from __future__ import annotations
3
3
  from abc import ABC, abstractmethod
4
4
  from collections import defaultdict
5
5
  from collections.abc import AsyncIterator, Iterator, MutableMapping
6
- from contextlib import (
7
- AsyncContextDecorator,
8
- AsyncExitStack,
9
- ContextDecorator,
10
- ExitStack,
11
- asynccontextmanager,
12
- contextmanager,
13
- )
6
+ from contextlib import AsyncExitStack, ExitStack, asynccontextmanager, contextmanager
14
7
  from contextvars import ContextVar
15
8
  from dataclasses import dataclass, field
16
9
  from types import TracebackType
@@ -19,6 +12,7 @@ from typing import (
19
12
  AsyncContextManager,
20
13
  ContextManager,
21
14
  Final,
15
+ NoReturn,
22
16
  Protocol,
23
17
  Self,
24
18
  runtime_checkable,
@@ -163,7 +157,7 @@ class BaseScope[T](Scope, ABC):
163
157
  )
164
158
 
165
159
 
166
- class AsyncScope(AsyncContextDecorator, BaseScope[AsyncExitStack]):
160
+ class AsyncScope(BaseScope[AsyncExitStack]):
167
161
  __slots__ = ()
168
162
 
169
163
  def __init__(self) -> None:
@@ -188,7 +182,7 @@ class AsyncScope(AsyncContextDecorator, BaseScope[AsyncExitStack]):
188
182
  return self.delegate.enter_context(context_manager)
189
183
 
190
184
 
191
- class SyncScope(ContextDecorator, BaseScope[ExitStack]):
185
+ class SyncScope(BaseScope[ExitStack]):
192
186
  __slots__ = ()
193
187
 
194
188
  def __init__(self) -> None:
@@ -206,7 +200,7 @@ class SyncScope(ContextDecorator, BaseScope[ExitStack]):
206
200
  ) -> Any:
207
201
  return self.delegate.__exit__(exc_type, exc_value, traceback)
208
202
 
209
- async def aenter[T](self, context_manager: AsyncContextManager[T]) -> T:
203
+ async def aenter[T](self, context_manager: AsyncContextManager[T]) -> NoReturn:
210
204
  raise ScopeError(
211
205
  "Synchronous scope doesn't support asynchronous context manager."
212
206
  )
@@ -0,0 +1,27 @@
1
+ from types import GenericAlias
2
+ from typing import Any, TypeAliasType
3
+
4
+ from fastapi import Depends
5
+
6
+ from injection import Module, mod
7
+
8
+ __all__ = ("Inject",)
9
+
10
+
11
+ def Inject[T]( # noqa: N802
12
+ cls: type[T] | TypeAliasType | GenericAlias,
13
+ /,
14
+ default: T = NotImplemented,
15
+ module: Module | None = None,
16
+ ) -> Any:
17
+ """
18
+ Declare a FastAPI dependency with `python-injection`.
19
+ """
20
+
21
+ module = module or mod()
22
+ lazy_instance = module.aget_lazy_instance(cls, default)
23
+
24
+ async def getter() -> T:
25
+ return await lazy_instance
26
+
27
+ return Depends(getter, use_cache=False)
@@ -24,7 +24,7 @@ test = [
24
24
 
25
25
  [project]
26
26
  name = "python-injection"
27
- version = "0.13.0"
27
+ version = "0.13.1"
28
28
  description = "Fast and easy dependency injection framework."
29
29
  license = { text = "MIT" }
30
30
  readme = "README.md"
@@ -61,6 +61,15 @@ exclude_lines = [
61
61
  [tool.coverage.run]
62
62
  omit = ["bench.py"]
63
63
 
64
+ [tool.hatch.build]
65
+ skip-excluded-dirs = true
66
+
67
+ [tool.hatch.build.targets.sdist]
68
+ include = ["injection"]
69
+
70
+ [tool.hatch.build.targets.wheel]
71
+ packages = ["injection"]
72
+
64
73
  [tool.mypy]
65
74
  check_untyped_defs = true
66
75
  disallow_any_generics = true
@@ -77,15 +86,6 @@ plugins = ["pydantic.mypy"]
77
86
  warn_redundant_casts = true
78
87
  warn_unused_ignores = true
79
88
 
80
- [tool.hatch.build]
81
- skip-excluded-dirs = true
82
-
83
- [tool.hatch.build.targets.sdist]
84
- include = ["injection"]
85
-
86
- [tool.hatch.build.targets.wheel]
87
- packages = ["injection"]
88
-
89
89
  [tool.pydantic-mypy]
90
90
  init_forbid_extra = true
91
91
  init_typed = true
@@ -1,38 +0,0 @@
1
- from collections.abc import Awaitable
2
- from types import GenericAlias
3
- from typing import Any, TypeAliasType
4
-
5
- from fastapi import Depends
6
-
7
- from injection import Module, mod
8
-
9
- __all__ = ("Inject",)
10
-
11
-
12
- def Inject[T]( # noqa: N802
13
- cls: type[T] | TypeAliasType | GenericAlias,
14
- /,
15
- module: Module | None = None,
16
- ) -> Any:
17
- """
18
- Declare a FastAPI dependency with `python-injection`.
19
- """
20
-
21
- dependency: InjectionDependency[T] = InjectionDependency(cls, module or mod())
22
- return Depends(dependency, use_cache=False)
23
-
24
-
25
- class InjectionDependency[T]:
26
- __slots__ = ("__awaitable",)
27
-
28
- __awaitable: Awaitable[T]
29
-
30
- def __init__(
31
- self,
32
- cls: type[T] | TypeAliasType | GenericAlias,
33
- module: Module,
34
- ) -> None:
35
- self.__awaitable = module.aget_lazy_instance(cls, default=NotImplemented)
36
-
37
- async def __call__(self) -> T:
38
- return await self.__awaitable