python-injection 0.8.4.post1__py3-none-any.whl → 0.8.5__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 python-injection might be problematic. Click here for more details.
- injection/__init__.pyi +11 -11
- injection/common/invertible.py +6 -6
- injection/core/module.py +41 -33
- {python_injection-0.8.4.post1.dist-info → python_injection-0.8.5.dist-info}/METADATA +1 -1
- {python_injection-0.8.4.post1.dist-info → python_injection-0.8.5.dist-info}/RECORD +6 -7
- injection/common/queue.py +0 -63
- {python_injection-0.8.4.post1.dist-info → python_injection-0.8.5.dist-info}/WHEEL +0 -0
injection/__init__.pyi
CHANGED
|
@@ -16,8 +16,8 @@ from typing import (
|
|
|
16
16
|
|
|
17
17
|
from .common.invertible import Invertible
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
_T = TypeVar("_T")
|
|
20
|
+
_T_co = TypeVar("_T_co", covariant=True)
|
|
21
21
|
|
|
22
22
|
default_module: Final[Module] = ...
|
|
23
23
|
|
|
@@ -88,24 +88,24 @@ class Module:
|
|
|
88
88
|
|
|
89
89
|
def set_constant(
|
|
90
90
|
self,
|
|
91
|
-
instance:
|
|
91
|
+
instance: _T,
|
|
92
92
|
on: type | Iterable[type] | UnionType = ...,
|
|
93
93
|
*,
|
|
94
94
|
mode: InjectableMode | Literal["fallback", "normal", "override"] = ...,
|
|
95
|
-
) ->
|
|
95
|
+
) -> _T:
|
|
96
96
|
"""
|
|
97
97
|
Function for registering a specific instance to be injected. This is useful for
|
|
98
98
|
registering global variables. The difference with the singleton decorator is
|
|
99
99
|
that no dependencies are resolved, so the module doesn't need to be locked.
|
|
100
100
|
"""
|
|
101
101
|
|
|
102
|
-
def resolve(self, cls: type[
|
|
102
|
+
def resolve(self, cls: type[_T]) -> _T:
|
|
103
103
|
"""
|
|
104
104
|
Function used to retrieve an instance associated with the type passed in
|
|
105
105
|
parameter or an exception will be raised.
|
|
106
106
|
"""
|
|
107
107
|
|
|
108
|
-
def get_instance(self, cls: type[
|
|
108
|
+
def get_instance(self, cls: type[_T]) -> _T | None:
|
|
109
109
|
"""
|
|
110
110
|
Function used to retrieve an instance associated with the type passed in
|
|
111
111
|
parameter or return `None`.
|
|
@@ -113,10 +113,10 @@ class Module:
|
|
|
113
113
|
|
|
114
114
|
def get_lazy_instance(
|
|
115
115
|
self,
|
|
116
|
-
cls: type[
|
|
116
|
+
cls: type[_T],
|
|
117
117
|
*,
|
|
118
118
|
cache: bool = ...,
|
|
119
|
-
) -> Invertible[
|
|
119
|
+
) -> Invertible[_T | None]:
|
|
120
120
|
"""
|
|
121
121
|
Function used to retrieve an instance associated with the type passed in
|
|
122
122
|
parameter or `None`. Return a `Invertible` object. To access the instance
|
|
@@ -177,13 +177,13 @@ class ModulePriority(str, Enum):
|
|
|
177
177
|
HIGH = ...
|
|
178
178
|
|
|
179
179
|
@runtime_checkable
|
|
180
|
-
class Injectable(Protocol[
|
|
181
|
-
def __init__(self, factory: Callable[[],
|
|
180
|
+
class Injectable(Protocol[_T_co]):
|
|
181
|
+
def __init__(self, factory: Callable[[], _T_co] = ..., /): ...
|
|
182
182
|
@property
|
|
183
183
|
def is_locked(self) -> bool: ...
|
|
184
184
|
def unlock(self): ...
|
|
185
185
|
@abstractmethod
|
|
186
|
-
def get_instance(self) ->
|
|
186
|
+
def get_instance(self) -> _T_co: ...
|
|
187
187
|
|
|
188
188
|
@final
|
|
189
189
|
class InjectableMode(str, Enum):
|
injection/common/invertible.py
CHANGED
|
@@ -5,19 +5,19 @@ from typing import Protocol, TypeVar, runtime_checkable
|
|
|
5
5
|
|
|
6
6
|
__all__ = ("Invertible", "SimpleInvertible")
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
_T_co = TypeVar("_T_co", covariant=True)
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
@runtime_checkable
|
|
12
|
-
class Invertible(Protocol[
|
|
12
|
+
class Invertible(Protocol[_T_co]):
|
|
13
13
|
@abstractmethod
|
|
14
|
-
def __invert__(self) ->
|
|
14
|
+
def __invert__(self) -> _T_co:
|
|
15
15
|
raise NotImplementedError
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
@dataclass(repr=False, eq=False, frozen=True, slots=True)
|
|
19
|
-
class SimpleInvertible(Invertible[
|
|
20
|
-
callable: Callable[[],
|
|
19
|
+
class SimpleInvertible(Invertible[_T_co]):
|
|
20
|
+
callable: Callable[[], _T_co]
|
|
21
21
|
|
|
22
|
-
def __invert__(self) ->
|
|
22
|
+
def __invert__(self) -> _T_co:
|
|
23
23
|
return self.callable()
|
injection/core/module.py
CHANGED
|
@@ -17,6 +17,7 @@ from dataclasses import dataclass, field
|
|
|
17
17
|
from enum import Enum
|
|
18
18
|
from functools import partialmethod, singledispatchmethod, update_wrapper
|
|
19
19
|
from inspect import Signature, isclass
|
|
20
|
+
from queue import Queue
|
|
20
21
|
from types import MethodType, UnionType
|
|
21
22
|
from typing import (
|
|
22
23
|
Any,
|
|
@@ -33,7 +34,6 @@ from typing import (
|
|
|
33
34
|
from injection.common.event import Event, EventChannel, EventListener
|
|
34
35
|
from injection.common.invertible import Invertible, SimpleInvertible
|
|
35
36
|
from injection.common.lazy import Lazy, LazyMapping
|
|
36
|
-
from injection.common.queue import LimitedQueue
|
|
37
37
|
from injection.common.tools.threading import synchronized
|
|
38
38
|
from injection.common.tools.type import find_types, format_type, get_origins
|
|
39
39
|
from injection.exceptions import (
|
|
@@ -48,9 +48,8 @@ __all__ = ("Injectable", "Mode", "Module", "Priority")
|
|
|
48
48
|
|
|
49
49
|
_logger = logging.getLogger(__name__)
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
_T = TypeVar("_T")
|
|
52
|
+
_T_co = TypeVar("_T_co", covariant=True)
|
|
54
53
|
|
|
55
54
|
"""
|
|
56
55
|
Events
|
|
@@ -135,10 +134,10 @@ Injectables
|
|
|
135
134
|
|
|
136
135
|
|
|
137
136
|
@runtime_checkable
|
|
138
|
-
class Injectable(Protocol[
|
|
137
|
+
class Injectable(Protocol[_T_co]):
|
|
139
138
|
__slots__ = ()
|
|
140
139
|
|
|
141
|
-
def __init__(self, __factory: Callable[[],
|
|
140
|
+
def __init__(self, __factory: Callable[[], _T_co] = None, /):
|
|
142
141
|
pass
|
|
143
142
|
|
|
144
143
|
@property
|
|
@@ -149,23 +148,23 @@ class Injectable(Protocol[_Co_T]):
|
|
|
149
148
|
return
|
|
150
149
|
|
|
151
150
|
@abstractmethod
|
|
152
|
-
def get_instance(self) ->
|
|
151
|
+
def get_instance(self) -> _T_co:
|
|
153
152
|
raise NotImplementedError
|
|
154
153
|
|
|
155
154
|
|
|
156
155
|
@dataclass(repr=False, frozen=True, slots=True)
|
|
157
|
-
class BaseInjectable(Injectable[
|
|
158
|
-
factory: Callable[[],
|
|
156
|
+
class BaseInjectable(Injectable[_T], ABC):
|
|
157
|
+
factory: Callable[[], _T]
|
|
159
158
|
|
|
160
159
|
|
|
161
|
-
class NewInjectable(BaseInjectable[
|
|
160
|
+
class NewInjectable(BaseInjectable[_T]):
|
|
162
161
|
__slots__ = ()
|
|
163
162
|
|
|
164
|
-
def get_instance(self) ->
|
|
163
|
+
def get_instance(self) -> _T:
|
|
165
164
|
return self.factory()
|
|
166
165
|
|
|
167
166
|
|
|
168
|
-
class SingletonInjectable(BaseInjectable[
|
|
167
|
+
class SingletonInjectable(BaseInjectable[_T]):
|
|
169
168
|
__slots__ = ("__dict__",)
|
|
170
169
|
|
|
171
170
|
__INSTANCE_KEY: ClassVar[str] = "$instance"
|
|
@@ -181,7 +180,7 @@ class SingletonInjectable(BaseInjectable[_In_T]):
|
|
|
181
180
|
def unlock(self):
|
|
182
181
|
self.cache.clear()
|
|
183
182
|
|
|
184
|
-
def get_instance(self) ->
|
|
183
|
+
def get_instance(self) -> _T:
|
|
185
184
|
with suppress(KeyError):
|
|
186
185
|
return self.cache[self.__INSTANCE_KEY]
|
|
187
186
|
|
|
@@ -193,8 +192,8 @@ class SingletonInjectable(BaseInjectable[_In_T]):
|
|
|
193
192
|
|
|
194
193
|
|
|
195
194
|
@dataclass(repr=False, frozen=True, slots=True)
|
|
196
|
-
class ShouldBeInjectable(Injectable[
|
|
197
|
-
cls: type[
|
|
195
|
+
class ShouldBeInjectable(Injectable[_T]):
|
|
196
|
+
cls: type[_T]
|
|
198
197
|
|
|
199
198
|
def get_instance(self) -> NoReturn:
|
|
200
199
|
raise InjectionError(f"`{format_type(self.cls)}` should be an injectable.")
|
|
@@ -210,7 +209,7 @@ class Broker(Protocol):
|
|
|
210
209
|
__slots__ = ()
|
|
211
210
|
|
|
212
211
|
@abstractmethod
|
|
213
|
-
def __getitem__(self, cls: type[
|
|
212
|
+
def __getitem__(self, cls: type[_T] | UnionType, /) -> Injectable[_T]:
|
|
214
213
|
raise NotImplementedError
|
|
215
214
|
|
|
216
215
|
@abstractmethod
|
|
@@ -259,7 +258,7 @@ class Container(Broker):
|
|
|
259
258
|
__records: dict[type, Record] = field(default_factory=dict, init=False)
|
|
260
259
|
__channel: EventChannel = field(default_factory=EventChannel, init=False)
|
|
261
260
|
|
|
262
|
-
def __getitem__(self, cls: type[
|
|
261
|
+
def __getitem__(self, cls: type[_T] | UnionType, /) -> Injectable[_T]:
|
|
263
262
|
for cls in get_origins(cls):
|
|
264
263
|
try:
|
|
265
264
|
injectable, _ = self.__records[cls]
|
|
@@ -372,7 +371,7 @@ class Module(EventListener, Broker):
|
|
|
372
371
|
def __post_init__(self):
|
|
373
372
|
self.__container.add_listener(self)
|
|
374
373
|
|
|
375
|
-
def __getitem__(self, cls: type[
|
|
374
|
+
def __getitem__(self, cls: type[_T] | UnionType, /) -> Injectable[_T]:
|
|
376
375
|
for broker in self.__brokers:
|
|
377
376
|
with suppress(KeyError):
|
|
378
377
|
return broker[cls]
|
|
@@ -431,11 +430,11 @@ class Module(EventListener, Broker):
|
|
|
431
430
|
|
|
432
431
|
def set_constant(
|
|
433
432
|
self,
|
|
434
|
-
instance:
|
|
433
|
+
instance: _T,
|
|
435
434
|
on: type | Iterable[type] | UnionType = (),
|
|
436
435
|
*,
|
|
437
436
|
mode: Mode | ModeStr = Mode.get_default(),
|
|
438
|
-
) ->
|
|
437
|
+
) -> _T:
|
|
439
438
|
cls = type(instance)
|
|
440
439
|
self.injectable(
|
|
441
440
|
lambda: instance,
|
|
@@ -468,11 +467,11 @@ class Module(EventListener, Broker):
|
|
|
468
467
|
|
|
469
468
|
return decorator(wrapped) if wrapped else decorator
|
|
470
469
|
|
|
471
|
-
def resolve(self, cls: type[
|
|
470
|
+
def resolve(self, cls: type[_T]) -> _T:
|
|
472
471
|
injectable = self[cls]
|
|
473
472
|
return injectable.get_instance()
|
|
474
473
|
|
|
475
|
-
def get_instance(self, cls: type[
|
|
474
|
+
def get_instance(self, cls: type[_T]) -> _T | None:
|
|
476
475
|
try:
|
|
477
476
|
return self.resolve(cls)
|
|
478
477
|
except KeyError:
|
|
@@ -480,10 +479,10 @@ class Module(EventListener, Broker):
|
|
|
480
479
|
|
|
481
480
|
def get_lazy_instance(
|
|
482
481
|
self,
|
|
483
|
-
cls: type[
|
|
482
|
+
cls: type[_T],
|
|
484
483
|
*,
|
|
485
484
|
cache: bool = False,
|
|
486
|
-
) -> Invertible[
|
|
485
|
+
) -> Invertible[_T | None]:
|
|
487
486
|
if cache:
|
|
488
487
|
return Lazy(lambda: self.get_instance(cls))
|
|
489
488
|
|
|
@@ -684,8 +683,10 @@ class InjectedFunction(EventListener):
|
|
|
684
683
|
update_wrapper(self, wrapped, updated=())
|
|
685
684
|
self.__dependencies = Dependencies.empty()
|
|
686
685
|
self.__owner = None
|
|
687
|
-
|
|
688
|
-
|
|
686
|
+
|
|
687
|
+
queue = Queue[Callable[[], Any]]()
|
|
688
|
+
queue.put_nowait(self.__set_signature)
|
|
689
|
+
self.__setup_queue = queue
|
|
689
690
|
|
|
690
691
|
def __repr__(self) -> str: # pragma: no cover
|
|
691
692
|
return repr(self.wrapped)
|
|
@@ -694,8 +695,12 @@ class InjectedFunction(EventListener):
|
|
|
694
695
|
return str(self.wrapped)
|
|
695
696
|
|
|
696
697
|
def __call__(self, /, *args, **kwargs) -> Any:
|
|
697
|
-
|
|
698
|
-
|
|
698
|
+
queue = self.__setup_queue
|
|
699
|
+
|
|
700
|
+
while not queue.empty():
|
|
701
|
+
setup = queue.get()
|
|
702
|
+
setup()
|
|
703
|
+
queue.task_done()
|
|
699
704
|
|
|
700
705
|
arguments = self.bind(args, kwargs)
|
|
701
706
|
return self.wrapped(*arguments.args, **arguments.kwargs)
|
|
@@ -753,7 +758,7 @@ class InjectedFunction(EventListener):
|
|
|
753
758
|
|
|
754
759
|
def on_setup(self, wrapped: Callable[[], Any] = None, /):
|
|
755
760
|
def decorator(wp):
|
|
756
|
-
self.__setup_queue.
|
|
761
|
+
self.__setup_queue.put(wp)
|
|
757
762
|
return wp
|
|
758
763
|
|
|
759
764
|
return decorator(wrapped) if wrapped else decorator
|
|
@@ -781,12 +786,15 @@ class InjectedFunction(EventListener):
|
|
|
781
786
|
self.__update_vars(variables)
|
|
782
787
|
|
|
783
788
|
def __update_vars(self, variables: Mapping[str, Any]):
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
restricted_vars = frozenset(var for var in dir(self) if not is_dunder(var))
|
|
789
|
+
restricted_vars = frozenset(
|
|
790
|
+
var for var in dir(self) if not self.__is_dunder(var)
|
|
791
|
+
)
|
|
788
792
|
vars(self).update(
|
|
789
793
|
(var, value)
|
|
790
794
|
for var, value in variables.items()
|
|
791
795
|
if var not in restricted_vars
|
|
792
796
|
)
|
|
797
|
+
|
|
798
|
+
@staticmethod
|
|
799
|
+
def __is_dunder(var: str) -> bool:
|
|
800
|
+
return var.startswith("__") and var.endswith("__")
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
injection/__init__.py,sha256=Bf6S99E2srD3752xlJf3uAdiGIzY2YHOZafcwEiwY70,739
|
|
2
|
-
injection/__init__.pyi,sha256=
|
|
2
|
+
injection/__init__.pyi,sha256=fNTW5TUZQmaxPooaa_vJ_nyR_-DqZ13hSWHh_TsdeOo,5913
|
|
3
3
|
injection/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
injection/common/event.py,sha256=TvkFv-5zF_oUTPhh5U0BKD5HanvCJKHA0H7yceMRy5c,1261
|
|
5
|
-
injection/common/invertible.py,sha256=
|
|
5
|
+
injection/common/invertible.py,sha256=BZnkDg_NZDsTXGca5w5Wg_nYE3oRO_Wlodi2XtE55ck,595
|
|
6
6
|
injection/common/lazy.py,sha256=1C34uoG229Gl0DEUcD9-eQrL4K_oIofOLzdQ1SiY6rw,1401
|
|
7
|
-
injection/common/queue.py,sha256=mV0AGxp5aYMr438MxmoIsZcV5jmqi5x_GD2S-utrnzA,1443
|
|
8
7
|
injection/common/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
8
|
injection/common/tools/threading.py,sha256=RAtzBFLVNJMflWIHxrP83fjafnFq8_JLgFoYQg8nVyE,182
|
|
10
9
|
injection/common/tools/type.py,sha256=05fD5UkUI1kPoFWEjQz4j266SYfJQMK-Ti88JXNxb_M,1276
|
|
11
10
|
injection/core/__init__.py,sha256=zuf0ubI2dHnbjn1059eduhS-ACIkkROa6-dhp10krh0,22
|
|
12
|
-
injection/core/module.py,sha256=
|
|
11
|
+
injection/core/module.py,sha256=9QAYw5u8ULev3UWZCJ3R2dH9-xCqjc5e_9_19hrVWWw,20626
|
|
13
12
|
injection/exceptions.py,sha256=f2lVSTAx-Nv89s0skn15y-sCkr656ROuWYs-XlrcEn8,683
|
|
14
13
|
injection/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
14
|
injection/integrations/blacksheep.py,sha256=dFXzrxkJRy9z44CcwG0ROYshT3zUZTVyuQkRy390RvU,765
|
|
16
15
|
injection/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
16
|
injection/utils.py,sha256=_79aiciimZpuoUTz5lojKySUMMzpkU-e7SotiHIFTI8,676
|
|
18
|
-
python_injection-0.8.
|
|
19
|
-
python_injection-0.8.
|
|
20
|
-
python_injection-0.8.
|
|
17
|
+
python_injection-0.8.5.dist-info/METADATA,sha256=ZUrcGLYxHJC3IIwnBDJgsA3wlZ25zTNHeopIVWi4EHM,3672
|
|
18
|
+
python_injection-0.8.5.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
19
|
+
python_injection-0.8.5.dist-info/RECORD,,
|
injection/common/queue.py
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
from abc import abstractmethod
|
|
2
|
-
from collections import deque
|
|
3
|
-
from collections.abc import Iterator
|
|
4
|
-
from dataclasses import dataclass, field
|
|
5
|
-
from typing import NoReturn, Protocol, TypeVar
|
|
6
|
-
|
|
7
|
-
__all__ = ("LimitedQueue",)
|
|
8
|
-
|
|
9
|
-
_T = TypeVar("_T")
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class Queue(Iterator[_T], Protocol):
|
|
13
|
-
__slots__ = ()
|
|
14
|
-
|
|
15
|
-
@abstractmethod
|
|
16
|
-
def add(self, item: _T):
|
|
17
|
-
raise NotImplementedError
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@dataclass(repr=False, frozen=True, slots=True)
|
|
21
|
-
class SimpleQueue(Queue[_T]):
|
|
22
|
-
__items: deque[_T] = field(default_factory=deque, init=False)
|
|
23
|
-
|
|
24
|
-
def __next__(self) -> _T:
|
|
25
|
-
try:
|
|
26
|
-
return self.__items.popleft()
|
|
27
|
-
except IndexError as exc:
|
|
28
|
-
raise StopIteration from exc
|
|
29
|
-
|
|
30
|
-
def add(self, item: _T):
|
|
31
|
-
self.__items.append(item)
|
|
32
|
-
return self
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class DeadQueue(Queue[_T]):
|
|
36
|
-
__slots__ = ()
|
|
37
|
-
|
|
38
|
-
def __bool__(self) -> bool:
|
|
39
|
-
return False
|
|
40
|
-
|
|
41
|
-
def __next__(self) -> NoReturn:
|
|
42
|
-
raise StopIteration
|
|
43
|
-
|
|
44
|
-
def add(self, item: _T) -> NoReturn:
|
|
45
|
-
raise TypeError("Queue is dead.")
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
@dataclass(repr=False, slots=True)
|
|
49
|
-
class LimitedQueue(Queue[_T]):
|
|
50
|
-
__state: Queue[_T] = field(default_factory=SimpleQueue)
|
|
51
|
-
|
|
52
|
-
def __next__(self) -> _T:
|
|
53
|
-
try:
|
|
54
|
-
return next(self.__state)
|
|
55
|
-
except StopIteration as exc:
|
|
56
|
-
if self.__state:
|
|
57
|
-
self.__state = DeadQueue()
|
|
58
|
-
|
|
59
|
-
raise exc
|
|
60
|
-
|
|
61
|
-
def add(self, item: _T):
|
|
62
|
-
self.__state.add(item)
|
|
63
|
-
return self
|
|
File without changes
|