python-injection 0.9.4.post0__tar.gz → 0.9.6__tar.gz
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.
- {python_injection-0.9.4.post0 → python_injection-0.9.6}/PKG-INFO +3 -2
- {python_injection-0.9.4.post0 → python_injection-0.9.6}/documentation/basic-usage.md +2 -1
- {python_injection-0.9.4.post0 → python_injection-0.9.6}/injection/__init__.py +3 -3
- {python_injection-0.9.4.post0 → python_injection-0.9.6}/injection/__init__.pyi +14 -14
- {python_injection-0.9.4.post0/injection → python_injection-0.9.6/injection/_core}/common/lazy.py +1 -1
- {python_injection-0.9.4.post0/injection/common/tools → python_injection-0.9.6/injection/_core/common}/threading.py +2 -1
- {python_injection-0.9.4.post0/injection/common/tools → python_injection-0.9.6/injection/_core/common}/type.py +3 -3
- {python_injection-0.9.4.post0/injection/core → python_injection-0.9.6/injection/_core}/module.py +49 -49
- {python_injection-0.9.4.post0 → python_injection-0.9.6}/injection/integrations/blacksheep.py +0 -1
- python_injection-0.9.6/injection/testing/__init__.py +35 -0
- {python_injection-0.9.4.post0 → python_injection-0.9.6}/injection/testing/__init__.pyi +1 -1
- {python_injection-0.9.4.post0 → python_injection-0.9.6}/injection/utils.py +14 -9
- {python_injection-0.9.4.post0 → python_injection-0.9.6}/pyproject.toml +1 -1
- python_injection-0.9.4.post0/injection/integrations/__init__.py +0 -0
- python_injection-0.9.4.post0/injection/testing/__init__.py +0 -35
- {python_injection-0.9.4.post0/injection/core → python_injection-0.9.6/injection/_core}/__init__.py +0 -0
- {python_injection-0.9.4.post0/injection → python_injection-0.9.6/injection/_core}/common/__init__.py +0 -0
- {python_injection-0.9.4.post0/injection → python_injection-0.9.6/injection/_core}/common/event.py +0 -0
- {python_injection-0.9.4.post0/injection → python_injection-0.9.6/injection/_core}/common/invertible.py +0 -0
- {python_injection-0.9.4.post0 → python_injection-0.9.6}/injection/exceptions.py +0 -0
- {python_injection-0.9.4.post0/injection/common/tools → python_injection-0.9.6/injection/integrations}/__init__.py +0 -0
- {python_injection-0.9.4.post0 → python_injection-0.9.6}/injection/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-injection
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.6
|
|
4
4
|
Summary: Fast and easy dependency injection framework.
|
|
5
5
|
Home-page: https://github.com/100nm/python-injection
|
|
6
6
|
License: MIT
|
|
@@ -59,7 +59,8 @@ from injection import set_constant
|
|
|
59
59
|
class ServiceC:
|
|
60
60
|
""" class implementation """
|
|
61
61
|
|
|
62
|
-
service_c =
|
|
62
|
+
service_c = ServiceC()
|
|
63
|
+
set_constant(service_c)
|
|
63
64
|
```
|
|
64
65
|
|
|
65
66
|
## Inject an instance
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
from .
|
|
2
|
-
from .
|
|
3
|
-
from .
|
|
1
|
+
from ._core import Injectable, Module
|
|
2
|
+
from ._core import Mode as InjectableMode
|
|
3
|
+
from ._core import Priority as ModulePriority
|
|
4
4
|
|
|
5
5
|
__all__ = (
|
|
6
6
|
"Injectable",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
2
|
from collections.abc import Callable
|
|
3
3
|
from contextlib import ContextDecorator
|
|
4
|
-
from enum import
|
|
4
|
+
from enum import Enum
|
|
5
5
|
from logging import Logger
|
|
6
6
|
from types import UnionType
|
|
7
7
|
from typing import (
|
|
@@ -13,11 +13,11 @@ from typing import (
|
|
|
13
13
|
runtime_checkable,
|
|
14
14
|
)
|
|
15
15
|
|
|
16
|
-
from .
|
|
17
|
-
from .
|
|
18
|
-
from .
|
|
19
|
-
from .
|
|
20
|
-
from .
|
|
16
|
+
from ._core import InjectableFactory as _InjectableFactory
|
|
17
|
+
from ._core import ModeStr as InjectableModeStr
|
|
18
|
+
from ._core import PriorityStr as ModulePriorityStr
|
|
19
|
+
from ._core.common.invertible import Invertible as _Invertible
|
|
20
|
+
from ._core.common.type import TypeInfo as _TypeInfo
|
|
21
21
|
|
|
22
22
|
_: Module = ...
|
|
23
23
|
|
|
@@ -62,9 +62,9 @@ class Module:
|
|
|
62
62
|
wrapped: Callable[..., T] = ...,
|
|
63
63
|
/,
|
|
64
64
|
*,
|
|
65
|
-
cls:
|
|
65
|
+
cls: _InjectableFactory[T] = ...,
|
|
66
66
|
inject: bool = ...,
|
|
67
|
-
on:
|
|
67
|
+
on: _TypeInfo[T] = ...,
|
|
68
68
|
mode: InjectableMode | InjectableModeStr = ...,
|
|
69
69
|
):
|
|
70
70
|
"""
|
|
@@ -79,7 +79,7 @@ class Module:
|
|
|
79
79
|
/,
|
|
80
80
|
*,
|
|
81
81
|
inject: bool = ...,
|
|
82
|
-
on:
|
|
82
|
+
on: _TypeInfo[T] = ...,
|
|
83
83
|
mode: InjectableMode | InjectableModeStr = ...,
|
|
84
84
|
):
|
|
85
85
|
"""
|
|
@@ -98,10 +98,10 @@ class Module:
|
|
|
98
98
|
def set_constant[T](
|
|
99
99
|
self,
|
|
100
100
|
instance: T,
|
|
101
|
-
on:
|
|
101
|
+
on: _TypeInfo[T] = ...,
|
|
102
102
|
*,
|
|
103
103
|
mode: InjectableMode | InjectableModeStr = ...,
|
|
104
|
-
) ->
|
|
104
|
+
) -> Self:
|
|
105
105
|
"""
|
|
106
106
|
Function for registering a specific instance to be injected. This is useful for
|
|
107
107
|
registering global variables. The difference with the singleton decorator is
|
|
@@ -125,7 +125,7 @@ class Module:
|
|
|
125
125
|
cls: type[T],
|
|
126
126
|
*,
|
|
127
127
|
cache: bool = ...,
|
|
128
|
-
) ->
|
|
128
|
+
) -> _Invertible[T | None]:
|
|
129
129
|
"""
|
|
130
130
|
Function used to retrieve an instance associated with the type passed in
|
|
131
131
|
parameter or `None`. Return a `Invertible` object. To access the instance
|
|
@@ -199,7 +199,7 @@ class Module:
|
|
|
199
199
|
"""
|
|
200
200
|
|
|
201
201
|
@final
|
|
202
|
-
class ModulePriority(
|
|
202
|
+
class ModulePriority(Enum):
|
|
203
203
|
LOW = ...
|
|
204
204
|
HIGH = ...
|
|
205
205
|
|
|
@@ -212,7 +212,7 @@ class Injectable[T](Protocol):
|
|
|
212
212
|
def get_instance(self) -> T: ...
|
|
213
213
|
|
|
214
214
|
@final
|
|
215
|
-
class InjectableMode(
|
|
215
|
+
class InjectableMode(Enum):
|
|
216
216
|
FALLBACK = ...
|
|
217
217
|
NORMAL = ...
|
|
218
218
|
OVERRIDE = ...
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from collections.abc import Iterator
|
|
1
2
|
from contextlib import contextmanager
|
|
2
3
|
from threading import RLock
|
|
3
4
|
|
|
@@ -5,7 +6,7 @@ __all__ = ("synchronized",)
|
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
@contextmanager
|
|
8
|
-
def synchronized():
|
|
9
|
+
def synchronized() -> Iterator[RLock]:
|
|
9
10
|
lock = RLock()
|
|
10
11
|
|
|
11
12
|
with lock:
|
|
@@ -59,9 +59,9 @@ def analyze_types(*types: type | Any) -> Iterator[TypeReport[Any]]:
|
|
|
59
59
|
|
|
60
60
|
def get_return_types(*args: TypeInfo[Any]) -> Iterator[type | UnionType]:
|
|
61
61
|
for arg in args:
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
if isinstance(arg, Iterable) and not (
|
|
63
|
+
isinstance(arg, type | str) or isinstance(get_origin(arg), type)
|
|
64
|
+
):
|
|
65
65
|
inner_args = arg
|
|
66
66
|
|
|
67
67
|
elif isfunction(arg):
|
{python_injection-0.9.4.post0/injection/core → python_injection-0.9.6/injection/_core}/module.py
RENAMED
|
@@ -30,12 +30,13 @@ from typing import (
|
|
|
30
30
|
Self,
|
|
31
31
|
runtime_checkable,
|
|
32
32
|
)
|
|
33
|
+
from uuid import uuid4
|
|
33
34
|
|
|
34
|
-
from injection.common.event import Event, EventChannel, EventListener
|
|
35
|
-
from injection.common.invertible import Invertible, SimpleInvertible
|
|
36
|
-
from injection.common.lazy import Lazy, LazyMapping
|
|
37
|
-
from injection.common.
|
|
38
|
-
from injection.common.
|
|
35
|
+
from injection._core.common.event import Event, EventChannel, EventListener
|
|
36
|
+
from injection._core.common.invertible import Invertible, SimpleInvertible
|
|
37
|
+
from injection._core.common.lazy import Lazy, LazyMapping
|
|
38
|
+
from injection._core.common.threading import synchronized
|
|
39
|
+
from injection._core.common.type import (
|
|
39
40
|
TypeInfo,
|
|
40
41
|
TypeReport,
|
|
41
42
|
analyze_types,
|
|
@@ -65,12 +66,12 @@ Events
|
|
|
65
66
|
|
|
66
67
|
|
|
67
68
|
@dataclass(frozen=True, slots=True)
|
|
68
|
-
class
|
|
69
|
-
|
|
69
|
+
class LocatorEvent(Event, ABC):
|
|
70
|
+
locator: Locator
|
|
70
71
|
|
|
71
72
|
|
|
72
73
|
@dataclass(frozen=True, slots=True)
|
|
73
|
-
class
|
|
74
|
+
class LocatorDependenciesUpdated(LocatorEvent):
|
|
74
75
|
reports: Collection[TypeReport]
|
|
75
76
|
mode: Mode
|
|
76
77
|
|
|
@@ -78,14 +79,14 @@ class ContainerDependenciesUpdated(ContainerEvent):
|
|
|
78
79
|
length = len(self.reports)
|
|
79
80
|
formatted_types = ", ".join(f"`{report.type}`" for report in self.reports)
|
|
80
81
|
return (
|
|
81
|
-
f"{length}
|
|
82
|
-
f"
|
|
82
|
+
f"{length} dependenc{"ies" if length > 1 else "y"} have been "
|
|
83
|
+
f"updated{f": {formatted_types}" if formatted_types else ""}."
|
|
83
84
|
)
|
|
84
85
|
|
|
85
86
|
|
|
86
87
|
@dataclass(frozen=True, slots=True)
|
|
87
88
|
class ModuleEvent(Event, ABC):
|
|
88
|
-
|
|
89
|
+
module: Module
|
|
89
90
|
|
|
90
91
|
|
|
91
92
|
@dataclass(frozen=True, slots=True)
|
|
@@ -93,7 +94,7 @@ class ModuleEventProxy(ModuleEvent):
|
|
|
93
94
|
event: Event
|
|
94
95
|
|
|
95
96
|
def __str__(self) -> str:
|
|
96
|
-
return f"`{self.
|
|
97
|
+
return f"`{self.module}` has propagated an event: {self.origin}"
|
|
97
98
|
|
|
98
99
|
@property
|
|
99
100
|
def history(self) -> Iterator[Event]:
|
|
@@ -113,7 +114,7 @@ class ModuleAdded(ModuleEvent):
|
|
|
113
114
|
priority: Priority
|
|
114
115
|
|
|
115
116
|
def __str__(self) -> str:
|
|
116
|
-
return f"`{self.
|
|
117
|
+
return f"`{self.module}` now uses `{self.module_added}`."
|
|
117
118
|
|
|
118
119
|
|
|
119
120
|
@dataclass(frozen=True, slots=True)
|
|
@@ -121,7 +122,7 @@ class ModuleRemoved(ModuleEvent):
|
|
|
121
122
|
module_removed: Module
|
|
122
123
|
|
|
123
124
|
def __str__(self) -> str:
|
|
124
|
-
return f"`{self.
|
|
125
|
+
return f"`{self.module}` no longer uses `{self.module_removed}`."
|
|
125
126
|
|
|
126
127
|
|
|
127
128
|
@dataclass(frozen=True, slots=True)
|
|
@@ -131,7 +132,7 @@ class ModulePriorityUpdated(ModuleEvent):
|
|
|
131
132
|
|
|
132
133
|
def __str__(self) -> str:
|
|
133
134
|
return (
|
|
134
|
-
f"In `{self.
|
|
135
|
+
f"In `{self.module}`, the priority `{self.priority}` "
|
|
135
136
|
f"has been applied to `{self.module_updated}`."
|
|
136
137
|
)
|
|
137
138
|
|
|
@@ -232,7 +233,7 @@ class Broker(Protocol):
|
|
|
232
233
|
|
|
233
234
|
|
|
234
235
|
"""
|
|
235
|
-
|
|
236
|
+
Locator
|
|
236
237
|
"""
|
|
237
238
|
|
|
238
239
|
|
|
@@ -259,13 +260,13 @@ class Record[T](NamedTuple):
|
|
|
259
260
|
|
|
260
261
|
|
|
261
262
|
@dataclass(repr=False, frozen=True, slots=True)
|
|
262
|
-
class
|
|
263
|
+
class Locator(Broker):
|
|
263
264
|
__records: dict[TypeReport, Record] = field(default_factory=dict, init=False)
|
|
264
265
|
__channel: EventChannel = field(default_factory=EventChannel, init=False)
|
|
265
266
|
|
|
266
267
|
def __getitem__[T](self, cls: type[T] | UnionType, /) -> Injectable[T]:
|
|
267
268
|
for report in analyze_types(cls):
|
|
268
|
-
for scoped_report in
|
|
269
|
+
for scoped_report in OrderedDict.fromkeys((report, report.no_args)):
|
|
269
270
|
try:
|
|
270
271
|
injectable, _ = self.__records[scoped_report]
|
|
271
272
|
except KeyError:
|
|
@@ -294,15 +295,16 @@ class Container(Broker):
|
|
|
294
295
|
mode: Mode | ModeStr,
|
|
295
296
|
) -> Self:
|
|
296
297
|
mode = Mode(mode)
|
|
298
|
+
record = Record(injectable, mode)
|
|
297
299
|
records = {
|
|
298
|
-
report:
|
|
300
|
+
report: record
|
|
299
301
|
for report in self.__prepare_reports_for_updating(classes, mode)
|
|
300
302
|
}
|
|
301
303
|
|
|
302
304
|
if records:
|
|
303
|
-
event =
|
|
305
|
+
event = LocatorDependenciesUpdated(self, records.keys(), mode)
|
|
304
306
|
|
|
305
|
-
with self.
|
|
307
|
+
with self.dispatch(event):
|
|
306
308
|
self.__records.update(records)
|
|
307
309
|
|
|
308
310
|
return self
|
|
@@ -318,7 +320,7 @@ class Container(Broker):
|
|
|
318
320
|
self.__channel.add_listener(listener)
|
|
319
321
|
return self
|
|
320
322
|
|
|
321
|
-
def
|
|
323
|
+
def dispatch(self, event: Event) -> ContextManager:
|
|
322
324
|
return self.__channel.dispatch(event)
|
|
323
325
|
|
|
324
326
|
def __prepare_reports_for_updating(
|
|
@@ -367,25 +369,25 @@ type InjectableFactory[T] = Callable[[Callable[..., T]], Injectable[T]]
|
|
|
367
369
|
|
|
368
370
|
|
|
369
371
|
@dataclass(eq=False, frozen=True, slots=True)
|
|
370
|
-
class Module(
|
|
371
|
-
name: str
|
|
372
|
+
class Module(Broker, EventListener):
|
|
373
|
+
name: str = field(default_factory=lambda: f"anonymous@{uuid4().hex[:7]}")
|
|
372
374
|
__channel: EventChannel = field(
|
|
373
375
|
default_factory=EventChannel,
|
|
374
376
|
init=False,
|
|
375
377
|
repr=False,
|
|
376
378
|
)
|
|
377
|
-
|
|
378
|
-
default_factory=
|
|
379
|
+
__locator: Locator = field(
|
|
380
|
+
default_factory=Locator,
|
|
379
381
|
init=False,
|
|
380
382
|
repr=False,
|
|
381
383
|
)
|
|
382
|
-
|
|
383
|
-
default_factory=
|
|
384
|
+
__loggers: list[Logger] = field(
|
|
385
|
+
default_factory=lambda: [getLogger(__name__)],
|
|
384
386
|
init=False,
|
|
385
387
|
repr=False,
|
|
386
388
|
)
|
|
387
|
-
|
|
388
|
-
default_factory=
|
|
389
|
+
__modules: OrderedDict[Module, None] = field(
|
|
390
|
+
default_factory=OrderedDict,
|
|
389
391
|
init=False,
|
|
390
392
|
repr=False,
|
|
391
393
|
)
|
|
@@ -393,7 +395,7 @@ class Module(EventListener, Broker):
|
|
|
393
395
|
__instances: ClassVar[dict[str, Module]] = {}
|
|
394
396
|
|
|
395
397
|
def __post_init__(self):
|
|
396
|
-
self.
|
|
398
|
+
self.__locator.add_listener(self)
|
|
397
399
|
|
|
398
400
|
def __getitem__[T](self, cls: type[T] | UnionType, /) -> Injectable[T]:
|
|
399
401
|
for broker in self.__brokers:
|
|
@@ -402,9 +404,6 @@ class Module(EventListener, Broker):
|
|
|
402
404
|
|
|
403
405
|
raise NoInjectable(cls)
|
|
404
406
|
|
|
405
|
-
def __setitem__[T](self, cls: type[T] | UnionType, injectable: Injectable[T], /):
|
|
406
|
-
self.update((cls,), injectable)
|
|
407
|
-
|
|
408
407
|
def __contains__(self, cls: type | UnionType, /) -> bool:
|
|
409
408
|
return any(cls in broker for broker in self.__brokers)
|
|
410
409
|
|
|
@@ -415,7 +414,7 @@ class Module(EventListener, Broker):
|
|
|
415
414
|
@property
|
|
416
415
|
def __brokers(self) -> Iterator[Broker]:
|
|
417
416
|
yield from tuple(self.__modules)
|
|
418
|
-
yield self.
|
|
417
|
+
yield self.__locator
|
|
419
418
|
|
|
420
419
|
def injectable[T](
|
|
421
420
|
self,
|
|
@@ -455,7 +454,7 @@ class Module(EventListener, Broker):
|
|
|
455
454
|
on: TypeInfo[T] = (),
|
|
456
455
|
*,
|
|
457
456
|
mode: Mode | ModeStr = Mode.get_default(),
|
|
458
|
-
) ->
|
|
457
|
+
) -> Self:
|
|
459
458
|
cls = type(instance)
|
|
460
459
|
self.injectable(
|
|
461
460
|
lambda: instance,
|
|
@@ -463,7 +462,7 @@ class Module(EventListener, Broker):
|
|
|
463
462
|
on=(cls, on),
|
|
464
463
|
mode=mode,
|
|
465
464
|
)
|
|
466
|
-
return
|
|
465
|
+
return self
|
|
467
466
|
|
|
468
467
|
def inject(
|
|
469
468
|
self,
|
|
@@ -517,7 +516,7 @@ class Module(EventListener, Broker):
|
|
|
517
516
|
injectable: Injectable[T],
|
|
518
517
|
mode: Mode | ModeStr = Mode.get_default(),
|
|
519
518
|
) -> Self:
|
|
520
|
-
self.
|
|
519
|
+
self.__locator.update(classes, injectable, mode)
|
|
521
520
|
return self
|
|
522
521
|
|
|
523
522
|
def init_modules(self, *modules: Module) -> Self:
|
|
@@ -544,7 +543,7 @@ class Module(EventListener, Broker):
|
|
|
544
543
|
priority = Priority(priority)
|
|
545
544
|
event = ModuleAdded(self, module, priority)
|
|
546
545
|
|
|
547
|
-
with self.
|
|
546
|
+
with self.dispatch(event):
|
|
548
547
|
self.__modules[module] = None
|
|
549
548
|
self.__move_module(module, priority)
|
|
550
549
|
module.add_listener(self)
|
|
@@ -555,7 +554,7 @@ class Module(EventListener, Broker):
|
|
|
555
554
|
event = ModuleRemoved(self, module)
|
|
556
555
|
|
|
557
556
|
with suppress(KeyError):
|
|
558
|
-
with self.
|
|
557
|
+
with self.dispatch(event):
|
|
559
558
|
self.__modules.pop(module)
|
|
560
559
|
module.remove_listener(self)
|
|
561
560
|
|
|
@@ -576,7 +575,7 @@ class Module(EventListener, Broker):
|
|
|
576
575
|
priority = Priority(priority)
|
|
577
576
|
event = ModulePriorityUpdated(self, module, priority)
|
|
578
577
|
|
|
579
|
-
with self.
|
|
578
|
+
with self.dispatch(event):
|
|
580
579
|
self.__move_module(module, priority)
|
|
581
580
|
|
|
582
581
|
return self
|
|
@@ -602,15 +601,20 @@ class Module(EventListener, Broker):
|
|
|
602
601
|
|
|
603
602
|
def on_event(self, event: Event, /) -> ContextManager:
|
|
604
603
|
self_event = ModuleEventProxy(self, event)
|
|
605
|
-
return self.
|
|
604
|
+
return self.dispatch(self_event)
|
|
606
605
|
|
|
607
606
|
@contextmanager
|
|
608
|
-
def
|
|
607
|
+
def dispatch(self, event: Event):
|
|
609
608
|
self.__check_locking()
|
|
610
609
|
|
|
611
610
|
with self.__channel.dispatch(event):
|
|
612
611
|
yield
|
|
613
|
-
|
|
612
|
+
message = str(event)
|
|
613
|
+
self.__debug(message)
|
|
614
|
+
|
|
615
|
+
def __debug(self, message: object):
|
|
616
|
+
for logger in tuple(self.__loggers):
|
|
617
|
+
logger.debug(message)
|
|
614
618
|
|
|
615
619
|
def __check_locking(self):
|
|
616
620
|
if self.is_locked:
|
|
@@ -626,10 +630,6 @@ class Module(EventListener, Broker):
|
|
|
626
630
|
f"`{module}` can't be found in the modules used by `{self}`."
|
|
627
631
|
) from exc
|
|
628
632
|
|
|
629
|
-
def __send_debug(self, message: object):
|
|
630
|
-
for logger in tuple(self.__loggers):
|
|
631
|
-
logger.debug(message)
|
|
632
|
-
|
|
633
633
|
@classmethod
|
|
634
634
|
def from_name(cls, name: str) -> Self:
|
|
635
635
|
with suppress(KeyError):
|
|
@@ -816,7 +816,7 @@ class InjectedFunction(EventListener):
|
|
|
816
816
|
@contextmanager
|
|
817
817
|
def _(self, event: ModuleEvent, /):
|
|
818
818
|
yield
|
|
819
|
-
self.update(event.
|
|
819
|
+
self.update(event.module)
|
|
820
820
|
|
|
821
821
|
def __setup(self):
|
|
822
822
|
queue = self.__setup_queue
|
{python_injection-0.9.4.post0 → python_injection-0.9.6}/injection/integrations/blacksheep.py
RENAMED
|
@@ -22,7 +22,6 @@ class InjectionServices(ContainerProtocol):
|
|
|
22
22
|
|
|
23
23
|
def register(self, obj_type: type | Any, *args, **kwargs):
|
|
24
24
|
self.__module.injectable(obj_type)
|
|
25
|
-
return self
|
|
26
25
|
|
|
27
26
|
def resolve[T](self, obj_type: type[T] | Any, *args, **kwargs) -> T:
|
|
28
27
|
return self.__module.find_instance(obj_type)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from contextlib import contextmanager
|
|
2
|
+
from functools import partial
|
|
3
|
+
|
|
4
|
+
from injection import Module, ModulePriority, mod
|
|
5
|
+
|
|
6
|
+
__all__ = (
|
|
7
|
+
"set_test_constant",
|
|
8
|
+
"should_be_test_injectable",
|
|
9
|
+
"test_injectable",
|
|
10
|
+
"test_singleton",
|
|
11
|
+
"use_test_injectables",
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
tmod = partial(mod, "testing")
|
|
16
|
+
|
|
17
|
+
set_test_constant = tmod().set_constant
|
|
18
|
+
should_be_test_injectable = tmod().should_be_injectable
|
|
19
|
+
test_injectable = tmod().injectable
|
|
20
|
+
test_singleton = tmod().singleton
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@contextmanager
|
|
24
|
+
def use_test_injectables(*, module: Module = None, test_module: Module = None):
|
|
25
|
+
module = module or mod()
|
|
26
|
+
test_module = test_module or tmod()
|
|
27
|
+
|
|
28
|
+
for m in (module, test_module):
|
|
29
|
+
m.unlock()
|
|
30
|
+
|
|
31
|
+
del m
|
|
32
|
+
|
|
33
|
+
with module.use_temporarily(test_module, priority=ModulePriority.HIGH):
|
|
34
|
+
yield
|
|
35
|
+
module.unlock()
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
from collections.abc import Callable
|
|
1
|
+
from collections.abc import Callable, Iterator
|
|
2
2
|
from importlib import import_module
|
|
3
3
|
from pkgutil import walk_packages
|
|
4
|
-
from types import ModuleType
|
|
4
|
+
from types import ModuleType as PythonModule
|
|
5
5
|
|
|
6
6
|
__all__ = ("load_package",)
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
def load_package(
|
|
9
|
+
def load_package(
|
|
10
|
+
package: PythonModule | str,
|
|
11
|
+
predicate: Callable[[str], bool] = lambda module_name: True,
|
|
12
|
+
) -> dict[str, PythonModule]:
|
|
10
13
|
"""
|
|
11
14
|
Function for importing all modules in a Python package.
|
|
12
15
|
Pass the `predicate` parameter if you want to filter the modules to be imported.
|
|
@@ -15,6 +18,13 @@ def load_package(package: ModuleType | str, predicate: Callable[[str], bool] = N
|
|
|
15
18
|
if isinstance(package, str):
|
|
16
19
|
package = import_module(package)
|
|
17
20
|
|
|
21
|
+
return dict(__iter_modules_from(package, predicate))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def __iter_modules_from(
|
|
25
|
+
package: PythonModule,
|
|
26
|
+
predicate: Callable[[str], bool],
|
|
27
|
+
) -> Iterator[tuple[str, PythonModule]]:
|
|
18
28
|
try:
|
|
19
29
|
path = package.__path__
|
|
20
30
|
except AttributeError as exc:
|
|
@@ -22,15 +32,10 @@ def load_package(package: ModuleType | str, predicate: Callable[[str], bool] = N
|
|
|
22
32
|
"Package has no `__path__` attribute, as it's probably a module."
|
|
23
33
|
) from exc
|
|
24
34
|
|
|
25
|
-
if predicate is None:
|
|
26
|
-
|
|
27
|
-
def predicate(_: str) -> bool:
|
|
28
|
-
return True
|
|
29
|
-
|
|
30
35
|
for info in walk_packages(path=path, prefix=f"{package.__name__}."):
|
|
31
36
|
name = info.name
|
|
32
37
|
|
|
33
38
|
if info.ispkg or not predicate(name):
|
|
34
39
|
continue
|
|
35
40
|
|
|
36
|
-
import_module(name)
|
|
41
|
+
yield name, import_module(name)
|
|
File without changes
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
from contextlib import contextmanager
|
|
2
|
-
from functools import partial
|
|
3
|
-
|
|
4
|
-
from injection import Module, ModulePriority, mod
|
|
5
|
-
|
|
6
|
-
__all__ = (
|
|
7
|
-
"set_test_constant",
|
|
8
|
-
"should_be_test_injectable",
|
|
9
|
-
"test_injectable",
|
|
10
|
-
"test_singleton",
|
|
11
|
-
"use_test_injectables",
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
testing_mod = partial(mod, "testing")
|
|
16
|
-
|
|
17
|
-
set_test_constant = testing_mod().set_constant
|
|
18
|
-
should_be_test_injectable = testing_mod().should_be_injectable
|
|
19
|
-
test_injectable = testing_mod().injectable
|
|
20
|
-
test_singleton = testing_mod().singleton
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@contextmanager
|
|
24
|
-
def use_test_injectables(*, on: Module = None, test_module: Module = None):
|
|
25
|
-
on = on or mod()
|
|
26
|
-
test_module = test_module or testing_mod()
|
|
27
|
-
|
|
28
|
-
for module in (on, test_module):
|
|
29
|
-
module.unlock()
|
|
30
|
-
|
|
31
|
-
del module
|
|
32
|
-
|
|
33
|
-
with on.use_temporarily(test_module, priority=ModulePriority.HIGH):
|
|
34
|
-
yield
|
|
35
|
-
on.unlock()
|
{python_injection-0.9.4.post0/injection/core → python_injection-0.9.6/injection/_core}/__init__.py
RENAMED
|
File without changes
|
{python_injection-0.9.4.post0/injection → python_injection-0.9.6/injection/_core}/common/__init__.py
RENAMED
|
File without changes
|
{python_injection-0.9.4.post0/injection → python_injection-0.9.6/injection/_core}/common/event.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|