python-injection 0.14.6__py3-none-any.whl → 0.14.6.post0__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.
- injection/_core/injectables.py +38 -34
- {python_injection-0.14.6.dist-info → python_injection-0.14.6.post0.dist-info}/METADATA +1 -1
- {python_injection-0.14.6.dist-info → python_injection-0.14.6.post0.dist-info}/RECORD +4 -4
- {python_injection-0.14.6.dist-info → python_injection-0.14.6.post0.dist-info}/WHEEL +0 -0
injection/_core/injectables.py
CHANGED
@@ -13,7 +13,10 @@ from typing import (
|
|
13
13
|
runtime_checkable,
|
14
14
|
)
|
15
15
|
|
16
|
-
from injection._core.common.asynchronous import Caller
|
16
|
+
from injection._core.common.asynchronous import Caller
|
17
|
+
from injection._core.common.asynchronous import (
|
18
|
+
create_semaphore as _create_async_semaphore,
|
19
|
+
)
|
17
20
|
from injection._core.scope import Scope, get_active_scopes, get_scope
|
18
21
|
from injection.exceptions import InjectionError
|
19
22
|
|
@@ -39,12 +42,8 @@ class Injectable[T](Protocol):
|
|
39
42
|
|
40
43
|
|
41
44
|
@dataclass(repr=False, eq=False, frozen=True, slots=True)
|
42
|
-
class
|
43
|
-
factory: Caller[...,
|
44
|
-
|
45
|
-
|
46
|
-
class SimpleInjectable[T](BaseInjectable[T, T]):
|
47
|
-
__slots__ = ()
|
45
|
+
class SimpleInjectable[T](Injectable[T]):
|
46
|
+
factory: Caller[..., T]
|
48
47
|
|
49
48
|
async def aget_instance(self) -> T:
|
50
49
|
return await self.factory.acall()
|
@@ -53,13 +52,13 @@ class SimpleInjectable[T](BaseInjectable[T, T]):
|
|
53
52
|
return self.factory.call()
|
54
53
|
|
55
54
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
55
|
+
class CacheLogic[T]:
|
56
|
+
__slots__ = ("__semaphore",)
|
57
|
+
|
58
|
+
__semaphore: AsyncContextManager[Any]
|
59
|
+
|
60
|
+
def __init__(self) -> None:
|
61
|
+
self.__semaphore = _create_async_semaphore(1)
|
63
62
|
|
64
63
|
async def aget_or_create[K](
|
65
64
|
self,
|
@@ -90,32 +89,37 @@ class CachedInjectable[R, T](BaseInjectable[R, T], ABC):
|
|
90
89
|
return instance
|
91
90
|
|
92
91
|
|
93
|
-
|
94
|
-
|
92
|
+
@dataclass(repr=False, eq=False, frozen=True, slots=True)
|
93
|
+
class SingletonInjectable[T](Injectable[T]):
|
94
|
+
factory: Caller[..., T]
|
95
|
+
cache: MutableMapping[str, T] = field(default_factory=dict)
|
96
|
+
logic: CacheLogic[T] = field(default_factory=CacheLogic)
|
95
97
|
|
96
98
|
__key: ClassVar[str] = "$instance"
|
97
99
|
|
98
100
|
@property
|
99
101
|
def is_locked(self) -> bool:
|
100
|
-
return self.__key in self.
|
101
|
-
|
102
|
-
@property
|
103
|
-
def __cache(self) -> MutableMapping[str, Any]:
|
104
|
-
return self.__dict__
|
102
|
+
return self.__key in self.cache
|
105
103
|
|
106
104
|
async def aget_instance(self) -> T:
|
107
|
-
return await self.aget_or_create(
|
105
|
+
return await self.logic.aget_or_create(
|
106
|
+
self.cache,
|
107
|
+
self.__key,
|
108
|
+
self.factory.acall,
|
109
|
+
)
|
108
110
|
|
109
111
|
def get_instance(self) -> T:
|
110
|
-
return self.get_or_create(self.
|
112
|
+
return self.logic.get_or_create(self.cache, self.__key, self.factory.call)
|
111
113
|
|
112
114
|
def unlock(self) -> None:
|
113
|
-
self.
|
115
|
+
self.cache.pop(self.__key, None)
|
114
116
|
|
115
117
|
|
116
118
|
@dataclass(repr=False, eq=False, frozen=True, slots=True)
|
117
|
-
class ScopedInjectable[R, T](
|
119
|
+
class ScopedInjectable[R, T](Injectable[T], ABC):
|
120
|
+
factory: Caller[..., R]
|
118
121
|
scope_name: str
|
122
|
+
logic: CacheLogic[T] = field(default_factory=CacheLogic)
|
119
123
|
|
120
124
|
@property
|
121
125
|
def is_locked(self) -> bool:
|
@@ -130,26 +134,26 @@ class ScopedInjectable[R, T](CachedInjectable[R, T], ABC):
|
|
130
134
|
raise NotImplementedError
|
131
135
|
|
132
136
|
async def aget_instance(self) -> T:
|
133
|
-
scope = self.
|
137
|
+
scope = self.__get_scope()
|
134
138
|
factory = partial(self.abuild, scope)
|
135
|
-
return await self.aget_or_create(scope.cache, self, factory)
|
139
|
+
return await self.logic.aget_or_create(scope.cache, self, factory)
|
136
140
|
|
137
141
|
def get_instance(self) -> T:
|
138
|
-
scope = self.
|
142
|
+
scope = self.__get_scope()
|
139
143
|
factory = partial(self.build, scope)
|
140
|
-
return self.get_or_create(scope.cache, self, factory)
|
141
|
-
|
142
|
-
def get_scope(self) -> Scope:
|
143
|
-
return get_scope(self.scope_name)
|
144
|
+
return self.logic.get_or_create(scope.cache, self, factory)
|
144
145
|
|
145
146
|
def setdefault(self, instance: T) -> T:
|
146
|
-
scope = self.
|
147
|
-
return self.get_or_create(scope.cache, self, lambda: instance)
|
147
|
+
scope = self.__get_scope()
|
148
|
+
return self.logic.get_or_create(scope.cache, self, lambda: instance)
|
148
149
|
|
149
150
|
def unlock(self) -> None:
|
150
151
|
if self.is_locked:
|
151
152
|
raise RuntimeError(f"To unlock, close the `{self.scope_name}` scope.")
|
152
153
|
|
154
|
+
def __get_scope(self) -> Scope:
|
155
|
+
return get_scope(self.scope_name)
|
156
|
+
|
153
157
|
|
154
158
|
class AsyncCMScopedInjectable[T](ScopedInjectable[AsyncContextManager[T], T]):
|
155
159
|
__slots__ = ()
|
@@ -5,7 +5,7 @@ injection/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
injection/utils.py,sha256=EuHMrix6gx2YnnUAn2_BPsDkvucGS5-pFhM3596oBK4,2796
|
6
6
|
injection/_core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
7
|
injection/_core/descriptors.py,sha256=7fSHlgAqmgR_Uta8KocBapOt1Xyj2dI7RY9ZdoStTzw,726
|
8
|
-
injection/_core/injectables.py,sha256=
|
8
|
+
injection/_core/injectables.py,sha256=idNkQZZ29vd73G_lE-eS5C7zGeVe_ALNkUt8M6YjZrk,5519
|
9
9
|
injection/_core/module.py,sha256=DLw0pD3HDXfNhzbWM0yeCDKg-Mwg8JAzqZq43tFAXik,31814
|
10
10
|
injection/_core/scope.py,sha256=SnjfYnZ62BkxEUh3wXKHl7ivCHRrPFiTa5GMxC-8ACM,5533
|
11
11
|
injection/_core/slots.py,sha256=6LoG0XtaRnIGDSG8s-FfUIw_50gL0bl4X3Fo_n-hdak,680
|
@@ -20,6 +20,6 @@ injection/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
20
20
|
injection/integrations/fastapi.py,sha256=YHSs85_3m6TUVtOwUcV157b3UZJQIw_aXWAg199a-YE,594
|
21
21
|
injection/testing/__init__.py,sha256=SiImXDd0-DO1a8S5nbUQRtgDX8iaU_nHcp8DdqwtD2M,896
|
22
22
|
injection/testing/__init__.pyi,sha256=iOii0i9F5n7znltGeGQYI2KXC_if9SAogLh1h03yx-0,540
|
23
|
-
python_injection-0.14.6.dist-info/METADATA,sha256=
|
24
|
-
python_injection-0.14.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
25
|
-
python_injection-0.14.6.dist-info/RECORD,,
|
23
|
+
python_injection-0.14.6.post0.dist-info/METADATA,sha256=sRxRmH0mUX84dvnm-e2Vw6dyZrSOqNqaoVdn5A82U_4,3205
|
24
|
+
python_injection-0.14.6.post0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
25
|
+
python_injection-0.14.6.post0.dist-info/RECORD,,
|
File without changes
|