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.
- {python_injection-0.13.0 → python_injection-0.13.1}/PKG-INFO +1 -1
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/__init__.pyi +7 -1
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/descriptors.py +8 -2
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/module.py +9 -9
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/scope.py +5 -11
- python_injection-0.13.1/injection/integrations/fastapi.py +27 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/pyproject.toml +10 -10
- python_injection-0.13.0/injection/integrations/fastapi.py +0 -38
- {python_injection-0.13.0 → python_injection-0.13.1}/.gitignore +0 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/README.md +0 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/__init__.py +0 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/__init__.py +0 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/common/__init__.py +0 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/common/asynchronous.py +0 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/common/event.py +0 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/common/invertible.py +0 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/common/key.py +0 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/common/lazy.py +0 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/common/type.py +0 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/hook.py +0 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/_core/injectables.py +0 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/exceptions.py +0 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/integrations/__init__.py +0 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/py.typed +0 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/testing/__init__.py +0 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/testing/__init__.pyi +0 -0
- {python_injection-0.13.0 → python_injection-0.13.1}/injection/utils.py +0 -0
@@ -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__(
|
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__(
|
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
|
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
|
-
|
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(
|
467
|
-
hint = get_yield_hint(
|
466
|
+
if isasyncgenfunction(wrapped):
|
467
|
+
hint = get_yield_hint(wrapped)
|
468
468
|
injectable_class = AsyncCMScopedInjectable
|
469
|
-
wrapper = asynccontextmanager(
|
469
|
+
wrapper = asynccontextmanager(wrapped)
|
470
470
|
|
471
|
-
elif isgeneratorfunction(
|
472
|
-
hint = get_yield_hint(
|
471
|
+
elif isgeneratorfunction(wrapped):
|
472
|
+
hint = get_yield_hint(wrapped)
|
473
473
|
injectable_class = CMScopedInjectable
|
474
|
-
wrapper = contextmanager(
|
474
|
+
wrapper = contextmanager(wrapped)
|
475
475
|
|
476
476
|
else:
|
477
477
|
injectable_class = SimpleScopedInjectable
|
478
|
-
hint = wrapper =
|
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
|
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(
|
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(
|
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]) ->
|
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.
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|