modern-di 0.16.2__py3-none-any.whl → 0.17.0__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.
Potentially problematic release.
This version of modern-di might be problematic. Click here for more details.
- modern_di/__init__.py +6 -4
- modern_di/containers/__init__.py +0 -0
- modern_di/containers/abstract.py +110 -0
- modern_di/containers/async_container.py +104 -0
- modern_di/containers/sync_container.py +105 -0
- modern_di/group.py +26 -0
- modern_di/helpers/type_helpers.py +33 -0
- modern_di/providers/__init__.py +2 -4
- modern_di/providers/abstract.py +62 -74
- modern_di/providers/async_factory.py +9 -11
- modern_di/providers/async_singleton.py +14 -26
- modern_di/providers/container_provider.py +4 -8
- modern_di/providers/context_provider.py +16 -0
- modern_di/providers/dict.py +20 -13
- modern_di/providers/factory.py +17 -23
- modern_di/providers/list.py +20 -13
- modern_di/providers/object.py +6 -11
- modern_di/providers/resource.py +38 -66
- modern_di/providers/singleton.py +23 -43
- modern_di/registries/__init__.py +0 -0
- modern_di/registries/context_registry.py +16 -0
- modern_di/registries/overrides_registry.py +22 -0
- modern_di/registries/providers_registry.py +38 -0
- modern_di/registries/state_registry/__init__.py +0 -0
- modern_di/{provider_state.py → registries/state_registry/state.py} +15 -11
- modern_di/registries/state_registry/state_registry.py +52 -0
- {modern_di-0.16.2.dist-info → modern_di-0.17.0.dist-info}/METADATA +1 -1
- modern_di-0.17.0.dist-info/RECORD +33 -0
- modern_di/container.py +0 -171
- modern_di/graph.py +0 -39
- modern_di/providers/context_adapter.py +0 -27
- modern_di/providers/injected_factory.py +0 -45
- modern_di/providers/selector.py +0 -39
- modern_di-0.16.2.dist-info/RECORD +0 -25
- {modern_di-0.16.2.dist-info → modern_di-0.17.0.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
import typing
|
|
3
|
+
|
|
4
|
+
from modern_di.providers import AbstractProvider
|
|
5
|
+
from modern_di.registries.state_registry.state import AsyncState, SyncState
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
T_co = typing.TypeVar("T_co", covariant=True)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclasses.dataclass(kw_only=True, slots=True, frozen=True)
|
|
12
|
+
class AsyncStateRegistry:
|
|
13
|
+
use_lock: bool
|
|
14
|
+
states: dict[str, AsyncState[typing.Any]] = dataclasses.field(init=False, default_factory=dict)
|
|
15
|
+
|
|
16
|
+
def fetch_provider_state(self, provider: AbstractProvider[T_co]) -> AsyncState[T_co] | None:
|
|
17
|
+
if not provider.HAS_STATE:
|
|
18
|
+
return None
|
|
19
|
+
|
|
20
|
+
if provider_state := self.states.get(provider.provider_id):
|
|
21
|
+
return provider_state
|
|
22
|
+
|
|
23
|
+
# expected to be thread-safe, because setdefault is atomic
|
|
24
|
+
return self.states.setdefault(provider.provider_id, AsyncState(use_lock=self.use_lock))
|
|
25
|
+
|
|
26
|
+
async def clear_state(self) -> None:
|
|
27
|
+
for provider_state in reversed(self.states.values()):
|
|
28
|
+
await provider_state.tear_down()
|
|
29
|
+
|
|
30
|
+
self.states.clear()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclasses.dataclass(kw_only=True, slots=True, frozen=True)
|
|
34
|
+
class SyncStateRegistry:
|
|
35
|
+
use_lock: bool
|
|
36
|
+
states: dict[str, SyncState[typing.Any]] = dataclasses.field(init=False, default_factory=dict)
|
|
37
|
+
|
|
38
|
+
def fetch_provider_state(self, provider: AbstractProvider[T_co]) -> SyncState[T_co] | None:
|
|
39
|
+
if not provider.HAS_STATE:
|
|
40
|
+
return None
|
|
41
|
+
|
|
42
|
+
if provider_state := self.states.get(provider.provider_id):
|
|
43
|
+
return provider_state
|
|
44
|
+
|
|
45
|
+
# expected to be thread-safe, because setdefault is atomic
|
|
46
|
+
return self.states.setdefault(provider.provider_id, SyncState(use_lock=self.use_lock))
|
|
47
|
+
|
|
48
|
+
def clear_state(self) -> None:
|
|
49
|
+
for provider_state in reversed(self.states.values()):
|
|
50
|
+
provider_state.tear_down()
|
|
51
|
+
|
|
52
|
+
self.states.clear()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: modern-di
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.17.0
|
|
4
4
|
Summary: Dependency Injection framework with IOC-container and scopes
|
|
5
5
|
Project-URL: repository, https://github.com/modern-python/modern-di
|
|
6
6
|
Project-URL: docs, https://modern-di.readthedocs.io
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
modern_di/__init__.py,sha256=3VNwCoKLtuRvHlw1LlEE_GqML6mSPxt2xiIb0lLPglE,296
|
|
2
|
+
modern_di/group.py,sha256=VUs8qHz_mzrFHr88Ztt4bEGJ1lNNcZuLdJD5SPksefc,707
|
|
3
|
+
modern_di/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
modern_di/scope.py,sha256=e6Olc-CF89clbYDNGciy-F8EqJt1Mw2703zfuJaEY94,113
|
|
5
|
+
modern_di/containers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
modern_di/containers/abstract.py,sha256=UopSKQYz7wdNKSmKdFSNY0DjptRjbzdGmEvfrvkeKTY,3994
|
|
7
|
+
modern_di/containers/async_container.py,sha256=dZHCkPlLU61BPiwRl4TThCLO1Io8XPrkVRCLKPikGwk,3903
|
|
8
|
+
modern_di/containers/sync_container.py,sha256=RvLzLwuAZdrPKTw6aYGesX9NZMLuuxyMlWTY96k7YOk,3908
|
|
9
|
+
modern_di/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
+
modern_di/helpers/attr_getter_helpers.py,sha256=HUjExWLRAz2h0YX2_h5xKPX9-_K3i-BZTeZb3u-Wq5k,221
|
|
11
|
+
modern_di/helpers/type_helpers.py,sha256=sIQmM6aLj8UJ-JL3cpFattdV8rVegDHPFODFAm-fjP0,795
|
|
12
|
+
modern_di/providers/__init__.py,sha256=NidhR4kH4HkgL4tLurG4S2W4mWuG5ENvPEZckWsMW2U,810
|
|
13
|
+
modern_di/providers/abstract.py,sha256=yY2elYgnFDZtKiPLnI1q1I7py2LxVdzOaTNjQpLxT-0,4618
|
|
14
|
+
modern_di/providers/async_factory.py,sha256=Bx_xHET6c_IKttEnwFc4VDpLft25gvVpZ_uDVx3kkYQ,815
|
|
15
|
+
modern_di/providers/async_singleton.py,sha256=jL0aB_uEUIlSsYamvUPHCTkeNxvS4ELjguOvnJ7kirs,1040
|
|
16
|
+
modern_di/providers/container_provider.py,sha256=QMOT767Yl00sPJKBW_926m7ZfyIUOG_zzOoPxg9Na2Q,337
|
|
17
|
+
modern_di/providers/context_provider.py,sha256=lZu_INZnbiWQsR-qMrKEOtZpYaSiE4-rf2ZIP5p3-x8,427
|
|
18
|
+
modern_di/providers/dict.py,sha256=ni2avO16XfX98mE6tgIX8v0Pn4iAPQYL_1YBDB4WlHo,708
|
|
19
|
+
modern_di/providers/factory.py,sha256=ocbdlsPoxtoc_t2D0wWsssP08_8gAUAJmr5IOb4Q3sQ,943
|
|
20
|
+
modern_di/providers/list.py,sha256=KZPBctoE5LqgHemBR3Viq5pA7w6CJMOsHbvlBlbF4Kg,674
|
|
21
|
+
modern_di/providers/object.py,sha256=5hoyLC5whtG2TNlOQe3LKTKTRvQEmhOWpzugN1hczhI,572
|
|
22
|
+
modern_di/providers/resource.py,sha256=avtPsVbmcJ00XQ9JUZSkqmcDQx4Gpg2SX5NyCOnUeZU,3174
|
|
23
|
+
modern_di/providers/singleton.py,sha256=IPI_6HB9z8d_7ftyy3vYJL6hyNyyRTuFDSUm-FkTW5U,1277
|
|
24
|
+
modern_di/registries/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
|
+
modern_di/registries/context_registry.py,sha256=fdHvQIHYyaRqAK8MFG80HXKixo-CRvFN20LeRBHSCs4,412
|
|
26
|
+
modern_di/registries/overrides_registry.py,sha256=Qh5D0z7_sh6Y1S94w7w61vjvVbdu4z9gnRvNGDDdWxk,706
|
|
27
|
+
modern_di/registries/providers_registry.py,sha256=wyuwoSNcLP3vjPw3vttkGuoZu7KmCd8WV6UF5QYLFyk,1564
|
|
28
|
+
modern_di/registries/state_registry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
+
modern_di/registries/state_registry/state.py,sha256=_y7mMDKdNOourTHVp2EYID8ZBVL-NXF0up8vJ80F1tk,1339
|
|
30
|
+
modern_di/registries/state_registry/state_registry.py,sha256=6m0NJRMdYufFXqVoIH5Um7xxGhpZXkDkMgWmCJj2I0E,1813
|
|
31
|
+
modern_di-0.17.0.dist-info/METADATA,sha256=GIGoTHxeslmaGUAzzpdIrB4f9G7RvNQkukB9mGdRKTA,3382
|
|
32
|
+
modern_di-0.17.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
33
|
+
modern_di-0.17.0.dist-info/RECORD,,
|
modern_di/container.py
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import contextlib
|
|
2
|
-
import enum
|
|
3
|
-
import types
|
|
4
|
-
import typing
|
|
5
|
-
|
|
6
|
-
from modern_di.provider_state import ProviderState
|
|
7
|
-
from modern_di.scope import Scope
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if typing.TYPE_CHECKING:
|
|
11
|
-
import typing_extensions
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
T_co = typing.TypeVar("T_co", covariant=True)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class Container(contextlib.AbstractAsyncContextManager["Container"], contextlib.AbstractContextManager["Container"]):
|
|
18
|
-
__slots__ = (
|
|
19
|
-
"_is_async",
|
|
20
|
-
"_overrides",
|
|
21
|
-
"_provider_states",
|
|
22
|
-
"_use_threading_lock",
|
|
23
|
-
"context",
|
|
24
|
-
"parent_container",
|
|
25
|
-
"scope",
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
def __init__(
|
|
29
|
-
self,
|
|
30
|
-
*,
|
|
31
|
-
scope: enum.IntEnum = Scope.APP,
|
|
32
|
-
parent_container: typing.Optional["Container"] = None,
|
|
33
|
-
context: dict[str, typing.Any] | None = None,
|
|
34
|
-
use_threading_lock: bool = True,
|
|
35
|
-
) -> None:
|
|
36
|
-
self.scope = scope
|
|
37
|
-
self.parent_container = parent_container
|
|
38
|
-
self.context: dict[str, typing.Any] = context or {}
|
|
39
|
-
self._is_async: bool | None = None
|
|
40
|
-
self._provider_states: dict[str, ProviderState[typing.Any]] = {}
|
|
41
|
-
self._overrides: dict[str, typing.Any] = parent_container._overrides if parent_container else {} # noqa: SLF001
|
|
42
|
-
self._use_threading_lock = use_threading_lock
|
|
43
|
-
|
|
44
|
-
def _exit(self) -> None:
|
|
45
|
-
self._is_async = None
|
|
46
|
-
self._provider_states = {}
|
|
47
|
-
self._overrides = {}
|
|
48
|
-
self.context = {}
|
|
49
|
-
|
|
50
|
-
def _check_entered(self) -> None:
|
|
51
|
-
if self._is_async is None:
|
|
52
|
-
msg = "Enter the context first"
|
|
53
|
-
raise RuntimeError(msg)
|
|
54
|
-
|
|
55
|
-
def build_child_container(
|
|
56
|
-
self, context: dict[str, typing.Any] | None = None, scope: enum.IntEnum | None = None
|
|
57
|
-
) -> "typing_extensions.Self":
|
|
58
|
-
self._check_entered()
|
|
59
|
-
if scope and scope <= self.scope:
|
|
60
|
-
msg = "Scope of child container must be more than current scope"
|
|
61
|
-
raise RuntimeError(msg)
|
|
62
|
-
|
|
63
|
-
if not scope:
|
|
64
|
-
try:
|
|
65
|
-
scope = self.scope.__class__(self.scope.value + 1)
|
|
66
|
-
except ValueError as exc:
|
|
67
|
-
msg = f"Max scope is reached, {self.scope.name}"
|
|
68
|
-
raise RuntimeError(msg) from exc
|
|
69
|
-
|
|
70
|
-
return self.__class__(scope=scope, parent_container=self, context=context)
|
|
71
|
-
|
|
72
|
-
def find_container(self, scope: enum.IntEnum) -> "typing_extensions.Self":
|
|
73
|
-
container = self
|
|
74
|
-
if container.scope < scope:
|
|
75
|
-
msg = f"Scope {scope.name} is not initialized"
|
|
76
|
-
raise RuntimeError(msg)
|
|
77
|
-
|
|
78
|
-
while container.scope > scope and container.parent_container:
|
|
79
|
-
container = typing.cast("typing_extensions.Self", container.parent_container)
|
|
80
|
-
|
|
81
|
-
if container.scope != scope:
|
|
82
|
-
msg = f"Scope {scope.name} is skipped"
|
|
83
|
-
raise RuntimeError(msg)
|
|
84
|
-
|
|
85
|
-
return container
|
|
86
|
-
|
|
87
|
-
def fetch_provider_state(
|
|
88
|
-
self,
|
|
89
|
-
provider_id: str,
|
|
90
|
-
is_async_resource: bool = False,
|
|
91
|
-
use_asyncio_lock: bool = False,
|
|
92
|
-
use_threading_lock: bool = False,
|
|
93
|
-
) -> ProviderState[typing.Any]:
|
|
94
|
-
self._check_entered()
|
|
95
|
-
if is_async_resource and self._is_async is False:
|
|
96
|
-
msg = "Resolving async resource in sync container is not allowed"
|
|
97
|
-
raise RuntimeError(msg)
|
|
98
|
-
|
|
99
|
-
if provider_state := self._provider_states.get(provider_id):
|
|
100
|
-
return provider_state
|
|
101
|
-
|
|
102
|
-
# expected to be thread-safe, because setdefault is atomic
|
|
103
|
-
return self._provider_states.setdefault(
|
|
104
|
-
provider_id,
|
|
105
|
-
ProviderState(
|
|
106
|
-
use_asyncio_lock=use_asyncio_lock,
|
|
107
|
-
use_threading_lock=self._use_threading_lock and use_threading_lock,
|
|
108
|
-
),
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
def override(self, provider_id: str, override_object: object) -> None:
|
|
112
|
-
self._overrides[provider_id] = override_object
|
|
113
|
-
|
|
114
|
-
def fetch_override(self, provider_id: str) -> object | None:
|
|
115
|
-
return self._overrides.get(provider_id)
|
|
116
|
-
|
|
117
|
-
def reset_override(self, provider_id: str | None = None) -> None:
|
|
118
|
-
if provider_id is None:
|
|
119
|
-
self._overrides = {}
|
|
120
|
-
else:
|
|
121
|
-
self._overrides.pop(provider_id, None)
|
|
122
|
-
|
|
123
|
-
def async_enter(self) -> "Container":
|
|
124
|
-
self._is_async = True
|
|
125
|
-
return self
|
|
126
|
-
|
|
127
|
-
def sync_enter(self) -> "Container":
|
|
128
|
-
self._is_async = False
|
|
129
|
-
return self
|
|
130
|
-
|
|
131
|
-
async def async_close(self) -> None:
|
|
132
|
-
self._check_entered()
|
|
133
|
-
for provider_state in reversed(self._provider_states.values()):
|
|
134
|
-
await provider_state.async_tear_down()
|
|
135
|
-
self._exit()
|
|
136
|
-
|
|
137
|
-
def sync_close(self) -> None:
|
|
138
|
-
self._check_entered()
|
|
139
|
-
for provider_state in reversed(self._provider_states.values()):
|
|
140
|
-
provider_state.sync_tear_down()
|
|
141
|
-
self._exit()
|
|
142
|
-
|
|
143
|
-
async def __aenter__(self) -> "Container":
|
|
144
|
-
return self.async_enter()
|
|
145
|
-
|
|
146
|
-
async def __aexit__(
|
|
147
|
-
self,
|
|
148
|
-
exc_type: type[BaseException] | None,
|
|
149
|
-
exc_val: BaseException | None,
|
|
150
|
-
traceback: types.TracebackType | None,
|
|
151
|
-
) -> None:
|
|
152
|
-
await self.async_close()
|
|
153
|
-
|
|
154
|
-
def __enter__(self) -> "Container":
|
|
155
|
-
return self.sync_enter()
|
|
156
|
-
|
|
157
|
-
def __exit__(
|
|
158
|
-
self,
|
|
159
|
-
exc_type: type[BaseException] | None,
|
|
160
|
-
exc_value: BaseException | None,
|
|
161
|
-
traceback: types.TracebackType | None,
|
|
162
|
-
) -> None:
|
|
163
|
-
self.sync_close()
|
|
164
|
-
|
|
165
|
-
def __deepcopy__(self, *_: object, **__: object) -> "typing_extensions.Self":
|
|
166
|
-
"""Hack to prevent cloning object."""
|
|
167
|
-
return self
|
|
168
|
-
|
|
169
|
-
def __copy__(self, *_: object, **__: object) -> "typing_extensions.Self":
|
|
170
|
-
"""Hack to prevent cloning object."""
|
|
171
|
-
return self
|
modern_di/graph.py
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import typing
|
|
2
|
-
|
|
3
|
-
from modern_di import Container
|
|
4
|
-
from modern_di.providers.abstract import AbstractCreatorProvider, AbstractProvider
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
if typing.TYPE_CHECKING:
|
|
8
|
-
import typing_extensions
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
T = typing.TypeVar("T")
|
|
12
|
-
P = typing.ParamSpec("P")
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class BaseGraph:
|
|
16
|
-
providers: dict[str, AbstractProvider[typing.Any]]
|
|
17
|
-
|
|
18
|
-
def __new__(cls, *_: typing.Any, **__: typing.Any) -> "typing_extensions.Self": # noqa: ANN401
|
|
19
|
-
msg = f"{cls.__name__} cannot not be instantiated"
|
|
20
|
-
raise RuntimeError(msg)
|
|
21
|
-
|
|
22
|
-
@classmethod
|
|
23
|
-
def get_providers(cls) -> dict[str, AbstractProvider[typing.Any]]:
|
|
24
|
-
if not hasattr(cls, "providers"):
|
|
25
|
-
cls.providers = {k: v for k, v in cls.__dict__.items() if isinstance(v, AbstractProvider)}
|
|
26
|
-
|
|
27
|
-
return cls.providers
|
|
28
|
-
|
|
29
|
-
@classmethod
|
|
30
|
-
async def async_resolve_creators(cls, container: Container) -> None:
|
|
31
|
-
for provider in cls.get_providers().values():
|
|
32
|
-
if isinstance(provider, AbstractCreatorProvider) and provider.scope == container.scope:
|
|
33
|
-
await provider.async_resolve(container)
|
|
34
|
-
|
|
35
|
-
@classmethod
|
|
36
|
-
def sync_resolve_creators(cls, container: Container) -> None:
|
|
37
|
-
for provider in cls.get_providers().values():
|
|
38
|
-
if isinstance(provider, AbstractCreatorProvider) and provider.scope == container.scope:
|
|
39
|
-
provider.sync_resolve(container)
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import enum
|
|
2
|
-
import typing
|
|
3
|
-
|
|
4
|
-
from modern_di import Container
|
|
5
|
-
from modern_di.providers import AbstractProvider
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
T_co = typing.TypeVar("T_co", covariant=True)
|
|
9
|
-
P = typing.ParamSpec("P")
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class ContextAdapter(AbstractProvider[T_co]):
|
|
13
|
-
__slots__ = [*AbstractProvider.BASE_SLOTS, "_function"]
|
|
14
|
-
|
|
15
|
-
def __init__(
|
|
16
|
-
self,
|
|
17
|
-
scope: enum.IntEnum,
|
|
18
|
-
function: typing.Callable[..., T_co],
|
|
19
|
-
) -> None:
|
|
20
|
-
super().__init__(scope)
|
|
21
|
-
self._function = function
|
|
22
|
-
|
|
23
|
-
async def async_resolve(self, container: Container) -> T_co:
|
|
24
|
-
return self._function(**container.find_container(self.scope).context)
|
|
25
|
-
|
|
26
|
-
def sync_resolve(self, container: Container) -> T_co:
|
|
27
|
-
return self._function(**container.find_container(self.scope).context)
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import functools
|
|
2
|
-
import typing
|
|
3
|
-
|
|
4
|
-
from modern_di import Container
|
|
5
|
-
from modern_di.providers.abstract import AbstractProvider
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
T_co = typing.TypeVar("T_co", covariant=True)
|
|
9
|
-
P = typing.ParamSpec("P")
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class SyncInjectedFactory(AbstractProvider[T_co]):
|
|
13
|
-
__slots__ = [*AbstractProvider.BASE_SLOTS, "_factory_provider"]
|
|
14
|
-
|
|
15
|
-
def __init__(self, factory_provider: AbstractProvider[T_co]) -> None:
|
|
16
|
-
super().__init__(factory_provider.scope)
|
|
17
|
-
self._factory_provider = factory_provider
|
|
18
|
-
|
|
19
|
-
async def async_resolve(self, container: Container) -> typing.Callable[[], T_co]: # type: ignore[override]
|
|
20
|
-
return self.sync_resolve(container)
|
|
21
|
-
|
|
22
|
-
def sync_resolve(self, container: Container) -> typing.Callable[[], T_co]: # type: ignore[override]
|
|
23
|
-
return functools.partial(self._factory_provider.sync_resolve, container)
|
|
24
|
-
|
|
25
|
-
@property
|
|
26
|
-
def cast(self) -> typing.Callable[[], T_co]: # type: ignore[override]
|
|
27
|
-
return typing.cast(typing.Callable[[], T_co], self)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class AsyncInjectedFactory(AbstractProvider[T_co]):
|
|
31
|
-
__slots__ = [*AbstractProvider.BASE_SLOTS, "_factory_provider"]
|
|
32
|
-
|
|
33
|
-
def __init__(self, factory_provider: AbstractProvider[T_co]) -> None:
|
|
34
|
-
super().__init__(factory_provider.scope)
|
|
35
|
-
self._factory_provider = factory_provider
|
|
36
|
-
|
|
37
|
-
async def async_resolve(self, container: Container) -> typing.Callable[[], typing.Awaitable[T_co]]: # type: ignore[override]
|
|
38
|
-
return self.sync_resolve(container)
|
|
39
|
-
|
|
40
|
-
def sync_resolve(self, container: Container) -> typing.Callable[[], typing.Awaitable[T_co]]: # type: ignore[override]
|
|
41
|
-
return functools.partial(self._factory_provider.async_resolve, container)
|
|
42
|
-
|
|
43
|
-
@property
|
|
44
|
-
def cast(self) -> typing.Callable[[], typing.Awaitable[T_co]]: # type: ignore[override]
|
|
45
|
-
return typing.cast(typing.Callable[[], typing.Awaitable[T_co]], self)
|
modern_di/providers/selector.py
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import enum
|
|
2
|
-
import typing
|
|
3
|
-
|
|
4
|
-
from modern_di import Container
|
|
5
|
-
from modern_di.providers.abstract import AbstractProvider
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
T_co = typing.TypeVar("T_co", covariant=True)
|
|
9
|
-
P = typing.ParamSpec("P")
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class Selector(AbstractProvider[T_co]):
|
|
13
|
-
__slots__ = [*AbstractProvider.BASE_SLOTS, "_function", "_providers"]
|
|
14
|
-
|
|
15
|
-
def __init__(
|
|
16
|
-
self, scope: enum.IntEnum, function: typing.Callable[..., str], **providers: AbstractProvider[T_co]
|
|
17
|
-
) -> None:
|
|
18
|
-
super().__init__(scope)
|
|
19
|
-
self._check_providers_scope(kwargs=providers)
|
|
20
|
-
self._function: typing.Final = function
|
|
21
|
-
self._providers: typing.Final = providers
|
|
22
|
-
|
|
23
|
-
async def async_resolve(self, container: Container) -> T_co:
|
|
24
|
-
container = container.find_container(self.scope)
|
|
25
|
-
selected_key = self._function(**container.context)
|
|
26
|
-
if selected_key not in self._providers:
|
|
27
|
-
msg = f"No provider matches {selected_key}"
|
|
28
|
-
raise RuntimeError(msg)
|
|
29
|
-
|
|
30
|
-
return await self._providers[selected_key].async_resolve(container)
|
|
31
|
-
|
|
32
|
-
def sync_resolve(self, container: Container) -> T_co:
|
|
33
|
-
container = container.find_container(self.scope)
|
|
34
|
-
selected_key = self._function(**container.context)
|
|
35
|
-
if selected_key not in self._providers:
|
|
36
|
-
msg = f"No provider matches {selected_key}"
|
|
37
|
-
raise RuntimeError(msg)
|
|
38
|
-
|
|
39
|
-
return self._providers[selected_key].sync_resolve(container)
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
modern_di/__init__.py,sha256=L01VkzSJiV0d0FPrh1DZ-Wy5mUmoG6X-oLz7xYxtehI,194
|
|
2
|
-
modern_di/container.py,sha256=sNHUGk8Y_eoQSLsSc-ZOqUBP2edsZwpifigcBH2Ka7g,5576
|
|
3
|
-
modern_di/graph.py,sha256=X60wtG3Mqus_5YZNiZlQuXoHODBp7rYl_IHJs7GzSQM,1356
|
|
4
|
-
modern_di/provider_state.py,sha256=oU08QnMr0yhIZKkz0Pee8_RnWtETDE9ux4JB83qhwTI,1358
|
|
5
|
-
modern_di/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
modern_di/scope.py,sha256=e6Olc-CF89clbYDNGciy-F8EqJt1Mw2703zfuJaEY94,113
|
|
7
|
-
modern_di/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
-
modern_di/helpers/attr_getter_helpers.py,sha256=HUjExWLRAz2h0YX2_h5xKPX9-_K3i-BZTeZb3u-Wq5k,221
|
|
9
|
-
modern_di/providers/__init__.py,sha256=u19TXXMG0Ex8YsAnLzsf2mz3K78zEFVLBT_SiD51Dyw,873
|
|
10
|
-
modern_di/providers/abstract.py,sha256=cRMTL09RRFzgtfzDu7Ba1qkcJ8uQ00WJ1xtDBZbWYhU,5873
|
|
11
|
-
modern_di/providers/async_factory.py,sha256=eW7Y517NwUg_lov6YccCaBNUNuOEVEfQbAXjDQ-DUOI,1075
|
|
12
|
-
modern_di/providers/async_singleton.py,sha256=DIrix--RxrfDJfjP1OaTqk7-NNrG2MCQIt_wCaF2O3I,1649
|
|
13
|
-
modern_di/providers/container_provider.py,sha256=r5IEQXgKtPwvHvbqkbPnmGyDGGCCjokTtdard9Rvt40,548
|
|
14
|
-
modern_di/providers/context_adapter.py,sha256=_b1x3ToQPWT-9KkDioFhw1W8Q1VXZYUnczfYzMTobVA,760
|
|
15
|
-
modern_di/providers/dict.py,sha256=k_6BH51xyyE1dJmk-cJG3Qzssyf8M90zgD7dEtLF3LI,856
|
|
16
|
-
modern_di/providers/factory.py,sha256=uQOZ7-_thFUsWE13JeBpJYkQa-e9tt__1tJF4u92WvY,1492
|
|
17
|
-
modern_di/providers/injected_factory.py,sha256=KkDww-zUgm41LFt5j8crRzzFuBSkmKvOfptzHWMgVok,1848
|
|
18
|
-
modern_di/providers/list.py,sha256=Y9rcAWR50EvV8ns8HYAw2ZMJbSASjmMBkr_SZXb8uhc,774
|
|
19
|
-
modern_di/providers/object.py,sha256=Sm0mb3Ua7cZ5Ay65fLvl7fnJDSQrQZwvzio3lkkXP2A,825
|
|
20
|
-
modern_di/providers/resource.py,sha256=jEP6Ppr0gmdgWaQGF4sU2PIdt5xSzxcSDubC_IqxE1k,4559
|
|
21
|
-
modern_di/providers/selector.py,sha256=8WCqdaIxb2SNp-hKs1F9pfW0v3PdFr2IfH9VGMxWejs,1417
|
|
22
|
-
modern_di/providers/singleton.py,sha256=gfJvAQ7L0JBYlhrzKvaYYDiWo8MPbp0CCU8hGtuzs7U,2357
|
|
23
|
-
modern_di-0.16.2.dist-info/METADATA,sha256=pjeBhf9ylEBUnbv6FNt161UCxlMuOAKMogo-n7s34pU,3382
|
|
24
|
-
modern_di-0.16.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
25
|
-
modern_di-0.16.2.dist-info/RECORD,,
|
|
File without changes
|