python-injection 0.8.3__py3-none-any.whl → 0.8.4__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__.py +3 -1
- injection/__init__.pyi +17 -11
- injection/common/event.py +2 -2
- injection/common/invertible.py +1 -1
- injection/common/tools/threading.py +2 -3
- injection/common/tools/type.py +1 -1
- injection/core/module.py +78 -77
- injection/exceptions.py +3 -1
- injection/integrations/blacksheep.py +9 -7
- {python_injection-0.8.3.dist-info → python_injection-0.8.4.dist-info}/METADATA +1 -1
- python_injection-0.8.4.dist-info/RECORD +19 -0
- python_injection-0.8.3.dist-info/RECORD +0 -19
- {python_injection-0.8.3.dist-info → python_injection-0.8.4.dist-info}/WHEEL +0 -0
injection/__init__.py
CHANGED
injection/__init__.pyi
CHANGED
|
@@ -16,7 +16,8 @@ from typing import (
|
|
|
16
16
|
|
|
17
17
|
from .common.invertible import Invertible
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
_In_T = TypeVar("_In_T", covariant=False)
|
|
20
|
+
_Co_T = TypeVar("_Co_T", covariant=True)
|
|
20
21
|
|
|
21
22
|
default_module: Final[Module] = ...
|
|
22
23
|
|
|
@@ -87,30 +88,35 @@ class Module:
|
|
|
87
88
|
|
|
88
89
|
def set_constant(
|
|
89
90
|
self,
|
|
90
|
-
instance:
|
|
91
|
+
instance: _In_T,
|
|
91
92
|
on: type | Iterable[type] | UnionType = ...,
|
|
92
93
|
*,
|
|
93
94
|
mode: InjectableMode | Literal["fallback", "normal", "override"] = ...,
|
|
94
|
-
) ->
|
|
95
|
+
) -> _In_T:
|
|
95
96
|
"""
|
|
96
97
|
Function for registering a specific instance to be injected. This is useful for
|
|
97
98
|
registering global variables. The difference with the singleton decorator is
|
|
98
99
|
that no dependencies are resolved, so the module doesn't need to be locked.
|
|
99
100
|
"""
|
|
100
101
|
|
|
101
|
-
def
|
|
102
|
+
def resolve(self, cls: type[_In_T]) -> _In_T:
|
|
102
103
|
"""
|
|
103
104
|
Function used to retrieve an instance associated with the type passed in
|
|
104
|
-
parameter or
|
|
105
|
-
|
|
105
|
+
parameter or an exception will be raised.
|
|
106
|
+
"""
|
|
107
|
+
|
|
108
|
+
def get_instance(self, cls: type[_In_T]) -> _In_T | None:
|
|
109
|
+
"""
|
|
110
|
+
Function used to retrieve an instance associated with the type passed in
|
|
111
|
+
parameter or return `None`.
|
|
106
112
|
"""
|
|
107
113
|
|
|
108
114
|
def get_lazy_instance(
|
|
109
115
|
self,
|
|
110
|
-
cls: type[
|
|
116
|
+
cls: type[_In_T],
|
|
111
117
|
*,
|
|
112
118
|
cache: bool = ...,
|
|
113
|
-
) -> Invertible[
|
|
119
|
+
) -> Invertible[_In_T | None]:
|
|
114
120
|
"""
|
|
115
121
|
Function used to retrieve an instance associated with the type passed in
|
|
116
122
|
parameter or `None`. Return a `Invertible` object. To access the instance
|
|
@@ -171,13 +177,13 @@ class ModulePriority(str, Enum):
|
|
|
171
177
|
HIGH = ...
|
|
172
178
|
|
|
173
179
|
@runtime_checkable
|
|
174
|
-
class Injectable(Protocol[
|
|
175
|
-
def __init__(self, factory: Callable[[],
|
|
180
|
+
class Injectable(Protocol[_Co_T]):
|
|
181
|
+
def __init__(self, factory: Callable[[], _Co_T] = ..., /): ...
|
|
176
182
|
@property
|
|
177
183
|
def is_locked(self) -> bool: ...
|
|
178
184
|
def unlock(self): ...
|
|
179
185
|
@abstractmethod
|
|
180
|
-
def get_instance(self) ->
|
|
186
|
+
def get_instance(self) -> _Co_T: ...
|
|
181
187
|
|
|
182
188
|
@final
|
|
183
189
|
class InjectableMode(str, Enum):
|
injection/common/event.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
|
-
from contextlib import
|
|
2
|
+
from contextlib import ExitStack, contextmanager, suppress
|
|
3
3
|
from dataclasses import dataclass, field
|
|
4
4
|
from typing import ContextManager
|
|
5
5
|
from weakref import WeakSet
|
|
@@ -24,7 +24,7 @@ class EventChannel:
|
|
|
24
24
|
__listeners: WeakSet[EventListener] = field(default_factory=WeakSet, init=False)
|
|
25
25
|
|
|
26
26
|
@contextmanager
|
|
27
|
-
def dispatch(self, event: Event)
|
|
27
|
+
def dispatch(self, event: Event):
|
|
28
28
|
with ExitStack() as stack:
|
|
29
29
|
for listener in tuple(self.__listeners):
|
|
30
30
|
context_manager = listener.on_event(event)
|
injection/common/invertible.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
from contextlib import
|
|
1
|
+
from contextlib import contextmanager
|
|
2
2
|
from threading import RLock
|
|
3
|
-
from typing import ContextManager
|
|
4
3
|
|
|
5
4
|
__all__ = ("synchronized",)
|
|
6
5
|
|
|
@@ -8,6 +7,6 @@ __lock = RLock()
|
|
|
8
7
|
|
|
9
8
|
|
|
10
9
|
@contextmanager
|
|
11
|
-
def synchronized()
|
|
10
|
+
def synchronized():
|
|
12
11
|
with __lock:
|
|
13
12
|
yield
|
injection/common/tools/type.py
CHANGED
injection/core/module.py
CHANGED
|
@@ -12,7 +12,7 @@ from collections.abc import (
|
|
|
12
12
|
Mapping,
|
|
13
13
|
MutableMapping,
|
|
14
14
|
)
|
|
15
|
-
from contextlib import
|
|
15
|
+
from contextlib import contextmanager, suppress
|
|
16
16
|
from dataclasses import dataclass, field
|
|
17
17
|
from enum import Enum
|
|
18
18
|
from functools import partialmethod, singledispatchmethod, update_wrapper
|
|
@@ -27,7 +27,6 @@ from typing import (
|
|
|
27
27
|
NoReturn,
|
|
28
28
|
Protocol,
|
|
29
29
|
TypeVar,
|
|
30
|
-
cast,
|
|
31
30
|
runtime_checkable,
|
|
32
31
|
)
|
|
33
32
|
|
|
@@ -45,12 +44,12 @@ from injection.exceptions import (
|
|
|
45
44
|
NoInjectable,
|
|
46
45
|
)
|
|
47
46
|
|
|
48
|
-
__all__ = ("Injectable", "
|
|
47
|
+
__all__ = ("Injectable", "Mode", "Module", "Priority")
|
|
49
48
|
|
|
50
49
|
_logger = logging.getLogger(__name__)
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
_In_T = TypeVar("_In_T", covariant=False)
|
|
52
|
+
_Co_T = TypeVar("_Co_T", covariant=True)
|
|
54
53
|
|
|
55
54
|
|
|
56
55
|
"""
|
|
@@ -66,7 +65,7 @@ class ContainerEvent(Event, ABC):
|
|
|
66
65
|
@dataclass(frozen=True, slots=True)
|
|
67
66
|
class ContainerDependenciesUpdated(ContainerEvent):
|
|
68
67
|
classes: Collection[type]
|
|
69
|
-
mode:
|
|
68
|
+
mode: Mode
|
|
70
69
|
|
|
71
70
|
def __str__(self) -> str:
|
|
72
71
|
length = len(self.classes)
|
|
@@ -104,7 +103,7 @@ class ModuleEventProxy(ModuleEvent):
|
|
|
104
103
|
@dataclass(frozen=True, slots=True)
|
|
105
104
|
class ModuleAdded(ModuleEvent):
|
|
106
105
|
module_added: Module
|
|
107
|
-
priority:
|
|
106
|
+
priority: Priority
|
|
108
107
|
|
|
109
108
|
def __str__(self) -> str:
|
|
110
109
|
return f"`{self.on_module}` now uses `{self.module_added}`."
|
|
@@ -121,7 +120,7 @@ class ModuleRemoved(ModuleEvent):
|
|
|
121
120
|
@dataclass(frozen=True, slots=True)
|
|
122
121
|
class ModulePriorityUpdated(ModuleEvent):
|
|
123
122
|
module_updated: Module
|
|
124
|
-
priority:
|
|
123
|
+
priority: Priority
|
|
125
124
|
|
|
126
125
|
def __str__(self) -> str:
|
|
127
126
|
return (
|
|
@@ -136,10 +135,10 @@ Injectables
|
|
|
136
135
|
|
|
137
136
|
|
|
138
137
|
@runtime_checkable
|
|
139
|
-
class Injectable(Protocol[
|
|
138
|
+
class Injectable(Protocol[_Co_T]):
|
|
140
139
|
__slots__ = ()
|
|
141
140
|
|
|
142
|
-
def __init__(self, __factory: Callable[[],
|
|
141
|
+
def __init__(self, __factory: Callable[[], _Co_T] = None, /):
|
|
143
142
|
pass
|
|
144
143
|
|
|
145
144
|
@property
|
|
@@ -147,26 +146,26 @@ class Injectable(Protocol[_T]):
|
|
|
147
146
|
return False
|
|
148
147
|
|
|
149
148
|
def unlock(self):
|
|
150
|
-
|
|
149
|
+
return
|
|
151
150
|
|
|
152
151
|
@abstractmethod
|
|
153
|
-
def get_instance(self) ->
|
|
152
|
+
def get_instance(self) -> _Co_T:
|
|
154
153
|
raise NotImplementedError
|
|
155
154
|
|
|
156
155
|
|
|
157
156
|
@dataclass(repr=False, frozen=True, slots=True)
|
|
158
|
-
class BaseInjectable(Injectable[
|
|
159
|
-
factory: Callable[[],
|
|
157
|
+
class BaseInjectable(Injectable[_In_T], ABC):
|
|
158
|
+
factory: Callable[[], _In_T]
|
|
160
159
|
|
|
161
160
|
|
|
162
|
-
class NewInjectable(BaseInjectable[
|
|
161
|
+
class NewInjectable(BaseInjectable[_In_T]):
|
|
163
162
|
__slots__ = ()
|
|
164
163
|
|
|
165
|
-
def get_instance(self) ->
|
|
164
|
+
def get_instance(self) -> _In_T:
|
|
166
165
|
return self.factory()
|
|
167
166
|
|
|
168
167
|
|
|
169
|
-
class SingletonInjectable(BaseInjectable[
|
|
168
|
+
class SingletonInjectable(BaseInjectable[_In_T]):
|
|
170
169
|
__slots__ = ("__dict__",)
|
|
171
170
|
|
|
172
171
|
__INSTANCE_KEY: ClassVar[str] = "$instance"
|
|
@@ -182,7 +181,7 @@ class SingletonInjectable(BaseInjectable[_T]):
|
|
|
182
181
|
def unlock(self):
|
|
183
182
|
self.cache.clear()
|
|
184
183
|
|
|
185
|
-
def get_instance(self) ->
|
|
184
|
+
def get_instance(self) -> _In_T:
|
|
186
185
|
with suppress(KeyError):
|
|
187
186
|
return self.cache[self.__INSTANCE_KEY]
|
|
188
187
|
|
|
@@ -194,8 +193,8 @@ class SingletonInjectable(BaseInjectable[_T]):
|
|
|
194
193
|
|
|
195
194
|
|
|
196
195
|
@dataclass(repr=False, frozen=True, slots=True)
|
|
197
|
-
class ShouldBeInjectable(Injectable[
|
|
198
|
-
cls: type[
|
|
196
|
+
class ShouldBeInjectable(Injectable[_In_T]):
|
|
197
|
+
cls: type[_In_T]
|
|
199
198
|
|
|
200
199
|
def get_instance(self) -> NoReturn:
|
|
201
200
|
raise InjectionError(f"`{format_type(self.cls)}` should be an injectable.")
|
|
@@ -211,7 +210,7 @@ class Broker(Protocol):
|
|
|
211
210
|
__slots__ = ()
|
|
212
211
|
|
|
213
212
|
@abstractmethod
|
|
214
|
-
def __getitem__(self, cls: type[
|
|
213
|
+
def __getitem__(self, cls: type[_In_T] | UnionType, /) -> Injectable[_In_T]:
|
|
215
214
|
raise NotImplementedError
|
|
216
215
|
|
|
217
216
|
@abstractmethod
|
|
@@ -233,7 +232,7 @@ Container
|
|
|
233
232
|
"""
|
|
234
233
|
|
|
235
234
|
|
|
236
|
-
class
|
|
235
|
+
class Mode(str, Enum):
|
|
237
236
|
FALLBACK = "fallback"
|
|
238
237
|
NORMAL = "normal"
|
|
239
238
|
OVERRIDE = "override"
|
|
@@ -247,12 +246,12 @@ class InjectableMode(str, Enum):
|
|
|
247
246
|
return cls.NORMAL
|
|
248
247
|
|
|
249
248
|
|
|
250
|
-
|
|
249
|
+
ModeStr = Literal["fallback", "normal", "override"]
|
|
251
250
|
|
|
252
251
|
|
|
253
252
|
class Record(NamedTuple):
|
|
254
253
|
injectable: Injectable
|
|
255
|
-
mode:
|
|
254
|
+
mode: Mode
|
|
256
255
|
|
|
257
256
|
|
|
258
257
|
@dataclass(repr=False, frozen=True, slots=True)
|
|
@@ -260,7 +259,7 @@ class Container(Broker):
|
|
|
260
259
|
__records: dict[type, Record] = field(default_factory=dict, init=False)
|
|
261
260
|
__channel: EventChannel = field(default_factory=EventChannel, init=False)
|
|
262
261
|
|
|
263
|
-
def __getitem__(self, cls: type[
|
|
262
|
+
def __getitem__(self, cls: type[_In_T] | UnionType, /) -> Injectable[_In_T]:
|
|
264
263
|
for cls in get_origins(cls):
|
|
265
264
|
try:
|
|
266
265
|
injectable, _ = self.__records[cls]
|
|
@@ -283,8 +282,13 @@ class Container(Broker):
|
|
|
283
282
|
return frozenset(injectable for injectable, _ in self.__records.values())
|
|
284
283
|
|
|
285
284
|
@synchronized()
|
|
286
|
-
def update(
|
|
287
|
-
|
|
285
|
+
def update(
|
|
286
|
+
self,
|
|
287
|
+
classes: Iterable[type | UnionType],
|
|
288
|
+
injectable: Injectable,
|
|
289
|
+
mode: Mode | ModeStr,
|
|
290
|
+
):
|
|
291
|
+
mode = Mode(mode)
|
|
288
292
|
records = {
|
|
289
293
|
cls: Record(injectable, mode)
|
|
290
294
|
for cls in self.__filter_classes(classes, mode)
|
|
@@ -309,13 +313,13 @@ class Container(Broker):
|
|
|
309
313
|
self.__channel.add_listener(listener)
|
|
310
314
|
return self
|
|
311
315
|
|
|
312
|
-
def notify(self, event: Event)
|
|
316
|
+
def notify(self, event: Event):
|
|
313
317
|
return self.__channel.dispatch(event)
|
|
314
318
|
|
|
315
319
|
def __filter_classes(
|
|
316
320
|
self,
|
|
317
|
-
classes: Iterable[type],
|
|
318
|
-
mode:
|
|
321
|
+
classes: Iterable[type | UnionType],
|
|
322
|
+
mode: Mode,
|
|
319
323
|
) -> Iterator[type]:
|
|
320
324
|
rank = mode.rank
|
|
321
325
|
|
|
@@ -343,7 +347,7 @@ Module
|
|
|
343
347
|
"""
|
|
344
348
|
|
|
345
349
|
|
|
346
|
-
class
|
|
350
|
+
class Priority(str, Enum):
|
|
347
351
|
LOW = "low"
|
|
348
352
|
HIGH = "high"
|
|
349
353
|
|
|
@@ -352,12 +356,12 @@ class ModulePriority(str, Enum):
|
|
|
352
356
|
return cls.LOW
|
|
353
357
|
|
|
354
358
|
|
|
355
|
-
|
|
359
|
+
PriorityStr = Literal["low", "high"]
|
|
356
360
|
|
|
357
361
|
|
|
358
362
|
@dataclass(repr=False, eq=False, frozen=True, slots=True)
|
|
359
363
|
class Module(EventListener, Broker):
|
|
360
|
-
name: str = field(default=None)
|
|
364
|
+
name: str | None = field(default=None)
|
|
361
365
|
__channel: EventChannel = field(default_factory=EventChannel, init=False)
|
|
362
366
|
__container: Container = field(default_factory=Container, init=False)
|
|
363
367
|
__modules: OrderedDict[Module, None] = field(
|
|
@@ -368,7 +372,7 @@ class Module(EventListener, Broker):
|
|
|
368
372
|
def __post_init__(self):
|
|
369
373
|
self.__container.add_listener(self)
|
|
370
374
|
|
|
371
|
-
def __getitem__(self, cls: type[
|
|
375
|
+
def __getitem__(self, cls: type[_In_T] | UnionType, /) -> Injectable[_In_T]:
|
|
372
376
|
for broker in self.__brokers:
|
|
373
377
|
with suppress(KeyError):
|
|
374
378
|
return broker[cls]
|
|
@@ -400,8 +404,8 @@ class Module(EventListener, Broker):
|
|
|
400
404
|
*,
|
|
401
405
|
cls: type[Injectable] = NewInjectable,
|
|
402
406
|
inject: bool = True,
|
|
403
|
-
on: type |
|
|
404
|
-
mode:
|
|
407
|
+
on: type | Iterable[type] | UnionType = (),
|
|
408
|
+
mode: Mode | ModeStr = Mode.get_default(),
|
|
405
409
|
):
|
|
406
410
|
def decorator(wp):
|
|
407
411
|
factory = self.inject(wp, return_factory=True) if inject else wp
|
|
@@ -419,7 +423,7 @@ class Module(EventListener, Broker):
|
|
|
419
423
|
self.update(
|
|
420
424
|
(wp,),
|
|
421
425
|
ShouldBeInjectable(wp),
|
|
422
|
-
mode=
|
|
426
|
+
mode=Mode.FALLBACK,
|
|
423
427
|
)
|
|
424
428
|
return wp
|
|
425
429
|
|
|
@@ -427,16 +431,16 @@ class Module(EventListener, Broker):
|
|
|
427
431
|
|
|
428
432
|
def set_constant(
|
|
429
433
|
self,
|
|
430
|
-
instance:
|
|
431
|
-
on: type |
|
|
434
|
+
instance: _In_T,
|
|
435
|
+
on: type | Iterable[type] | UnionType = (),
|
|
432
436
|
*,
|
|
433
|
-
mode:
|
|
434
|
-
) ->
|
|
437
|
+
mode: Mode | ModeStr = Mode.get_default(),
|
|
438
|
+
) -> _In_T:
|
|
435
439
|
cls = type(instance)
|
|
436
440
|
self.injectable(
|
|
437
441
|
lambda: instance,
|
|
438
442
|
inject=False,
|
|
439
|
-
on=(cls, on),
|
|
443
|
+
on=(cls, on), # type: ignore
|
|
440
444
|
mode=mode,
|
|
441
445
|
)
|
|
442
446
|
return instance
|
|
@@ -464,24 +468,22 @@ class Module(EventListener, Broker):
|
|
|
464
468
|
|
|
465
469
|
return decorator(wrapped) if wrapped else decorator
|
|
466
470
|
|
|
467
|
-
def
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
except KeyError as exc:
|
|
471
|
-
if none:
|
|
472
|
-
return None
|
|
473
|
-
|
|
474
|
-
raise exc
|
|
471
|
+
def resolve(self, cls: type[_In_T]) -> _In_T:
|
|
472
|
+
injectable = self[cls]
|
|
473
|
+
return injectable.get_instance()
|
|
475
474
|
|
|
476
|
-
|
|
477
|
-
|
|
475
|
+
def get_instance(self, cls: type[_In_T]) -> _In_T | None:
|
|
476
|
+
try:
|
|
477
|
+
return self.resolve(cls)
|
|
478
|
+
except KeyError:
|
|
479
|
+
return None
|
|
478
480
|
|
|
479
481
|
def get_lazy_instance(
|
|
480
482
|
self,
|
|
481
|
-
cls: type[
|
|
483
|
+
cls: type[_In_T],
|
|
482
484
|
*,
|
|
483
485
|
cache: bool = False,
|
|
484
|
-
) -> Invertible[
|
|
486
|
+
) -> Invertible[_In_T | None]:
|
|
485
487
|
if cache:
|
|
486
488
|
return Lazy(lambda: self.get_instance(cls))
|
|
487
489
|
|
|
@@ -491,9 +493,9 @@ class Module(EventListener, Broker):
|
|
|
491
493
|
|
|
492
494
|
def update(
|
|
493
495
|
self,
|
|
494
|
-
classes: Iterable[type],
|
|
496
|
+
classes: Iterable[type | UnionType],
|
|
495
497
|
injectable: Injectable,
|
|
496
|
-
mode:
|
|
498
|
+
mode: Mode | ModeStr = Mode.get_default(),
|
|
497
499
|
):
|
|
498
500
|
self.__container.update(classes, injectable, mode)
|
|
499
501
|
return self
|
|
@@ -502,7 +504,7 @@ class Module(EventListener, Broker):
|
|
|
502
504
|
self,
|
|
503
505
|
module: Module,
|
|
504
506
|
*,
|
|
505
|
-
priority:
|
|
507
|
+
priority: Priority | PriorityStr = Priority.get_default(),
|
|
506
508
|
):
|
|
507
509
|
if module is self:
|
|
508
510
|
raise ModuleError("Module can't be used by itself.")
|
|
@@ -510,7 +512,7 @@ class Module(EventListener, Broker):
|
|
|
510
512
|
if module in self.__modules:
|
|
511
513
|
raise ModuleError(f"`{self}` already uses `{module}`.")
|
|
512
514
|
|
|
513
|
-
priority =
|
|
515
|
+
priority = Priority(priority)
|
|
514
516
|
event = ModuleAdded(self, module, priority)
|
|
515
517
|
|
|
516
518
|
with self.notify(event):
|
|
@@ -535,14 +537,14 @@ class Module(EventListener, Broker):
|
|
|
535
537
|
self,
|
|
536
538
|
module: Module,
|
|
537
539
|
*,
|
|
538
|
-
priority:
|
|
539
|
-
)
|
|
540
|
+
priority: Priority | PriorityStr = Priority.get_default(),
|
|
541
|
+
):
|
|
540
542
|
self.use(module, priority=priority)
|
|
541
543
|
yield
|
|
542
544
|
self.stop_using(module)
|
|
543
545
|
|
|
544
|
-
def change_priority(self, module: Module, priority:
|
|
545
|
-
priority =
|
|
546
|
+
def change_priority(self, module: Module, priority: Priority | PriorityStr):
|
|
547
|
+
priority = Priority(priority)
|
|
546
548
|
event = ModulePriorityUpdated(self, module, priority)
|
|
547
549
|
|
|
548
550
|
with self.notify(event):
|
|
@@ -570,7 +572,7 @@ class Module(EventListener, Broker):
|
|
|
570
572
|
return self.notify(self_event)
|
|
571
573
|
|
|
572
574
|
@contextmanager
|
|
573
|
-
def notify(self, event: Event)
|
|
575
|
+
def notify(self, event: Event):
|
|
574
576
|
self.__check_locking()
|
|
575
577
|
|
|
576
578
|
with self.__channel.dispatch(event):
|
|
@@ -581,8 +583,8 @@ class Module(EventListener, Broker):
|
|
|
581
583
|
if self.is_locked:
|
|
582
584
|
raise ModuleLockError(f"`{self}` is locked.")
|
|
583
585
|
|
|
584
|
-
def __move_module(self, module: Module, priority:
|
|
585
|
-
last = priority !=
|
|
586
|
+
def __move_module(self, module: Module, priority: Priority):
|
|
587
|
+
last = priority != Priority.HIGH
|
|
586
588
|
|
|
587
589
|
try:
|
|
588
590
|
self.__modules.move_to_end(module, last=last)
|
|
@@ -641,7 +643,7 @@ class Dependencies:
|
|
|
641
643
|
) -> Iterator[tuple[str, Injectable]]:
|
|
642
644
|
for name, annotation in cls.__get_annotations(signature, owner):
|
|
643
645
|
try:
|
|
644
|
-
injectable = module[annotation]
|
|
646
|
+
injectable: Injectable = module[annotation]
|
|
645
647
|
except KeyError:
|
|
646
648
|
continue
|
|
647
649
|
|
|
@@ -685,18 +687,18 @@ class InjectedFunction(EventListener):
|
|
|
685
687
|
self.__setup_queue = LimitedQueue[Callable[[], Any]]()
|
|
686
688
|
self.on_setup(self.__set_signature)
|
|
687
689
|
|
|
688
|
-
def __repr__(self) -> str:
|
|
690
|
+
def __repr__(self) -> str: # pragma: no cover
|
|
689
691
|
return repr(self.wrapped)
|
|
690
692
|
|
|
691
|
-
def __str__(self) -> str:
|
|
693
|
+
def __str__(self) -> str: # pragma: no cover
|
|
692
694
|
return str(self.wrapped)
|
|
693
695
|
|
|
694
696
|
def __call__(self, /, *args, **kwargs) -> Any:
|
|
695
697
|
for function in self.__setup_queue:
|
|
696
698
|
function()
|
|
697
699
|
|
|
698
|
-
|
|
699
|
-
return self.wrapped(*args, **kwargs)
|
|
700
|
+
arguments = self.bind(args, kwargs)
|
|
701
|
+
return self.wrapped(*arguments.args, **arguments.kwargs)
|
|
700
702
|
|
|
701
703
|
def __get__(self, instance: object = None, owner: type = None):
|
|
702
704
|
if instance is None:
|
|
@@ -713,7 +715,7 @@ class InjectedFunction(EventListener):
|
|
|
713
715
|
|
|
714
716
|
@property
|
|
715
717
|
def wrapped(self) -> Callable[..., Any]:
|
|
716
|
-
return self.__wrapped__
|
|
718
|
+
return self.__wrapped__ # type: ignore
|
|
717
719
|
|
|
718
720
|
def bind(
|
|
719
721
|
self,
|
|
@@ -741,7 +743,7 @@ class InjectedFunction(EventListener):
|
|
|
741
743
|
if self.__owner:
|
|
742
744
|
raise TypeError("Function owner is already defined.")
|
|
743
745
|
|
|
744
|
-
self.__owner = owner
|
|
746
|
+
self.__owner = owner # type: ignore
|
|
745
747
|
return self
|
|
746
748
|
|
|
747
749
|
@synchronized()
|
|
@@ -757,12 +759,12 @@ class InjectedFunction(EventListener):
|
|
|
757
759
|
return decorator(wrapped) if wrapped else decorator
|
|
758
760
|
|
|
759
761
|
@singledispatchmethod
|
|
760
|
-
def on_event(self, event: Event, /):
|
|
761
|
-
|
|
762
|
+
def on_event(self, event: Event, /) -> ContextManager | None: # type: ignore
|
|
763
|
+
return None
|
|
762
764
|
|
|
763
765
|
@on_event.register
|
|
764
766
|
@contextmanager
|
|
765
|
-
def _(self, event: ModuleEvent, /)
|
|
767
|
+
def _(self, event: ModuleEvent, /):
|
|
766
768
|
yield
|
|
767
769
|
self.update(event.on_module)
|
|
768
770
|
|
|
@@ -783,9 +785,8 @@ class InjectedFunction(EventListener):
|
|
|
783
785
|
return var.startswith("__") and var.endswith("__")
|
|
784
786
|
|
|
785
787
|
restricted_vars = frozenset(var for var in dir(self) if not is_dunder(var))
|
|
786
|
-
|
|
788
|
+
vars(self).update(
|
|
787
789
|
(var, value)
|
|
788
790
|
for var, value in variables.items()
|
|
789
791
|
if var not in restricted_vars
|
|
790
792
|
)
|
|
791
|
-
vars(self).update(variables)
|
injection/exceptions.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
1
3
|
from injection.common.tools.type import format_type
|
|
2
4
|
|
|
3
5
|
__all__ = (
|
|
@@ -16,7 +18,7 @@ class InjectionError(Exception):
|
|
|
16
18
|
class NoInjectable(KeyError, InjectionError):
|
|
17
19
|
__slots__ = ("__class",)
|
|
18
20
|
|
|
19
|
-
def __init__(self, cls: type):
|
|
21
|
+
def __init__(self, cls: type | Any):
|
|
20
22
|
super().__init__(f"No injectable for `{format_type(cls)}`.")
|
|
21
23
|
self.__class = cls
|
|
22
24
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from typing import Any, TypeVar
|
|
2
2
|
|
|
3
|
+
from rodi import ContainerProtocol
|
|
4
|
+
|
|
3
5
|
from injection import Module, default_module
|
|
4
6
|
|
|
5
7
|
__all__ = ("InjectionServices",)
|
|
@@ -7,7 +9,7 @@ __all__ = ("InjectionServices",)
|
|
|
7
9
|
_T = TypeVar("_T")
|
|
8
10
|
|
|
9
11
|
|
|
10
|
-
class InjectionServices:
|
|
12
|
+
class InjectionServices(ContainerProtocol):
|
|
11
13
|
"""
|
|
12
14
|
BlackSheep dependency injection container implemented with `python-injection`.
|
|
13
15
|
"""
|
|
@@ -17,12 +19,12 @@ class InjectionServices:
|
|
|
17
19
|
def __init__(self, module: Module = default_module):
|
|
18
20
|
self.__module = module
|
|
19
21
|
|
|
20
|
-
def __contains__(self,
|
|
21
|
-
return
|
|
22
|
+
def __contains__(self, item: Any) -> bool:
|
|
23
|
+
return item in self.__module
|
|
22
24
|
|
|
23
|
-
def register(self,
|
|
24
|
-
self.__module.injectable(
|
|
25
|
+
def register(self, obj_type: type | Any, *args, **kwargs):
|
|
26
|
+
self.__module.injectable(obj_type)
|
|
25
27
|
return self
|
|
26
28
|
|
|
27
|
-
def resolve(self,
|
|
28
|
-
return self.__module.
|
|
29
|
+
def resolve(self, obj_type: type[_T] | Any, *args, **kwargs) -> _T:
|
|
30
|
+
return self.__module.resolve(obj_type)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
injection/__init__.py,sha256=Bf6S99E2srD3752xlJf3uAdiGIzY2YHOZafcwEiwY70,739
|
|
2
|
+
injection/__init__.pyi,sha256=U3HBDYYrlxiwqMBIVVzgbI7VREP2N8_5Ysimzh6LmZo,5960
|
|
3
|
+
injection/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
injection/common/event.py,sha256=TvkFv-5zF_oUTPhh5U0BKD5HanvCJKHA0H7yceMRy5c,1261
|
|
5
|
+
injection/common/invertible.py,sha256=bG-_0u8T13lrZbauHoa8n7KzXg0Acpi3hurIIKhlqes,574
|
|
6
|
+
injection/common/lazy.py,sha256=1C34uoG229Gl0DEUcD9-eQrL4K_oIofOLzdQ1SiY6rw,1401
|
|
7
|
+
injection/common/queue.py,sha256=mV0AGxp5aYMr438MxmoIsZcV5jmqi5x_GD2S-utrnzA,1443
|
|
8
|
+
injection/common/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
injection/common/tools/threading.py,sha256=RAtzBFLVNJMflWIHxrP83fjafnFq8_JLgFoYQg8nVyE,182
|
|
10
|
+
injection/common/tools/type.py,sha256=05fD5UkUI1kPoFWEjQz4j266SYfJQMK-Ti88JXNxb_M,1276
|
|
11
|
+
injection/core/__init__.py,sha256=zuf0ubI2dHnbjn1059eduhS-ACIkkROa6-dhp10krh0,22
|
|
12
|
+
injection/core/module.py,sha256=UpkT6xLMUW9IG1yCywzyZo_X5RVU8N3ATFmPyKItLu4,20590
|
|
13
|
+
injection/exceptions.py,sha256=f2lVSTAx-Nv89s0skn15y-sCkr656ROuWYs-XlrcEn8,683
|
|
14
|
+
injection/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
+
injection/integrations/blacksheep.py,sha256=dFXzrxkJRy9z44CcwG0ROYshT3zUZTVyuQkRy390RvU,765
|
|
16
|
+
injection/utils.py,sha256=_79aiciimZpuoUTz5lojKySUMMzpkU-e7SotiHIFTI8,676
|
|
17
|
+
python_injection-0.8.4.dist-info/METADATA,sha256=P-ER2tDlSc4aDyzfrBneT7k8_lr6obXcIPJ7O3RfS0g,3672
|
|
18
|
+
python_injection-0.8.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
19
|
+
python_injection-0.8.4.dist-info/RECORD,,
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
injection/__init__.py,sha256=6Z4-h68LLXJ6FlrLqEMeJjw_RG7jyl0b-GQwKC2vIEY,685
|
|
2
|
-
injection/__init__.pyi,sha256=DrMtI3q4JYqPT2nwEoSmY3gVO62TwOUOJToEv9rtPVk,5755
|
|
3
|
-
injection/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
injection/common/event.py,sha256=uFoGRnxxkohH53JEStn4tN2Pn79HlgGExh7VkXdBwVQ,1316
|
|
5
|
-
injection/common/invertible.py,sha256=CyGp57Ik1pSQ2G7bRvnFWkY0kJkZDD5_19OjMYNvQes,558
|
|
6
|
-
injection/common/lazy.py,sha256=1C34uoG229Gl0DEUcD9-eQrL4K_oIofOLzdQ1SiY6rw,1401
|
|
7
|
-
injection/common/queue.py,sha256=mV0AGxp5aYMr438MxmoIsZcV5jmqi5x_GD2S-utrnzA,1443
|
|
8
|
-
injection/common/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
injection/common/tools/threading.py,sha256=02mBkIir2kQaXt47ewMJnOvhCldXCmPI2V-BW_l_6V8,271
|
|
10
|
-
injection/common/tools/type.py,sha256=-zL0dtoVZme71Mscvav7iEWxY2-JltzNTekbWOCPSFo,1276
|
|
11
|
-
injection/core/__init__.py,sha256=zuf0ubI2dHnbjn1059eduhS-ACIkkROa6-dhp10krh0,22
|
|
12
|
-
injection/core/module.py,sha256=mO8vHhbbvYTMFEucmpjFbGrJTeBrtlPiERmQDCxBGao,20545
|
|
13
|
-
injection/exceptions.py,sha256=nE56jW00ZB1T-Z-dvfPczPShs3CwIc7tIvdYlOXlaXA,653
|
|
14
|
-
injection/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
injection/integrations/blacksheep.py,sha256=vcLil1IccS7JtXpuVu7s2LqN5Zravfe_7xpAt5cTIU0,723
|
|
16
|
-
injection/utils.py,sha256=_79aiciimZpuoUTz5lojKySUMMzpkU-e7SotiHIFTI8,676
|
|
17
|
-
python_injection-0.8.3.dist-info/METADATA,sha256=148AKRb_jDQah38kKBXqLv185AoQeq8NTgg_9JMZDY4,3672
|
|
18
|
-
python_injection-0.8.3.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
19
|
-
python_injection-0.8.3.dist-info/RECORD,,
|
|
File without changes
|