python-injection 0.13.0__tar.gz → 0.13.1__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
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